Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

But without immutable data structures, even in a language like C you end up with a very expensive copying for FP work.


Immutability typically requires lots of copying anyways, even in functional languages. There is no free lunch to be had.


I would say that the opportunity to freely share values without needing to defensively copy is of greater benefit, especially with an increasingly multicore future. Updating in-place also requires memory barriers, which don't scale.


Surely immutability works well when sharing values that shouldn't change anyways, in functional or other styles of programming.

What we are talking about here are immutable data structures that replace mutable ones, where mutability is pushed off to a higher reference cell (so instead of having a mutable set, we have a mutable variable that points to a new immutable version of the set). In both cases, locking is required if thread safety is desired.


> so instead of having a mutable set, we have a mutable variable that points to a new immutable version of the set

This is not at all how functional data structures work. You're assuming that the data structures are the same as non-functional data structures, but merely without the ability to mutate them. That is not correct. Proper functional data structures are implemented completely differently.

One obvious exception to this is the Swift language, which is not really a functional programming language, and it does not have functional data structures. It uses copy-on-write which is somewhat similar to what you describe, but is not how functional programming languages do it.


Why do you need a mutable variable? I thought we were discussing functional programming, in which case they should be rarely needed :)


If you want to keep track of world-current, then you need a variable that changes from world-0 to world-1 somewhere. Conceptual mutability (change over time) doesn't go away because you are using immutable data structures.


> If you want to keep track of world-current, then you need a variable that changes from world-0 to world-1 somewhere.

Putting on my FP hat: if you need the state of the current world then somewhere you need a side-effect free function that can report that state. If you're managing that state over time then you'll need other functions to handle that stream of immutable data.

Conceptual mutability very often isn't a change of data, it's a change in usage/reporting context.

And since we're in FP land we could compose those input and handling functions together and splay them across infinite vectors in both directions creating infinite functional chains of potential data interactions that are only calculated on demand based on incoming data. We can be highly confident that those calculations will scale from 1 to 1 million CPUs/machines. We can be highly confident about state-based testing of future states (a la Y2K bug). We can formally verify system behaviour and the underlying data flow. We can also safely and logically match those flows to new and interesting transformations through exhaustive pattern matching with guarantees that we are not impacting the current system behaviour...

Granted: there are likely mutable variables somewhere in that turtle-stack, but the overall systems relationship to state will not be impugned by them as long as they are appropriately contained.


In functional programming one should model change over time as a stream of immutable values, there is no "conceptual mutability" and no need for mutable variables.


"Things that change over time" = mutable. It's in the dictionary even.


Mathematics has successfully modelled change over time for hundreds of years without mutable memory cells in a computer.

Please don't build software that mutates my data. I want history/provenance and reproducibility. I don't mind the odd bit of optimisation, but your use of the phrase "conceptual mutability" would have me worried if I was a customer of yours :)


I can give you all that with imperative mutation:

https://www.microsoft.com/en-us/research/publication/program...

Of course, I'm a researcher who deals with this field daily, I'm not going to be your ideologue functional programmer who meets your ideological criteria for twisted language with a poor understanding of the wider field.


Less of the insults please, I've spent most of my career trying to escape the 'wider field'. The way we choose to model the world is clearly very different.


Because that's how you do inter thread communication in haskell.

https://hackage.haskell.org/package/base-4.10.0.0/docs/Contr...

>An MVar t is mutable location that is either empty or contains a value of type t.

>They can be used in multiple different ways:

>1. As synchronized mutable variables,


I did say they were rarely needed, if one does need interthread communication then yes an MVar or two will probably be used under the bonnet somewhere. Threads can however be used without MVars. Haskell offers many concurrency and parallel programming primitives.

Compare with C++ where every smartpointer holds mutable state (even if it points to a immutable value) and triggers a memory barrier whenever it is accessed.


You do not understand how immutable data structures work; you are thinking about them from the context of mutation when they are very much not based on that mode of change. They are entirely different ways to organize data, and the implementations are quite different from what you seem to think they are.


Strongly disagree. You can do radically less copying when GC is available. Yes, the graph needs to be traced eventually, but we know how to make GC fairly fast, especially if we can afford more memory.


Nobody really does that and it has serious multi threading problems. All the tricks to avoid copying are fragile in some way.


A major benefit of immutable data is worry-free sharing, and it's how you make persistent data structures fast. You simply can't afford to copy the whole world on every update.

There are some performance implications with NUMA, but there aren't serious multi-threading problems with immutable structures. Immutability means there isn't anything to race with, as long as initial construction is retired properly before other threads see anything, which is a compiler / runtime implementation problem, not an end user programmer problem.


I think you need to study how the BEAM VM works with immutable data and GC in order to revise your opinion a bit, here


Isn't Erlang single threaded (i.e. no shared memory between threads)?


IIRC there is a sort of database bolted onto the language where threads can stash data if they need to.


ETS, DETS, Mnesia are shared mutable state DB's included in the box


You really should read up on the implementation of FP data structures in languages like Clojure or Haskell before making statements like this. You sound silly. Clojure's immutable data structures are thread-safe, fast, and quite different than your apparent idea of what these kinds of data structures actually are.


This is not true at all. That's the whole point of functional data structures: they prevent copying for doing work on immutable data.


If you need a writable version of the data a copy must be made.

Now, you might argue such needs ought not arise. In practice, due to resource constraints, however, they often do.


That is not how functional data structures work. Check out Okasaki's book "Purely functional data structures" if you want to know what we are talking about here. There is not a whole copy of data being made. They use structural sharing and there is almost never a need for the implementation to make a data copy. You can have a piece of data that "changes" as it passes through the data flow, but in reality very tiny changes are actually happening behind the scenes, even if the perception to the programmer is that large changes are happening.


I know what you're talking about. I simply disagree with you. Not about "purely functional data structures", but about implementation details and how computation occurs in actual practice, in the context of their use.


The reason you disagree about implementation details is because you do not understand the implementations.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: