-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request - method .hammer
#431
Comments
I think I'm not sure |
FWIW, I've cobbled an implementation of method hammer() {
my class HammerIterator does Iterator {
has $!iterator;
has $!next;
method new($iterator) {
my $self := nqp::create(self);
nqp::bindattr($self,HammerIterator,'$!next',nqp::list);
nqp::p6bindattrinvres(
$self,HammerIterator,'$!iterator',$iterator
)
}
method pull-one() {
nqp::while(
nqp::eqaddr((my $pulled := $!iterator.pull-one),IterationEnd),
nqp::if(
nqp::elems($!next),
($!iterator := nqp::pop($!next)),
(return IterationEnd)
)
);
nqp::if(
nqp::istype($pulled,Iterable),
nqp::stmts(
nqp::push($!next,$!iterator),
($!iterator := $pulled.iterator),
self.pull-one
),
$pulled
)
}
}
Seq.new: HammerIterator.new(self.iterator)
} |
Alternately, maybe |
UPDATE: actually, that would be a bad idea, as So maybe we should give
|
I think @lizmat has the right approach here. I agree with @librasteve that the functionality is clearly useful but I believe the right place for a user to be looking for it is in 'flat'. I don't like the idea of adding a new 'map' though. It seems to me that it only saves a single period and is also ambiguous, as has been pointed out. |
- add positional to indicate number of levels to flatten. Defaults to Inf / Whatever - add boolean named arg :hammer. If specified with a true value, will disregard any containerization on Iterables, and flatten those iterables. Defaults to False Inspired by Raku/problem-solving#431
Now as a PR: rakudo/rakudo#5594 |
that's perfect - brilliant! |
Re-opening as the discussion is not over yet! |
Discussion on #raku-dev: https://irclogs.raku.org/raku-dev/2024-06-11.html#13:07 |
OK - i see the concerns which I think deserve an evidence based response: from Discord channels... [16:19] Raku bridge: [4] > (@a.List Z @b.List).map: *.flat [00:19]Nemokosch: oh damn, not this again... [16:44]Nemokosch: unfortunately, if you look into the output of (1...3, (5...7)), the result of (5...7) is so much treated as an element that it will disobey even .flat Admittedly this is only a couple of folks (plus me) - but it not nothing ;-) |
I recall that this has come up periodically on the channel quite often, actually. We can't know how many people have bounced off of Raku solely as a result of this, but it seems realistic to assert that the number is non-zero. Regarding the objections raised on IRC: The idea that a user would easily or intuitively reach for a combination of 'tree', 'xx', and 'flat' feels relatively outlandish to me. Why shouldn't flat have optional arguments to accomplish a variety of flattenings? |
- add positional to indicate number of levels to flatten. Defaults to Inf / Whatever - add boolean named arg :hammer. If specified with a true value, will disregard any containerization on Iterables, and flatten those iterables. Defaults to False - make sure Arrays also get hammered The Array class had a shortcut to .flat, because all of the elements in an Array are always containerized, so calling .flat on it wouldn't change anything anyhow. Until we added the :$hammer named argument. So if that is specified with a True value, call the Iterable's version of .flat instead. Inspired by Raku/problem-solving#431
Sorry, I see this as an extension of indexing/flattening problems noted here: Not sure a newbie is going to reach for a Additionally/alternatively, is there a symbolic notation that accomplishes the same thing, for example, "double-squarebracket" notation? [0] > my @a = 1,3,5
[1 3 5]
[1] > my @b = 2,4,6
[2 4 6]
[2] > (@a.List Z @b.List).map: *.flat
((1 2) (3 4) (5 6))
[3] > my @c = 10...20
[4] > say @c[ (@a.List Z @b.List).map: *.flat ] #really cool result
((11 12) (13 14) (15 16))
[5] > say @c[ (@a.List Z @b.List) >>->> 1 ].Array #really cool result
[(10 11) (12 13) (14 15)]
[5] > # right now this works like so:
[5] > say @c[[ (@a.List Z @b.List) >>->> 1 ]].Array
[12 12 12]
[6] > # but what if we could get it to work (i.e. flatten) like this instead?
[6] > say @c[[ (@a.List Z @b.List) >>->> 1 ]].Array #wished for result
[10 11 12 13 14 15] |
I would much rather see all the elements of the relevant original design completed unless there's consensus that some elements are the wrong way to go. In this case that means implementing I see multiple merits to that design, including it being nicely consistent with the existing N level hammer syntax (eg |
@jubliatious1
Yes. A consensus was established around 2 decades ago for a
Other ways that do work right now in current Rakudo include:
What |
FWIW, I hadn't realized this. This should be trivial to implement now as a shortcut to |
Sounds pretty amazing! I'm still on ancient [4] > say @c[ (@a Z @b) >>->> 1 ][**];
HyperWhatever in array index not yet implemented. Sorry.
in block <unit> at <unknown file> line 1 The other ones work just as @raiph has stated: [4] > say [@c[ flat (@a Z @b) >>->> 1 ]];
[10 11 12 13 14 15]
[4] > say [@c[(@a Z @b) >>->> 1 ][*;*]];
[10 11 12 13 14 15]
[4] > |
@raiph could you provide a link to the consensus re See also rakudo/rakudo#5609 |
First, thanks for acting on what I raised / creating the PR. Something I hope is at least slightly helpful for tonight is current (old) design doc verbiage:
(See also discussion of The above verbiage, which arrived sometime during the 2000s, documents where the design ended up rather than any discussion preceding that point. Presuming the earlier discussion is (more) important then I'll have to dig another time because I'm recalling it from memory, and my initial quick and rough searches of the most likely emailing list perl.perl6.language (eg (There may well have been discussions on IRC too that were about use of flattening. But I suspect those would have come after I think there was clear consensus on the need for / desirability of a sledgehammer, and a subscript sledgehammer being a thing to have, and |
(BTW, I don't recall anyone calling it hammer or sledgehammer. I'm just sticking with steve's nomenclature. In the past I've called it a steamroller or bulldozer. I recall thinking of suggesting the mnemonic that |
I would like to test initial response to a new possible method, namely
.hammer
and its relative.hammermap(&block)
This method recursively hammers flat nested lists (and forcably flattens any itemized lists and Array elements) and is guaranteed to produce a flat list.
Does anyone thing this is a good idea?
I think that this is needed since, from time-to-time on the raku-beginner channel, someone will ask ("why doesn't my list go flat when I use
@l.flat
. While raku is intended to protect nested structure by default so that the structure will survive being be passed around a chain of functions, this is not always the desired behaviour. Indeed the docs mention that this default can irk users of data.In contrast to
@l.flat
,@l.hammer
will give the desired "simplistic" behaviour of "just give it to me flat". This slightly eases the difficulty level of not following the default, but a slightly comedy name hopefully retains the hint that this is slightly undesired vs. keeping the structure.The documents currently say:
This can irk users of data you provide if you have deeply nested Arrays where they want flat data. Currently they have to deeply map the structure by hand to undo the nesting:
say gather [0, [(1, 2), [3, 4]], $(5, 6)].deepmap: *.take; # OUTPUT: «(0 1 2 3 4 5 6)»
The text was updated successfully, but these errors were encountered: