4 ms·
The key insight is that immutability is not an end in itself, it's a tool to give us referential transparency. If a language can allow mutability in an area of
by michaelfeathers 10y ago
The key insight is that immutability is not an end in itself, it's a tool to give us referential transparency.
If a language can allow mutability in an area of code without allowing side effects to escape from it we can have all of the reasoning advantage that FP gives us at a level above the mutations. We can also have the performance we want.
- stcredzero 10y agoThe key insight is that immutability is not an end in itself, it's a tool to give us referential transparency. How about a programming environment tailored for small simulations or games? I could imagine such an environment maintaining referential transparency without strict immutability. Rather, such a system could provide a kind of "poor-man's" immutability by only allowing pure functions that take state from tick N and output state for tick N+1. Perhaps such a system could even achieve high performance by exploiting its constraints? Maybe the language could essentially be built on top of a custom VM and around the mechanism of bump allocation, read/write barriers, and Beltway garbage collection?
- efnx 10y agoThis is what StateT in Haskell is for.
- samuell 10y ago> If a language can allow mutability in an area of code without allowing side effects to escape from it we can have all of the reasoning advantage that FP gives us at a level above the mutations. We can also have the performance we want. As far as I see and can tell from experience, this exactly the power of the black-box processes of Flow-based Programming (FBP), communicating only via message passing (on buffered channels) [1]. FBP processes can be compared to "functions", but are free to change state etc. The "only communicate via message passing" means funny side-effects are effectively contained to the process itself. Furthermore, I would argue that FBP, via its specification of keeping the network connectivity separate from the process implementation, makes FBP programs so extremely much more composable than most typical FP programs, which often allow references to other functions be hard-coded inside function code. It is like making the call graph of an FP program declaratively configured by a list of processes and connections: Processes: A (ports out1, out2) B (ports in1, out1) C (ports in1, out1) Connections: A.out1 -> B.in1 A.out2 -> C.in1 etc. I wrote a little text processing app in this style some time ago (The network connectivity scheme can be seen here: https://github.com/rdfio/rdf2smw/blob/master/main.go#L100-L125 https://github.com/rdfio/rdf2smw/blob/master/main.go#L100-L1... ) and was amazed by the clarity and composability that emerged, even though I just used my own little experimental subset of full FBP ( http://flowbase.org http://flowbase.org ). As far as I can tell, this helped me going from first line of code to finished app go extremely fast ... app written in 2 days without ever really getting stuck in any strange bug due to bad code organization, which use to happen all the time otherwise. [1] https://en.wikipedia.org/wiki/Flow-based_programming https://en.wikipedia.org/wiki/Flow-based_programming
- samuell 10y agoOuch, didn't see that the formatting got lost before editing was frozen ... should be: Processes: A (ports out1, out2) B (ports in1, out1) C (ports in1, out1) Connections: A.out1 -> B.in1 A.out2 -> C.in1