C<map> returns a lazily evaluated list which is comprised of
the return value of the expression, evaluated once for every
one of the C<@values> that are passed in.
But both pugs and rakudo respect the arity of the code ref passed to it,
so that (1..6).map({$^a + $^b + $^c}) returns the list (6, 15), which is
very nice and very DWIM'my.
But it opens the question what should happen if there is a number of
items in the list that's not easily divisible by the arity - should the
rest just be padded with undef's? or just ignored? Or fail() with a
friendly error message?
I don't really mind either way, just want to test and implement it
correctly.
The same question also arises for "magical" List.reduce and similar methods.
Cheers,
Moritz
I think the basic rule has to be simply can the signature bind to
the remaining arguments. If not, we get a warning on unused arguments.
We can mark arguments as optional if that's what we mean. About the
only thing I see to decide is whether the 2nd and subsequent placeholders
consider themselves optional parameters. Is it better to get a single warning
earlier when some arguments go unused, or is it better to assume the
subsequent code can handle undefined paramets, with the likely result
of more undefined access warnings later on? My gut feeling is that
placeholder variables probably should not be considered optional; in
most cases a non-divisible number of arguments indicates a logic error
in the program, and an earlier message is better, even at the expense
of thowing away some (possibly valid) partial data. Especially since
we do have a way to indicate that partial data is acceptable:
-> $a, $b?, $c? { $a + ($b//0) + ($c//0) }
Larry
Presumably whatever we decide for C<map()> also applies to C<for>, yes?
for 1..4 -> $a, $b, $c { ... } # error
for 1..4 -> $a, $b, $c? { ... } # error
for 1..4 -> $a, $b?, $c? { ... } # ok
Pm
Just to put here an idea I sent on irc...
What if Signature.ACCEPTS set $/ with the matched arguments?
That way we can both know how many arguments the Signature can receive
as well as allow us to use the match as the capture to that call...
... $capture ~~ $signature ...;
my $args_matched = @($/).elems;
&code.(|$/);
daniel
Yes, the only difference between C<for> and C<map> is that you can
only use C<for> at the start of a statement. But we're more liberal
about where statements are expected in Perl 6, so you can say things
like:
my @results = do for @list -> $x {...};
my @results = (for @list -> $x {...});
and either of those is equivalent to:
my @results = map -> $x {...}, @list;
I also Officially Don't Care if you use map in a void context. :)
Larry
> the only difference between C<for> and C<map> is that you can only use
> C<for> at the start of a statement. But we're more liberal about where
> statements are expected in Perl 6, so you can say things like:
>
> my @results = do for @list -> $x {...};
> my @results = (for @list -> $x {...});
>
> and either of those is equivalent to:
>
> my @results = map -> $x {...}, @list;
>
> I also Officially Don't Care if you use map in a void context. :)
(Good.)
<tongue-in-cheek> Maybe we should just treat "map" as a synonym for "for". </tongue-in-cheek>
I'd like to be able to use grep, map, etc in a currying fashion. Can I do:
my &square_list := -> $x { $x * $x }.map();
And if so, what is the signature of &square_list ?
Maybe that's why there's a difference between "for" and "map"
@list = @array.map(&code);
&iterator = &code.for($signature);
@list = iterator(@list);
But I suspect they should logically be the other way around:
&iterator = &code.map($signature);
@list = iterator(@list);
@list = @array.for(&code);
-Martin
if $capture ~~ $signature :partial {
$capture = $<remaining>;
&code.(|@($/));
}
daniel
I would propose there to be one difference between for an map: map
should bind its arguments read-only, for should bind them read-write.
That would make at least one bad practice an error.
Leon
> I would propose there to be one difference between for an map: map
> should bind its arguments read-only, for should bind them read-write.
> That would make at least one bad practice an error.
That sounds very impractical, because the ro/rw distinction is part of
the signature, not of the capture.
Cheers,
Moritz
Why is r/w map a bad practice if r/w for is not?
Do you look at Perl's "map" and think "A-ha! The map operation is a
functional programming idiom, therefore it must be side-effect free!"?
Because that view doesn't feel terribly Perlish to me.
While I mostly use both map and for in readonly mode, I've been known
to use map for quickie in place mutations, and not necessarily in void
context:
my @prev = map { $_++ } @values;
I'm not arguing for the binding to default to rw - you can always use
"is rw" when needed. I just don't see any reason why the default
binding behavior of map and for should be different.
--
Mark J. Reed <mark...@gmail.com>
> I would propose there to be one difference between for an map: map
> should bind its arguments read-only, for should bind them read-write.
> That would make at least one bad practice an error.
That sounds very impractical, because the ro/rw distinction is part of