Stream: beginners

Topic: List.insert


view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:34):

Is there a function for inserting something into the middle of a list? I can't seem to find it. Otherwise, I feel like it should be there

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:35):

List.replace ?

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:35):

https://www.roc-lang.org/builtins/List#replace

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:35):

No I mean putting it in the middle and shifting everything above. Something like List.insert [0, 1, 2, 3] 2 42 == [0, 1, 42, 2, 3]

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:36):

I know it isn't good for performance, but if order matters, it can be the only way to do something

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:40):

No, I think you'd have to implement yourself

listInsert = \list, item, index ->
  start = List.sublist {start: At 0, end: Length index}
  end = List.sublist {start: After index}
  l = List.withCapacity ((List.len list) + 1)
  List.concat l start
  |> LIst.append item
  |> List.concat end

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:41):

Or something like that

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:41):

And def won't be the best perf

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:42):

Don't know a way to get Roc to do a memcpy straight from the original list to the new list, maybe LLVM will get rid of the interstitial list

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:43):

In pure roc, I'd pop to the end and use List.swap in repeatedly to put it in place. It would have good performance I think, since no new memory is allocated

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:44):

But I really think it should be a builtin

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:45):

Oh, yeah, like List.reserve list 1 and then do the swaps? I think if the list is created AND this all happens in a single function it will mutate in place

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:47):

something like this

insert : List a, U64, a -> List a
insert = \list, index, value ->
    pushed = List.append list value
    List.range { start: At (List.len list), end: At index }
    |> List.walk pushed \acc, i ->
        List.swap acc i (i + 1)

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:48):

probably an of-by-1 error or something. Just wrote it real quick. The range list has to be allocated though

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:50):

If you are going to do that, I think my implementation would be faster. You should do both, measure and compare. And let me know

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:50):

Sublist is fast since it's mostly just creating a new stack-allocated struct

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:51):

It should just be a builtin though :sweat_smile:, then the discussion doesn't matter. I want to use it for AOC, so there is probably another way. But it feels missing

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:51):

Mine'll be just three new stack-allocated structs, a heap allocation, and two memcpys

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:51):

I agree :smile:

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:52):

If you are doing day 9, I have a different idea

view this post on Zulip Anthony Bullard (Dec 09 2024 at 18:52):

But I only have 8 minutes left on lunch

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:53):

Enjoy!
Once there is some more feedback on the feature request, I think I might take a stab at implementing it. It's been a while since I have done a contribution

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 18:55):

Assuming everyone agrees this should be a builtin, what should happen if the index is out of bounds? Leave the list unchanged, push the value to the end, or return a Result? (Or another option I can't think of?)

view this post on Zulip Anton (Dec 09 2024 at 19:00):

Can you put something in the #ideas channel?

view this post on Zulip Kilian Vounckx (Dec 09 2024 at 19:03):

Oh yeah, this was the wrong channel al along. I created a new topic there. Someone with more zulip-fu knowledge is welcome to move this if they want, but I don't feel it's necessary


Last updated: Jul 05 2025 at 12:14 UTC