3 ms·
This is incredibly simple yet incredibly powerful, and something that everyone who becomes proficient at delivering things of value learns eventually, but is ra
by jimbokun 2y ago
This is incredibly simple yet incredibly powerful, and something that everyone who becomes proficient at delivering things of value learns eventually, but is rarely taught so succinctly.
By the way, for the programming case, this is a big part of the reason functional programming is so powerful. Avoiding shared state allows you to write your outline of smaller and smaller pieces, then write each piece as a stateless function, then pipe your data through a graph of these functions.
With other programming paradigms, you can't just knock out all the little pieces without thinking about the other pieces because the state is all tangled up. Which slows you down.
It's surprising how very simple the individual components can be, even for very complex systems, when following this approach.
- intelVISA 2y agoYes. Ideally a codebase is just a monorepo of pure functions and apps are simply the control flow that weaves them. Write reusable libraries not microservices (silos). Sadly incentives are not aligned for this at scale - easier to buy cloud SaaS n+1 whose sales team insist "this $badware solves a Hard Problem" while your devs sit in ceremonies all day.
- jimbokun 2y agoThat's why Paul Graham started Y Combinator and handed the entrepreneurial reins to the developers instead of the project managers and MBAs and made billions in the process.
- intelVISA 2y agomaybe that was true once, as I understand it current YC is just a finishing school for t1 grads to pad the CV between graduation and working as a "thought leader" (lol)
- jahewson 2y agoI’m not so convinced that this is a property of functional programming as much as simply good programming. I’ve seen functional programs that pass around huge data structures that couple functionality. I’ve never seen the benefit of performing elaborate monadic dances to avoid state that would have been simpler to represent in a non-functional language.
- djtango 2y agoOne benefit there if it's statically typed is that you've pushed some correctness validation into the compiler. In dynamic languages like Clojure it is far too easy to couple functionality and write implicitly imperative but superficially functional code. Something I'm guilty of because it's too easy to do and takes a lot of experience and discipline to avoid.
- jimbokun 2y agoWell this seems to me a violation of the spirit of functional programming, even if it's written in a functional programming language. Isolating state is the key principle. Philosophically you could say a program following this principle written in an object oriented or procedural language is more "functional" than a program that passes around a big tangle of state in a single data structure written in a functional language.
- jahewson 2y agoYes, indeed. That’s my point really. Functional programming only delivers its promised benefits in the hands of skilled users. We’re just not used to seeing that given that it’s at a self-selecting crowd. Lambdas, ADTs, immutability - all of these exist in non-functional languages now and it’s great! It seems to me that this may be where the bulk of the value is, rather than functional purity.
- viraptor 2y agoTo be fair to other styles, we generally learned already that shared state is bad. It's avoided in basically every language/service these days. It may be enforced more strictly with functional programming. But "With other programming paradigms, you can't just knock out all the little pieces without thinking about the other pieces" is taking it too far. For example, you want to add email sending to your app? The library for it is a little piece of software independent of the rest.
- diggan 2y ago> To be fair to other styles, we generally learned already that shared state is bad. It's avoided in basically every language/service these days. I don't know how true that really is. JavaScript added `class` relatively late in it's lifespan, and most JavaScript/TypeScript projects use `class` to hide shared state/mutations behind that interface, in the name of `encapsulation`, rather than just passing stateless data from function to function. Both patterns obviously has their places, no silver bullets and all that, but you'll have a hard time finding any relatively popular JS/TS project that doesn't overtly rely on shared state one way or another.
- viraptor 2y agoObjects with instance variables don't automatically mean the state is shared. A JS event loop holding onto a simple object with some data is not practically different from a functional event loop with some big context carried between executions. One will have mutations, the other will do effectively the same with tail call and some IO executor. In both you have to add the shared state explicitly, one just makes it way harder. > you'll have a hard time finding any relatively popular JS/TS project that doesn't overtly rely on shared state one way or another That's sampling bias. Where's the thousands of the event driven DOM UI Haskell projects, which doesn't rely on shared state?
- diggan 2y ago> Objects with instance variables don't automatically mean the state is shared. Agree, but JS's syntax and constructs are almost begging the user to encapsulate their state in classes and instances and share those instances between function calls, rather than passing the data itself around. This is very visible if you browse the various JS APIs as well.
- brabel 2y ago> With other programming paradigms, you can't just knock out all the little pieces without thinking about the other pieces because the state is all tangled up. Which slows you down. I don't think so. I use the style of programming described in the post, and my code is mostly OOP, but almost entirely without mutable state. You may claim "but that's not OOP", but I would reply that FP is not about having no shared state either (which a lot of people were quick to tell me when I myself made the mistake of confusing immutability with FP, as almost all FP languages allow mutation without much cerimony), that's just something encouraged in FP, and it's something that can be easily encouraged in OOP as well.
- jimbokun 2y agoI think FP has a much stronger emphasis on avoiding shared state than classical OOP precepts. Smalltalk style OOP is about encapsulating state in objects, which is queried or implicitly updated by sending messages to the object. Whereas FP emphasizes a cleaner separation of functions and the data structures those functions operate on. Interestingly, Erlang is very much a functional language. But Erlang procedures are a lot like Smalltalk objects, as explained by Joe Armstrong. You send messages to a pid (process id) which then update some state held by the process and possibly sends back a value in response. But the new state is always computed by a pure function. Maybe this is similar to your design philosophy?
- mandeepj 2y agoState is not tied to type of programming language but to the App architecture
- igornadj 2y agoTo tack on to the other responses, this is just good programming. The testability/maintainability/extendability tenets push you to write small pieces of functionality before wiring it all together.
- CyberDildonics 2y agoWith other programming paradigms, you can't just knock out all the little pieces without thinking about the other pieces because the state is all tangled up. Which slows you down. Of course you can. I don't know why people think you can't write functions that don't change a global state in any programming language. Pretty much any experienced programmer does that whenever they can.