Raku / problem-solving

🦋 Problem Solving, a repo for handling problems that require review, deliberation and possibly debate
Artistic License 2.0
70 stars 16 forks source link

Routines shift and pop on lists should allow an option to pop or shift multiple elements in one op #436

Open tbrowder opened 2 months ago

tbrowder commented 2 months ago

Currently it is awkward to accomplish that with routine splice. For example, to shift two elements into another list:

my @a = 1, 2, 3;
my @b = @a.splice(0, 2):

To pop two elements is even more awkward if you want the elements removed from the end as one would expect. The routine name is not intuitive, either.

It would be much easier, and intuitive, to do this:

my @b = @a.shift: 2;

or

my @b = @a.pop: 2;
ab5tract commented 2 months ago

I'm hesitant about this because the functionality you want is very easily composed using xx:

my @new = @old.pop xx $n

FWIW I would not have reached for splice here, as I associate it more for what it can do regarding putting things into arrays rather than what it can do taking things out.

But I have done the above with xx many times. We might be able to save a few cycles by making a dedicated pop($n), and I don't have strong objections to it beyond it feeling superfluous (which may be an argument easily deflated by TMTOWTDI).

lizmat commented 2 months ago

Note that .chop, which you could consider the equivalent of .pop for strings, allows the number of graphemes to chop.

tbrowder commented 2 months ago

I'm hesitant about this because the functionality you want is very easily composed using xx:

my @new = @old.pop xx $n

I was not aware of that, thanks! But, as @lizmat said, .pop is similar to .chop, so there is that precedent. And my proposal seems more natural to me. (What would Larry say?)

FWIW I would not have reached for splice here,...

Nor would I, but that was the easiest thing at hand. I had never needed it before, and it was the only thing suggested on IRC that took care of my immediate need.

I rest my case on the beauty of TMTOWTDI (as opposed to the ugly Pythonic way).

patrickbkr commented 2 months ago

I think this is a low-risk change (API design wise). I for one would have guessed right what the meaning of the arg is. So my vote is: Why not?

niner commented 2 months ago

Before we get to a decision, we first need a fully specified proposal. We do not have that yet. We have an intriguing idea. What we still need is the rest of the design. Most notably, how would we treat edge cases like [1].shift(2). Would this throw? Would it return the only element? And what other edge cases are there?

lizmat commented 2 months ago

Other things to consider:

Should .pop(N) / .shift(N) return a List, Seq or an Array?

Should Callables be allowed, as in .pop(*-1), .shift(*-3)?

Which should be the order in which multiple elements are to be returned?

my @a = ^10;
dd @a.pop(2);  # (8,9) or (9,8) ??