Re: Smart match isn't on Bool

2010-08-04 Thread Aaron Sherman
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

2010-08-03 Thread Martin D Kealey
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

2010-08-03 Thread David Green
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

2010-08-02 Thread TSa (Thomas Sandlaß)
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

2010-08-02 Thread Aaron Sherman
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

2010-08-02 Thread Mark J. Reed
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

2010-08-01 Thread Jonathan Worthington

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

2010-08-01 Thread Darren Duncan

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

2010-08-01 Thread TSa (Thomas Sandlaß)
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

2010-07-31 Thread Darren Duncan

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

2010-07-31 Thread David Green
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

2010-07-31 Thread David Green
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

2010-07-31 Thread David Green
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

2010-07-31 Thread David Green
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

2010-07-31 Thread Carl Mäsak
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

2010-07-31 Thread Darren Duncan

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

2010-07-31 Thread Patrick R. Michaud
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

2010-07-31 Thread Aaron Sherman
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

2010-07-31 Thread TSa (Thomas Sandlaß)
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

2010-07-31 Thread Patrick R. Michaud
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

2010-07-31 Thread Brandon S Allbery KF8NH
-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

2010-07-31 Thread David Green
> 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

2010-07-31 Thread Patrick R. Michaud
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

2010-07-31 Thread Brandon S Allbery KF8NH
-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

2010-07-31 Thread Mark J. Reed
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

2010-07-31 Thread Brandon S Allbery KF8NH
-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

2010-07-31 Thread Moritz Lenz
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