Re: Demagicalizing pairs
HaloO, Luke Palmer wrote: The whole point was to deautomatize it! However, here's an interesting solution: pairs are scanned for *syntactically* *on the top level* of a function call (allowing named() or however we spell it as a fallback when we want to be dynamic). However, :foo(bar) and foo => bar are equivalent again. foo $x, $y; # two positionals, regardless of what they contain foo $x, :y($y)# a positional and a named foo $x, y => $y # a positional and a named foo $x, (y => $y) # two positionals: $x and the pair y => $y foo $x, (:y($y)) # same In the fourth example, y => $y is no longer on the syntactic top level, so it is not interpreted as a named argument. Isn't that a task for the itemizer? I mean foo $x, [y => $y] # syntactic arg type = (Item,Item) # but staticarg type = (Item,Pair) foo $x, [:y($y)] # same compared to foo $x, y => $y# syntactic arg type = (Item,Pair) # and staticarg type = (Item,Pair) foo $x, (y => $y) # same because () only groups for changed precedence I hate to say it, but the named args should probably be marked with : instead of + in the signature. That's pretty cool. Can't say I like the secondary sigil: it's really not marking a property of the variable, but a property of the parameter list. That information should probably be kept inside the parameter list alone. I have changed my mind on $.foo and $:foo because these forms just lack some identifyer chars between the two sigils $what.foo and $what:foo where now $what indicates an item and .foo a method on it. Well, and :foo indicates a keyed access on $what, but that isn't currently specced, right? So what does 'what' default to in $.foo and $:foo? I think it simply is '?SELF' and the twigil syntax gives a compile error if $?SELF is unbound. The other two twigil combinations .$foo and :$foo in that logic would be a method ref and a key ref respectively and as such both need something on their left side. If that happens to be a bare word as in blahh :$foo; my interpretation is that first of all the symbol lookup for blahh has to yield a sub. Since it's not sigiled &blahh it is a not yet invoked sub invocation---to me this is not weirder than an unthrown exception---and $foo has to contain a pair that is bound by name in the pending blahh invocation. In other words it's a parametric, named parameter. BTW, if you want the same through a sub call I would write it as blahh :&foo(); See also my 'syntactic, static and dynamic type' mail. The forms blahh .$foo; blahh .&foo(); require blahh to be callable without params and return a suitable invocant type for the method referenced by $foo and returned by calling the sub foo respectively. This (il)logic can be applied to other twigil combinations as well: blahh [EMAIL PROTECTED]; # call on blahh ret val through method ref from @foo[42] blahh :%foo # call blahh with named param from %foo All of these forms fail at runtime if e.g. @foo[42] doesn't yield a method ref and even if it does the dispatch on the retval of blahh might fail. The compiler could also warn or give errors if the invocations can be proven to fail from the static type information, e.g. my Int @foo; blahh [EMAIL PROTECTED]; # Int not a Method subtype Hmm, and if you mentally unify sub and class you get the idea that $?SELF is bound to the current invocation err instance of the sub and as such is amenable to the $:foo syntax for replacing placeholder variables. That means { $:y < $:z && $:x != 2 } is a shorthand for sub ($x,$y,$z) { $y < $z && $x != 2 } and hints at the possibility for writing sub definitions as sub foo:(Item,Item,Item --> bool) { has $x; # first, has $y; # second, has $z; # and third Item has $:trace; if defined $:trace { say $:trace } return $y < $z && $x != 2; } and call them as usual foo 1,2,3; # no trace foo 1,2,3, trace => 'should be false'; foo:trace 1,2,3; # same foo 1,2,3, :trace($count++); foo 1,2,3, :$count++; # works? and curry them with slot assignment my &foo ::= &OUTER::foo:trace; foo 1,2,3; # prints traces -- $TSa.greeting := "HaloO"; # mind the echo!
Re: Demagicalizing pairs
On Thu, Aug 25, 2005 at 20:23:55 +1000, Stuart Cook wrote: > Here's a suggestion: > Within argument lists, both of them are special syntactic forms for > named arguments: > > foo(a => 'b', :c); # both named args > my $pair = :a; > foo($pair); # not a named-arg call > ...or else find new syntax to disambiguate: For disambiguation I think we should have symmetric functions: foo(pairs(a => 'b', :c)); my $pair = :a; foo(named($pair)); This can be implemented in a number of ways (NamedArg isa Pair, macros, special construct). Edge case: foo(my $x = :foo); bar($x); As I see it in this example bar is getting a pair, not a named argument. foo() on the other hand could get either a named argument since :foo was in it's parameters, or a pair, since (my $x = :foo) is an expression. If the named semantics are in the micro-lexical scope of the call to the pair constructor, foo() gets a named. If not, it gets a pair. In either condition, there should be a warning: "Possible unintended use of pair instead of named argument in :foo, call to foo() at ..." and disambiguation can fix this: foo(named(my $x = :foo)); foo(pair(my $x = :foo)); -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me groks YAML like the grasshopper: neeyah!! pgp4XME69xRIb.pgp Description: PGP signature
Re: Demagicalizing pairs
Here's a suggestion: Outside of argument lists, both a=>'b' and :a('b') (and friends) are equivalent, and denote an ordinary pair value. Within argument lists, both of them are special syntactic forms for named arguments: foo(a => 'b', :c); # both named args If you want to pass pair values into a sub, either use an intermediate variable... my $pair = :a; foo($pair); # not a named-arg call ...or else find new syntax to disambiguate: foo( (a => 'b') ); # ok, so maybe parens aren't such a good idea Or just use existing language constructs: foo( do{a=>'b'}, {:c;}() ); # both positional args And if you explicitly want to use individual pair values as named args, just exploit the fact that a pair can act like a one-element hash, and splat it: my $arg = :echo; foo( *%$arg ); # yes, I know it's three symbols Then the only magic rule most people need to remember is: "Pair syntax denotes named-arg passing, but only in an arg list." Magic can never be hidden (or happen accidentally), people can explicitly circumvent the default behaviour, and the whole system has very little inconsistency. Thoughts? Stuart
Re: Demagicalizing pairs
On 8/24/05, Damian Conway <[EMAIL PROTECTED]> wrote: > Larry wrote: > > > Plus I still think it's a really bad idea to allow intermixing of > > positionals and named. We could allow named at the beginning or end > > but still keep a constraint that all positionals must occur together > > in one zone. > > If losing the magic from =>'d pairs isn't buying us named args wherever we > like, why are we contemplating it? Well, that was one of the nice side-effects of the proposal, solving something that had been bugging me. But the main reason for this proposal was to demote Pair into a regular data type that wouldn't sneak into somebody's named argument when we weren't looking. In the Old Regime, I fear that I would never ever use Pair *except* for named arguments precisely because I need to keep far too much information in my head to use them safely. > > so we should put some thought into making it syntactically trivial, if > > not automatic like it is now. The whole point was to deautomatize it! However, here's an interesting solution: pairs are scanned for *syntactically* *on the top level* of a function call (allowing named() or however we spell it as a fallback when we want to be dynamic). However, :foo(bar) and foo => bar are equivalent again. foo $x, $y; # two positionals, regardless of what they contain foo $x, :y($y)# a positional and a named foo $x, y => $y # a positional and a named foo $x, (y => $y) # two positionals: $x and the pair y => $y foo $x, (:y($y)) # same In the fourth example, y => $y is no longer on the syntactic top level, so it is not interpreted as a named argument. > > > I hate to say it, but the named args should probably be marked > > with : instead of + in the signature. That's pretty cool. Can't say I like the secondary sigil: it's really not marking a property of the variable, but a property of the parameter list. That information should probably be kept inside the parameter list alone. Luke
Re: Demagicalizing pairs
On Wed, Aug 24, 2005 at 10:12:39AM -0700, Chip Salzenberg wrote: > On Wed, Aug 24, 2005 at 08:38:39AM -0400, John Macdonald wrote: > > When calling a function, I would like to be able to have a > > mixture of named and positional arguments. The named argument > > acts as a tab into the argument list and subsequent unnamed > > arguments continue on. > > I see a main point of named parameters to free the caller from the > tyranny of argument order (and vice versa). It seems to me you're > asking for the worst of both worlds. Perhaps I didn't make it clear in my original message - I agree that arbitrary mixing of named and positional is usually a bad thing. The only place where I find it useful is with a group of arguments that are always provided in the same order, used one or more times each by a number of functions, with additional arguments for some/all of those functions. So, a function that takes position and/or vector values would provide a name for each vector/position, but expect each to have an x, a y, and (possibly) a z argument following the name. I saw this in the DO system - a shell written at CDC back in the late 70's. The provided scripts were designed so that all programming scripts used the same sequence of arguments after the OPT keyword, the LINK keywork, etc. As I said originally, the value is diluted in a language with structured data types - you can use a single argument for a position that is a hash or array which contains the x/y/z components within it. The named group helps especially if you generally want to provide separate-but-related arguments. This tends to be things like an optional sub-action that requires multiple parameters if it is used at all. So, I'm mostly saying that a mixture of named and positional arguments is not ALWAYS bad, and that there may be some value in permitting such a mixture in certain circumstances. --
Re: Demagicalizing pairs
I've been trying to thing about how to make this read right without too much line noise. I think Lukes keyword approach ("named") is on the right track. If we want named params at both start and end, then its bound to be a bit confusing. But perhaps we can say that they're always at the end -- but either at the end of the invocant section or the end of the args. Also, "named" is a bit of a clumsy name. "Where" and "given" are taken, so I'll use "with": I think something like these read nicely, without too much line noise: draw_polygon $canvas: @verticies with color => "red"; draw_polygon $canvas with color => "red": @vertices; Dave.
Re: Demagicalizing pairs
On Wed, Aug 24, 2005 at 08:38:39AM -0400, John Macdonald wrote: > When calling a function, I would like to be able to have a > mixture of named and positional arguments. The named argument > acts as a tab into the argument list and subsequent unnamed > arguments continue on. I see a main point of named parameters to free the caller from the tyranny of argument order (and vice versa). It seems to me you're asking for the worst of both worlds. -- Chip Salzenberg <[EMAIL PROTECTED]>
Re: Demagicalizing pairs
On Wed, 24 Aug 2005, Damian Conway wrote: > Larry wrote: > > > Plus I still think it's a really bad idea to allow intermixing of > > positionals and named. We could allow named at the beginning or end > > but still keep a constraint that all positionals must occur together > > in one zone. > > If losing the magic from =>'d pairs isn't buying us named args wherever we > like, why are we contemplating it? I've lost track of the score in this thread, but I thought I would throw a couple pennies into the fountain. I really dread the thought of losing C< name => value > for named parameters. Off the top of my head, ADA, PL/SQL, and php all use that syntax, so it would be a shame to lose something that newbies might find familiar. On the other hand I would like it if the adverbial named parameter style C< :name(value) > were allowed at the begining as well as the end of the parameter list. I think adverbs read better when they are next to the verbs they modify, and I would be nice if I didn't have to resort to macro magic to get them there. Mixing named and positionals is bad though. ~ John Williams
Re: Demagicalizing pairs
I don't think this example reads very clearly. Visually you have to parse until you see the next => and then back track one word to figure out the key. > move( from=> $x, $y, delta=> $up, $right ); Personally I'd write that as either move(from => [$x, $y], delta => [$up, $right]); OR assuming I has a Position object and a vector object move(from => $pos1, delta => $vec1); The original example just seems difficult to parse. Paul
Re: Demagicalizing pairs
On Wed, Aug 24, 2005 at 04:27:03PM +1000, Damian Conway wrote: > Larry wrote: > > >Plus I still think it's a really bad idea to allow intermixing of > >positionals and named. We could allow named at the beginning or end > >but still keep a constraint that all positionals must occur together > >in one zone. > > If losing the magic from =>'d pairs isn't buying us named args wherever we > like, why are we contemplating it? When calling a function, I would like to be able to have a mixture of named and positional arguments. The named argument acts as a tab into the argument list and subsequent unnamed arguments continue on. That allows you to use a name for a group of arguments: move( from=> $x, $y, delta=> $up, $right ); In this case, there could even be an optional z-coordinate argument for each of the from and delta groups. The named group concept works well for interfaces that use the same groups in many different functions. It is especially powerful in languages which do not have structured types, which means it is not so necessary in Perl, but even here, you often are computing the components (like $up and $right above) separately, rather than always computing a single structured value (which would mean writing delta=>(x=>$up, y=>$right) instead). --
Re: Demagicalizing pairs
Larry mused: On the other hand, I'm not all that attached to colon itself. I *am*!!! If, as proposed elsewhere, we get rid of the %Foo:: notation in favor of some Foo<> variant, then trailing :: becomes available (ignoring ??/:: for the moment), and new Dog:: tail => 'long' almost makes sense, insofar as it kinda looks like it's marking Dog as a type name, even though it isn't. But new Dog:: :tail doesn't look so good. Nor do object methods: wag $dog:: 'tail'; say $fh:: $whatever; On the other hand, looking at it from the other end, the MMD notation tiebreaking notation is a little hard to spot, since colon is easy to miss. Is it??? I've been writing quite a bit of MMD notation, and I think the colon is very obvious...and exactly the right visual "weight". Maybe there's something that shows up better in a signature that also works as the invocant marker and, by extension, the indirect object marker. Since it's an ordering kind of thing, you'd kind of like to work > into it somehow, since the left side is of "greater" importance than the left. Unfortunately, though, "the good ones are all taken". Maybe some digraph like method new ($what*> $:tail) {...} method new ($what+> $:tail) {...} method new ($what.> $:tail) {...} method new ($what|> $:tail) {...} method new ($what>> $:tail) {...} giving new Dog*> :tail new Dog+> :tail new Dog.> :tail new Dog|> :tail new Dog>> :tail I guess that last one is eqivalent to: method new ($what» $:tail) {...} new Dog» :tail which I could maybe get used to. It kind of looks like a prompt to me. Not one of these is anything close to as readable as: new Dog: :tail name $dog: 'Rover'; say fh: @whatever *Please* don't give up on the colon there. It's much more readable. I especially like it for setting up objects: $person = Contact.new; first_name $person: "George"; family_name $person: "Bush"; title $person: "President"; email $person: "[EMAIL PROTECTED]"; spouse $person: search $contacts: "Laura"; The ordinary MMD might look like multi foo ($a, $b, $c» $d) And Lisp-like MMD fallback on every argument would look like multi foo ($a» $b» $c» $d») I suppose that particular use of » could be construed as encouraging people not to do that. :-) I truly believe that using the French quotes or (shudder!) their Texan equivalents here would be a dire step backwards. They're already overloaded for word lists and hyperoperators. I think using them for an invocant marker as well would simply be too much. The colon really was (and still is) the right choice here. Damian
Re: Demagicalizing pairs
Larry wrote: Plus I still think it's a really bad idea to allow intermixing of positionals and named. We could allow named at the beginning or end but still keep a constraint that all positionals must occur together in one zone. If losing the magic from =>'d pairs isn't buying us named args wherever we like, why are we contemplating it? I suspect a lot of people would still prefer to write named args with =>, I'd say so. so we should put some thought into making it syntactically trivial, if not automatic like it is now. Even making named() a listop would help. I'd say that's the best alternative. I'd certainly prefer that to repurposing :(...) I hate to say it, but the named args should probably be marked with : instead of + in the signature. One other idle thought is that, if we don't mind blowing a different kind of consistency, and if we s/+/:/ in sigs, a sig containing :$foo could instead be written $:foo (presuming we take : away from privates as we've postulated), Yes please. Underscore is much better in that role. Damian
Re: Demagicalizing pairs
On Mon, Aug 22, 2005 at 09:54:36 -0700, Larry Wall wrote: > That's not a problem as long as you keep your positionals together. Oh, I assumed the it's /(* *)|(* *)/, not /* * */ > : If there is some really odd code signature which takes in a mess, I > : may want to intermix positionals and named's in order to increase > : readability. > > This is Perl 6, which means it'll be trivially easy to implement > > no strict "positionals"; > > or whatever you want to call it. By the way, how does FFI relate to this? Say I'm calling a remote function, like use icky_language:SomePackage; some_function( #not for the children ); > : new Dog; # uh, didn't you mean 'new Dog:;'? > > The colon makes no difference there. Oops... Tee hee =) > The use of colon as the SMD invocant marker is actually just a > degenerate case of MMD tiebreaking syntax. Again with the coughing > : I would much rather see it go away, frankly, and let the issues be > : resolved by simplifying the OOP system. *cough*, *cough*. > > Well, I can see the appeal of optimizing for the implementor rather than > the user. A lot of languages have already tried that... :-) My OOP simplification coughs were actually because I think the OOP system is a little too complex for the user, not the implementor, but I've brought that up enough times. For the implementor SMD is just MMD with some constraints, so it's really just an extension of the implementation, so I'm not worried either way. If you're interested I can dig up a chat log where autrijus and I argue over this a bit. -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me sushi-spin-kicks : neeyah pgpE6IEEhOIaB.pgp Description: PGP signature
Re: Demagicalizing pairs
On Mon, Aug 22, 2005 at 10:51:25AM -0600, Eric wrote: : Just my two cents then back to lurking. The idea of having named parameters : with different names than the variables ++. Otherwise your public API is : dependent on private variables which is a Bad Thing and the only thing that : realy bugged me about current named parameters in P6. : : BTW why is it that just because they are defined as named they can't be used : positionaly as well? Because then the named marker would be redundant with the ? marker, which can already be supplied as named parameters, as can mandatory positionals. : Guess you could always use your same positional to named magic for the : positionals. Then the programmer is expliciting defining the order in case : the cases they want to use ordered versus named. : : multi sub seek ( $x, $y ) { seek( $:x, $:y) }: : multi sub seek ( :x($horizontal), :y($vertical)) { ... }; Which would mean that :x() doesn't imply named-only, so we'd still need a separate marker for that. But that seems like the wrong default. And you can always alias the variable at the top of the body if you're desperate for a different name than the public interface. Also, we'd have to look at how these things degrade in partially specified stubs: sub mystery { :x($), +:y(Dog @ where Beagle) } It looks like it could get messy. Er, messier. Larry
Re: Demagicalizing pairs
On Fri, Aug 19, 2005 at 06:42:04PM +0300, Yuval Kogman wrote: : On Fri, Aug 19, 2005 at 08:27:38 -0700, Larry Wall wrote: : : > Plus I still think it's a really bad idea to allow intermixing of : > positionals and named. We could allow named at the beginning or end : > but still keep a constraint that all positionals must occur together : > in one zone. : : This is something I think code style should take care of. : : I would probably put all of my named "nouns" in the begining, : positional nouns after that, and named adjectives at the end, : because that's usually their order of importance for me. That's not a problem as long as you keep your positionals together. : If there is some really odd code signature which takes in a mess, I : may want to intermix positionals and named's in order to increase : readability. This is Perl 6, which means it'll be trivially easy to implement no strict "positionals"; or whatever you want to call it. : In both these scenarios I see no use in the language limiting me : "just because"... I think this is a reiteration of the "I'm not : stupid, Perl should give me credit" issue. I think it's really easy for newbies to confuse themselves this way, and that's where strictures are most useful. : > ...since another little niggly inconsistency is that we'd be marking : > named params with : on the call side but + on the receiving side. : > I hate to say it, but the named args should probably be marked : > with : instead of + in the signature. : : I agree : : > Not sure what that does to : > invocant colon though. : : Invocant colon as a metaphor is nice for : : method $object : ; : : But I think that kinda sucks for : : new Dog; # uh, didn't you mean 'new Dog:;'? The colon makes no difference there. : And I personally never ever liked it in in signatures. The use of colon as the SMD invocant marker is actually just a degenerate case of MMD tiebreaking syntax. : I would much rather see it go away, frankly, and let the issues be : resolved by simplifying the OOP system. *cough*, *cough*. Well, I can see the appeal of optimizing for the implementor rather than the user. A lot of languages have already tried that... :-) On the other hand, I'm not all that attached to colon itself. If, as proposed elsewhere, we get rid of the %Foo:: notation in favor of some Foo<> variant, then trailing :: becomes available (ignoring ??/:: for the moment), and new Dog:: tail => 'long' almost makes sense, insofar as it kinda looks like it's marking Dog as a type name, even though it isn't. But new Dog:: :tail doesn't look so good. On the other hand, looking at it from the other end, the MMD notation tiebreaking notation is a little hard to spot, since colon is easy to miss. Maybe there's something that shows up better in a signature that also works as the invocant marker and, by extension, the indirect object marker. Since it's an ordering kind of thing, you'd kind of like to work > into it somehow, since the left side is of "greater" importance than the left. Unfortunately, though, "the good ones are all taken". Maybe some digraph like method new ($what*> $:tail) {...} method new ($what+> $:tail) {...} method new ($what.> $:tail) {...} method new ($what|> $:tail) {...} method new ($what>> $:tail) {...} giving new Dog*> :tail new Dog+> :tail new Dog.> :tail new Dog|> :tail new Dog>> :tail I guess that last one is eqivalent to: method new ($what» $:tail) {...} new Dog» :tail which I could maybe get used to. It kind of looks like a prompt to me. The ordinary MMD might look like multi foo ($a, $b, $c» $d) And Lisp-like MMD fallback on every argument would look like multi foo ($a» $b» $c» $d») I suppose that particular use of » could be construed as encouraging people not to do that. :-) Larry
Re: Demagicalizing pairs
Just my two cents then back to lurking. The idea of having named parameters with different names than the variables ++. Otherwise your public API is dependent on private variables which is a Bad Thing and the only thing that realy bugged me about current named parameters in P6. BTW why is it that just because they are defined as named they can't be used positionaly as well? Guess you could always use your same positional to named magic for the positionals. Then the programmer is expliciting defining the order in case the cases they want to use ordered versus named. multi sub seek ( $x, $y ) { seek( $:x, $:y) }: multi sub seek ( :x($horizontal), :y($vertical)) { ... }; On 8/19/05, Larry Wall <[EMAIL PROTECTED]> wrote: > > On Fri, Aug 19, 2005 at 08:39:24AM -0700, Larry Wall wrote: > : Actually, that's an argument that : is in a different class than the > regex > : quantifiers, and required named should be > : > : sub bar (+$:key) > : > : as I speculated earlier. Maybe we just force that to bind to $key > instead > : of $:key. > > Which makes me wonder whether, in ordinary code (not sigs) > > $:key > > is short for > > :key($key) > > The idea being that it makes it really easy to pass delegate particular > pairs to subfunctions as long as you keep the names consistent. It'd > also make it drop-dead easy to write positional-to-named constructors: > > method new ($proto: $a, $b, $c) { > ... > return $proto.bless($:a, $:b, $:c); > } > > instead of > > method new ($proto: $a,$b,$c) { > ... > return $proto.bless(:a($a), :b($b), :c($c)); > } > > I suppose if we pushed it we could even allow $:foo in adverbial position. > > 1 .. 100 $:by > > But I wonder if people will think that > > foo 1, 2, 3, @:foo > > should interpolate @foo as a list of pairs rather than binding to the > 'foo' argument. Likewise for %:bar. But those are still [EMAIL PROTECTED] and > *%bar, I suspect, and people can learn that the : twigil always means > rewrite. Hmm. That seems to indicate that the actual signature for > named parameters is > > sub foo (:foo($foo)) > > and that > > sub foo ($:foo) > > is just shorthand for that. That would give us the ability to give the > variable a different name than the parameter. I like. > > sub seek (:x($horizontal),:y($vertical)) > > On the other hand, it's now unclear whether you can call that as > seek(1,2). > Needs to be allowed somehow. > > Larry > -- __ Eric Hodges
Re: Demagicalizing pairs
On Fri, Aug 19, 2005 at 06:42:04PM +0300, Yuval Kogman wrote: > If there is some really odd code signature which takes in a mess, I > may want to intermix positionals and named's in order to increase > readability. AFAIR, named parameter syntax will work for positionals as well[*]. So even if you want to intermix the positional parameters with named, there's no need for us to support intermixing positional parameter *syntax* with named...? /me relurks -- Chip Salzenberg <[EMAIL PROTECTED]>
Re: Demagicalizing pairs
On Fri, Aug 19, 2005 at 08:39:24AM -0700, Larry Wall wrote: : Actually, that's an argument that : is in a different class than the regex : quantifiers, and required named should be : : sub bar (+$:key) : : as I speculated earlier. Maybe we just force that to bind to $key instead : of $:key. Which makes me wonder whether, in ordinary code (not sigs) $:key is short for :key($key) The idea being that it makes it really easy to pass delegate particular pairs to subfunctions as long as you keep the names consistent. It'd also make it drop-dead easy to write positional-to-named constructors: method new ($proto: $a, $b, $c) { ... return $proto.bless($:a, $:b, $:c); } instead of method new ($proto: $a,$b,$c) { ... return $proto.bless(:a($a), :b($b), :c($c)); } I suppose if we pushed it we could even allow $:foo in adverbial position. 1 .. 100 $:by But I wonder if people will think that foo 1, 2, 3, @:foo should interpolate @foo as a list of pairs rather than binding to the 'foo' argument. Likewise for %:bar. But those are still [EMAIL PROTECTED] and *%bar, I suspect, and people can learn that the : twigil always means rewrite. Hmm. That seems to indicate that the actual signature for named parameters is sub foo (:foo($foo)) and that sub foo ($:foo) is just shorthand for that. That would give us the ability to give the variable a different name than the parameter. I like. sub seek (:x($horizontal),:y($vertical)) On the other hand, it's now unclear whether you can call that as seek(1,2). Needs to be allowed somehow. Larry
Re: Demagicalizing pairs
On Fri, Aug 19, 2005 at 06:30:41PM +0300, Yuval Kogman wrote: : On Fri, Aug 19, 2005 at 10:31:34 +, Luke Palmer wrote: : : In short, "me too". : : Now some comments: : : > foo($a, $b, $c) : > : > You *know* that you're passing three positionals. : : This is very very important for least surprise and all that. Yes, that's why we were already syntacticalizing with the *%foo proposal. : > It's much less work for the runtime. You don't have to scan for : > pairs, you just have the caller stuff them where you need them. : : This will also allow more static binding of named parameters, which : is a good thing, because it will simplify the type inferencer code. That too. : > You only lose a *little* bit of flexibility at a great gain of : > usability of pairs. That little bit is this ability: : > : > my @args = (1, 2, 3, foo => 'bar'); : > baz([EMAIL PROTECTED]); # $foo gets argument 'bar' : : To be honest, I don't see how that is a feature, this strengthens my : support for demagicalizing. Seems to me that the * processor could easily install a pair-to-named promoter if that was deemed to be desirable. The * already says you're cheating. Alternately, instead of a normal list composer, have one that generates a special list that is predigested into zones. my @args := arglist(1, 2, 3, :foo('bar') <== @slurpme); baz([EMAIL PROTECTED]); # Just Works Presumably we need that funny list type anyway to collect named vs positionals vs slurpies at compile time, so all we need to do is expose that type via arglist() or whatever we call it. Maybe it's just my @args := ArgList.new(1, 2, 3, :foo('bar') <== @slurpme); Doesn't have to be Huffshort. Larry
Re: Demagicalizing pairs
On Fri, Aug 19, 2005 at 08:27:38 -0700, Larry Wall wrote: > Plus I still think it's a really bad idea to allow intermixing of > positionals and named. We could allow named at the beginning or end > but still keep a constraint that all positionals must occur together > in one zone. This is something I think code style should take care of. I would probably put all of my named "nouns" in the begining, positional nouns after that, and named adjectives at the end, because that's usually their order of importance for me. If there is some really odd code signature which takes in a mess, I may want to intermix positionals and named's in order to increase readability. In both these scenarios I see no use in the language limiting me "just because"... I think this is a reiteration of the "I'm not stupid, Perl should give me credit" issue. > ...since another little niggly inconsistency is that we'd be marking > named params with : on the call side but + on the receiving side. > I hate to say it, but the named args should probably be marked > with : instead of + in the signature. I agree > Not sure what that does to > invocant colon though. Invocant colon as a metaphor is nice for method $object : ; But I think that kinda sucks for new Dog; # uh, didn't you mean 'new Dog:;'? And I personally never ever liked it in in signatures. I would much rather see it go away, frankly, and let the issues be resolved by simplifying the OOP system. *cough*, *cough*. -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: uhm, no, I think I'll sit this one out..: neeyah! pgpYO92WR49S5.pgp Description: PGP signature
Re: Demagicalizing pairs
Hmm, if we take + away from named, it can become the "required" marker, so sub foo ($a,$b,?$c) is really short for sub foo (+$a,+$b,?$c) and required named parameters then become sub bar (+:$key) And, of course, that means that sub baz (+?$key) is a required optional parameter. :-) Actually, that's an argument that : is in a different class than the regex quantifiers, and required named should be sub bar (+$:key) as I speculated earlier. Maybe we just force that to bind to $key instead of $:key. That screws up the submethod BUILD ($.attribute) syntax though, unless we say that any twigil forces named argument passing, or otherwise just force it to work. Though with BUILD we've basically said already that all arguments must be passed +$: (required name) form. Maybe it can be made to work. Larry
Re: Demagicalizing pairs
On Fri, Aug 19, 2005 at 10:31:34 +, Luke Palmer wrote: In short, "me too". Now some comments: > foo($a, $b, $c) > > You *know* that you're passing three positionals. This is very very important for least surprise and all that. > It's much less work for the runtime. You don't have to scan for > pairs, you just have the caller stuff them where you need them. This will also allow more static binding of named parameters, which is a good thing, because it will simplify the type inferencer code. > You only lose a *little* bit of flexibility at a great gain of > usability of pairs. That little bit is this ability: > > my @args = (1, 2, 3, foo => 'bar'); > baz([EMAIL PROTECTED]); # $foo gets argument 'bar' To be honest, I don't see how that is a feature, this strengthens my support for demagicalizing. -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me climbs a brick wall with his fingers: neeyah! pgp1RiuLmrDoz.pgp Description: PGP signature
Re: Demagicalizing pairs
On Fri, Aug 19, 2005 at 10:31:34AM +, Luke Palmer wrote: : I propose that we move the magic out of the Pair type, and into a : syntactic form. That's kinda the direction we were already moving with the *%foo proposal, so I think I like it, but I'll need to steep my brain in a bit more caffeine. : Here's the best we have (from #perl6) at the moment: : : a => b# always a plain-vanilla pair, never a named argument : :a(b) # always a named argument (in sub calls) : # degenerates to a plain pair when not in a sub call : named(a => b) # make an ordinary pair (or list of pairs) into : # runtime named arguments : named(%named) # same Offhand I don't like the name of named(). Actually, it's kind of a shame we've already used :() for sigs, since we could say that :a(b) is :(a=>b). Damian had a proposal at our meeting to demote sigs to methods, but I've forgotten (or at least, haven't remembered) why that didn't fly. Probably something about having to at least be a macro because the parser has to start out at a different state inside. Plus I still think it's a really bad idea to allow intermixing of positionals and named. We could allow named at the beginning or end but still keep a constraint that all positionals must occur together in one zone. : This has a couple of advantages. First of all, in the call: : : foo($a, $b, $c) : : You *know* that you're passing three positionals. It looks like what : it is. Also, you don't have to take extra cautionary measures if : you're dealing with generic data. : : It's much less work for the runtime. You don't have to scan for : pairs, you just have the caller stuff them where you need them. We already had it as pure syntax with the * proposal, albeit with the => still indicating named args. : You only lose a *little* bit of flexibility at a great gain of : usability of pairs. That little bit is this ability: : : my @args = (1, 2, 3, foo => 'bar'); : baz([EMAIL PROTECTED]); # $foo gets argument 'bar' I suspect a lot of people would still prefer to write named args with =>, so we should put some thought into making it syntactically trivial, if not automatic like it is now. Even making named() a listop would help. I guess a downside to stealing :() is that it doesn't listopify readily, and if you tried to, it would look weird, and you'd have to leave a space after it. my @args = (1, 2, 3, :(foo => 'bar')); my @args = (1, 2, 3, : foo => 'bar'); Pity this doesn't work: my @args = (1, 2, 3, [:] foo => 'bar'); Maybe "where" as a term would work my @args = (1, 2, 3, where foo => 'bar'); Nah, people would omit the last comma and wonder why it's trying to subtype 3. Hmm. my @args = (1, 2, 3, plus foo => 'bar'); Assuming we stick with the + marker... ...since another little niggly inconsistency is that we'd be marking named params with : on the call side but + on the receiving side. I hate to say it, but the named args should probably be marked with : instead of + in the signature. Not sure what that does to invocant colon though. Probably requires that sigs with an explicitly unnamed invocant start ($:...) or (Type:...) rather than just (:...). Maybe that's not terribly important, since most invocants are either entirely there or entirely missing. : And you lose the ability to pretend that you're taking named arguments : when you're not; that is, you say you're not being order dependent : when you are. : : I think this is fixable with a trait on the sub: : : sub form ([EMAIL PROTECTED]) is unnameable # refuse named parameters altogether : { } More likely a trait on the slurpy. Or maybe there's still room for a type wider than Item on the slurpy array. In either case it would imply some kind of logic in argument unpacking that says, "I don't have a place for named arguments, so splice any named list on the front of the slurpy list." Offhand I don't see a problem with that approach. On the other hand, how else is the default p5-ish [EMAIL PROTECTED] going to behave when there's no sig? (Though it's still a problem for methods that generate *%_ for you, so we still need some explicit way to control it on explicit slurpies.) One other idle thought is that, if we don't mind blowing a different kind of consistency, and if we s/+/:/ in sigs, a sig containing :$foo could instead be written $:foo (presuming we take : away from privates as we've postulated), which would get the colon next to the name and have better visual correspondence with the :foo(), syntax, and maybe even allow adverbs to include an optional sigil on the front. On the other hand, then people would want to write $:foo in the body, and that won't do. So nevermind. Stick with :$foo for that. Larry
Demagicalizing pairs
We've seen many problems come up with the current special treatment of pairs. Here's what I can think of: * Pairs are restricted to a particular position in the argument list, which leads to confusion (why isn't this being passed named?) and poor end-weight in something like this: foo { # lots of code in here # blah blah blah ... } :delay(1) which would probably be more readable with :delay(1) up at the top * We had to special-case pointy blocks not to take named arguments because of this construct: for %hash.pairs -> $pair { ... } * (IIRC) We still have to scan potentially infinite lists when using the foo([EMAIL PROTECTED]) caller-side flattening form. I propose that we move the magic out of the Pair type, and into a syntactic form. Here's the best we have (from #perl6) at the moment: a => b# always a plain-vanilla pair, never a named argument :a(b) # always a named argument (in sub calls) # degenerates to a plain pair when not in a sub call named(a => b) # make an ordinary pair (or list of pairs) into # runtime named arguments named(%named) # same This has a couple of advantages. First of all, in the call: foo($a, $b, $c) You *know* that you're passing three positionals. It looks like what it is. Also, you don't have to take extra cautionary measures if you're dealing with generic data. It's much less work for the runtime. You don't have to scan for pairs, you just have the caller stuff them where you need them. You only lose a *little* bit of flexibility at a great gain of usability of pairs. That little bit is this ability: my @args = (1, 2, 3, foo => 'bar'); baz([EMAIL PROTECTED]); # $foo gets argument 'bar' And yet, you can fudge that back in on the callee side: sub baz ([EMAIL PROTECTED]) { my (@pos, %named); for @args { when Pair { $named{.key} = .value; } default { push @pos: $_ } } real_baz([EMAIL PROTECTED], named(%named)) } And you lose the ability to pretend that you're taking named arguments when you're not; that is, you say you're not being order dependent when you are. I think this is fixable with a trait on the sub: sub form ([EMAIL PROTECTED]) is unnameable # refuse named parameters altogether { } Anything more magical than that can be dealt with explicitly. Luke