01:56 MasterDuke joined 02:45 MasterDuke left
librasteve @timemelon - great question, seems that you have stumbled on one of the more intricate routines in Raku - ie. list 09:01
first I would say any Capitalized method .List, .Seq and so on is a coercer - that is it will try to convert the type of the invocant to the type indicated by the name of the method (so Seq(1, 2, 3).List coerces a Seq type to a List type 09:04
routine list on the other hand is much more adaptable. The definitive information is set out in the docs docs.raku.org/routine/list ... but that takes a bit of deciphering is you are relatively new to Raku 09:06
the first code to decipher is the initial definition: 09:07
multi list(+list) multi method list(List:D:)
note that this is in the In List section, also section In Any has this definition: 09:08
multi method list(Any:U:) multi method list(Any:D \SELF:)
The first line tells us that list can be used as a subroutine, the second line is the method declaration - you will note that these are different. In Raku, a "routine" is a function that can be used either via subroutine or via method call syntax. It is a bit unusual for Raku routines, but in this case there is a slightly different behaviour depending on how you use it. 09:17
so, when In List, you get The method just returns the invocant self. The subroutine adheres to the single argument rule: if called with a single argument that is a non-itemized Iterable it returns a List based on the argument's iterator; otherwise it just returns the argument list. 09:20
and when In Any, you get Applies the infix , operator to the invocant and returns the resulting List. 09:21
All this seems pretty convoluted I guess, but the design intent is to dwim (do what I mean): that is, when I say list something I am emphatically asking Raku to make a List of what I give it. ;-) 09:23
now, maybe you already know, but there are two natural follow on questions you may have: (i) wtf is the single argument rule and (ii) what is the , comma operator 09:35
The single argument rule docs say This rule is equivalent to saying that arguments to iterators will not flatten, will not de-containerize, and will behave as if a single argument has been handed to them, whatever the shape that argument has. 09:38
m: my @a = (1,2,3); .say for @a;
Raku eval 1 2 3
librasteve M; my $x = (1,2,3); .say for $x; 09:39
m: my $x = (1,2,3); .say for $x;
Raku eval (1 2 3)
lizmat m: my $x := (1,2,3); .say for $x; 09:40
camelia 1
2
3
lizmat putting the list in a container will make it an item
librasteve so list routine gives you the same behaviour as for
and finally (from me), the , operator always makes a list, even with one argument like this: 09:41
m: say (1,).WHAT
Raku eval (List)
librasteve phew
sorry must &afk 09:42
timemelon thank you for the detailed answer! I'm assuming that when I use the list sub it goes through the multi list(+list) signature you mentioned. since I'm just calling it with one Seq argument, which isn't itemised, surely it's supposed to turn it into a list? when I try the same thing with an array or range, it does turn the single argument into a list, what's the difference? [0] > list([1, 2, 3]).WHAT (List) [1] > 13:03
list(1 .. 3).WHAT (List) [2] > list(Seq(1, 2, 3)).WHAT (Seq)
librasteve oh, haha - I didn't pick that one up - having read the docs, I agree that either the docs or the compiler is wrong - since it seems that the design of list to follow the single arg rule is pretty emphatic, I would say that it's a compiler bug - maybe someone with more core know how than I (@lizmat?) can comment 16:42
lizmat not looking at docs atm nor code, but the "list" sub is supposed to return something listy 16:44
m: dd list (1,2,3).Seq
camelia (1, 2, 3).Seq
lizmat A Seq is considered listy enough as is, so is returned verbatim
m: dd list 42 16:45
camelia (42,)
lizmat a single value such as an Int, is *not* listy enough, so is turned into a list
timemelon so list the function is just a bit more vibes-based than .list and .List 19:36
oh the implementation (I think this is it) is just multi sub list(+l) { l } 19:53
and the docs do say > Sigilless parameters can also be used slurpily, preceded by a + sign, to work with whatever initial type they started with which I guess you can read as 'keep the given type if it's listy enough' 20:00