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

Another option is for the language's runtime to use copy-on-write (COW):

https://en.wikipedia.org/wiki/Copy-on-write

So basically every buffer can be made immutable and then only copied when written to, using something like refcounts and diff trees to internally track mutations from an immutable parent buffer. Languages like Clojure due this to manage state. I believe the Redux also does this internally, although I've only studied it and haven't had a chance to use it professionally.

In practice, this looks like a language where everything is value-based instead of reference-based.

So like, in C# where you pass objects by reference, a COW language passes everything by const value. Then an imperative language statically analyzes the code to detect mutation (my own theory is that this can never be accomplished with 100% certainty, at least not with a simple implementation). So basically buffers act like Git instead of byte arrays, creating a new snapshot with every mutation.

Or functional languages can disallow mutation altogether, or reduce the code into its most minimal representation and handle mutation at special breaks in execution (like monads). I'm grossly oversimplifying all of this and probably using the wrong terminology, but am more than 50% confident that I can derive what I'm talking about, so will just go with it hah.

I think that the complex imperative implementation I'm talking about is probably Rust. The simple functional implementation would look like a pure immutable Lisp running within the Actor model, handling state only through IO, and dropping monads altogether. The catch being that complex functional code might have so many breaks in execution that it would practically be happening on every single line and begin to look like an imperative language with all its flaws. This is the primary reason why I shy away from impure functional languages like Haskell, because I don't think they have solved this core issue of mutation clearly enough (not to mention, I think functional language syntax is generally write-only and not readable by others or yourself in 6 months hahah). As far as I'm concerned, this is still an open problem.

In another life, I want to make an imperative language that's primarily immutable, that uses higher order functions (or better yet, statically analyzes code for side effects and converts foreach loops into higher order functions automagically), and transpiles to a purely immutable Lisp. It would be associative array-based and look like Javascript. The idea being that we could write code in the human-readable imperative style and let the computer distill it down to its pure functional equivalent.



> not to mention, I think functional language syntax is generally write-only and not readable by others or yourself in 6 months

This is rather tangential, and sorry to hijack your message to get on my soapbox, but I and many others who program in Haskell and a dynamic language (Python in my case) find that Haskell code we've written is far easier to come back to than code we've written in the dynamic language.


Ya I tend to agree actually, but in the real world I keep getting scolded for being too "functional". I think that it might come down to the easy != simple argument, which the whole CS industry is still grappling with in other areas as well.


I also think an imperative language that's preliminary immutable, that uses higher order functions (and some other techniques to get performance). I think this is the future of programming and can be taken much further than current languages.

<shameless self promotion> I'm working on a language for this. Right now it uses LLVM to compile to native and uses HAMT (see Clojure) to store data. It looks similar to Javascript. https://github.com/Floydlang/floyd

There are no references in Floyd, only values. This opens possibilities of great performance without complex/risk analysis of ptrs and aliasing.

The next phase is to create an intermediate AST (equivalent to your idea about compile-to-LISP) that lets programmer/tool tweak how the data structures map to the HW.

I'd love to pick your brain about these ideas!


> The idea being that we could write code in the human-readable imperative style and let the computer distill it down to its pure functional equivalent

Here we are, folks pulling their hairs for decades wrt how to most efficiently trans/compile higher-order FP idioms to minimal-overhead imperative --- and you want to go the other way around!

Kidding aside, the "functional sub-language" of cell-lang.net has a feature like this, functions are pure but you get the imperative sugars (loops, branches) while preserving purity guarantees like referential transparency.


For reference, Redux doesn't "do anything" internally. It only calls the reducer function _you_ provide, and you are supposed to follow the rules of immutable updates inside that reducer:

https://redux.js.org/recipes/structuring-reducers/immutable-...




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

Search: