develooper Front page | perl.perl6.language | Postings from October 2006

where constraints as roles (was Re: how typish are roles)

Thread Previous | Thread Next
From:
Trey Harris
Date:
October 28, 2006 05:53
Subject:
where constraints as roles (was Re: how typish are roles)
Message ID:
20061028045359.Y46238@bowser.eecs.harvard.edu
In a message dated Sat, 28 Oct 2006, Trey Harris writes:

> In a message dated Sat, 28 Oct 2006, chromatic writes:
>> When you specify a type to constrain some operation, you specify that the 
>> target entity must perform that role.
>
> That statement is very concise and direct. If the fuzziness I observed about 
> the identity of the basic building block of type was unintentional, this 
> statement should be added to S06.

Incidentally, this would mean that a C<where> clause or junctive type 
defines an anonymous role, and a type parameter defines a lexical role, 
doesn't it?  Seems like a useful characteristic of these constructs to 
make explicit, perhaps in L<S12/Roles>.

I find this a little unintuitive given the way these typing particles are 
used, though... If I were insane in a different way than I actually am, I 
might think I could use this "every constraint is a role" behavior to 
write:

    sub pairs_up_to (Int $x where { $^x % 2 == 0 } ) {
        (1..^$x:by(2)) >>=><< (2..$x:by(2))
    }

    pairs_up_to(4)};        # 1 => 2, 3 => 4

    try { pairs_up_to(3) }
        err say $!;         # "No compatible subroutine found"

    my $even_three = 3 but where { $_ % 2 == 0 };  # Huh?
    try { pairs_up_to($even_three) }
        err say $!;                                # What?

Not a useful example, I admit--which is why I had assumed C<where> 
constraints were not roles, because I can't think of a useful example of 
treating them as roles.  But I suppose if you're determined to shoot 
yourself in the foot like that, you'll find some way (like overloading 
C<%> so it always returns 0).

You could probably even make Perl be able to call the sub in the second 
C<try>, perhaps by making the anonymous roles generated by C<where> first 
match by AST equivalence before testing their value against the constraint 
or something.

Not that I think Perl should be able to do that... I'm just saying I 
*might* think it would, given how roles usually work (and if I could come 
up with a less contrived case, I might actually expect it to).

But *why* wouldn't it work?  One of two reasons I think:

1. The first C<where> clause in the sub signature defines a different
    anonymous role from the second C<where> clause after C<but>, even
    though they're defined identically.  In that case, $even_three would
    have no practical difference from any other 3, because it merely mixes
    in a role that never gets used.

2. The assignment would throw a mistyped value exception, just like
    "my Num $foo = 'hi, mom'" does.  (Except it doesn't.  Should it?  I
    don't see a test that addresses this in the suite, nor something in
    the Synopses to say that that assignment should fail.)

In either case, C<where> clauses create roles that values might do without 
even realizing they're doing them, and which mutable objects might do and 
then not do, willy-nilly, even in the course of the scope in which they 
were typed to do it... which I think is new unless I just haven't been 
paying attention.

     sub saturate (Color $c where { $^c.saturation < 100 } ) {
         $c.saturation = 100;  # ???
         correct_gama($c);
     }

Did that mutation throw an exception, by changing $c's type to one it 
can't have in this sub?  If no, did we just lose gradual typing (assuming 
correct_gamma cares)?  Can we detect that, or do the roles created by 
C<where> not participate in gradual typing?  If C<where> constraints 
weren't roles, this would make sense to me again.

It's duck-typing, but a very different type of duck typing than, say Ruby 
has... it isn't a duck because it walks and quacks, but because when you 
examine it with your particular duckish litmus test (your C<where> 
clause), the litmus test turns the duckish color (Bool::True) you're 
looking for.

A trifling issue, I guess, as you can just ignore how C<where> works so 
long as it does work.  But when I see a statement like "every X is really 
syntactic sugar for a Y", I want to poke at all the X's to see how they 
behave deeply as Y's.

Trey

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About