Comment by shakow

1 year ago

IMHO, all these comes from the million dollar mistake that Go made from the very beginning, with slices being a bastard between both an owned and non-owned data container. Indeed, any function accepting a slice may simply use it as an immutable view on whatever data it needs, or modify it, potentially re-alloc it, and wreak havoc by invalidating all previous references to it and/or its elements. And God forbid you passed a subslice to such a function, you're in for a nasty surprise.

Even without going the whole 9 yards of the Rust memory model, something like the views in C++, or the java {Array,Linked}Lists containing references to objects and thus being resistant to re-alloc, or even plainly immutable list like in OCaml are all working and simple enough solutions to the issue.

I still can't wrap my mind around how supposedly experienced people like Pike & co. may have designed slices, then went ‶yep, that makes perfect sense for a robust, basic, widely used data structure to create our language around″, outside of a few toy programs.

my feeling with slices is that go wanted to really make programmers mindful of the cost of allocating new space on array operations.

By having this weird API on slices, they force you to be explicit on allocating new memory.

  • None of that makes any sense. Slices don't force you to be explicit on allocating new memory in any way. you can literally do this:

        s := []int{}
        for i := range 29754 {
            s = append(s, i)
        }
    

    do you see explicit allocation of new memory? As far as I'm concerned that's not in any way more explicit than e.g.

        var s = new List();
        foreach(var i in Enumerable.Range(0, 29754)) {
            s.Add(i);
        }

  • > they force you to be explicit on allocating new memory.

    Not at all. With e.g. `append` being a “maybe I'll allocate, maybe not, take a guess” kind of method, it's basically just like Java's `List.add` with extra steps and much worse egonomics.