On Fri, Aug 13, 2004 at 08:41:35PM -0400, Matt Diephouse wrote: : > You know, at some point you just break down and write them positionally: : > : > @array.each( { $^odd.bar() }, { $^even.baz() }); : : Speaking of which, let's talk a little bit about how I'd write these : methods. After looking at Apocalypse, Exegesis, and Synopsis 6 again, : I have a few more questions. There are two different ways used to : declare a subroutine or method: : : sub foo (&block) { : &block('foo'); : }
The second & is unnecessary there. If you declare a &foo, you get foo() for free. : sub foo (Code $block) { : $block('foo'); : } : : Which is right? both? The second seems more extensible. Either should work. Scalars are always more general, since they can hold anything. But sometimes the point is to be less general... : And that leads : me to another question: can a slurpy array pick up a block? : : sub foo ([EMAIL PROTECTED]) { : say ref @args[0]; # @args[0].type? : } Probably "typeof", actually, since "ref" is unclear, and "type" is a keyword that prevents an indirect object syntax. Though arguably "type" should be "subtype" or "constrain" or some such, which would free up "type" for a unary. : foo { $^a =~ /bar/ }; # does this print "Block\n"? Maybe something more like "Code<scalar>". Haven't revisited the Code hierarchy in a while though. But the signature type is in angles (this week), since parens are taken for actual arguments. : It'd be nice to be able to declare my each method like so: : : class Array { : method each($self: [EMAIL PROTECTED]) { Could go as far as to say Code [EMAIL PROTECTED], I expect. And you can probably get away with @self too. (I also wouldn't call it "each", since there's likely to be a built-in of that name, but I understand you're just playing here...) method roundrobin(@self: Code [EMAIL PROTECTED]) { : my $i = 0; : my @results; : for @$self -> $elem { : my $block = @blocks[ $i++ % [EMAIL PROTECTED] ]; The + is redundant there, though okay as documentation, which I suppose is why you put it. : @results.push( $block($elem) ); You can also write those two lines as: my &block = @blocks[ $i++ % [EMAIL PROTECTED] ]; @results.push( block($elem) ); or as @results.push( @blocks[ $i++ % [EMAIL PROTECTED] ]($elem) ); : } : return @results; : } : } : : But that still doesn't let me call that like I'd want; : : my @r = @array.each :{ $^first * 2 } : :{ $^second * 9 } : :{ $^third * 42 }; Which would take some special dispensation like "Multiple anonymous closures are pushed onto the slurp array if there's no slurp closure." On the other hand, we've not really specified very well what happens if you pass two named parameters of the same name, other than saying the first one binds to the named parameter (if any) and the second one ends up in the slurpy hash. But what happens to the third one? An argument could be made for creating a subarray in the hash when there are multiples, in which case your multiple blocks would come through as %hash{""}[]. But I hate it that you'd have to treat a single argument differently. Maybe there's some way to extend signature syntax similarly to what we did for [$head, [EMAIL PROTECTED] arguments. There seems to be some kind of generic problem here with assuming named array arguments are always passed as a reference to a single array rather than a list of arguments with the same name. I'd much prefer a general solution than a bandaid just for blocks. : The other thing I'm wondering is how to apply adverbs to the results : of a function, if that's even possible. I believe this is valid: Adverbs by definition modify verbs, not nouns. : my $odd = 1... :by(2) # an infinite list of odd numbers I suppose an adverb can apply itself directly to a postfix operator like that, given that it still sets up the expectation for an operator rather than a term. : But this? : : sub odd_numbers([EMAIL PROTECTED] of Pair) { : return 1...; : } : my $odd = odd_numbers :by(2); : : Does that pass C<by => 2> as a Pair to the function? Yes. A term is expected, :by(2) is just a pair. : Or does it apply the adverb to the result? Maybe I need to do this? : : my $odd = (odd_numbers) :by(2); : : My head is swimming at this point, so I'd better give it a rest. That would apply the adverb to the =, which would make anyone's head swim, especially anyone trying to figure out how to implement assignment "by 2". Larry