5 ms·
Well said. And #3 is also an area where Functional Programming falls completely flat. There is simply no easy way in any FP language that I know to capture su
by hota_mazi 7y ago
Well said.
And #3 is also an area where Functional Programming falls completely flat.
There is simply no easy way in any FP language that I know to capture such a simple mechanism as: "Reuse 90% of this piece of code but alter just this 10%".
Specialization is a very, very powerful aspect of OOP, one that's extremely easy to explain and which comes in handy to model a surprisingly wide variety of problems.
- colllectorof 7y agoFunctional programmers will reply that you can use partial evaluation and higher-order functions to do that. The sad reality is that since so many people are only familiar with the strawman version of OOP rather than the real thing intelligently discussing the advantages and disadvantages of these paradigms is very hard.
- hota_mazi 7y agoYes, I've heard them say that indeed. They often gloss over a lot of issues about these. For example, partial evaluation is limited by the fact that parameters need to be ordered a certain way and you can't realistically cover all combinations. Higher order functions don't enable any kind of useful specialization at all. And of course, all modern OOP languages also support higher order functions, so they are the ones giving you more tools.
- tome 7y agoCould you give some concrete examples? At the moment it's just assertions.
- nitrogen 7y agoDo any functional languages support partial evaluation using named parameters? That would solve the parameter ordering complaint. As for higher order functions you would write a function that does the 90% and accepts a function parameter for the other 10%.
- kragen 7y agoOCaml has named (“labeled”) parameters, and of course you can use combinators like flip to bind positional parameters like the second or third. I'm not sure what the relevance to inheritance is, though, and “partial evaluation” usually means an optimization strategy rather than just currying.
- catalogia 7y agoRacket's curry supports keyword arguments. https://docs.racket-lang.org/reference/procedures.html#%28def._%28%28lib._racket%2Ffunction..rkt%29._curry%29%29 https://docs.racket-lang.org/reference/procedures.html#%28de... (god links into the racket docs are ugly...)
- hota_mazi 7y ago> As for higher order functions you would write a function that does the 90% and accepts a function parameter for the other 10%. Surely you see how this doesn't scale, right? You would need to first write your code, then abstract every single piece of it as a call to a function passed in parameters. Now your function is accepting five different functions in parameters, and calls them. This is a terrible and impossible to scale way to emulate class specialization.
- ErotemeObelus 7y ago> Surely you see how this doesn't scale, right?... This is a terrible and impossible to scale way to emulate class specialization. <Kelsey Grammar Voice> Heretic! Have not the elders of our holy church indeed canonized the ex cathedra dogmas of variable immutability and higher-order functions with closed variables? And indeed have we not been in ecumenical agreement over the incomprehensible mystery of the trinity of higher order types, dependent types, and polymorphic types? Dare ye teach heresy proudly with thy contumely? Anathema sit!
- tome 7y agoSo put those parameters in a single record type and just override the 10% of them that you need to.
- CBLT 7y ago>There is simply no easy way in any FP language that I know to capture such a simple mechanism as: "Reuse 90% of this piece of code but alter just this 10%". Honest question: why does the Common Lisp Object System not do this for you?
- hota_mazi 7y agoHonest answer: you have a point :-) Yes, CLOS offers all of that. I just didn't quite consider it to be in the bucket of FP languages I had in mind (which to me means: statically typed, and some derivative of Haskell or OCaml).
- xyzzyz 7y agoAnd #3 is also an area where Functional Programming falls completely flat. There is simply no easy way in any FP language that I know to capture such a simple mechanism as: "Reuse 90% of this piece of code but alter just this 10%". Haskell’s typeclasses and OCaml modules solve this problem neatly. It is not as easy as in Java, because you need to spend a few minutes thinking how to abstractly specify the interface you expect, but really if your object hierarchy is supposed to satisfy Liskov’s substitution principle, you need to do that just the same.
- hota_mazi 7y ago> Haskell’s typeclasses and OCaml modules solve this problem neatly. Neither do, really. Imagine you have an existing typeclass with three functions. How do you create your own typeclass that reuses two of these three functions but your own instance reimplements the third one? Try it. It's pretty much impossible, or at least not without a lot of boilerplate and forwarding.
- xyzzyz 7y agoNot sure what you mean, exactly. Could you sketch a simple example with some types and typeclasses?
- callmeal 7y agoThis is how it would be done in Java: class Parent { public void first() {}; public void second() {}; public void third() {}; } class Child extends Parent { @Override public void third() {}; //change implementation of third function, reusing the first two. }
- mrkeen 7y agothird = first + second
- Hermitian909 7y agoI would accomplish this in modules in the following way. I use reasonML syntax but it's OCaml under the hood module Parent { let first = () => (); let second = () => (); let third = () => (); }; module Child { include Parent; //add parent funcs to namespace //@Override let third = () => (); }; I make regular use of this pattern production.
- deleted 7y ago[deleted]
- gigatexal 7y agoGive me a new function that is a partial of some other function where I can define the 10% to change than any of the arcane polymorphism magic.
- Mathnerd314 7y agoIt doesn't seem hard to add a parameter and then make two stubs: complex_function small_part = do a <- complex_thing_a b <- small_part a other_variables_in_scope more_complex thing original = complex_function orig_version mine = complex_function my_version There are some issues if you have a lot of parameters where you might want a record to pass them around, but specialization is easier to use than inheritance in all the cases I've seen.
- dwohnitmok 7y agoI actually think FP languages I know of have this functionality, although it's used to differing degrees in each ecosystem. ML modules have modules and functors, which can exactly mimic this and in fact can be even more flexible because they are structurally rather than nominally typed. Clojure can get some of this via multimethods, but it's not quite the same thing. Haskell has Backpack. This is fairly new, but takes an approach similar to ML modules. (Interestingly enough to your point elsewhere in this thread, this is a good example of how type classes were not sufficient for this use case). Scala has it, but that's cheating :). Although it does have a really cool thing which is that every object instance is itself an importable package, which leads to some really nice code reuse at times. Stepping back, I actually think "Reuse 90% of this piece of code but alter just this 10%" is actually best captured just with splitting things up into functions/procedures in imperative and functional programming languages, rather than building a large class hierarchy, but that's another story altogether. EDIT: I suppose what you're talking about specifically is overriding an already implemented method, which you can get via module name shadowing and re-exporting of a parent module as Hermitian909 points out elsewhere.
- voidhorse 7y agoHaskell’s typeclasses[1] support this use case—though they are oftentimes a bit clukier to use than OOP approaches. [1]: https://en.m.wikipedia.org/wiki/Type_class https://en.m.wikipedia.org/wiki/Type_class
- camgunz 7y agoIsn't this just composition? Function A calls B, C, and D. You make a new function E that calls B, C and F. Or higher order functions like map?
- unexaminedlife 7y agoWhen I stopped thinking about code and data as being inherently intertwined it liberated me as both an OOP and Functional programmer.
- wowthisanacct 7y agohttps://news.ycombinator.com/item?id=21304512 https://news.ycombinator.com/item?id=21304512