Re: Capture Object: why no verb?
Audrey Tang wrote: Hm, Perl 6 actually has two different ways of putting Capture to some Code object... Following yesterday's P6AST draft I'll call them Call and Apply respectively: moose($obj: 1, 2); # this is Call moose.($obj: 1, 2); # this is Apply elk(named = 'arg'); # this is Call elk.(named = 'arg'); # this is Apply The difference is whether the Code is an object (Apply), or a message name (Call). As the same argument list can be reused in both cases, it seems the method part is better left out from the abstraction. That allows: My understanding is that Capture objects are intended to superceed perl5 references. Synopsys 2 states: | You may retrieve parts from a Capture object with a prefix sigil | operator: | |$args = \3; # same as $args = \(3) |$$args; # same as $args as Scalar or Scalar($args) |@$args; # same as '$args as Array or Array($args) |%$args; # same as '$args as Hash or Hash($args) | | When cast into an array, you can access all the positional arguments; | into a hash, all named arguments; into a scalar, its invocant. I find myself wanting to add the obvious extra case to this list. Should it read: $args; # 'fail' ? (runtime error, or compile time?) I'd prefer it to do something more analagous to a perl5 coderef dereference -- assuming that it is possible to create a reference to code using a Capture. Also, I'm a bit confused By the idea that the invocant is obtained by a scalar dereference, because I know that arrays and hashes can be invocants, too. E.g. @a.pop. So, If I do: my $args = \(@a:); my $b = $$args; # @a as a scalar my @c = @$args; # empty list my @d := $$args; # bound to @a Is there any way that a deref can determine that the invocant stored in the capture was placed there using the '@' sigil? Perhpas this leads to the question of whether there is ever a reason for code to distinguish between @ invocants and $ invocants. I'm guessing that the answer must be no.
Re: Capture Object: why no verb?
Dave Whipp wrote: Also, I'm a bit confused By the idea that the invocant is obtained by a scalar dereference, because I know that arrays and hashes can be invocants, too. E.g. @a.pop. So, If I do: my $args = \(@a:); my $b = $$args; # @a as a scalar my @c = @$args; # empty list my @d := $$args; # bound to @a That is totally correct. Scalar here really means any one thing, any Array is but one kind of one-thing. Is there any way that a deref can determine that the invocant stored in the capture was placed there using the '@' sigil? Perhpas this leads to the question of whether there is ever a reason for code to distinguish between @ invocants and $ invocants. I'm guessing that the answer must be no. No. If you really want to flatten at list context the content of invocant, then @$$args will do what you want, though it's a bit heavy. :) Audrey signature.asc Description: OpenPGP digital signature
Re: Capture Object: why no verb?
Dave Whipp wrote: Perhaps I'm not fully groking the abstraction of the capture-object, but it seems to me that there should be a slot in it for the method. For dispatch, all three things are needed (invocant, method, args); so if you're going to put two of them in one object, then maybe the third thing belongs, too. Hm, Perl 6 actually has two different ways of putting Capture to some Code object... Following yesterday's P6AST draft I'll call them Call and Apply respectively: moose($obj: 1, 2); # this is Call moose.($obj: 1, 2); # this is Apply elk(named = 'arg'); # this is Call elk.(named = 'arg'); # this is Apply The difference is whether the Code is an object (Apply), or a message name (Call). As the same argument list can be reused in both cases, it seems the method part is better left out from the abstraction. That allows: my $cap = \(Hello, World); outs(*$cap); # Sub Call (may optimize to Apply if outs is lexical) $fh.say(*$cap); # Method Call $output(*$cap); # Apply This also makes multiple Captures easily composable: say(*$cap, *$cap, *$cap); # HelloWorldHelloWorldHelloWorld P6C Of course, if we go all Smalltalkish, we can say that Apply is merely sending the postcircumfix:( ) message to the Code object, so that we can treat _everything_ as a closure by defining: # Below demonstrates a (IMHO) bad idea sub postcircumfix:( ) ($inv: \$cap) { say Foo! } 1.(); # Foo! - method call falling back to sub call But this defeats common closure-based optimizations, and penalizes functional programming style for no apparent gain, so I think the method-full form and method-less form are still better separated in the AST. /P6C Audrey signature.asc Description: OpenPGP digital signature