I've recently forayed into the world of functional programming (FP) and am wondering how to "think functionally" for even moderately sized applications? Especially w.r.t. the analysis and design of FPs.
With OOP we're trained to think in terms of objects, their attributes and relations. We model our analyses/designs using class and sequence diagrams. However, the same models seem to be a bad fit when designing for FPs. What are the equivalent modeling paradigms for functional programming? It seems DFDs maybe a good fit but I maybe wrong.
For example: I was thinking of designing a simulation of Monopoly, the board game using Haskell, just to learn the language. When doing OOAD you come up with classes like board
contains items
that have attributes/methods attached to it. You have player
and various other objects and their associated relations that can be captured in a class diagram. And their interactions in a sequence diagram. However, these modeling paradigms doesn't seem to transfer well for functional programs. So just "how" do you model functionally?
Note: I'm looking for concrete references/examples that can explain how to analyze and design functional programs given that I'm coming from a heavily object-oriented way of thinking/modeling.
According to Simon Peyton Jones:
The language in which you write profoundly affects the design of programs written in that language. For example, in the OO world, many people use UML to sketch a design. In Haskell or ML, one writes type signatures instead. Much of the initial design phase of a functional program consists of writing type definitions. Unlike UML, though, all this design is incorporated in the final product, and is machine-checked throughout.
Source: Masterminds of Programming
So instead of drawing all the fancy UML diagrams, you actually write type definitions coupled with undefined
in the design phase.
All of my programming these days consists of single-person projects. If I were collaborating on a project with other programmers, I think that writing type definitions and using undefined
would be a good approach.
But I gather what you're really looking for is some advice about how you can learn to think functionally. So here are some thoughts.
When programming in Haskell, there are two ways I think about the program I'm writing.
If the program is mathematical, I think of the program as a set of equations.
Otherwise, I tend to think of the program as one or more chains of of data transformations. (So perhaps DFDs would be useful.)
So in your Monopoly example, my first thought would be to figure out how I'm going to represent the state of the board (e.g., which properties have houses, who owns them). Then I might have a function that transforms the board when someone buys a property, and other functions for other things players might do. (There's also monads for representing state, State
and StateT
. I might use them, if and when I feel they will make the code clearer, but I usually keep things basic to start.)
One of the mistakes I made most often as a beginner was to create a lot of unnecessary classes and data types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With