A quick note to guide discussion: a clear prerequisite for a change of this magnitude would be benchmarking before and after to make sure it actually makes sense from a performance perspective. There's no way to tell what the results of those benchmarks will be without running them, so let's discuss assuming that this won't happen if the benchmarks say it shouldn't—and instead discuss what the other pros and cons would be assuming the benchmarks check out.
Proposed Changes
1. Square brackets are now literals for Array values, not List values. In other words:
stuff : Array String
stuff = [ "foo", "bar", "baz" ]
This would be a breaking change.
2. The default data structure for libraries (in Core, etc.) becomes Array instead of List.
For example, this would mean the following changes for Dict:
This would also be a breaking change.
Motivation
A comment in another thread by @TheSeamau5 got me thinking about this and discussing some things with @evancz.
There are several reasons to do this:
1. Performance
We have already seen, in WebGL cases, specific examples of Elm programs that run noticeably faster when using Array instead of List on otherwise equivalent code. We have yet to seen the reverse, although granted that is harder to reproduce because literals produce List values and libraries tend to prefer List.
Because Elm's Arrays are implemented using Relaxed Radix Balanced Trees, the performance characteristics associated with (for example) recursively pattern matching should be substantially better here than they are with large vanilla JS arrays. For pattern matching on small lists, the extra overhead of instantiating N extra arrays may be comparable (and perhaps even less) to the extra overhead of instantiating N Cons cell objects, which is required to instantiate even a List that does not use pattern matching.
Benchmarks should be able to shed better light on this.
2. Familiarity to JS Programmers
As @TheSeamau5 said:
JS users are a big part of Elm's target. JS people are accustomed to having efficient indexing in collections and never really deal with linked lists. (I don't remember ever using a linked list in JS to be honest)
[Redefining] the square bracket syntax to mean array instead of list...would break with the ML family. But like @evancz pointed out in his talk, the goal is not to make Haskell or Standard ML more usable and more maintainable. The goal is to make Javascript more usable and more maintainable. Javascript has Arrays. JS people know arrays, not linked lists. We can cater to JS people by having square brackets mean Arrays.
I have encountered a significant number of capable JS programmers who did not study Computer Science in school, and as such have never even had occasion to use a linked list. Linked lists are not terribly hard to explain, of course, but their use by default does add fuel to the "Elm seems alien" fire.
3. Future Compilation Targets
Although this is not happening any time in the near future, it is worth thinking about how this proposal would affect Elm's long-term compilation target prospects.
One of the compilation targets with the most potential is machine code (or WebAssembly). There's no way to benchmark that yet, since Elm does not currently compile to these targets, but we do know that mandatory JS Object overhead will disappear, and that arrays enjoy significant performance benefits from locality over linked lists. Of course, we would need to run (future) benchmarks to ascertain the real impact.
A quick note to guide discussion: a clear prerequisite for a change of this magnitude would be benchmarking before and after to make sure it actually makes sense from a performance perspective. There's no way to tell what the results of those benchmarks will be without running them, so let's discuss assuming that this won't happen if the benchmarks say it shouldn't—and instead discuss what the other pros and cons would be assuming the benchmarks check out.
Proposed Changes
1. Square brackets are now literals for
Arrayvalues, notListvalues. In other words:This would be a breaking change.
2. The default data structure for libraries (in Core, etc.) becomes
Arrayinstead ofList.For example, this would mean the following changes for
Dict:Dict.keysreturns anArrayDict.valuesreturns anArrayDict.toListbecomesDict.toArrayDict.fromListbecomesDict.fromArrayThis would also be a breaking change.
Motivation
A comment in another thread by @TheSeamau5 got me thinking about this and discussing some things with @evancz.
There are several reasons to do this:
1. Performance
We have already seen, in WebGL cases, specific examples of Elm programs that run noticeably faster when using
Arrayinstead ofListon otherwise equivalent code. We have yet to seen the reverse, although granted that is harder to reproduce because literals produceListvalues and libraries tend to preferList.Because Elm's Arrays are implemented using Relaxed Radix Balanced Trees, the performance characteristics associated with (for example) recursively pattern matching should be substantially better here than they are with large vanilla JS arrays. For pattern matching on small lists, the extra overhead of instantiating N extra arrays may be comparable (and perhaps even less) to the extra overhead of instantiating N
Conscell objects, which is required to instantiate even aListthat does not use pattern matching.Benchmarks should be able to shed better light on this.
2. Familiarity to JS Programmers
As @TheSeamau5 said:
I have encountered a significant number of capable JS programmers who did not study Computer Science in school, and as such have never even had occasion to use a linked list. Linked lists are not terribly hard to explain, of course, but their use by default does add fuel to the "Elm seems alien" fire.
3. Future Compilation Targets
Although this is not happening any time in the near future, it is worth thinking about how this proposal would affect Elm's long-term compilation target prospects.
One of the compilation targets with the most potential is machine code (or WebAssembly). There's no way to benchmark that yet, since Elm does not currently compile to these targets, but we do know that mandatory JS Object overhead will disappear, and that arrays enjoy significant performance benefits from locality over linked lists. Of course, we would need to run (future) benchmarks to ascertain the real impact.