3 ms·
> Essentially, the fusion of [functional and object-oriented programming] can have a power that neither of the two paradigms individually can have. I tend to d
by cies 12y ago
> Essentially, the fusion of [functional and object-oriented programming] can have a power that neither of the two paradigms individually can have.
I tend to disagree. OOP can borrow some FP stuff (as we see with map/each/select/reject in Ruby for instance, or lambda's in Java); or to take it broader: imperative can borrow some from declarative.
But "fusing" the two will cause FP's ease-of-reasoning ("just functions and data structures") to be lost. On top of that, when using a strictly typed discipline (like Scala does), the types will become really messy.
So when it comes to FP, I like it pure-and-typed (a la Haskell), or untyped (like the Lisps), but not mixed-paradigm.
When it comes to OOP/imperative I like to mix in as much of FP/declarative as makes sense (like Ruby does for instance).
- seanmcdirmid 12y agoI agree with this, but I always used scala as a OO language mixed with FP features. I prefer OO, but many in the scala community were adamantly on the FP side (7 years ago, not sure today). About OO: subtyping leads to semi unification which really complicated type inference. I'm beginning to think it might not be a good idea to combine FP unified features with OO semi unified features.
- cies 12y ago> I always used scala as a OO language mixed with FP features Good point! Must admit that I did not write a lot of Scala, but I always approached it from the FP side :)
- pjmlp 12y agoSo you don't use type classes in Haskell? Neither touch F# or OCaml. Nor CLOS in Lisps.
- cynicalkane 12y agoA major advantage of typeclass polymorphism vs dynamic polymorphism is that typeclasses enable parameteric polymorphism, and parameteric polymorphism enables reasoning that is lost if types can "pretend" to be a supertype. For instance, in Haskell you can prove a functor instance has at most one implementation (if we disallow diverging values), uniquely given by fmap id === id. GHC can automatically derive it for you. If you have dynamic polymorphism this is lost because now you can have "nonuniform" functor instances that behave differently for different types while still satisfying the functor laws. More generally, parameteric polymorphism eliminates a large number of "behavior surprises" that can lurk in OO code. And with existential types I never find myself missing dynamic polymorphism. Similarly, in Clojure, if I find myself using dynamic behavior, it's either to interact with Java or as a hacky version of parameteric behavior.
- skybrian 12y agoI don't understand your example. Is there an explanation for people who aren't Haskell experts somewhere?
- deleted 12y ago[deleted]
- frowaway001 12y ago> For instance, in Haskell you can prove a functor instance has at most one implementation How would one do that?
- tome 12y agoI believe the technique is relational parametricity, but I don't actually know how to apply it in this case.
- cies 12y ago> So you don't use type classes in Haskell? Sorry, how does this remark relates to my comment?
- dllthomas 12y agoI assume it was intended to be 1) an assertion that type classes are OO, and 2) an implication that using them is mixing OO in your FP (which you said you don't like to do), and so 3) an allegation of inconsistency which should be clarified or examined. There are a few places where this chain is weak.
- pjmlp 12y agoYes.
- cies 12y ago> an assertion that type classes are OO They never occurred to me as OO. Could someone explain this?
- pjmlp 12y agoSure, since I mentioned it. Sorry if I misassume your OOP experience. Many think about OOP as introduced by Simula/Smalltalk, or how it is served by Java/C#... ones. However there are many other ways of doing OOP, which many of us in the old (early 90's) experimented with, while OOP was striving to become mainstream. Type classes in Haskell and their use, can be easilly mapped to interfaces/protocols/traits/... in the OO world. From the OOP point of view, type classes are a group of operations that can be applied to a given type and refereed to by a specific name. Which allows writing polymorphic operations over types that support a specific a specific group of functionality. Polymorphism and data hiding are the common concepts across all OOP proposals. As for the remaining concepts, there are lots of languages that agree to disagree, between mainstream, academia and lost OOP battles. And I can call one of the many Simon Peyton Jones talks that describe this, http://yow.eventer.com/events/1004/talks/1054 http://yow.eventer.com/events/1004/talks/1054, starting at 00:42.
- the_af 12y agoCorrect me if I'm wrong, but isn't OO in OCaml frowned-upon, or at least not used frequently by seasoned programmers? Not an OCaml programmer myself, but I heard this multiple times. For example, in Real World OCaml [ https://realworldocaml.org/v1/en/html/objects.html https://realworldocaml.org/v1/en/html/objects.html ]), and I quote from Chapter 11: > You might wonder when to use objects in OCaml, which has a multitude of alternative mechanisms to express the similar concepts. First-class modules are more expressive (a module can include types, while classes and objects cannot). Modules, functors, and data types also offer a wide range of ways to express program structure. In fact, many seasoned OCaml programmers rarely use classes and objects, if at all. To be fair, the chapter goes on to explain why you'd want objects. It also states they are very different from objects as understood by other OO languages. I'd say OCaml is therefore a bad example for OO. -- How are type classes in Haskell an OO feature?
- a-nikolaev 12y agoThe fact that OO is not used frequently in OCaml does not mean that it is useless. Objects in OCaml are typed structurally, not nominally, i.e. object's type is the set of the methods it provides. Consider an example: let a = object method f x = 1 end;; val a : < f : 'a -> int > = <obj> We define an object a, and the interpreter tells us that the type of the object is "< f : 'a -> int >", i.e. it provides method f. Define another object let b = object method f x = 2; method g x = x end;; val b : < f : 'a -> int; g : 'b -> 'b > = <obj> Define a function that takes calls method f of its argument: let f obj = obj#f ();; val f : < f : unit -> 'a; .. > -> 'a = <fun> The type of the function tells us that its argument must be an object that provides method f, and maybe some other methods. Now, we can call this function with object a, and object b: f a;; - : int = 1 f b;; - : int = 2 This structural typing, (or if I'm not mistaken, it's called row polymorphism) is an interesiting feature of the language, and it may be useful in some situations. It does not harm the rest of the language, and I see it as a good feature that probably does not get a lot of attention, but it's theoretically solid and works well. Compared to more usual OO systems, it is cleaner and, imho, easier to reason about. That said, I think, the authors of "Real World OCaml" are right, encouraging the use of Modules rather than Objects. But they do so primarily because in many mainstream languages the main means of abstractions are objects, and they are used for everything. OCaml has functors, modules, it has records, it has ADTs, it has functions, so the need for objects is very limited, and so the new users must get this message very clearly. An article on objects in OCaml: http://roscidus.com/blog/blog/2013/09/28/ocaml-objects/ http://roscidus.com/blog/blog/2013/09/28/ocaml-objects/
- cokleisli 12y ago> So when it comes to FP, I like it pure-and-typed (a la Haskell), or untyped (like the Lisps), but not mixed-paradigm. You overrate pure programming.
- pron 12y agoBut look at Clojure. It's imperative yet quite FP, but much of the language rests on OO polymorphism. Clojure certainly isn't an OO language (in fact, it is decisively "anti-OOP"), but it does mix an essential OO idea, and that actually helps keep the language simple.
- cies 12y agoI would not call Clojure imperative myself. To my best knowledge it allows imperative style just as much as declarative. And having read some Clojure code before I thought that it's community kind of prefers declarative for most things.
- pjmlp 12y ago> Clojure certainly isn't an OO language Multi-methods and protocols
- pron 12y agoThat was my point: even though Rich Hickey pretty much touts Clojure as an anti-OOP language, Clojure still relies heavily on OO polymorphism, yet it doesn't make the language any more complicated -- in fact, it helps keep it simple.
- pjmlp 12y agoSorry I misinterpreted it. As someone that likes multi-paradigm languages, I tend to dislike that many FP guys "forget" their languages also do have first class support for OO when needed. Somehow, I did not read you comment properly and spitted out a bad comment.
- tel 12y agoI think there's a huge opportunity for FP+OO... but that OO will have to be rethought from first principles (which are lacking in OO). More specifically, I think OO-style code interactions are great but that they need to be separated from ambient mutability, subtyping, subclassing, inheritance, etc. Late binding/open corecursion is really cool however. I would like to see a language which starts with ML modules as a base and build a totally novel semi-OO system into FP. I don't think it would, at the end of the day, look much at all like OO the way that OO appears today, but I think it could still gather many of the advantages while maintaining ease of reasoning, good type inference, etc.
- cies 12y agoI feel that Golang in many ways is on that path, the way it does not allow no-subclassing really got me thinking. > I don't think it would, at the end of the day, look much at all like OO the way that OO appears today Won't it be more like a Actor-oriented thing then?
- jerf 12y ago"I feel that Golang in many ways is on that path, the way it does not allow no-subclassing really got me thinking." I'm pretty decent in Haskell and fluent in Go at this point, and it really depends on what you mean by that. Is Go a certain brand of very refined OO? Yes. I've even found certain ideas from PF are surprisingly adaptable [1], the "surprise" being that it's not the usual "Look, Ma, I can map/filter/reduce!" that an OO language borrows from the FP world, which Go is actually really hostile to. (Go does have closures and they are important, but the type system precludes a lot of the "good stuff".) However, is Go headed in the direction of Haskell? No. It's definitely not. Trying to turn it into Haskell would be nothing but pain. Mutability is pretty fundamental in Go, and while there's a culture of isolating it to goroutines, the language itself does little to help with that. [1]: http://www.jerf.org/iri/post/2923 http://www.jerf.org/iri/post/2923
- cies 12y ago> it really depends on what you mean by that. Is Go a certain brand of very refined OO? Yes. Indeed that's what I meant.
- frowaway001 12y agoSo what are you proposing to prevent functional languages form being a complete nightmare from a modularity point of view? (See Haskell.) Module systems aren't much more than castrated object systems, so I don't see a real benefit of picking some half-assed module system over a first-class object system.
- cies 12y agoHaskell modules may be lacking in some aspect, but I certainly dont think they are half-assed. They are conceptually very simple and the community got quite far with them. I also dont think that Haskell-modules and objects are on the same level, for instance: Haskell's modules do not encapsulate state.
- tootie 12y agoIn Java 7 it was pretty trivial to create a closure with an anonymous class and if that anonymous class implemented Callable or Runnable it was effectively a lambda with strong types.