5 ms·
after some functional programming experience, you may learn that functions just compose more elegantly than objects. "Objects are a poor man's closures" (NN)
by toolslive 8y ago
after some functional programming experience, you may learn that functions just compose more elegantly than objects.
"Objects are a poor man's closures" (NN)
- jcmoscon 8y agoI can't do OO anymore after I learned FP!
- pdpi 8y agoKeep trying, then. I found myself in that space for a while, but everything kind of made sense when the "Erlang is the most object-oriented language in the market" meme clicked into place: a (micro-)service, an Erlang-style actor and an object are almost the exact same unit of abstraction, applied in different ways. The model is always the same: you communicate by message passing — and, for the most part, you want your objects to be given orders rather than be asked questions. When I went back to Java, it became evident how damaging the "everything is an object" mentality of Java really is — it really pushes people towards a whole bunch of anti-patterns. One obvious example is that structs are not objects, and you shouldn't try to make them be. Getters/setters are a clear sign that your entity is a struct rather than an object — if you're at that stage, stop trying to apply OOP principles around its design. Another recurring problem is abusing inheritance, and underusing interfaces. I've written maybe 2-3 abstract classes over the last few years, and, when I code review a PR with any abstract classes (or inheritance of any sort) in it, I can almost always get the original author to factor it away while agreeing that it was a problem in the design. I suggest giving Kotlin a try. Data classes are as close to structs as you'll ever get in the JVM (until Valhalla ships), delegation is crazy easy to achieve, inheritance is heavily discouraged (by having everything be final by default), bare functions and extension functions help keep interfaces clean, and the lambda situation is much better than Java's (receiver lambdas are the language's killer feature, IMO).
- Koshkin 8y agoAren't these things orthogonal to each other?
- crimsonalucard 8y agoOOP as described by java and C++ involves a graph of objects changing each others' state. This is not an orthogonal pattern to functional programming. If you're thinking of functions operating on immutable objects and returning new objects then that is not typically what we refer to as a OOP pattern though technically it may fit the definition.
- pjmlp 8y agoJava and C++ are just one way of doing OOP. More universities should spend time teaching BETA, Self, CLOS, Smalltak, component based architectures.
- crimsonalucard 8y agoI know. The dominant paradigm has changed the definition of the vernacular. Right now the default definition of OOP is the Java and C++ way unless you explicitly state otherwise.
- pjmlp 8y agoI wonder how many of us managed to use Smalltalk and CLOS then.
- pddubs 8y ago"Objects are a poor man's closures" Yea but don't forget that closures are a poor man's objects!
- bachmeier 8y ago"A closure is an object that supports exactly one method: 'apply'." -- Guy Steele
- HumanDrivenDev 8y agoIn some languages they also have methods like 'curry', which further blurs the lines.
- jimbokun 8y agoToo bad it took the Java language committee forever to figure out they can just use lambda syntax to make those objects look like functions.
- pjmlp 8y agoWhen you have too many cooks and care about keeping backwards compatibility, things take time.
- HumanDrivenDev 8y agoIn my career I started off with OO/imperative, then got heavily into functional programming. I came out at the other end strongly preferring immutable objects over struct+procedure function programming. It's a style I consider deeply OO, and still has referential transparency, but which usually gets ignored in these discussions.
- arwhatever 8y agoMay I ask for what reason? My guess: encapsulation and/or data hiding? That's the biggest thing I miss when doing FP.
- HumanDrivenDev 8y agoI find it to be cleaner than having module M with struct t and functions M.create: () -> t, M.doStuff: t -> 'a. Which is what tends to happen. It just looks like immutable objects for slow learners...