3 ms·
5. Once created, objects and collections must be immutable. So this language would not be general purpose, as it would not be suitable for high-performance com
by leephillips 6y ago
5. Once created, objects and collections must be immutable.
So this language would not be general purpose, as it would not be suitable for high-performance computing.
Large scale simulations almost always involve arrays that are modified in place. Being able to somehow declare a collection to be immutable would be highly useful, but not having the option of mutable collections limits the kinds of problems that can be approached with the language.
- Athas 6y agoI'm not going to claim that mutability is never useful for performance, but many large scale simulations can be expressed quite elegantly using bulk operations on arrays or other structures, with no mutability in sight. Both particle simulations a la n-body and stencil operations are in this category. An efficient low-level implementation of such bulk operations involves mutable updates, just like any functional language is compiled to "impure" assembly code, but the programming model used for application programming can remain pure.
- leephillips 6y agoI concur, I should have been more precise in my comment.
- vram22 6y agoInteresting. Can you explain, with a somewhat simple example, how this can be efficiently implemented, or at all? I mean preserving the appearance of immutability at the source language level, while mutating the original structure under the hood for performance.
- zabzonk 6y agoC++ supports this via the mutable keyword https://stackoverflow.com/questions/105014/does-the-mutable-keyword-have-any-purpose-other-than-allowing-the-variable-to https://stackoverflow.com/questions/105014/does-the-mutable-... though not particularly for performance purposes.
- deleted 6y ago[deleted]
- Athas 6y agoAny vectorised operation in Numpy is an example of this. The pure subset of Numpy can be used to write useful programs, but the Numpy functions/methods are mostly implemented in impure C. Another example is completely pure array programming such as in Accelerate[0] or Futhark[1]. [0]: http://www.acceleratehs.org/ http://www.acceleratehs.org/ [1]: https://futhark-lang.org https://futhark-lang.org
- kdmccormick 6y agoNot very knowledgable on this myself, unfortunately, but I believe that in graphics programming, shaders written in GLSL often take the form of a series of functional, mathematical transformations of vertices. Those transforms are run in the GPU as highly parallelized array operations, probably using a lot of mutable state. But those details are mostly hidden from the shader programmer.
- vram22 6y agoThanks to all who replied.
- senkora 6y agoA somewhat related idea is called "benign effects." The idea is that you write code with an immutable interface that uses mutation in its implementation. So there are "effects" (non-functional state changes) that are encapsulated ("benign"). I learned this term in reference to Standard ML at CMU. This is different from what you're asking because it isn't a compiler optimization and it isn't actually checked by the language at all, but it works pretty well in practice. It's like unsafe in Rust: you write most of your code assuming a useful property that you then break in the small percentage of code that needs to break it.
- catlifeonmars 6y agoIsn’t it possible (at least in theory) to make mutability an implementation detail of the compiler/runtime? Rust’s borrow checker approaches this, but the abstraction leaky or nonexistent. Additionally, many high performance computing applications (e.g. Tensorflow) abstract away expensive mutable operations, so at least in theory, it should be possible to isolate mutability to small segments of code where mutability is opt-in.
- retrac 6y agoYes, Haskell as a pure functional language does this too. A naive copy-by-value handling of lists will usually end up in the same order of magnitude for performance as mutate-in-place linked lists in C. The compiler can track those immutable values and just mutate them in place, when it can guarantee that's a safe operation. The vast majority of the time, you can get away with just copying a pointer or renaming, not the whole variable. The caveat is that, in my experience, it's a fair bit harder to reason about performance, as the execution model is even more abstracted away from the hardware than even something like the C model is (which is no longer a good fit either, in this era of speculative execution and multi-level caches.)
- msla 6y ago> The caveat is that, in my experience, it's a fair bit harder to reason about performance, as the execution model is even more abstracted away from the hardware than even something like the C model is (which is no longer a good fit either, in this era of speculative execution and multi-level caches.) One solution is to have a tool developed and distributed along with the compiler (so it can never fall out of sync with the compiler, that's why) annotate the code with notes about performance.
- heavenlyblue 6y agoI think if performance is part of the requirements of your code, then performance must be a part of your type signature. For example, a tail-recursive function needs to have it’s type as tail-recursive.
- bgorman 6y agoF# and OCaml have mutable arrays.
- jasonhansel 6y agoLinear types fix this problem, by letting you prove to the compiler that logically immutable operations can be implemented as in-place updates.
- qppo 6y agoMutability is an abstraction, it doesn't forbid in place modification of data. What it forbids is other code accessing data that holds references the array prior to the modification, which creates a logical error.