5

Haskell is a purely functional language, breaking from traditional object-oriented languages. However, consider the following quote from Alan Kay on the "true" meaning of OOP:

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them. -- Alan Kay

and later on:

I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages (so messaging came at the very beginning -- it took a while to see how to do messaging in a programming language efficiently enough to be useful).

I'm curious to what extent this style of programming can be achieved in Haskell. In particular, is it possible to structure a Haskell program as a sequence of (something resembling) encapsulated objects passing messages back and forth to each other?

NOTE: I'm looking for examples specific to Haskell, not functional languages at large (when in conflict).

George
  • 6,927
  • 4
  • 34
  • 67
  • 3
    In Objective C, you need very little imagination to see message passing, because that's what it's called. In C++, you need a bit more to understand method calls as messages. In C, you need quite a lot of imagination to see any sort of message passing. Whether you're using "message passing" depends on what names the language uses for its concepts and how strong your imagination is. –  Oct 30 '16 at 15:15
  • 1
    Possible duplicate of [Object-oriented programming in a purely functional programming context?](http://stackoverflow.com/questions/4113138/object-oriented-programming-in-a-purely-functional-programming-context) – duplode Oct 30 '16 at 15:28
  • (Perhaps not an exact duplicate, but it should bring you closer to an answer of some sort.) – duplode Oct 30 '16 at 15:29
  • I thinks it makes more sense to put the question on http://softwareengineering.stackexchange.com – Uko Oct 30 '16 at 15:31
  • 1
    I guess it should be possible to do that in Haskell, but it would be quite unidiomatic. A program in that style doing task X would likely ignore all the convenient solutions to achieve X in Haskell and choose a weird, verbose, inconvenient way to solve X. This is not specific to Haskell. For instance, I would never use a `State` monad built on closures in Java to express mutability -- that would be silly, when mutable objects are the predominant idiom. Doing OOP in Haskell is, IMO, similarly pointless. – chi Oct 30 '16 at 16:05
  • Sure, why not: `type Message a = a; type Messaging a r = Message a -> r; sendMessage :: Message a -> Messaging a r -> r; sendMessage m k = k m`. Without specifying in more detail what you mean by 'structure a Haskell program' this completely trivial model fits your requirements quite fine. Modelling OOP in a functional language can be simple or absurdly complicated depending on precisely the domain you want to model. – user2407038 Oct 30 '16 at 16:34
  • Who knows what OOP is supposed to be, but it seems to me OOP is about scoping mutable state. "Messaging" too is not an apt word unless you're dealing with mutability and side-effects (consider a "pure" actor: `newtype Actor msg = Actor (msg -> MonadForSendingMessages (Actor msg))`; such an "object" is pure and can be stateful, changing its behavior for the next message based on the current one, but this would be rather useless without `MonadForSendingMessages`). So to answer your question you should explore how state flows and is encapsulated in a pure program – jberryman Oct 30 '16 at 16:44

1 Answers1

3

only messaging, local retention and protection and hiding of state-process

like biological cells and/or individual computers on a network, only able to communicate with messages

I believe certain Haskell programming patterns do resemble Kay's description, to a degree.

In streaming libraries like conduit, pipes or streaming, it is common to build a computation as a pipeline composed of different stages. Each part of the pipeline is quite independent of the others and can maintain its own private state (you can have "shared" state in the pipeline as well).

The topologies tend to be linear and unidirectional. That said, abstractions like conduit's ZipSink—and the Applicative instance for Folds in the foldl package—let you build "tree-like" topologies that branch out. And pipes can be bidirectional, although I haven't seen many examples that make use of it.

Then there's arrowized functional reactive programming. It lets you build "circuits" of automaton arrows that can even include loops. Each part of the circuit can maintain its own state. As the description of the netwire FRP library states:

This library provides interfaces for and implements wire arrows useful both for functional reactive programming (FRP) and locally stateful programming (LSP).

And from the docs of the auto library:

auto works by providing a type that encapsulates value stream transformers, or locally stateful functions; by specifying your program as a (potentially cyclic) graph of relationships between value streams, you create a way of declaring a system based simply on static relationships between quantities.

Instead of a state monad type solution, where all functions have access to a rigid global state, auto works by specifying relationships which each exist independently and on their own, without any global state.

danidiaz
  • 26,936
  • 4
  • 45
  • 95