13

This post only discusses scala.collection.mutable.LinkedList. Other implementations are not the topic of this thread.

My question is: what is the use case of this class? I find it has the problems of both mutable and immutable type of structures while yielding the benefits of none. I say that because:

  • the API looks to me as if it were an immutable API (filter, map, drop, take etc all return a new LinkedList instead of doing in-place modifications)
  • all the benefits of immutable linked list are, at least I guess, not present, ie maximum sharing between structures, since those are still mutable (through var elem and var next.

So basicly we have a linear access time, linear append time, linear space etc and nothing to show for it in space complexity or in ability to reason about code (except maybe the O(1) prepend but it's still the case with immutable lists).

Do I fail to see an important benefit of this type of structure? I'm looking for objective measures and/or use-cases appliable to this class.

om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
m09
  • 7,490
  • 3
  • 31
  • 58
  • 1
    Looks like a thin wrapper around the immutable class. Benefit: whoever wrote it was able to do it very quickly, without worrying about introducing bugs? –  Oct 02 '12 at 12:04
  • 4
    @bdares what makes you think that? I had a quick look at the source and it appears to be no such thing. – Luigi Plinge Oct 02 '12 at 13:44
  • hmmm... like any mutable type, it can be referenced from several pointers and once edited, the changes will be seen from all pointers. This has nothing to do with time-complexity. – Oren Oct 02 '12 at 15:15
  • 2
    I'm aware of only 5/6 ways to modify the list: `append`, `update`, `insert` and manipulating `elem` and `next` by hand, and modifying by hand one of its elements, which means that any quite complex computation (map filter etc) won't lead to a modification of the original list, as I said in my question. Plus, time complexity __IS__ related to mutability. – m09 Oct 02 '12 at 15:23

1 Answers1

5

I'd say the reason is complexity - the linked list class allows you to hold a reference to a node in the middle of the list, and use insert or update at that node, instead of going through the head of the list.

[] --> [] --> ... --> [] --> ... --> [] --|
^                     ^
head                  myReference

In an application where I know exactly where a change in some sequence will happen (myReference above), it costs much less to modify that location than copying everything up to that location as would be the case with immutable.List (i.e. I just insert a new node after myReference).

                             myNewNode
                             v
[] --> [] --> ... --> [] --> [] ---> ... --> [] --|
^                     ^
head                  myReference

An example of such an application - an L-system where you expand parts of a string. It's much cheaper to insert new nodes in-place, than it is to copy the entire string each time it needs to be expanded.

Another reason is completeness - since DoubleLinkedList and LinkedListLike share a lot of common infrastructure, providing an extra LinkedList class came as a low cost to the standard library size.

axel22
  • 32,045
  • 9
  • 125
  • 137
  • good enough reasons. Though I wonder, is there any special reason why there isn't implementations for in-place idioms such as map, filter etc? – m09 Oct 02 '12 at 17:39
  • There has been a lot of discussion about this. This is partly because many are not implementable easily or at all (in-place `filter` on an `Array`, or a `patch`, or even a `flatMap`!), partly due to performance reasons (believe it or not, an in-place update is not always faster than a copy-update) and somewhat due to naming issues. There is, however, one operation which is generically implementable on mutable sequences, and that is `transform` - which simply calls `update` on every element. – axel22 Oct 02 '12 at 18:53
  • it kinda makes sense to me, but still I wonder why most general traits on which those implementations would be possible are left empty. I guess anyway they're not too hard to implement and reducing the noise in the API is preferable to giving already made implementations. Thanks :) – m09 Oct 02 '12 at 18:56