A case for functional programming and another against fear

avatraxiom on Designing Too Far Into the Future

…design for the specific requirement (singular) that you know is broadly needed, and implement that on top of the system you already have. If that can’t be done, or can’t be done with simple code, then you do re-architecture. Rinse and repeat.

You do re-architecture. There must be some wicked spirit hiding in a dark corner of the collective unconscious of programmers, probably born when re-architecting involved re-punching a card. Fact is, many still try to get a system right the first time, out of fear that they will have to later change it otherwise. Bad news, you will have to anyway; good news, it’s no longer that painful if you accept it from the start and for each line of code you write you don’t just ask yourself “will this run” but also “will it be harder to change things because of this”.

And:

This is how many, many people can be working on an open source project simultaneously without knowing what the others are doing. They design their code so that it doesn’t matter what’s going on anywhere else, the code just works, and can be modified and extended easily by anybody. There are lots of ways to do this—they mostly fall under the rules for good object-oriented design.

That is actually an excellent case for functional programming—and for function without side-effects in particular. If the things that the outcome of a piece of code depends on are clearly spelled out under your eyes in an argument list, instead of floating somewhere in outer space (and that means not just global variables, but also instance variables once the class definition gets taller than a couple of pages), it becomes much easier to reason about that piece of code and change/grow it in ways that do not impair other parts of the system.

2 thoughts on “A case for functional programming and another against fear

  1. Jesse Andrews

    I have several friends who love functional programming, and while I’ve dabbled in ocaml/sml/haskell/… I’ve never made the jump to really understanding why this model is better.

    I’ve been leaning more towards a functional approach in my ruby (and somewhat my javascript) code as it seems to make more sense for micro-level clarity. Macro-level, I can now see why functional programming would be very helpful. (although when I start thinking about an App or a component, it almost always has state… so I’m not sure how to reconcile this… more reading to do I guess)

  2. bard Post author

    Hmmm. I think the jump, for me, was not so much in doing away with state, as in questioning the need for state that’s not explicitly handed down to the code that uses it.

    This little gem about modelling a server was an eye-opener:

    Suppose that the internal state of the server is described by the state variable S and that the server receives a query Q. The server responds by sending a reply R back to the client and changes its internal state to S’. This can be described as follows: {R, S'} = f(Q, S)

    In Erlangish pseudocode this would be:

    
    loop(F, State) ->
        {Client, Query} = get_query(),
        {Reply, State1} = F(Query, State),
        send(Client, Reply),
        loop(F, State1)
    end.
    
    

    (Real code here)

    But why hang to data that tight? Because a program’s source shows at once all courses the program can take; it’s data that narrows them down to those that are likely to happen, so seeing data near to where it comes into play (as in an argument list) makes it easier to see what’s going on.

    (By the way, Jesse, happy to see you around!)

Comments are closed.