Precedence of "where" ("of", "is", "will")?

Nobody on #perl6 today could answer this one.  Is:
    Str | Int where { $_ }
the same as:
    (Str | Int) where { $_ }
or:
    Str | (Int where { $_ })
?
Followup questions, Mr. President:
What kind of operators are "where", "of", "is", and "will"?
Is there a reason that S03 doesn't list them?
What are their precedence(s)?
-- 
Chip Salzenberg            - a.k.a. -            <chip@pobox.com>
         Open Source is not an excuse to write fun code
            then leave the actual work to others.
0
chip
3/19/2005 2:36:49 AM
πŸ“ perl.perl6.language
πŸ“ƒ 6843 articles.
⭐ 0 followers.

πŸ’¬ 4 Replies
πŸ‘οΈβ€πŸ—¨οΈ 4166 Views


Chip Salzenberg writes:
> Nobody on #perl6 today could answer this one.  Is:
>     Str | Int where { $_ }
> the same as:
>     (Str | Int) where { $_ }
I think it's this one.  The junctive operators naturally feel pretty
tight precedence, and named operators feel loose. 
> or:
>     Str | (Int where { $_ })
> ?
> 
> Followup questions, Mr. President:
> 
> What kind of operators are "where", "of", "is", and "will"?
> Is there a reason that S03 doesn't list them?
> What are their precedence(s)?
`will` and `is` are trait auxiliaries (see A12).  I don't know the names
of the other ones.  Maybe they're type modifiers.  Maybe they're also
trait auxiliaries.
Luke
0
luke
3/19/2005 10:24:45 AM
On Fri, Mar 18, 2005 at 09:36:49PM -0500, Chip Salzenberg wrote:
: Nobody on #perl6 today could answer this one.  Is:
:     Str | Int where { $_ }
: the same as:
:     (Str | Int) where { $_ }
: or:
:     Str | (Int where { $_ })
: ?
"where" binds looser than |, but it's a member of a select group of
operators that are considered declarational.  You couldn't replace |
with + there, for instance.
: Followup questions, Mr. President:
: 
: What kind of operators are "where", "of", "is", and "will"?
They're basically keywords that are for use only in type declarations
(where complex type names inside run-time expressions can be considered
a form of anonymous type declaration, with some proviso that anonymous
types declared similarly are considered structurally equivalent,
for some definition of "similarly").
: Is there a reason that S03 doesn't list them?
They aren't really operators in any general sense.
: What are their precedence(s)?
They might not actually have an official precedence if they're typically
parsed top-down.  We can say how they behave relative to the other
declarational keywords, but they're sort of in a different world than
the ordinary operators.  Your Str | Int above could be considered
a thunk that is forced to be evaluated at compile time.
Anyway, "is" is what we call a "trait_auxiliary" because it introduces
another identifier plus its associated argument, while "of" is what
we call a "trait_verb" because it just takes an ordinary argument.
The "is" is left associative in the sense that it always applies to
the main thing being declared to its left, so a sequence of is clauses
all refer to the same object.  On the other hand, "of" is right associative
and modifies the rightmost thing to its left.
"will" is just a variant of "is" that parses its two arguments with
the assumption that a closure is expected for the second one, but is
otherwise identical in precedence and associativity.
"returns" is an exact synonym for "of".  Both of them parameterize the
type to their left, though that type may be implicit in the cases where
the variable doesn't have an explicit "is" type.  That is,
    my @array of Int;
is really short for
    my @array is Array of Int
which is really something like
    my @array is Array[:returns(Int)]
and because of right associativity,
    my @array is Array of Array of Int
means something like:
    my @array is Array[:returns(Array[:returns(Int)])]
As for "where", it probably associates like "of" and other trait verbs,
though it means something different, associating a Selector with the
leftward type rather than a return type.
Larry
0
larry
3/19/2005 7:39:36 PM
Larry Wall wrote:
>     my @array of Int;
>=20
> is really short for
>=20
>     my @array is Array of Int;
How does 'is' relate to 'does'?  I mean is the above @array
ready for operation? Whilst
my @array does Array of Int;
still needs a compatible object to be put into @array?
Like so:
class Blubber does Array of Int {...}
@array =3D Blubber.new; # or with :=3D ?

BTW, does
my Int $value;
expand to
my $value is Ref of Int;
or the often mentioned
my $value is Scalar of Int;
and what is the difference between the two, if any?

What exactly does the 'is shape' syntax expand to?
I guess it is some parser gymnastics that somehow
puts more aguments into the Array class closure.
Which brings me to the question: how does this parameter
list look like?.
class Array[ ::ContentType, List of List $shape ] {...}

And yet another one: when is the resulting expansion of
such a class template or whatever it is performed? Or does
the implementor of the class have to revert to blessing in
the constructor?  Wouldn't this prevent static type checking
unless the compiler would call the constructor in some
hypotheticality mode to produce type information.

Regards,
--=20
TSa (Thomas Sandla=DF)
0
Thomas
3/23/2005 5:58:51 PM
On Wed, Mar 23, 2005 at 06:58:51PM +0100, Thomas SandlaοΏ½ wrote:
: Larry Wall wrote:
: >    my @array of Int;
: >
: >is really short for
: >
: >    my @array is Array of Int;
: 
: How does 'is' relate to 'does'?  I mean is the above @array
: ready for operation?
Yes, I think "is" typically implies construction of the variable's
main object.  Note that this is the trait "is" rather than the ISA
"is".  (The way it currently stands, ISA "is" is just the usual side
effect of applying a trait to a class.)
: Whilst
: 
: my @array does Array of Int;
: 
: still needs a compatible object to be put into @array?
I would think that'd be short for
    my @array is Array does Array of Int;
which is kind of redundant, so no, I don't think it stubs out @array.
: Like so:
: 
: class Blubber does Array of Int {...}
: 
: @array = Blubber.new; # or with := ?
If there were a syntax for stubbing @array, it'd have to use := I think
to initialize.
: BTW, does
: 
: my Int $value;
: 
: expand to
: 
: my $value is Ref of Int;
: 
: or the often mentioned
: 
: my $value is Scalar of Int;
: 
: and what is the difference between the two, if any?
The latter, I expect.  The former kind of implies to me that you
could only assign a reference to it, not a normal integer value.
Though there's certainly some overlap there, and they effectively
come out to the same thing in most cases, so it's possible they
might be forced to mean the same thing.  On the other hand, maybe
    my @value is Ref of Array of Int;
is the syntax you're looking for to stub out an array type without
allocating an array.
: What exactly does the 'is shape' syntax expand to?
: I guess it is some parser gymnastics that somehow
: puts more aguments into the Array class closure.
Traits are just names for code that is run at compile time to tweak
whatever they are applied to.  A trait can do anything it pleases
with the object you apply it to.  In the case of "shape" it might
even swap in a different set of methods entirely.  (Change vtable
in Parrot terms.)
: Which brings me to the question: how does this parameter
: list look like?.
: 
: class Array[ ::ContentType, List of List $shape ] {...}
I would not assume it has to come in as a parameter to the type name.
The type correspondences of arrays will have to be negotiated by the
types involved somehow, and that may or may not be done by comparing
the "long names" of types that include the parameters.  (If we don't
do it that way, then there has to be some other interface for it,
of course.)  I'd like to leave a little wiggle room for structural
correspondence of types, not just named correspondence.  This being
Perl, we need to provide a little room to dwim in, even if the user
doesn't take us up on it.
If this sounds inadequately handwavy, please allow me to wave my
hands some more till it's adequately handwavy.  :-)
: And yet another one: when is the resulting expansion of
: such a class template or whatever it is performed?
At compile time, by the trait(s) in question, and perhaps by an implicit
instantiate call of some sort after the last explicit trait is parsed.
: Or does the implementor of the class have to revert to blessing in
: the constructor?
Somebody's gotta construct the variable at some point, whether it's
with .bless or some other mechanism.
: Wouldn't this prevent static type checking
: unless the compiler would call the constructor in some
: hypotheticality mode to produce type information.
There very little that is "static" about compiling Perl, except insofar
as things like traits are guaranteed to run code at compile time.
So there's no need to run things hypothetically.  You run it really,
and then look to see if you're happy with what you ended up with.
I suspect "static" type checking in this Brave New World is less
about evaluating passive data structures for consistency and more
about asking various objects if they're happy with each other so far.
We just have to define the right interfaces for asking the right
questions at the right time.  Piece of cake.  I'll let you work on
that part.  :-)
Larry
0
larry
3/25/2005 1:49:23 AM
Reply: