In the test suite and on IRC there was quite some confusion about how
list builtins are specced, and how they should behave in corner cases.

One is join():
our Str multi method join ( @values: Str $separator = ' ' )
our Str multi join ( Str $separator = ' ', [EMAIL PROTECTED] )

It is quite clear that the perl 5-style
   join 'sep', $value, $value2;
invocation remains valid, and
is the new method form.

The confusion arises what to do with
should be.

Fallback semantics in S12 suggest that since no matching multi method is
found, subs are tried - that is, the expression is interpreted as
   join('str', 'other_str')
yielding 'other_str'. t/spec/S29-list/join.t disagrees, and wants the
result to be 'str'.

Daniel Ruoso argued in favour of the tested behaviour, suggesting that
perhaps the specs should be updated accordingly, mostly because
would be confusing otherwise.

Patrick Michaud argued in favour of the specced behaviour, and I agree.
Mostly because nobody sane will write things like
'str'.join('other_str') with a literal string as the invocant in first
place. And if it's not a literal, and you want it to behave as list, the
invocant is either something that returns a list, or a variable with the
'@' sigil. We just need to be careful that everything that should return
really does that, even if it contains a single list.

Currently both pugs and rakudo make <a b> return a list (pugs actually
an array, but that's a different problem), but <a> is a Str.
If we'd just be more consistent and always return a list, I don't see a
problem with the spec. If not, it would be rather weird to have <a
b>.join('c') return 'abc', but <a>.join('c') return 'c'.

my $x =;
$x.y = <a>;
say $x.y.join('b')
The output is different for the two possible declarations of class A:
class A { has $y is rw } # -> b
class A { has @y is rw } # -> a
not pretty IMHO.

So I see the following options:
 1) be more consistent with what returns a list
 2) Add a method with invocant Any for each list builtin
 3) drop method fallback, thus disallowing Str.join(Str) outright
 4) be lisp, make everything a list *g* (not serious)

I haven't thought a lot about the third option, and what it would mean
to the language as a whole, so I have no idea if it's a viable alternative.

Any thoughts on the topic are welcome. I hope I didn't confuse too much
here ;-)


Moritz Lenz |

Reply via email to