
The most basic Erlang service ⇒ worker pattern - signa11
http://zxq9.com/archives/1311
======
rtpg
It's always a bit frustrating to read people say that FP doesn't really have
design patterns. Most of the OOP design patterns usually don't apply, but
there are definitely design patterns.

The most universal one in functional programming is modelling mutating state.
This is solved by placing the state in some container, and then building
functions that take a state, and then return an updated state (maybe with a
value). You can then build your program by chaining these state modifiers.

So instead of doing

    
    
       stack = [1, 2, 3]
       def pop_stack():
          return stack.pop()
    
       final_value = pop_stack()
       # stack = [1, 2]

you do

    
    
       initial_stack = [3]
       def pop(s):
          return (s[-1], s[:-1])
    
       popped_value, final_stack = pop(initial_stack)
       # final_stack = [1, 2]
       # initial_stack = [1, 2, 3]
    

You can then write programs like the following:

    
    
       def push(s, val):
          return ((), s + [val])
    
       def add(s):
          x, s1 = pop(s)
          y, s2 = pop(s1)
          return push(s2, x+y)
    
    

This seems sillier in python, but is essential to doing "real work" in
immutable languages. Languages like Haskell offer syntactic tools to make the
chaining be more natural, in particular.

~~~
tome
That's a pattern with a functional nature indeed but it's not "a pattern in an
FP language". In a (typed) FP language you don't need it to be a "pattern"
because it's just a type.

To my mind a "pattern" is a structure you encode into a program where the
language you are using doesn't allow you to encode that structure directly
using the facilities it provides.

~~~
rtpg
I disagree with the sentiment that it's just a type.

I understand that you don't need much plumbing, but you're still following a
pattern that you have used elsewhere when working on these.

The beauty is that there's usually exactly one way of doing it (so by
definition it is the simplest way). But if you're coming from a language based
around mutability and are just in front of an Haskell REPL, I don't think you
find this very easily.

In my mind patterns are about agreed-upon architectures for dealing with
common issues. Another example that comes to mind in typed FP languages are
wrapper types to prevent misuse of values (wrapping user input, unwrapping via
"escape" calls).

When you have a problem, usually you'll have one or two canonical solutions
come to mind. Those are the patterns for me.

Though given how simple everything usually is, it involves a lot less
boilerplate. Choosing the right type is still essential.

~~~
tome
Right, I don't really disagree with you, I think. It's just that I associate
"pattern" with things that are "done by convention". By contrast the state
monad is encoded in the language in Haskell rather than just "done by
convention".

On the other hand, I would say that your state monad in Python _is_ a pattern,
because there's no way of expressing the structure of the state monad in
Python.

