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

OO context is internalized linguistically, via lots of metaphors. Those metaphors can lie, of course, but your brain can apply abstractions to the state of the machine to deal with its complexity, for better or worse. Ideal FP debugging, which I don't think exists in practice, relies on ultimate truth with equational reasoning realized through techniques like referential transparency. In the ideal case, you just reason about the equation and there are no hidden surprises, fuzzy metaphorical reasoning is minimized. In practice, there is still plenty of metaphorical reasoning going on for any non-trivial program as even explicit state necessarily becomes implicit as it increases in quantity (our brains can't handle seeing everything even if it is technically all in front of us).

OO thinking optimizes for the less ideal cases that are far more common. Ideal FP has this ideal mathematical view of the world that rarely pans out in practice, while less ideal FP just resorts to OO-style metaphors and abstraction in practice. For the kinds of experiences I work on (heavily reactive, lots of state, complex interactions), this works well for me, and we are developing techniques to make it less painful (live programming). "Worse is better", as RPG would say.



It sounds like we agree that lexically scoped immutable values are easier to understand, either precisely or with fuzzy metaphors. I'm not sure what "ideal" FP is or how it might have a certain "mathematical view of the world". The features I mentioned are just a subset of semantics that every high-level language programmer already knows, but are pointlessly hobbled in popular languages.

Why should expressing something basic like a tagged union require a detour through the quirks of a particular object system? Ditto for polymorphism, modularity, etc, etc. Clearly we disagree on how useful objects really are in practice, fine. Why not add these domain-specific features on top of a core language with simple semantics? It worked fine for lisps. Luckily, after a couple of decades of "everything is an object!" nonsense, that seems to be where newer languages (Rust, Swift) are headed.


You mean CLOS? This is exactly the context RPG coined "worse is better".

Languages are not so much a collection of features but mindsets. So polymorphism, dynamic dispatch, subtyping, etc...do not define OOP so much as they are leveraged by those languages to enable reasoning with names and metaphors. Calling them just domain specific features misses the point like talking about some dish only as the sum of its ingredients.

Tagged unions and GADTs are quite different in expressiveness and modularity, I still remember the mega case matches used in scalac. Should one function really be given so much functionality when a layered design with several virtual method implementations would be much more amenable to change and modular reasoning? Well, I guess it's a matter of how you view code.


  Languages are not so much a collection of features ...
If you want to define objects precisely, even just to have a language spec, they are absolutely made up of sums, products, recursive types, etc. Whatever useful metaphors one might have to work with objects doesn't change what they actually are. If you give the programmer access to these building blocks, you get ML.

  Calling them just domain specific ...
I meant that the particular way they're combined to get OOP is domain-specific.

Again, I'm just asking: why mess with the basics? Why require encoding simple, universal concepts in terms of an ad-hoc object system? You can still have an object system on top, if you find that helps with the really complicated cases, but why encode the parts of your code that are simple in terms of much more complicated, derived concepts?




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

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

Search: