4 ms·
this explains virtually everything: - that's why OOP failed - side effects, software too liquid for its complexity - that's why functional and generic program
by bpavuk 10mo ago
this explains virtually everything:
- that's why OOP failed - side effects, software too liquid for its complexity
- that's why functional and generic programming are on their rise - good FP implementations are natively immutable, generic programming makes FP practical.
- that's why Kotlin and Rust are in position to purge Java and C, philosophically speaking - the only things that remain are technical concerns, such as JetBrains' IDEA lock-in (that's basically the only place where you can do proper Kotlin work) as well Rust's "hostility" to other bare-metal languages, embedded performance, and compiler speed.
- Ygg2 10mo agoHaving tried Kotlin in IDEA, I must admit their refactoring tools for Java are miles ahead of Kotlin. I don't know how strong lock in is.
- bpavuk 10mo agonear-infinite until they finish Kotlin LSP alpha. also, hot take: Kotlin simply does not need this many tools for refactoring, thanks in part to the first-class FP support. in fact, almost every non-Android Kotlin dev I have ever met would be totally happy with analysis and refactoring levels on par with Rust Analyzer. but even with LSP, I would still need IDEA (at least Community) to perform Java -> Kotlin migration and smooth Java interoperability.
- i_am_a_peasant 10mo agowhat is it with this take that oop is dead… even the linux kernel heavily uses OOP. inheritance is what has been changing in scope, where it’s discouraged to base your inheritance structure on your design domain.
- beagle3 10mo agoOOP is different things to different people, see e.g. [0]. Many types of OOP that were popular in the past, are, indeed, dead. Many are still alive. [0] https://paulgraham.com/reesoo.html https://paulgraham.com/reesoo.html
- bpavuk 10mo agoI'd personally declare dead everything except 3 and 4 because, unlike the rest, polymorphism is genuinely useful (e.g. Rust traits, Kotlin interfaces) trivia: Kotlin interfaces were initially called "traits", but with Kotlin M12 release (2015), they renamed it to interfaces because Kotlin traits basically are Java interfaces. [0] [0]: https://blog.jetbrains.com/kotlin/2015/05/kotlin-m12-is-out/#traits-are-now-interfaces https://blog.jetbrains.com/kotlin/2015/05/kotlin-m12-is-out/...
- i_am_a_peasant 10mo ago1 is about encapsulation, that makes it really easy to unit test stuff. Say you need to access a file or a database in your test, you could write an abstraction on top of file or db access and mock that. 2 indeed never made sense to me since once everything is ASM "protected" means nothing, and if you can get a pointer to the right offset you can read "passwords". This claim of enforcing what can and cannot be reached from a subclass to help security never made sense to me. 3 i never liked function overloading, prefer optional arguments with default values.. if you need a function to work with multiple types of one parameter, make it a template and constrain what types can be passed 7 interfaces are a must have for when you want to add tests to a bunch of code that has no tests. 8 rust macros do this, and it's a great way to add functionality to your types without much hassle 9 idk what this is
- jstimpfle 10mo agoIt always depends on the definition of OOP. Typical enterprise OOP is grounded of the idea of creating black boxes that you can't misuse. That creates silos that are hard to understand externally (and often internally as well, because their implementation tends to be composed of smaller black box objects). That practice may prevent some misuse but it creates a lot of problems globally because nobody understands what's happening anymore on the global scale. This leads to inefficiencies, both performance wise as well as development wise. Even with some understanding, there is typically so much boilerplate that changing things around becomes extremely tedious. Actually, I have some similar concerns about powerful type systems in general -- not just OOP. Obsessing about expression and enforcement of invariants on the small scale can make it hard to make changes, and to make improvements on the large scale. Instead of creating towers of abstraction, what can work better often is to try and structure things as a loosely coupled set of smaller components -- bungalows when possible. Interaction points should be limited. There is little point in building up abstraction to prevent every possible misuse, when dependencies are kept in check, so module 15 is only used by 11 and 24. The callers can easily be checked when making changes to 15. But yeah -- I tend to agree with GP that immutability is a big one. Writing things once, and making copies to avoid ownership problems (deleting an object is mutation too), that prevents a lot of bugs. And there are so many more ways to realize things with immutable objects than people knew some time ago. The typical OOP codebase from the 90s and 00s is chock-full with unnecessary mutation.
- ksclk 10mo ago> the idea of creating black boxes that you can't misuse Could you please expand upon your idea, particularly the idea that creating (from what I understood) a hierarchical structure of "blackboxes" (abstractions) is bad, and perhaps provide some examples? As far as I understand, the idea that you compose lower level bricks (e.g. classes or functions that encapsulate some lower level logic and data, whether it's technical details or business stuff) into higher level bricks, was what I was taught to be a fundamental idea in software development that helps manage complexity. > structure things as a loosely coupled set of smaller components Mind elaborating upon this as well, pretty please?
- 10mo ago
- rightbyte 10mo agoI wouldn't say OOP failed in any general sense. There seem to these strawman exceptions and Convay's law is often what actually is the problem.
- mrkeen 10mo agoI'm all for FP, but there's no way the mainstream is taking side-effects seriously. Neither Kotlin nor Rust cares about effects. Switching to Kotlin/Rust for FP reasons (and then relying on programmer discipline to track effects) is like switching to C++ for RAII reasons.
- bpavuk 10mo agoside effects are not necessarily a bad thing. unintentional side effects are. with some exceptions, such as UI frameworks, I find it harder to unintentionally create a side effect. also, UI is basically one huge side effect. Kotlin and Rust are just a lot more practical than, say, Clojure or Haskell, but they both take lessons from those languages.
- mrkeen 10mo ago> side effects are not necessarily a bad thing. unintentional side effects are Right. Just like Strings aren't inherently bad. But languages where you can't tell whether data is a String or not are bad. No language forbids effects, but some languages track effects.