skippable arguments in for loops
hcchien raised the following question on #perl6[1]: If I want to loop through a nine-element array three elements at a time, I do my @a = 1..9; for @a - $x, $y, $z { say $x } But what if I don't care about the elements 1,4,7? Would the following be a sane syntax? my @a = 1..9; for @a - undef, $x, $y { say $x } FWIW, to me it looks fairly intuitive. undef here means don't alias the element, just throw it away... gaal joked about using _ instead of undef. :) If the appropriate authority (p6l or @larry) likes this idea, I can add a few tests to that end in the pugs tree. [1] http://colabti.de/irclogger/irclogger_log/perl6?date=2005-09-22,Thusel=182#l318
Re: skippable arguments in for loops
On 9/22/05, Carl Mäsak [EMAIL PROTECTED] wrote: FWIW, to me it looks fairly intuitive. undef here means don't alias the element, just throw it away... gaal joked about using _ instead of undef. :) Joked? Every other language that has pattern matching signatures that I know of (that is, ML family and Prolog) uses _. Why should we break that? IMO, it's immediately obvious what it means. Something tells me that in signature unification, undef means this has to be undef, much like 1 means this has to be 1. Luke
Re: Stringification, numification, and booleanification of pairs
Mark A. Biggar skribis 2005-09-21 17:44 (-0700): Now for a related question: is it intended that ~$x and +$n be the same as $x.as(Str) and $x.as(Num)? How locked in stone would this be, I.e., ~ and + are macros that give the .as() form? If I read everything correctly, this is the case. This is also why I'm not sure stringification is done by a prefix:~ method -- it's probably done by something that does coercion in general, but I have no idea what the syntax for that would be. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Stringification, numification, and booleanification of pairs
Stuart Cook skribis 2005-09-22 10:39 (+1000): If there's no (single) obvious interpretation of turn a value into a number for a particular type, then don't struggle to come up with a non-obvious one--I say just leave it undefined, or have it fail(), or whatever. Leaving it undefined is wrong whenever it can be avoided. Iff it has no meaningful value, then we should try and make it meaningful in the scope of the other two. ~$pair, because it has a \t in it, will always be true booleanly, and so will ?$pair off course. Because of this, I think that ?+$pair should also be true. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Sort of do it once feature request...
On Wed, 21 Sep 2005, Joshua Gatcomb wrote: I have mocked up an example of how you could do this in p5 with some ugly looking code: You may be interested to know that this has had an echo at http://www.perlmonks.org/index.pl?node_id=493826 mostly misunderstood in the replies, IMHO. Basically the idea is that not unexpectedly if you want a workaround TIMTWOWTDI already in Perl5. But what is conceptually interesting would be the possibility, In L~R's much better phrasing than mine, of modifying the optree or (P6's equivalent) as the code is running. The only ad-hoc solution given there that is really along these lines is Diotalevi's one at http://www.perlmonks.org/index.pl?node_id=493947 which -not completely undexpectedly either- made my head hurt... ;-) Michele -- Democracy is two wolves and a sheep deciding what to eat for lunch. Liberty is a well-armed sheep contesting the vote.
Re: Sort of do it once feature request...
On Wed, 21 Sep 2005, Joshua Gatcomb wrote: Cheers, Joshua Gatcomb a.k.a. Limbic~Region Oops... I hadn't noticed that you ARE L~R... Michele -- Your ideas about Cantorian set theory being awful suffer from the serious defect of having no mathematical content. - Torkel Franzen in sci.math, Re: Die Cantor Die
Re: Sort of do it once feature request...
Michele Dondi wrote: On Wed, 21 Sep 2005, Joshua Gatcomb wrote: Cheers, Joshua Gatcomb a.k.a. Limbic~Region Oops... I hadn't noticed that you ARE L~R... In the tradition of i18n, etc., I had assumed that L~R was shorthand for Luke Palmer. You may want to keep up the old tradition of defining your acronyms once. :) =Austin
Re: Stringification, numification, and booleanification of pairs
Eric wrote: Since you wouldn't expect an object to stringify or numify... You wouldn't??! I certainly would. Object references already stringify/numerify/boolify in Perl 5. Unfortunately, they do so with problematic default behaviours, which is why Cuse overload allows you to overload q{}, q{0+} and q{bool} (a practice I strongly recommend in Perl Best Practices). Finding useful and predictable defaults for the basic coercions on all built-in types is a vital part of the design of Perl 6. Damian
Re: conditional wrapper blocks
Excuse my noobness, I really have no idea about any of the inner workings, but am just concerned with a more elegant syntax of doing it. How about something like: if ($condition) { pre; always { # maybe uncond instead of always, or both -- always could # mean 'ignore all conditions' and uncond could mean # 'ignore the current block's condition mid_section; } post; } Or maybe: if ($condition) { pre; } is continued; mid_section; continue { post; } A flaw I see in the latter though is that you could not use the is continued trait inside of mid_section without confusing the parser. On 9/20/05, Yuval Kogman [EMAIL PROTECTED] wrote: Today on #perl6 I complained about the fact that this is always inelegant: if ($condition) { pre } unconditional midsection; if ($condition) { post } Either you put the condition in a boolean var and check it twice, or you use a higher order function and give it three blocks, and the conditional. But no matter how much we try, it always feels too manual. I asked for some ideas and together with Aankhen we converged on the following syntax: if ($condition) { pre; } uncond { middle; } cond { post; } s/uncond/pause regardless.pick/e; s/cond/resume again.pick/e; Some restrictions: The block structure must always be ternary - for other cases we already have enough control flow. The if is not the same if that can cuddle with else - it's either or. Does anybody have any comments, or synonyms for the control structure naming? BTW, I expect readability to be optimal with 1-2 lines of pre/post, and 1-5 lines of middle. Any observations? -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me groks YAML like the grasshopper: neeyah!!
Re: Stringification, numification, and booleanification of pairs
Ingo Blechschmidt asked: my $pair = (a = 42); say ~$pair; # a\t42? a\t42\n? a 42? Not yet specified but I believe it should be 42 (i.e. stringifies to value). Note that S02 does specify that pairs *interpolate* to key-tab-val-newline, so you can still get a\t42\n by writing $pair instead. say +$pair; # 0 (pairs aren't numbers)? # 42? # 0 (a is not a number)? # 0 (~$pair can't be used as a number)? Not yet specified, but I believe it should be 42 (i.e. numerifies to the value) say ?$pair; # true (because 42 is true)? # true (because pairs are always true)? Not yet specified but I believe it should be true because 42 is true In summary: when applied to a pair, the value-coercing operators should coerce the pair's value. Damian
Re: conditional wrapper blocks
On 22/09/05, Shane Calimlim [EMAIL PROTECTED] wrote: How about something like: if ($condition) { pre; always { # maybe uncond instead of always, or both -- always could # mean 'ignore all conditions' and uncond could mean # 'ignore the current block's condition mid_section; } post; } That's quite elegant, but overloading `if` like that is completely insane and unpredictable, because you can no longer assume that all the code inside is tied to the conditional. A more maintenance-programmer-friendly version might look more like this: # doesn't really matter what it's called, so long as it's not `if` sometimes $condition { pre; ALWAYS { body; } # caps help too post; } Which is exactly the same, except that by using a different keyword, we're telling the reader that the rules of `if` don't apply here--there's going to be some unconditional code in the conditional block. This way, `if` always means 'if', rather than 'if, except on a Tuesday'. Mind you, this sort of solution is probably implementable purely as a module, so if people don't think it's useful enough to go in core then those who do need it won't really miss out. Stuart
Re: skippable arguments in for loops
On Sep 22, 2005, at 3:08 AM, Luke Palmer wrote: On 9/22/05, Carl Mäsak [EMAIL PROTECTED] wrote: FWIW, to me it looks fairly intuitive. undef here means don't alias the element, just throw it away... gaal joked about using _ instead of undef. :) Joked? Every other language that has pattern matching signatures that I know of (that is, ML family and Prolog) uses _. Why should we break that? Because the way Carl has it is more consistent with Perl 5, from whence most of our users will be coming? Because 'undef' has a nice visual weight, while '_' can all too easily disappear? Because throwing away values is something that we probably shouldn't make too easy? IMO, it's immediately obvious what it means. Not IMO. _ in this context is content-free for me. But, whatever. I'm sure it will end up being _ if this feature is added. --Dks
pause/cont
Both recently discussed situations with blocks can be solved by introducing a way to leave the current block and resume it elsewhere. I'll demonstrate it assuming there is a pause/cont combination. For these examples to work, pause needs to take effect after the entire statement it's in is evaluated. Also, the original block no longer plays any role when it is continued later. The cont block is executed only if the previous block paused. Skipping the check after it matched the first time: my macro loopbody { ... } for (...) { pause, next if condition; loopbody; } cont { loopbody; } Having an unconditional midsection: if (condition) { pre; pause; } midsection; cont { post; } Many combinations are thinkable, and this probably needs some support for labels in order to work in more complex code: FOO: ... { pause; } BAR: ... { ... pause if condition; ... } FOO: cont { ... } BAR: cont { ... } pause always pauses the innermost pauseable block, it doesn't take an argument. This is because I can think of no good way or reason to make this work: FOO: ... { BAR: ... { pause FOO; } } Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Stringification, numification, and booleanification of pairs
Damian Conway skribis 2005-09-22 8:20 (+1000): Note that S02 does specify that pairs *interpolate* to key-tab-val-newline, so you can still get a\t42\n by writing $pair instead. I think separating stringification and interpolation leads to unpredictability, and is a very bad thing. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: skippable arguments in for loops
HaloO, Carl Mäsak wrote: But what if I don't care about the elements 1,4,7? Would the following be a sane syntax? my @a = 1..9; for @a - undef, $x, $y { say $x } I think that, if the concept of lazy list evaluation is running deep in Perl 6 than the obvious solution to me is: for @a - $x, $y, $z { say $y } and $x and $z are never evaluated. Other ways that come to my mind are: for @a - $,$y,$ { say $y } for @a - (,$y,) { say $y } for @a - ,$y, { say $y } # same? unparseable? All the above depend on really lazy lists that somehow hook onto what they are susposed to contain in a very lightweight, shallow fashion. And it must be possible to iterate lists in several modes. Here this would be (:skip,:fetch,:skip) or whatever the syntax could be. Or in a non-native-attempt-to-sound-funny-with-deep-philosophical-meaning way I would say: If Carl doesn't want to care about the first and last item of the three element list, he should do so! And Perl6 cares for his carelessness not beeing punished with a performance penalty. :) Here's a lengthy version that also comes to my mind: for @a - @three is shape(Void,Item,Void) { say @three[1] } if this is not how the shape trait works s/shape/tuple/. Actually, it could as well just be @three:(Void,Item,Void). Hmm, or with typing the topic: for @a - $_:(Void,Item,Void) { say } -- $TSa.greeting := HaloO; # mind the echo!
Re: pause/cont
HaloO, Juerd wrote: Both recently discussed situations with blocks can be solved by introducing a way to leave the current block and resume it elsewhere. With first class code types, _ and label beeing bound lexically to the current instance of the sub class, the set of current control flow procedures (next, leave, goto, ...) are sufficient. Skipping the check after it matched the first time: my macro loopbody { ... } for (...) { pause, next if condition; loopbody; } cont { loopbody; } Why not simply: for (...) { if condition { # or OUTER::_ ? _ = loopbody; # or (re)binding with := ? next if first_true_skips_loopbody_once; } loopbody: ... } Only drawback is that assignment to _ plays in the same league of bad programming practices as goto. OTOH, I expect the optimizer to pull exactly the above stunt given enough type information about the condition. And I hope we all agree, that goto behind the scenes is not a bad thing :) -- $TSa.greeting := HaloO; # mind the echo!
Re: skippable arguments in for loops
On Thu, Sep 22, 2005 at 07:23:06 -0400, David Storrs wrote: On Sep 22, 2005, at 3:08 AM, Luke Palmer wrote: On 9/22/05, Carl Mäsak [EMAIL PROTECTED] wrote: FWIW, to me it looks fairly intuitive. undef here means don't alias the element, just throw it away... gaal joked about using _ instead of undef. :) Joked? Every other language that has pattern matching signatures that I know of (that is, ML family and Prolog) uses _. Why should we break that? Because the way Carl has it is more consistent with Perl 5, from whence most of our users will be coming? But not with MMD pattern matching stuff, since you are now allowed to declare that a body behaves a certain way when receiving certain values.. For example multi factorial (0) { 1 } multi factorial ($n) { $n * factorial($n -1) } I find this approach much more intuitive than special casing the behavior of certain values when they are used inside prototypes. Because 'undef' has a nice visual weight, while '_' can all too easily disappear? sub foo ($x, _, $y) { # i feel this has a big enough weigh sub foo ($x, __, $y) { # even better Because throwing away values is something that we probably shouldn't make too easy? It should be made very easy - this encourages reuse of calling code, not only callee code. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: *shu*rik*en*sh*u*rik*en*s*hur*i*ke*n*: neeyah pgp4rntfFfYIk.pgp Description: PGP signature
Re: ~ and + vs. generic eq
On Wed, Sep 21, 2005 at 13:53:20 +0200, TSa wrote: HaloO Yuval, you wrote: On Mon, Aug 29, 2005 at 14:07:51 +0200, TSa wrote: role Object does Compare[Object, =:=] role Numdoes Compare[Num, ==] role Strdoes Compare[Str, eq] What is the implication of from the perspective of the person using Object, Num and Str? Do they have one unified comparator? No, the role installs homogenious targets into the generic binary-MMD comparator which I think is called eqv. Err, why? We already have that with regular MMD semantics. role Num { multi *infix:eqv ($x:, Num $y) { $x == $y } } That's an interesting question which is related to my retention to metric MMD. We must distinguish homogenous from heterogenous comparisons. My role Compare from above ensures that the comparor can be deduced from the unique (super)type of the two values to be compared. As such the comparator indirectly is class or type specific. The heterogenous cases however have to fallback to real MMD. Now metric MMD could spoils this approach by picking the wrong eqv target even though a proper homogenous target were available! Then MMD must be fixed, as I've argued several times before. MMD cannot work unless it does what almost everyone means and complains when there is no obvious way. What you're describing is a problem that a broken (by this definition) MMD system can provide. I'm not sure if I get you right, but I think we agree that there should be only one comparer for a certain type/class. Everything else is nonsense. I mean apples should know how to eqv to other apples and oranges with oranges. MMD enters the picture only if you want to compare apples with oranges. By color, by weight, as fruits in general, etc. Comparing apples with oranges should do two equivalent MMD lookups on coercion, one of apples to oranges, the other of oranges to apples (unless there is an MMD compare between apples and oranges already), and if they are equivalent then there is an error. It seems that the Code type is still some kind of second class citizen in Perl6 because you can't nicely apply prefix ops to pending invocations without some help from the meta categories. And I'm unsure if $x (+eqv)() $y works even when prefix:+:(Comparor) exists and returns a numeric Comparor. But named params next to the operator could work I think it should even without the parens... isn't the sigil enough to make it clear? is just like $ in this respect -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me tips over a cow: neeyah!! pgpwtz063b7N7.pgp Description: PGP signature
Re: Stringification, numification, and booleanification of pairs
Yuval~ On 9/22/05, Yuval Kogman [EMAIL PROTECTED] wrote: On Thu, Sep 22, 2005 at 08:20:42 +1000, Damian Conway wrote: Ingo Blechschmidt asked: my $pair = (a = 42); say ~$pair; # a\t42? a\t42\n? a 42? Not yet specified but I believe it should be 42 (i.e. stringifies to value). Note that S02 does specify that pairs *interpolate* to key-tab-val-newline, so you can still get a\t42\n by writing $pair instead. Can we override circumfix: ? Seriously though, this is too much dichotomy between correctness and ease of use. A pair is not it's value, it is a pair, and should be consistently handled as such when e.g. stringifying. The reasons for this claim are: * Coercion to a string creates something interpolatable. Introducing another type or context or metaphor for string handling is counter intuitive and surprising. * We have powerful facilities for interpolation and stringification that don't have to be hidden behind operator overloading: this is my special pair: $pair; otherwise: $pair.key - $pair.value; my multi prefix:~ (Pair $p) { key: $p.key, value: $key.value; } not like the first interpolation: $pair; $pair.as(...); These examples are flexible, explicit and stable in their behavior. They are good enough as they are and don't need to be improved by adding flexibility in something that is almost a special case. * This adds complexity without much benefit. It heaps up the core with a special case that people will have to look out for later, and it hinders the usability of higher order functions by making it harder for them to accept the stringiciation operator, for instance. This lessens Perl 6 stability and cleanliness into something resembling Perl 5 with more builtin data types and operations Well said! I completely agree that string interpolation should be handled exactly the same as stringification. I would like C (foo is $foo of course) eq (foo is ~ $foo ~ of course) at all times. Matt -- Computer Science is merely the post-Turing Decline of Formal Systems Theory. -Stan Kelly-Bootle, The Devil's DP Dictionary
Re: ~ and + vs. generic eq
HaloO, Yuval Kogman wrote: No, the role installs homogenious targets into the generic binary-MMD comparator which I think is called eqv. Err, why? We already have that with regular MMD semantics. role Num { multi *infix:eqv ($x:, Num $y) { $x == $y } } What you mean is double dispatch, cascading, delegation or what ever. I had the two juxtapositions of $x eqv $y versus $x ee $y # or even $x $ee $y when $ee is a coderef in mind. In the latter case you a get a complicated mix of parsing that in the first place and generating code for a three invocant anonymous dispatch or whatever it is. I mean with *no* :eqv in the definition. multi *infix: ($lhs, Compare comp, $rhs) {...} BTW, is that now valid syntax? I thought there is no sigil but one of the two keywords sub or method: multi sub *infix: ($lhs, Compare comp, $rhs) {...} I'm not sure if I get you right, but I think we agree that there should be only one comparer for a certain type/class. Everything else is nonsense. I mean apples should know how to eqv to other apples and oranges with oranges. MMD enters the picture only if you want to compare apples with oranges. By color, by weight, as fruits in general, etc. Comparing apples with oranges should do two equivalent MMD lookups on coercion, one of apples to oranges, the other of oranges to apples (unless there is an MMD compare between apples and oranges already), and if they are equivalent then there is an error. Sorry, I don't understand what an MMD lookup on coercion should be? Do you think of eqv as a simple two parameter sub that *single* dispatches first on the $one then on the $other arg with the respective non-invocant as parameter and then xor's and negates the results for consistency? sub eqv ($one, $other -- Bit) { # .compare_to:(Object: Object -- Bit) note the single invocant! return !($one.compare_to($other) ^^ $other.compare_to($one)); } Apart from the fact that somehow two types are involved I don't see MMD in that. To me a method's name is a concept that is realized differently for different types of arguments. At hand we are discussion the well known problem of generic equality versus more specific equalities of strings, numbers or objects/refs. And now Perl6 addresses the ternary problem of remaining generic with respect of the infix operator name or precise concept such that it ends up comparing numbers numerically, strings textually, colors colorfully plus all the mixed cases while at the same time keeping compatible to Perl5's operator semantics. The first problem you face in this quest is naming the beast---and the three letters 'eqv' aren't it to me because variable stuff in Perl is expressed with sigils. I'm not sure if the above discribed extreme case if $x $ee $y { say Hurray, we have equality } has a chance not to end up with a 'two terms in a row' parse error. And I'm unsure if $x (+eqv)() $y works even when prefix:+:(Comparor) exists and returns a numeric Comparor. But named params next to the operator could work I think it should even without the parens... isn't the sigil enough to make it clear? is just like $ in this respect Which parens? The ones around (+eqv) or the trailing call op ()? Note that the precedence of postfix () is higher than prefix +. And +eqv might simply mean a numerified coderef and not a dispatched call of prefix + where the returned value is type checked at runtime for infix operator type compatibility. And then after this successfull type check this returned operator is MM dispatched on ($x,$y). And I can increase the challenge level easily to my $o := eqv; # or with \eqv ? if $x +$o $y {...} # parseable without type info about $o? Just to mention one possible alternate interpretation, imagine prefix + on $o returning a postfix op that given $x returns yet another prefix op that given $y returns a value that is booleanized by the if which then executes or skips the trailing block correspondingly. That is with explicit parens we would get: if (($x(+$o))($y)) {...} # parseable? That is like parsing the sentence: Time flies like an arrow, and asking yourself: What are time flies and why do they like arrows? If the above works, I guess variability against the if will not parse? sub foo ($i, $x, $y, $z) { $i $x $y $z { say something got us here } } Or does it? Actually sigiling i and y with instead of $ reduces the possibilities a lot and might even imply to associate the trailing block literal with i and default y to an infix op. Thus a call foo( *if, 42, infix:==, 42); will indeed say something got us here---that something beeing the numeric equality of 42 and 42 :) With some parsing magic thrown in, I would still propose to make junctions in the style of the above foo such that if any( $points @highscores ) { say a new entry! } means what auto-threaded ($points == any(@highscores)) means now, but makes junctions a Code subtype
Re: pause/cont
TSa skribis 2005-09-22 14:55 (+0200): Why not simply: loopbody: Because I don't like non-block labels. It reminds me too much of bad-goto. This, and I fear this would have bad performance. That's based on nothing, though. And I hope we all agree, that goto behind the scenes is not a bad thing :) I still consider sub calls, loops, conditions, etc, to be controlled forms of goto. They're good-goto. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html