given too little
I know why the following doesn't work: given $food { when Pizza | Lazagna { .eat } when .caloric_value $doctors_orders { warn no, no no } # ... } The expression in the second when clause is smart-matched against $food, not tested for truth like an if. So currently the right way to code this is something like DINER: given $food { when Pizza | Lazagna { .eat } if .caloric_value $doctors_orders { warn no, no no; leave DINER } # ... } (Or whatever the way to address labels is.) I'm a little bothered that this is consistent but (to me, at least) unintuitive. Testing methods on the topic is something people may want to do often: is there a way to hide away the control logic? I'm tempted to propose that when a .method is seen in the when expression, the whole thing should become a terminal if. Inconsistent but possibly what people want. -- Gaal Yahas [EMAIL PROTECTED] http://gaal.livejournal.com/
Re: given too little
HaloO, Gaal Yahas wrote: I know why the following doesn't work: given $food { when Pizza | Lazagna { .eat } when .caloric_value $doctors_orders { warn no, no no } # ... } The expression in the second when clause is smart-matched against $food, not tested for truth like an if. The smart match is hopefully *type* aware. In the above second case the match could be :( Item ~~ Code ) the Item is $food, the Code is the block { .caloric_value $doctors_orders }. So far so bad, you say?! But I think the type inferencer will type the Code as :(Item -- bool) and as such we could specify that a booleanizing, inline block just does what you expect. If the same should be the case for sub foo:( -- bool) {...} given $food { when foo {...} # call foo and enter if true is returned } I would like that. --
Re: given too little
On 11/10/05, Gaal Yahas [EMAIL PROTECTED] wrote: I'm a little bothered that this is consistent but (to me, at least) unintuitive. Testing methods on the topic is something people may want to do often: is there a way to hide away the control logic? I'm tempted to propose that when a .method is seen in the when expression, the whole thing should become a terminal if. Inconsistent but possibly what people want. That all looks good but you don't realy want it to be just if there is a .method in there. It would have to be more magical than that becuase i might want to do something else. given $num { when 5 { } when 5 { } when == 5 {} } I'm not sure that can be done in a whay that makes sense but I would settle for given $num { when $_ 5 { } when $_ 5 { } when $_ == 5 {} } I'm pretty sure i've heard this discussed but checking S04/Switch Statments doesn't make any mention of it. If it has been settled could we get some doc updates? -- -- __ Eric Hodges
Re: given too little
On Thu, Nov 10, 2005 at 07:23:15AM -0700, Eric wrote: I'm pretty sure i've heard this discussed but checking S04/Switch Statments doesn't make any mention of it. If it has been settled could we get some doc updates? I looked again more carefully at S04 and saw that Any ~~ Code$ and Any ~~ Code do in fact have definitions in the smartmatch table. Any Code$ scalar sub truth match if $x($_) Any Codesimple closure truth*match if $x() (ignoring $_) What is Code$ and Code? Closures accepting a single scalar and no arguments? If so then my and Eric's wishes are answered: when { $_ 5 } { ... } when { .caloric_value $doctors_orders } { ... } This isn't implemented in pugs yet, but I guess it can be once this is clarified. -- Gaal Yahas [EMAIL PROTECTED] http://gaal.livejournal.com/
Re: given too little
On Thu, Nov 10, 2005 at 10:11:50AM +0100, TSa wrote: : HaloO, : : Gaal Yahas wrote: : I know why the following doesn't work: : : given $food { : when Pizza | Lazagna { .eat } : when .caloric_value $doctors_orders { warn no, no no } : # ... : } : : The expression in the second when clause is smart-matched against $food, : not tested for truth like an if. : : The smart match is hopefully *type* aware. In the above second case : the match could be :( Item ~~ Code ) the Item is $food, the Code is the : block { .caloric_value $doctors_orders }. So far so bad, you say?! : But I think the type inferencer will type the Code as :(Item -- bool) : and as such we could specify that a booleanizing, inline block just : does what you expect. If the same should be the case for : :sub foo:( -- bool) {...} : :given $food :{ :when foo {...} # call foo and enter if true is returned :} : : I would like that. And, in fact, the original Apocalypse specified that behavior for operators that were known to return boolean. The problem is that there are objects that *can* return boolean that you want to nevertheless want to smartmatch against. So you want some way to restrict it to operations that can *only* return boolean, and only do delayed evaluation of those. But the phrase delayed evaluation says that the correct workaround is: given $food { when Pizza | Lazagna { .eat } when { .caloric_value $doctors_orders } { warn no, no no } # ... } But if we have a mandatory type inferencer underneath that is merely ignored when it's inconvenient, then we could probably automatically delay evaluation of the code. It's not much different from the problem of delete %foo{$bar} realizing that the last operation (returning the looked-up value from the hash) has to be delayed till after the value is deleted. In any event, you're right about the fact that it depends only on the booleanness of the return result, not on whether the expression consumes $_. A when true should always execute whether or not the topic is true or false. We'll need to train people that given $boolean { when true {...} when false {...} } needs to be rewritten as given $boolean { when .true {...} when .not {...} } Fortunately, we can know something is bogus when we see the when false. The question is, is it just semantically bogus or also syntactically bogus? The fact is that it can be syntactically bogus two different ways. I think this is a good argument for never importing the bool enum false true into the current scope as bare names. true() is a predicate, not a value, so it is syntactically bogus because it will try to eat the {...}. true and false aren't values in Perl. The names of the values are bool::true and bool::false, but the values of the values are 0 and 1. And the name of the values of the values is bit. (Shades of Lewis Carrol, but hey, it's before breakfast.) So false is not a valid name of a value in standard Perl 6! The actual values are just bit values. So another way to write the switch is: given $boolean { when 1 {...} when 0 {...} } Of course, they'll try to outsmart us and write: given $boolean { when bool::true {...} when bool::false {...} } which we can still recognize and carp about because the second case creates unreachable code. Of course, the best way to rewrite is probably just: if $boolean {...} else {...} The long and the short of it is that I think we can depend on the type inferencer here without the naïve user being aware of it, as long as we restrict the autodelay to apply only to things that can only return boolean officially. We mustn't apply it to things that just happen to be able to return boolean in boolean context, or things like when %foo can't work. Larry
Re: given too little
[EMAIL PROTECTED] wrote: If so then my and Eric's wishes are answered: when { $_ 5 } { ... } when { .caloric_value $doctors_orders } { ... } This isn't implemented in pugs yet, but I guess it can be once this is clarified. Actually when $_ 5 { ... } when .caloric_value $doctors_orders { ... } should also work because ~~ match table states that Anything ~~ boolean returns the boolean on the right. Miro
Re: given too little
snarky But if we have a mandatory type inferencer underneath that is merely ignored when it's inconvenient, then we could probably automatically delay evaluation of the code. . . . I'm not so certain that ignoring the mandatory type inferencer is a good idea, even when it's inconvenient. I don't know about you, but my son keeps trying to get me to let him ignore his homework when it's inconvenient (ie, the gamecube calls) and I don't let him. So, just because the gamecube is calling, we should probably listen to the mandatory type inferencer. /snarky