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

I am not really getting what the thesis of this article is, and rather than try to hone in on that, I figured I'd give some thoughts on what OOP in functional languages means to me.

In terms of OOP, I primarily think of the paradigm being one that provides mechanisms for the encapsulation of both data and behavior and for relating these through inheritance or composition. The "only messaging" part of Kay's famous quote is too constraining in my view because it overly species the implementation details of the access of how one taps into an object's data and behavior.

For most people, their OOP experience has seen them use reference-based OOP languages like C#, Java, and C++. In such cases, there is a distinct line between that and what's typically thought of functional programming. This jarring difference is probably best noticed in F# where you have the referenced-based OOP and arrays brought about by C# and .NET/CLR interoperability and the functional layer of immutable-by-default discriminated unions, tuples, and records in the rest of the language. However, my experience in OOP has centered around value-based OOP, and this is where the line between OOP and functional programming is blurred.

This is because, in my view, one of the pillars of functional programming is that of immutable data. In a value-based OOP implementation, objects are merely immutable values, where methods are functions that take in the object and possibly some extra parameters and return a new one and possibly some extra data. It's just that classes and objects and the relationships that can be defined between them gives us the ability to encapsulate data and behavior and expose it in controlled ways.

F# records are very nearly functional OOP when viewed this way. F# records can contain member functions, where are "methods" in that they act upon records through dot notation but they do not mutable the record passed in. F# records can also implement interfaces, which is inheritance that defines relationships between specifications of behavior. It's just that F# records expose and do not encapsulate the data and, by some extension, methods.

I think value-based OOP has a place in functional languages. Records and tuples are product types that form new data by concatenating data, discriminated unions are sum types that form new data by or-ing data together through a flat hierarchy, and objects are types that form new data by collating data and behavior together with relationships formed between these types. If all one ever does to any of these is provide some functions, either defined externally as in functions operating on immutable types or internally in the case of member functions or methods, then this still satisfies one of the major tenets of functional programming, that being immutable and collections of functions operating on such data.

I think Kay's thoughts on message passing lies at a higher level or is an adjacent idea. One sees such message passing in actor models such as Elixir and Erlang, but those processes do not have hierarchical relationships like objects do, although they do have compositional relationships, nor do they provide mechanisms for strictly and cleanly defining data the processes are responsible for like what classes do. In my experience, coupling a system like Elixir and Erlang's processes with value-based OOP is a huge win, because these things are really different but complementary ideas. In my opinion, OOP being about message passing isn't really the case. It just so happens that Smalltalk married these two ideas (OOP and message passing) together.



A more general pillar of functional languages is referential transparency, which does not rule out mutability. It simply means that a function’s output is determined by its input alone. Have a look at Clean, uniqueness types and linear types in general, for instance.




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

Search: