Since machine language (e.g.,
0110101000110101) computer languages have generally evolved to higher forms of abstraction, generally making it easier to understand the code when it's applied to a problem. Assembler was an abstraction over machine code, C was an abstraction over assembler, etc.
Object-oriented design seems to be very good at allowing us to model a problem in terms of objects, e.g., the problem of a university course registration system can be modeled with a
Course class, a
Student class, etc. Then, when we write the solution in an OO language, we have similar classes which get responsibilities and that generally is helpful for design, especially for modularizing the code. If I give this problem to 10 independent teams who solve it with an OO method, generally the 10 solutions will have the classes relating to the problem in common. There can be lots of differences when you start to get into coupling and interactions of those classes, so there's no such thing as "zero representational gap."
My experience with Functional Programming is very limited (no real-world use, only Hello World type programs). I'm failing to see how such languages allow easily mapping FP solutions to problems (with a low representational gap) the way OO languages do.
I understand the advantages of FP with respect to concurrent programming. But am I missing something, or is FP not about reducing a representational gap (making solutions easier to understand)?
Another way to ask this: would the FP code of 10 different teams solving the same real-world problem have a lot in common?
From Wikipedia on Abstraction (computer science) (emphasis mine):
Functional programming languages commonly exhibit abstractions related to functions, such as lambda abstractions (making a term into a function of some variable), higher-order functions (parameters are functions), bracket abstraction (making a term into a function of a variable).
The representational gap could be potentially increased, because [some] real-world problems aren't modeled easily with such abstractions.
Another way I see decreasing representational gap is in tracing the solution elements back to the problem. The
1s in machine code is very hard to trace back, whereas the
Student class is easy to trace back. Not all OO classes trace easily to the problem space, but many do.
Don't FP abstractions always need explaining to find out which part of the problem space they are solving (apart from math problems)? OK - I'm good on this part. After looking at many more examples, I see how FP abstractions are very clear for parts of the problem that are expressed in data processing.
The accepted answer to a related question Can UML be used to model a Functional program? -- says "Functional programmers don't have a lot of use for diagrams." I really don't care if it's UML, but it makes me wonder about FP abstractions being easy to understand/communicate, if there are no diagrams that are widely used (assuming this answer is correct). Again, my level of FP use/understanding is trivial, so I understand no need for diagrams on simple FP programs.
OO design has function/class/package-levels of abstraction, with encapsulation (access control, information hiding) at each, which makes managing complexity easier. These are elements that allow going from the problem to the solution and back easier.
Many answers speak of how analysis and design are done in FP in a way analogous to OO, but nobody cites anything high-level so far (paul cited some interesting stuff, but it's low-level). I did a lot of Googling yesterday and found some interesting discussion. The following is from Refactoring Functional Programs by Simon Thompson (2004) (emphasis mine)
In designing an object-oriented system, it is taken for granted that design will precede programming. Designs will be written using a system like UML which is supported in tools such as Eclipse. Beginning programmers may well learn a visual design approach using systems like BlueJ. Work on a similar methodology for functional programming is reported in FAD: Functional Analysis and Design, but little other work exists. There may be a number of reasons for this.
Existing functional programs are of a scale which does not require design. Many functional programs are small, but others, such as the Glasgow Haskell Compiler, are substantial.
Functional programs directly model the application domain, thus rendering design irrelevant. Whilst functional languages provide a variety of powerful abstractions, it is difficult to argue that these provide all and only the abstractions needed to model the real world.
Functional programs are built as an evolving series of prototypes.
In the PhD thesis cited above, the benefits of using Analysis and design methodologies (ADM) are outlined independent of paradigms. But an argument is made that ADMs should align with the implementation paradigm. That is, OOADM works best for OO programming and is not well applied to another paradigm such as FP. Here's a great quote that I think paraphrases what I call representational gap:
one can argue at length regarding which paradigm provides the best support for software development, but one achieves the most natural, efficient and effective development package when one remains within a single paradigm from problem description through to implementation and delivery.
Here are the set of diagrams proposed by FAD:
- function dependency diagrams which present a function with those it uses in its implementation;
- type dependency diagram which provides the same service for types; and,
- module dependency diagrams which present views of the module architecture of the system.
There's a case study in section 5.1 of the FAD thesis, which is a system to automate the production of data relating to a football (soccer) league. The requirements are 100% functional, e.g., input football results, produce league tables, scoring tables, attendance tables, transfer players between teams, updating data after new results, etc. No mention of how FAD works to solve non-functional requirements is documented, apart from stating that "new functionality should be allowed at a minimal cost", something that is nearly impossible to test.
Sadly, apart from FAD, I don't see any modern references for modeling languages (visual) that are proposed for FP. UML is another paradigm, so we should forget that.