Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concrete example of functional knowledge allowing you to write better imperative/OO code [closed]

I've been working with functional programming for a while now and I think it's great so I would like to teach some of my friends Haskell.

Unfortunately, I can't think of any particular piece of code to show them and say "See, this is how it would look imperatively, see how much better functional is"

So, could someone that's more of an expert than I am (and that's a very low requirement) help me out?

This doesn't seem to oppinionated to me, but in case it is, please tell me how to fix it.

like image 444
Luka Horvat Avatar asked Mar 27 '14 08:03

Luka Horvat


People also ask

Is functional programming declarative or imperative?

Functional programming is a form of declarative programming that expresses a computation directly as pure functional transformation of data. A functional program can be viewed as a declarative program where computations are specified as pure functions.

Is imperative programming same as functional?

The difference between functional programming and imperative programming is that functional programming considers the computations as mathematical functions and avoids changing state and mutable data while imperative programming uses the statements that change the programs state.

What is functional programming language?

Functional programming languages are specially designed to handle symbolic computation and list processing applications. Functional programming is based on mathematical functions. Some of the popular functional programming languages include: Lisp, Python, Erlang, Haskell, Clojure, etc.


2 Answers

Probably the best notions to carry back are so called "value semantics" and "purity".

Each of these play off one another so much it's hard to separate them in practice. In principle, however, value semantics means that each "thing" should act like a value instead of an object. It leads to simpler passing, less "spooky action at a distance" from statefulness, and it provides some amount of background to perform equational reasoning on code. Purity means that side effects do not occur wherever you have code but instead only at carefully demarcated points. This means that most of your code ends up independent and reusable while only the core "application" bits entangle themselves deeply with state and effect.

You might say that purity is having value semantics everywhere or that values are pure computations—so perhaps it's worth saying that "values" refer to the nouns (statics) of your system and "purity" the verbs (dynamics).


These techniques are well known to be useful in other languages. It's a common idea in OO languages these days to happily sacrifice some speed for value semantics due to the organizational and correctness benefits. If you become comfortable with Haskell then you will understand how value semantics and purity work if they are applied to every single aspect of an entire program without compromise. That means you've been exposed to some powerful patterns for reasoning about and building pure programs.

One place I've been thinking about making a comparison is between free monads and the Command pattern. Both are solving very similar problems—"how do I make explicit a structure containing instructions to be performed by a program and execute it at a later time, perhaps in various ways?"—but the Command pattern tends to dance around a lot mutability in, at the very least, the interpreter if not the commands themselves.

Can we write Command patterns which behave more like Free monads? What would be the benefits? These are the kinds of questions you can ask with much more acuity if you've got a strong Haskell background.

like image 171
J. Abrahamson Avatar answered Sep 21 '22 04:09

J. Abrahamson


It's an interesting, and tricky question. There has been a trend of concepts from functional languages making their way into imperative languages for some time now, and the line between functional/imperative languages is quite blurred. For example, say you want to square every element of a list xs and store the result in a new list, ys.

>> xs = [1, 2, 3]                   #  Python

>> xs = [1, 2, 3]                   -- Haskell

If you didn't know about functional idioms, you might do this:

>> ys = [0] * len(xs)               #  Python
>> for i in range(len(xs)):
       ys[i] = xs[i] * xs[i]

In Haskell you would just write

>> ys = map (\x -> x * x) xs        -- Haskell

This idiom also exists in Python, of course

>> ys = map(lambda x: x * x, xs)    #  Python

Arguably, an even nicer way to write it is using a list comprehension

>> ys = [x * x | x <- xs]           -- Haskell

which also exists in Python

>> ys = [x * x for x in xs]         #  Python

Certainly, the functional way is much nicer (and more composable, more reusable) than the imperative way. But in this case, you don't need to use a functional language to get the benefit - you just have to be ready to "think in a functional way."

like image 41
Chris Taylor Avatar answered Sep 19 '22 04:09

Chris Taylor