kephasp
But when it's only a feature available in niche languages or many languages make it unsafe or unreliable, then very few people will get to the point where it naturally pops up in their mind as a solution to their problem.
And in a more general sense, you can ask the compiler to forbid escape hatches altogether.
We already have a pragmatic, reliable solution.
But I see the need to change the code as a good thing when it is necessary: I don't want a dependency, inside or outside my codebase, to suddenly add network calls without me knowing it. Same goes for code that was pure and has become stateful. Not knowing this kind of fundamental change is a recipe for a nightmare.
It should be especially apparent with the recent supply chain attacks.
I don't doubt they exist but what we hear about are the opposite cases, where this was obviously not implemented and sensitive data was leaked.
http://wiki.erights.org/wiki/Walnut/Secure_Distributed_Compu...
http://www.skyhunter.com/marcs/ewalnut.html#proofOfPurchase
If the opaque handle is part of the Membrane pattern, you can even avoid most race conditions, because even during the indexing, the capabilities can be used to access documents and that removes the possibility of a TOCTOU race.
http://wiki.erights.org/wiki/Walnut/Secure_Distributed_Compu...
No it won't, not at the myriads of places they're needed when there are mutations all over the place.
Of course there are mutations in FP, so of course sometimes we need write locks and use things like CAS.
The point is not that FP doesn't use them, but that it uses them far less because they are needed only in a very limited number of places.
When I write code with STM, for example, the only uses of locks or CAS are in the STM engine, not in my Haskell code, and not even in my compiled code, because my code only ever reads memory that's immutable, and immutable data structures.
When I write pure code, there are no locks at all. And that makes it trivial to execute in parallel, either out of order or on several cores.
First of all, yes they do, you can use const on structs and objects and methods to ensure your C/C++ data structure is immutable.
But this is moot anyway:
> so those persistent data structures with their immutable API are implemented using mutable C structs or C++ classes
ZFS isn't something that's in memory, it's a file system… It's a data structure on disk, it's language-agnostic.
> That's because the set of mutable data structures is a strict superset of (i.e., contains all) the set of immutable data structures.
In theory, that's true. It's just a useless fact.
We use immutable data structures because they have benefits. Using the same data structure without immutability may just render it worse as a software tool. So people don't use immutable data structures with the immutability removed.
Immutable data structures are shaped by trade-offs like any other design.
I get that you can imagine it. I'm saying it wouldn't work in practice.
Also no one claims there's one immutable data structure that's faster than all mutable data structures. That's a ridiculous strawman argument.
And I don't think recursion is a GOTO that should be avoided. It's a useful tool that's easy to read and reason about.
When you need a state that you can rollback, an immutable data structure lets you share the parts of the structure that didn't change between states. That's what ZFS does and that's also how many transactional databases store data.
A mutable data structure would need an entire copy at each state change or it would need to store deltas and apply them backwards when you rollback. Both options are significantly slower than the immutable data structure (where rollback means updating a single pointer).
I'd be interested to see benchmarks.
I think you're right, it's the compiler that'll insert the locks according to the semantics of the language.
> For an out-of-order superscalar machine, mutability has nothing to do with it;
Yes it does, because it creates data dependencies. If a piece of code B loads the contents of memory where a piece of code A writes that's before B, then you can never execute B before or in parallel with A.
Even when you aren't writing concurrent code, mutability will prevent the CPU from using its internal concurrency to execute it faster.
Also, immutable data structures can include caches that are extremely simple whereas mutable data structure would face the problem if cache invalidation if they tried.
And a mutable data structure that would operate as if it's immutable? That's a nice recipe for an epic disaster.
I agree that the absence of liability enables this.
And why are you saying that requiring more memory would make a program slower? I don't see the link.
I don't need infinite memory to make a finite number of modifications to an optimized persistent data structure.