r25807 - docs/Perl6/Spec
Author: lwall Date: 2009-03-12 22:30:47 +0100 (Thu, 12 Mar 2009) New Revision: 25807 Modified: docs/Perl6/Spec/S03-operators.pod Log: Clarify value syntax inconsistency noticed by pmichaud++ Modified: docs/Perl6/Spec/S03-operators.pod === --- docs/Perl6/Spec/S03-operators.pod 2009-03-12 17:38:06 UTC (rev 25806) +++ docs/Perl6/Spec/S03-operators.pod 2009-03-12 21:30:47 UTC (rev 25807) @@ -12,9 +12,9 @@ Maintainer: Larry Wall Date: 8 Mar 2004 - Last Modified: 4 Mar 2009 + Last Modified: 12 Mar 2009 Number: 3 - Version: 157 + Version: 158 =head1 Overview @@ -2660,18 +2660,52 @@ A function predeclared with an empty signature is considered 0-ary at run time but is still parsed as a list prefix operator, and looks -for a following list. To declare a function that is parsed -as a simple 0-ary term, you must use the form C<< term: >>. -Such a term is never considered a list prefix operator, though it -allows an optional set of empty parentheses (because it represents a -C object). Unlike functions and list operators with arguments -(see above), a 0-ary term does not require parentheses even if followed -immediately by a postfix. +for a following argument list, which it may reject at run time. +my sub foo () {...} +foo; # okay +foo();# okay +foo (),(),(); # okay +foo 1;# fails to dispatch + +The compiler is allowed to complain about anything it knows cannot +succeed at run time. Note that a multi may contain () as one +of its signatures, however: + +my multi foo () {...} +my multi foo ($x) {...} +foo; # okay +foo();# okay +foo (),(),(); # okay +foo 1;# okay + +To declare an item that is parsed as a simple term, you must use the +form C<< term: >>, or some other form of constant declaration such +as an enum declaration. Such a term never looks for its arguments, +is never considered a list prefix operator, and may not work with +subsequent parentheses because it will be parsed as a function call +instead of the intended term. (The function in question may or +may not exist.) For example, C is a simple term in Perl 6 +and does not allow parens, because there is no C function +(though there's a C<$n.rand> method). Most constant values such as +C and C are in the same category. After parsing one of these +the parser expects to see a postfix or an infix operator, not a term. +Therefore any attempt to use a simple value as a list operator is +destined to fail with an error indicating the parser saw two terms +in a row. + +For those values (such as types) that do respond to parentheses +(that is, that do the C role), the parentheses (parsed as +a postfix operator) are required in order to invoke the object: + +my $i = Int.($x); # okay +my $i = Int($x);# okay +my $i = Int $x; # ILLEGAL, two terms in a row + =item * A non-multi sub predeclared with an arity of exactly 1 also still -parses as a list prefix operator. You must explicitly use the form +parses as a list prefix operator expecting multiple arguments. You must explicitly use the form C<< prefix: >> to declare C as a named unary in precedence; it must still take a single positional parameter (though any number of named parameters are allowed, which can be bound to adverbs).
Re: r25807 - docs/Perl6/Spec
> +To declare an item that is parsed as a simple term, you must use the > +form C<< term: >>, or some other form of constant declaration such > +as an enum declaration. Such a term never looks for its arguments, > +is never considered a list prefix operator, and may not work with > +subsequent parentheses because it will be parsed as a function call > +instead of the intended term. (The function in question may or > +may not exist.) For example, C is a simple term in Perl 6 > +and does not allow parens, because there is no C function > +(though there's a C<$n.rand> method). So if I were to say: rand $n: is the compiler smart enough to notice that trailing colon and recognize this as an indirect method call rather than two adjacent terms? Or would I have to say: rand($n:) to get the indirect method call? -- Jonathan "Dataweaver" Lang
Re: r25807 - docs/Perl6/Spec
On Thu, Mar 12, 2009 at 06:29:19PM -0700, Jon Lang wrote: : > +To declare an item that is parsed as a simple term, you must use the : > +form C<< term: >>, or some other form of constant declaration such : > +as an enum declaration. Such a term never looks for its arguments, : > +is never considered a list prefix operator, and may not work with : > +subsequent parentheses because it will be parsed as a function call : > +instead of the intended term. (The function in question may or : > +may not exist.) For example, C is a simple term in Perl 6 : > +and does not allow parens, because there is no C function : > +(though there's a C<$n.rand> method). : : So if I were to say: : : rand $n: : : is the compiler smart enough to notice that trailing colon and : recognize this as an indirect method call rather than two adjacent : terms? No, currently under STD you get: Obsolete use of rand(N); in Perl 6 please use N.rand or (1..N).pick instead at (eval) line 1: : Or would I have to say: : : rand($n:) : : to get the indirect method call? That would work, but then why not: rand*$n $n*rand $n.rand (1..$n).pick In fact, given that you usually want to integerize anyway, I could almost argue myself out of supporting the $n.rand form as well... Larry
Re: r25807 - docs/Perl6/Spec
On Sat, Mar 14, 2009 at 7:29 AM, Larry Wall wrote: > : So if I were to say: > : > : rand $n: > : > : is the compiler smart enough to notice that trailing colon and > : recognize this as an indirect method call rather than two adjacent > : terms? > > No, currently under STD you get: > > Obsolete use of rand(N); in Perl 6 please use N.rand or (1..N).pick > instead at (eval) line 1: > > : Or would I have to say: > : > : rand($n:) > : > : to get the indirect method call? > > That would work, but then why not: > > rand*$n > $n*rand > $n.rand > (1..$n).pick > > In fact, given that you usually want to integerize anyway, I could > almost argue myself out of supporting the $n.rand form as well... It's largely a matter of principle: if I can say $x.foo, I expect to be able to say foo $x: as well. Every time you introduce an exception to the rule, you're throwing something in that has the potential to cause confusion; so you should do so with some caution. I think that "best uses" should include something to the effect of "avoid using the same identifier for both a term and a routine". IMHO, rand should either be a term or a method; but not both. There are also some linguistic reasons for this "best uses" proposal: people tend to think of terms as nouns and routines as verbs. And gerunds are more akin to "&foo" than to "term:". Left-field idea here: there was recently some discussion on this list about the possibility of continuous ranges, which would be in contrast to how 1..$n is a discrete list of options. If you were to do this, then you could use .pick on a continuous range to generate a random number anywhere within its bounds. So: (1 to 5).pick (where infix: creates a continuous range, inclusive of both boundaries) would in theory be as likely to return 2.5 or pi as 3. IMHO, this does a better job of handling what most people want rand to do when they start thinking in terms of assigning parameters to it. And with that in place, rand could become a term that's short for something like: pick (0 to^ 1): -- Jonathan "Dataweaver" Lang