Re: Smart match isn't on Bool
On Tue, Aug 3, 2010 at 3:30 PM, David Green wrote: > On 2010-08-02, at 2:35 pm, TSa (Thomas Sandlaß) wrote: > > On Monday, 2. August 2010 20:02:40 Mark J. Reed wrote: > >> [...] it's at least surprising. I'd expect (anything ~~ True) to be > synonymous with ?(anything) > > Note also that ($anything ~~ foo()) just throws away $anything. > > No; only if foo() returns a Bool. How do you define that? Any type which is compatible with Bool? What happens if, in a bold and innovative stroke, some future revision of Perl 6 decides that Type is compatible with Bool? Who wins in "$a ~~ Int"? If my function returns "1 but False" will "1 ~~ func()" match? I guess what I'm really asking, here, is do we use the first rule in the smart-match table from S03 or is there some other priority system at work? Do we consider only exact type matches and shunt everything else into Any or do we call X.does()? On a related note, I re-read S03 a bit and I've come to the conclusion that the ~~ op (not the implicit smart match of given/when) should produce a warning when its RHS is Bool (assuming we resolve what "is Bool" means, above). There's just no good reason to confuse the issue that way, and the Bool behavior of smart-matching is really just there to support given/when. Beyond that, once we start getting into deeper warnings on semantic mistakes, it's likely that it will make sense to warn at run-time if when is asked to work on a boolean value which isn't the result of some form of comparison. Again, it's just confusing for no benefit. If we add the above warnings and the ones already listed in S03, then I think I'll be fine with it. I understand why we want "when .foo == .bar" and I can't think of a good way to replace it, so I'll buy that it's worth making so many other obvious uses deprecated. -- Aaron Sherman Email or GTalk: a...@ajs.com http://www.ajs.com/~ajs
Re: Smart match isn't on Bool
On the one hand, I've had 25 years of being annoyed about the idiom if foo() == True ... So I'd be delighted if P6 were to treat that case as a fatal compile-time error. And given that "==" are "!=" are just funny ways of writing "!xor" and "xor", that prohibition could reasonably be extended to all statically-typed expressions (not just constants), with the error message suggesting the use of "!xor" or "xor" instead. On the other hand it feels it'd be wrong if foo() ~~ bar() simply ignored the value of one of its operands based on the type of the other. Overall I'd rather see a solution that factors out the implicit "last" from the implicit "$_ ~~". My feeling is that "if" and "when" should be for the implicit "last", since they're all alphabetic tokens; then it's just a case of deciding how to spell the contextualizer. The most obvious would be if == VALUE-TO-MATCH {...} if ~~ VALUE-TO-MATCH {...} when == VALUE-TO-MATCH {...} when ~~ VALUE-TO-MATCH {...} however I'm not sure if that conflicts with any prefix:<~~> or prefix:<==>, and it also conflicts with Huffmanizing the implicit match to something shorter than the explicit comparison. One possibility is to make all options explicit: if= VALUE-TO-MATCH{...} # no implicit last if? BOOLEAN-EXPRESSION{...} if~ VALUE-TO-SMARTMATCH {...} when= VALUE-TO-MATCH {...} # implicit last when? BOOLEAN-EXPRESSION {...} when~ VALUE-TO-SMARTMATCH {...} and then make bald "if" and "when" be DWIMmy shorthand. Oh, and then "A ~~ B" just works like "?! (A) xor B", if B is a Bool. -Martin PS: I also considered some other possibilities, but I don't like them as much: if -> VALUE-TO-MATCH {...} when -> VALUE-TO-MATCH {...} -> if VALUE-TO-MATCH {...} -> when VALUE-TO-MATCH {...} .if VALUE-TO-MATCH {...} .when VALUE-TO-MATCH {...} ==> if VALUE-TO-MATCH {...} ==> when VALUE-TO-MATCH {...}
Re: Smart match isn't on Bool
On 2010-08-02, at 2:35 pm, TSa (Thomas Sandlaß) wrote: > On Monday, 2. August 2010 20:02:40 Mark J. Reed wrote: >> [...] it's at least surprising. I'd expect (anything ~~ True) to be >> synonymous with ?(anything) > Note also that ($anything ~~ foo()) just throws away $anything. No; only if foo() returns a Bool. Do check the section on Smart-Matching in S03 and Switch Statements in S04; the specced behaviour isn't just a mistake. There are only two cases where ~~ ignores the LHS: one is a block that takes no args. A block that takes one arg runs foo($_) (and of course if it takes more args, that's an error), but if the block can't take any args, how would you apply $_ anyway? If you want to compare $_ against its result, then you should call the block instead of using the Callable code object directly. > Could someone please give a rational for the interspersing technique > given $anything { when $one {...} when two() {...} when $three {...} } > where two() returning a true value prevents the case $three. That's the other case that ignores $_: not merely returning a "true" value, but a Bool (whether that Bool is true or false). Trying to match a literal True or False will warn you, so even if you're surprised by it, you won't be caught unaware. If that's what you really want to do, say ?* or !* (which even happens to be shorter than 'True' or 'False'!). The rationale for ignoring the topic with a non-literal Bool is that "when 3<4" will tempt people to read that like "if 3<4". (Human beings don't interpret context rigidly enough for the Principle of Least Surprise to be consistent!) Saying "when /foo/" or "when bigger-than(4)" obviously call for something to compare against, i.e. the topic, but "3<4" or "foo() < $bar" *look* like complete conditionals. So people will get it wrong occasionally no matter which way it's specced. However, it's arguably more useful to accept conditions in 'when' without comparing the result to $_ because that is surely the more common case. If you really want something like "?$_ == (foo given $anything { when $one {...} if two() {...} else { when $three {...} } > } > still smart match $anything with $three? Or is the topic the return value of > two() at that point? No, if two() returns false, then the 'else' is executed with the original topic. (Well, unless two() sneakily changed its parent $_, which, being Perl, is possible.) Now it seems Rakudo breaks out of the 'else' block when $three is true, but then continues with the rest of the 'given' block — I think that's a bug, because it ought to break out of the scope that took $_ as a param, i.e. it should break directly out of the 'given'. > I would opt for a regularization of the smart match table. First of all the > generic scalar rule should coerce the LHS to the type of the RHS and then > use === on them. And that's close to what it does, except when the RHS is something "indeterminate" like a regex or a range or a type. The Any-Any case just does $_ === $X, which instead could arguably cast $_ to the type of $X first. That might be quite useful, especially if there's a way to tell 'when' to use another operator (like plain ===) when you need it. Apart from that, the Bool cases have been optimised for ordinary use in typical given/when blocks (as opposed to staring at the smart-match table and saying, Why isn't it more consistent??). They are more obviously exceptional used directly with ~~, but also less likely to occur (although to some extent this does rely on having a habit of using ? or == to check boolean conditionals). Despite that, it still rubs me the wrong way a little bit. (I guess it's like a picture hanging crooked on the wall — it's not actually hurting anything, but once you notice it, it's gonna bug you.) And there are legitimate, if less common, reasons to expect the more consistent behaviour: checking for 'when True' as a catch-all near the end of a series of 'when's is not unreasonable. And what I said above about using "if" for Bools because there are only two possibilities isn't quite true — since this is Perl, there are at least four useful values a Bool can have: true, false, undef, or Whatever. It wouldn't be unnatural to reach for 'when' if you need to distinguish those. I did like "whenever" because it seems to fit well psychologically. (Your psyche may vary.) But now that I've started thinking of the two issues here separately (i.e., breaking out of a block vs a shortcut for $_~~), I'm less inclined to make a special case just for "when". It really would be useful to have a $_~~-shortcut that worked with "if", or other places. My first thought was separating the -ever somehow, so that you could say "when ever(3<4)" or "if ever (3<4)"; but that means most ordinary 'if's would have to be written 'if ever...' which is no good. (Except perhaps for Perl poetry.) Using "if:" or "when:" with the colon to ind
Re: Smart match isn't on Bool
HaloO, On Monday, 2. August 2010 20:02:40 Mark J. Reed wrote: > On Sun, Aug 1, 2010 at 6:02 PM, Jonathan Worthington wrote: > > No, given-when is smart-matching. The RHS of a smart-match decides what > > happens. If you do True ~~ 1 then that's 1.ACCEPTS(True) which is going > > to do +True and thus match. > > OK, but what about 0 ~~ True? That's what started this thread, > extricated from the complicating trappings of given/when. Right now, > (anything ~~ True) is true, and IMHO that's a misfeature; it's at > least surprising. I'd expect (anything ~~ True) to be synonymous with > ?(anything): true only if the LHS boolifies to true. By the same > token, (anything ~~ False) would be synonymous with !?(anything). Note also that ($anything ~~ foo()) just throws away $anything. I would opt for a regularization of the smart match table. First of all the generic scalar rule should coerce the LHS to the type of the RHS and then use === on them. This is how the Any ~~ Set case is specced. The cases Stringy and Numeric fall out naturally from this definition. The Bool case should become a special case just like Stringy and Numeric. The auto-invocation of Callable is a good thing but the fact that the return value is not subject to the generic scalar case is a misfeature. That is we loose: given 42 { when foo() {...} when bar() {...} when baz() {...} } which could mean to execute that block whose controlling sub complies with the given and not the one that returns True first. Note that this style is particularly usefull with given True. But then we sort of have the coercing the wrong way around because the idea is to check the return value in boolean context not coercing the True to whatever the type of the return value is. BTW, how is the case with a unary sub written? Could someone please give a rational for the interspersing technique given $anything { when $one {...} when two() {...} when $three {...} } where two() returning a true value prevents the case $three. And if it is considered usefull I support the whenever proposal because different things should look different. BTW, would given $anything { when $one {...} if two() {...} else { when $three {...} } } still smart match $anything with $three? Or is the topic the return value of two() at that point? Regards TSa -- "The unavoidable price of reliability is simplicity" -- C.A.R. Hoare "Simplicity does not precede complexity, but follows it." -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Smart match isn't on Bool
On Mon, Aug 2, 2010 at 2:02 PM, Mark J. Reed wrote: > On Sun, Aug 1, 2010 at 6:02 PM, Jonathan Worthington > wrote: >> No, given-when is smart-matching. The RHS of a smart-match decides what >> happens. If you do True ~~ 1 then that's 1.ACCEPTS(True) which is going to >> do +True and thus match. > > OK, but what about 0 ~~ True? That's what started this thread, > extricated from the complicating trappings of given/when. Right now, > (anything ~~ True) is true, and IMHO that's a misfeature; it's at > least surprising. I'd expect (anything ~~ True) to be synonymous with > ?(anything): true only if the LHS boolifies to true. By the same > token, (anything ~~ False) would be synonymous with !?(anything). Again, sorry for starting a long thread (I seem to do that, and I swear I'm not trying... just pointing out the surprises I run into as I try to code). I want to stress that what you've said above is kind of moot: the spec says that ~~True gets a parser warning, so we can consider that deprecated. The only usage we're supporting, here, is a Bool value stored in a variable or otherwise generated. I would argue that that's even worse. For example: my Bool $trash-status = take-out-the-trash(); ... some time later ... my Bool $dishes-status = wash-the-dishes(); if !$dishes-status && $dishes-status ~~ $trash-status { say "No chores this week!"; } Of course, that's a bug, but imagine the poor maintenance programmer that tries to figure out what's going on. I feel for him/her. The only advantage he/she will have is that this is likely to be so common an error that they'll quickly learn to look for it first when smart-matching is involved :-/ -- Aaron Sherman Email or GTalk: a...@ajs.com http://www.ajs.com/~ajs
Re: Smart match isn't on Bool
On Sun, Aug 1, 2010 at 6:02 PM, Jonathan Worthington wrote: > No, given-when is smart-matching. The RHS of a smart-match decides what > happens. If you do True ~~ 1 then that's 1.ACCEPTS(True) which is going to > do +True and thus match. OK, but what about 0 ~~ True? That's what started this thread, extricated from the complicating trappings of given/when. Right now, (anything ~~ True) is true, and IMHO that's a misfeature; it's at least surprising. I'd expect (anything ~~ True) to be synonymous with ?(anything): true only if the LHS boolifies to true. By the same token, (anything ~~ False) would be synonymous with !?(anything). I don't think the capability to use an arbitrary block/sub/method/boolean as a "when" condition should trump the intuitiveness of smartmatching. Instead of overloading the smartmatch, I think we need a different way of specifying a condition that isn't meant to be compared to the topic, and so doesn't invoke smartmatching at all: it's just evaluated in Boolean context as-is. I like the suggestion of "whenever" for that; it has the "no matter what" sense that goes with ignoring the topic. -Mark -- Mark J. Reed
Re: Smart match isn't on Bool
Darren Duncan wrote: TSa (Thomas Sandlaß) wrote: ... unless you want C to do a value-and-type check, in which case it doesn't exactly follow the pattern for smartmatching of the other builtin types (which only check value equivalence, not type equivalence). This is true only if you want to distinguish 1 and True which are the same value. But 42 should be distinct from this. Same goes for "viaduct". So these three should be a valid disjoint set of choices that can be made given $something. Is that so? 1 and True *are* the same value now? No, they aren't. Not Bool wraps Int rather than being a subset type and it and has wholly distinct values? We look at Bool as an enumeration type. The base type of that enumeration type may well represent False and True as 0 and 1, but that's an implementation detail. They're not "eqv" or "===". Carl Mäsak wrote: > I don't know whence you got the impression that Bool is a subtype. > Bool is an enumeration type, which makes True and False distinct > objects both of which aren't (but instead wrap) their corresponding > Int values. > >> Asking "False eqv 0" should be false, though either "False eqv ?0" or >> "+False eqv 0" being true is okay. > > All those are as you want them. I would like for what Carl said to be true, but TSa seems to be contradicting it. Carl is correct. 1 and True should *not* be the same value, and they should be distinguishable in any generic context like eqv Correct. or given-when. No, given-when is smart-matching. The RHS of a smart-match decides what happens. If you to True ~~ 1 then that's 1.ACCEPTS(True) which is going to do +True and thus match. They should only compare alike when cast into the same type such as with a ? or +. Right, which happens in given/when. Jonathan
Re: Smart match isn't on Bool
TSa (Thomas Sandlaß) wrote: ... unless you want C to do a value-and-type check, in which case it doesn't exactly follow the pattern for smartmatching of the other builtin types (which only check value equivalence, not type equivalence). This is true only if you want to distinguish 1 and True which are the same value. But 42 should be distinct from this. Same goes for "viaduct". So these three should be a valid disjoint set of choices that can be made given $something. Is that so? 1 and True *are* the same value now? Not Bool wraps Int rather than being a subset type and it and has wholly distinct values? Carl Mäsak wrote: > I don't know whence you got the impression that Bool is a subtype. > Bool is an enumeration type, which makes True and False distinct > objects both of which aren't (but instead wrap) their corresponding > Int values. > >> Asking "False eqv 0" should be false, though either "False eqv ?0" or >> "+False eqv 0" being true is okay. > > All those are as you want them. I would like for what Carl said to be true, but TSa seems to be contradicting it. 1 and True should *not* be the same value, and they should be distinguishable in any generic context like eqv or given-when. They should only compare alike when cast into the same type such as with a ? or +. -- Darren Duncan
Re: Smart match isn't on Bool
HaloO, On Saturday, 31. July 2010 20:47:49 Patrick R. Michaud wrote: > On Sat, Jul 31, 2010 at 10:56:47AM -0600, David Green wrote: > > It's not unreasonable, especially if that's what you expect. > > But it's even more reasonable to expect this to work: > > given $something { > > when True { say "That's the truth!" } > > when 42 { say "Good answer!" } > > when "viaduct" { say "You guessed the secret word!" } > > } > > I'm not so sure about this. There's an argument to be made that > the C and C cases should never be reachable, > since both C<42> and C<"viaduct"> are considered "true" values... Sorry, I don't understand this possible argument. Isn't the intent of a given/when to select one alternative by means of the given? This is what a switch statement does. Perl 6 allows non-constants after when, so it's reasonable to have the constant in the given and to see e.g. which function returns it. Of course the first actually doing this determines the switch. > ... unless you want C to do a value-and-type check, > in which case it doesn't exactly follow the pattern for smartmatching > of the other builtin types (which only check value equivalence, > not type equivalence). This is true only if you want to distinguish 1 and True which are the same value. But 42 should be distinct from this. Same goes for "viaduct". So these three should be a valid disjoint set of choices that can be made given $something. Regards, TSa. -- "The unavoidable price of reliability is simplicity" -- C.A.R. Hoare "Simplicity does not precede complexity, but follows it." -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Smart match isn't on Bool
David Green wrote: given $foo :using( [===] ) { ... } given $foo :using(&binary-func) { ... } I do like the general principle of what you're proposing, that one can customize the semantics of how given-when picks options. But I have no further details to suggest at this time. -- Darren Duncan
Re: Smart match isn't on Bool
On 2010-07-31, at 2:00 pm, TSa (Thomas Sandlaß) wrote: > On Saturday, 31. July 2010 18:56:47 David Green wrote: >> given $who-knows-what { >> when True { say "It's a true thing!" } # ^--oops, this still shouldn't come first! >> when 42 { say "It's numbery!" } >> whenever timeout() { say "Who cares what you say, time's up!" } >> whenever $override { say "Whatever, switching to automatic override" } >> } > > Am I getting your intention to be that when honors the given and whenever > just checks truth? Couldn't we use if for this? That would avoid the new > keyword. Right; except that "whenever" still breaks out, unlike "if". I like having a new keyword because it makes it perfectly clear that "whenever $foo" does not mean the same thing as "when $foo" (though it suggests something related by having "when" in the name). However, as suggested in my previous message, we could also distinguish them with something like "when" vs. "when:". The colon there isn't quite a new keyword, but it still is something to make the distinction visible. Plus it allows us to extend the same useful behaviour to "if" vs "if:". -David
Re: Smart match isn't on Bool
On 2010-07-31, at 5:55 pm, Darren Duncan wrote: > I would prefer if given/when was nothing more than an alternate syntax for > if/then that does comparisons. And that breaks out of its enclosing scope. > On the other hand, Perl 6 has multiple equality comparison operators, eqv, > eq, ==, ===, etc, and hence ~~ semantics instead of eqv may seem to make some > sense, though I think that would cause more problems. Yes, since if you've got a whole list of when's to compare against, it's not unlikely that they're different types of things, so ~~ would be more useful than === or eqv. Of course, given the bool-exception spec, one workaround is "when $_ eqv $x". But I was already thinking of a more elegant possibility. Using "when ~~ $bar" is problematic because Perl couldn't know whether to expect a term or an operator after "when". But what if ~~ were merely the default operator, and you could override it? given $foo :using( [===] ) { ... } given $foo :using(&binary-func) { ... } such that any 'when's inside the block use ===, or the provided operator/function instead, of ~~. Actually, the option should be on 'when', so that above line would mean something like: given $foo { my &when = &when.assuming( :using( [===] )) ... } ...er, except 'when' isn't a function, so that doesn't actually work. Anyway, the idea is that there could be some way to set the default operation to use for 'when' in a given scope. Here's another thought: 'when' is different from 'if' in two ways. One is that it does an implicit comparison on the topic; the other is that it breaks out of its enclosing block. Maybe the comparison could be indicated another way, leaving 'when' and 'if' to differ in breaking out or not. Suppose a colon indicated "compare against $_ using ~~, or whatever the default operation is" (we're not using the colon for anything else, are we?!?): when $a > $b { ... } if $foo.does($bar) { ... } when: /foo/ { ... } if: .defined { ... } -David
Re: Smart match isn't on Bool
On 2010-07-31, at 11:38 am, Brandon S Allbery KF8NH wrote: > Thank you; *that* is the real point I was trying to make. That, and that > special-casing one particular type is *not* actually helpful; it means I must > remember a special case, when one of the goals of Perl 6 was supposedly to > eliminate all the special cases in Perl 5, "helpful" or no. I don't know if it was supposed to eliminate *all* special cases, but I'm happy that it eliminates lots of them. I think some exceptions can be justified if it's a way humans naturally think (though it may be "exceptional" to a machine), or if there is some construct that isn't useful at all (if it has no legitimate use, why not use that syntax to mean something else? — but in that case, the trade-off is remembering an exception [of something you'd never want to do anyway] versus remembering extra syntax to do the other thing). I'm even prepared to accept exceptions for something that isn't meaningless. (My no-exception rule has exceptions!) "0 but true" in P5 is a good example. The exception is that it suppresses a warning, and that warning isn't totally useless; there *could* be a situation where you accidentally get that exact string when you wanted a pure number, but it's unlikely *and* the warning doesn't actually do anything — the code works the same way with or without the warning. "$foo ~~ True" is different. It may be less useful than the exception in that it's less frequent; but it still has a legitimate (non-exceptional) meaning. A bear of little memory like me will see "when timeout()" but instead of internalising "P6 handles when $bool differently from when $anything-else", I will take away "Perl DWIM". And then I'll expect it to DWIM in "$true-false-queston ~~ $bool-answer". -David
Re: Smart match isn't on Bool
On 2010-07-31, at 12:47 pm, Patrick R. Michaud wrote: > On Sat, Jul 31, 2010 at 10:56:47AM -0600, David Green wrote: >> given $something { >> when True { say "That's the truth!" } >> when 42 { say "Good answer!" } >> when "viaduct" { say "You guessed the secret word!" } >> } > I'm not so sure about this. There's an argument to be made that the C 42> and C cases should never be reachable, since both C<42> > and C<"viaduct"> are considered "true" values... Oops, no, I don't want it to do a value-and-type-check. I guess in this case the "when True" could be moved last, but it's still not a great example. Aaron's example with "when True" as a fallback at the end of a block is better. > [re Aaron's example with: if time > $limit { say "tick" } ] > The problem with this formulation is that a successful 'when' exits the > block, while a successful 'if' does not. This is one of the significant > differences between 'if' and 'when'. It's possible to break out with an explicit "leave" or "succeed". Slightly less elegant, but still straightforward and it doesn't require any exceptions. And it makes the different tests look different. Meanwhile, from one of your earlier replies: > The problem is that there are at least two interpretations of a true result > of : >when True { ... }# execute when $_ is exactly "True" >when foo() { ... } # execute when foo() returns true Except that the latter 'when' isn't executed when foo() returns true; only when it returns True! Well, maybe by "true" you meant "Bool::True" -- after all, that's a comment, not code; or maybe you were even thinking "True" and the lowercase T was a typo. At any rate, it confused me for several moments. -David
Re: Smart match isn't on Bool
Darren (>): > All this being said, I really do *not* like the idea of saying Bool is just > a subset of Int as it seems to be. Bool should be disjoint from every other > common type like Int/Str/etc instead. I don't know whence you got the impression that Bool is a subtype. Bool is an enumeration type, which makes True and False distinct objects both of which aren't (but instead wrap) their corresponding Int values. > Asking "False eqv 0" should be false, though either "False eqv ?0" or > "+False eqv 0" being true is okay. All those are as you want them. // Carl
Re: Smart match isn't on Bool
Brandon S Allbery KF8NH wrote: I think there's a confusion about what given/when is doing. Naïvely(?), I expect it to be shorthand where the value for "when" is matched against the one for "given", thus your example would be (pseudocode) "if 0 == True" and expecting "OH NOEZ" *would* be unreasonable. Is given/when trying to do too many things at once? I would prefer if given/when was nothing more than an alternate syntax for if/then that does comparisons. That is, these would be equivalent: given $foo { when $bar {...} when $baz {...} default {...} } if $foo eqv $bar {...} else if $foo eqv $baz {...} else {...} On the other hand, Perl 6 has multiple equality comparison operators, eqv, eq, ==, ===, etc, and hence ~~ semantics instead of eqv may seem to make some sense, though I think that would cause more problems. So I think if given-when just used eqv semantics and then users explicitly coerced their arguments instead, that might be best. For example, in the general case, say they want numeric semantics and the arguments aren't necessarily already numbers: given +$foo { when +$bar {...} when +$baz {...} default {...} } All this being said, I really do *not* like the idea of saying Bool is just a subset of Int as it seems to be. Bool should be disjoint from every other common type like Int/Str/etc instead. Asking "False eqv 0" should be false, though either "False eqv ?0" or "+False eqv 0" being true is okay. If people want ~~ semantics, let them ask for it explicitly, such as with: given $foo { when ~~ $bar {...} when ~~ $baz {...} default {...} } -- Darren Duncan
Re: Smart match isn't on Bool
On Sat, Jul 31, 2010 at 04:29:00PM -0400, Aaron Sherman wrote: > My problem with that is that it's a really odd use of given/when, and given > the implicit smart-match, it doesn't make much sense. Now, to slightly > backtrack, I do agree that there should be at least one way to do something, > and if that were the only way to perform independent tests within a given, > I'd agree. Thankfully, it's not: > > given $_ { >when /clock/ { say "clock" } >if time > $limit { say "tick" } >default { say "tock" } > } The problem with this formulation is that a successful 'when' exits the block, while a successful 'if' does not. This is one of the significant differences between 'if' and 'when'. So in the above, the default say "tock" is executed regardless of the result of the time > $limit test. > Well, since it's easy to do both, as demonstrated above, I think we can > agree that we've satisfied the first rule. It's not as easy to do both as your example seems to illustrate. Perhaps you can provide a better example that does illustrate testing for a condition that also results in exiting the C block? Pm
Re: Smart match isn't on Bool
On Sat, Jul 31, 2010 at 12:56 PM, David Green wrote: > > On 2010-07-30, at 4:57 pm, Aaron Sherman wrote: > >> given False { when True { say "True" } when False { Say "False" } > default { say "Dairy" } } > >> I don't think it's unreasonable to expect the output to be "False". > >> However, it actually outputs "True". Why? Well, because it's in the spec > that way. So... why is it in the spec that way? > > Well, if you want to do a boolean test, you'd probably use "if" instead; I'm sorry, I didn't know I'd sent this message to the python-language list ;-) Seriously though, I don't want "there's more than one way to do it" to be an excuse for redundancy, but on the other hand, it's rather odd for a rationale in Perl to be "there's already a way to do that" rather than the intuitiveness of the feature, even when it's only situational. It's also quite useful for testing truth as a fallback: given $_ { when $motor-oil { say "mmm syrupy!" } when $methane { say "dangerou!" } when $jet-fuel { say "I can haz skaiz?" } when /crude/ { say "refine it first" } when False { say "Sorry, no petroleum products" } when True { say "Unknown petroleum products" } default { say "Unpossible!" } } but something that already gives you a Bool, like "when time>$limit", is > likely to be the result you want to test itself rather than comparing it > against $_ (which is likely not to be a Bool). > My problem with that is that it's a really odd use of given/when, and given the implicit smart-match, it doesn't make much sense. Now, to slightly backtrack, I do agree that there should be at least one way to do something, and if that were the only way to perform independent tests within a given, I'd agree. Thankfully, it's not: given $_ { when /clock/ { say "clock" } if time > $limit { say "tick" } default { say "tock" } } And the really nice thing about that usage is that you immediately see that we're not testing time with respect to $_, but with respect to $limit. If you use when, that's left rather confusingly ambiguous unless you know that boolean values are a special case. > So Perl is trying to be helpful by doing something useful instead of making > the useful thing much harder at the expense of something that isn't useful > anyway. Well, since it's easy to do both, as demonstrated above, I think we can agree that we've satisfied the first rule. But given isn't very interesting compared to smart matching in general, and that's where: $foo ~~ True Really does seem to me as a very intuitive question, and that question isn't "is the RHS true?" > The catch is that I think that comparing against a boolean IS useful. The > fact that this question keeps coming up, even on the p6l list, seems to > demonstrate that the "helpful" way isn't completely natural or obvious (at > least, not to everyone). > Agreed. -- Aaron Sherman Email or GTalk: a...@ajs.com http://www.ajs.com/~ajs
Re: Smart match isn't on Bool
HaloO, On Saturday, 31. July 2010 18:56:47 David Green wrote: > On 2010-07-31, at 1:33 am, Moritz Lenz wrote: > > sub test() { True }; > > given 0 { when test() { say "OH NOEZ" } } > > I don't think it's unreasonable to expect the output to be "OH NOEZ". How does this relate the given to the when? If I get you right the given is completely ignored and the truth of test() gives "OH NOEZ". I think the given must determine the result. > It's not unreasonable, especially if that's what you expect. But it's even > more reasonable to expect this to work: given $something { > when True { say "That's the truth!" } > when 42 { say "Good answer!" } > when "viaduct" { say "You guessed the secret word!" } > } Here I expect the $something to *select* one of the alternatives. It can't be that a literal True ignores the given and just executes the block. > In both these examples, the intent is fairly clear from the context. It's > easier to forget that Bools behave differently from other types when you > only have some variable that could be any type: if $guess ~~ $answer { say > "Correct!" } # hope your question wasn't T/F! > > Maybe we can't please everyone, but we can at least try not to displease > anyone. Perl is awfully clever at keeping your eaten ponies, and there is > a way we can have both the "helpful" syntax and the "consistent" one: > > given $who-knows-what { > when True { say "It's a true thing!" } > when 42 { say "It's numbery!" } > whenever timeout() { say "Who cares what you say, time's up!" } > whenever $override { say "Whatever, switching to automatic > override" } > } Am I getting your intention to be that when honors the given and whenever just checks truth? Couldn't we use if for this? That would avoid the new keyword. Regards, TSa. -- "The unavoidable price of reliability is simplicity" -- C.A.R. Hoare "Simplicity does not precede complexity, but follows it." -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Smart match isn't on Bool
On Sat, Jul 31, 2010 at 10:56:47AM -0600, David Green wrote: > It's not unreasonable, especially if that's what you expect. > But it's even more reasonable to expect this to work: > given $something { > when True { say "That's the truth!" } > when 42 { say "Good answer!" } > when "viaduct" { say "You guessed the secret word!" } > } I'm not so sure about this. There's an argument to be made that the C and C cases should never be reachable, since both C<42> and C<"viaduct"> are considered "true" values... ... unless you want C to do a value-and-type check, in which case it doesn't exactly follow the pattern for smartmatching of the other builtin types (which only check value equivalence, not type equivalence). Pm
Re: Smart match isn't on Bool
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 7/31/10 12:56 , David Green wrote: > a boolean IS useful. The fact that this question keeps coming up, > even on the p6l list, seems to demonstrate that the "helpful" way > isn't completely natural or obvious (at least, not to everyone). Thank you; *that* is the real point I was trying to make. That, and that special-casing one particular type is *not* actually helpful; it means I must remember a special case, when one of the goals of Perl 6 was supposedly to eliminate all the special cases in Perl 5, "helpful" or no. (Maybe make it more concrete? There's another discussion going on about how "a" .. "b" should behave. Arguably it is an argument about helpfulness versus purity... and the decision is clearly in the direction of purity. Why, then, is *this* in the direction of helpfulness at the expense of purity? It's just another arbitrary decision I have to remember instead of a general rule.) - -- brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkxUX4UACgkQIn7hlCsL25X1DACeIQryF49L/90FRDuYUQraRlW/ 7UEAniG4lw5FhhnfNIDKqg+QZTolzFlc =DDaL -END PGP SIGNATURE-
Re: Smart match isn't on Bool
> On 2010-07-30, at 4:57 pm, Aaron Sherman wrote: >> given False { when True { say "True" } when False { Say "False" } default { >> say "Dairy" } } >> I don't think it's unreasonable to expect the output to be "False". >> However, it actually outputs "True". Why? Well, because it's in the spec >> that way. So... why is it in the spec that way? Well, if you want to do a boolean test, you'd probably use "if" instead; but something that already gives you a Bool, like "when time>$limit", is likely to be the result you want to test itself rather than comparing it against $_ (which is likely not to be a Bool). So Perl is trying to be helpful by doing something useful instead of making the useful thing much harder at the expense of something that isn't useful anyway. The catch is that I think that comparing against a boolean IS useful. The fact that this question keeps coming up, even on the p6l list, seems to demonstrate that the "helpful" way isn't completely natural or obvious (at least, not to everyone). On 2010-07-31, at 1:33 am, Moritz Lenz wrote: > sub test() { True }; > given 0 { when test() { say "OH NOEZ" } } > I don't think it's unreasonable to expect the output to be "OH NOEZ". It's not unreasonable, especially if that's what you expect. But it's even more reasonable to expect this to work: given $something { when True { say "That's the truth!" } when 42 { say "Good answer!" } when "viaduct" { say "You guessed the secret word!" } } In both these examples, the intent is fairly clear from the context. It's easier to forget that Bools behave differently from other types when you only have some variable that could be any type: if $guess ~~ $answer { say "Correct!" } # hope your question wasn't T/F! Maybe we can't please everyone, but we can at least try not to displease anyone. Perl is awfully clever at keeping your eaten ponies, and there is a way we can have both the "helpful" syntax and the "consistent" one: given $who-knows-what { when True { say "It's a true thing!" } when 42 { say "It's numbery!" } whenever timeout() { say "Who cares what you say, time's up!" } whenever $override { say "Whatever, switching to automatic override" } } This way (or something similar) is just as clear when reading something in context, but also makes it clear(er) when the context doesn't help (like 'when who-knows()') or when you reasonably expect more consistent matching. [Or do I mean "whenever"??] -David
Re: Smart match isn't on Bool
On Sat, Jul 31, 2010 at 11:47:13AM -0400, Brandon S Allbery KF8NH wrote: > [...], and > if the point is to be a general case statement then "when " > should smartmatch against $_ instead of evaluating it with $_ > available as a shorthand/topic. This is exactly what "when block" does -- it smartmatches against $_. The problem is that there are at least two interpretations of a true result of : when True { ... }# execute when $_ is exactly "True" when foo() { ... } # execute when foo() returns true It's been decided that the latter is far more useful in general; there are plenty of ways to express the former that are much less ambiguous. Pm
Re: Smart match isn't on Bool
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 7/31/10 11:17 , Mark J. Reed wrote: > What if you say 'when test($_)'? Or just 'when &test'? How do you > smart match on a function: call the func with the target as argument > and use the return value, or call it without any argument and compare > the return value to the target? Does arity matter? Or whether the > function is declared to return a Boolean value/called in a Boolean > context? As I understand the spec: given sets $_ to when test() calls test with no argument when test($_) calls test with the topic when &testuses the function object &test It seems like this leaves $_ in an odd place, no longer really a "topic", just a sort of shorthand which is sometimes implied (see for example ".foo" as calling method foo() of $_) and sometimes not (given/when). "when" as currently specced seems like it's just a synonym for "if". Overgeneralization seems to have left $_ and "when" in a rather muddy spot. I feel like if the point of given/when is an overly general case statement (as it currently seems to be), then using $_ is a Huffmanization waste (surely $^a is good enough?) and confuses what $_ is supposed to mean, and if the point is to be a general case statement then "when " should smartmatch against $_ instead of evaluating it with $_ available as a shorthand/topic. Thus the confusion in the message that started this thread: most people expect the latter behavior, but are getting the former which feels like a Huffmanization failure in addition to confusing the question of implicit vs. explicit topicalization/$_. (Am I making any sense here? I know what I'm trying to say, but am unsure that I am describing it sensibly.) - -- brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkxURYEACgkQIn7hlCsL25X/4QCfT3xbqtyY9sJ8UvT0VycKqetf nYgAnR5dw7sDNsMj6hSnwHYT90TzFxia =u4Hj -END PGP SIGNATURE-
Re: Smart match isn't on Bool
What if you say 'when test($_)'? Or just 'when &test'? How do you smart match on a function: call the func with the target as argument and use the return value, or call it without any argument and compare the return value to the target? Does arity matter? Or whether the function is declared to return a Boolean value/called in a Boolean context? On Saturday, July 31, 2010, Brandon S Allbery KF8NH wrote: > -BEGIN PGP SIGNED MESSAGE- > Hash: SHA1 > > On 7/31/10 03:33 , Moritz Lenz wrote: >> In this code: >> >> sub test() { True }; >> >> given 0 { >> when test() { say "OH NOEZ" } >> } >> >> I don't think it's unreasonable to expect the output to be "OH NOEZ". > > I think there's a confusion about what given/when is doing. Naïvely(?), I > expect it to be shorthand where the value for "when" is matched against the > one for "given", thus your example would be (pseudocode) "if 0 == True" and > expecting "OH NOEZ" *would* be unreasonable. > > Is given/when trying to do too many things at once? > > - -- > brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com > system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu > electrical and computer engineering, carnegie mellon university KF8NH > -BEGIN PGP SIGNATURE- > Version: GnuPG v2.0.10 (Darwin) > Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ > > iEYEARECAAYFAkxUOJsACgkQIn7hlCsL25WPlwCeJKwKQWDl+qaNbJMyAOcZ5UXf > R2EAn1AQBqB5hZIFmqymcaqSSGJdx9GJ > =cmZ6 > -END PGP SIGNATURE- > -- Mark J. Reed
Re: Smart match isn't on Bool
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 7/31/10 03:33 , Moritz Lenz wrote: > In this code: > > sub test() { True }; > > given 0 { > when test() { say "OH NOEZ" } > } > > I don't think it's unreasonable to expect the output to be "OH NOEZ". I think there's a confusion about what given/when is doing. Naïvely(?), I expect it to be shorthand where the value for "when" is matched against the one for "given", thus your example would be (pseudocode) "if 0 == True" and expecting "OH NOEZ" *would* be unreasonable. Is given/when trying to do too many things at once? - -- brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkxUOJsACgkQIn7hlCsL25WPlwCeJKwKQWDl+qaNbJMyAOcZ5UXf R2EAn1AQBqB5hZIFmqymcaqSSGJdx9GJ =cmZ6 -END PGP SIGNATURE-
Re: Smart match isn't on Bool
Aaron Sherman wrote: > In this code: > > given False { > when True { say "True" } > when False { Say "False" } > default { say "Dairy" } > } > > I don't think it's unreasonable to expect the output to be "False". In this code: sub test() { True }; given 0 { when test() { say "OH NOEZ" } } I don't think it's unreasonable to expect the output to be "OH NOEZ". > However, it actually outputs "True". Why? Well, because it's in the > spec that way. So... why is it in the spec that way? Because you can't have a ponie, and eat it. Or so. You can't please everyone, so we try to please at least some of the people, and in the future you can expect a warning from a bare True or False in a 'when', or on the RHS of a smart-match. STD.pm already implements that warning, Rakudo doesn't. (But I'd appreciate it if some brave soul could port the warning over to Rakudo, shouldn't be too hard) Cheers, Moritz