Thinking Functional

Hi Guys,
I’m studing Elixir since last month but, I have a lot dificulty to change the form of thinking to solve a problem with functional design, I’m programing with OO and I would like to add Functional Programing in my toolbox, there’s someone the indicate a guide, book, tutorial to help me?

7 Likes

We have this topic on forum. Maybe it will help.

4 Likes

You may want to have a look at Erlang and Elixir for Imperative Programmers (I haven’t read it, so I can’t really comment).

Personally given that even Erlang/Elixir aren’t “purely functional” I started reading Haskell Programming from First Principles - admittedly an extreme approach but I felt that my brain needed an extreme push :slight_smile: (I think Erik Meijer just finally wore me down with his “learn Haskell”).

4 Likes

I am also reading http://haskellbook.com/ plus http://learnyouahaskell.com/ . There is also Erlang book http://learnyousomeerlang.com/.

2 Likes

There was a talk by Morgan Laco at ElixirConf about switching to Functional Programming(/Elixir) when coming from OOP. It might still take a few days before a video version of that talk appears online, however.

2 Likes

I recommend The Little Schemer. It’s not a comprehensive introduction to functional programming, but it will rewire your brain to think recursively, which is the single biggest obstacle to overcome with functional programming. Rewriting the programs into Elixir would make for good exercises.

I’m currently doing SICP in Elixir. Elixir is a lot like Lisp but much easier to mentally parse.

2 Likes

There’s also https://github.com/jwhiteman/a-little-elixir-goes-a-long-way!

2 Likes

Thank you everybody!!!

1 Like

2014 NDC London,UK
Functional programming design patterns by Scott Wlaschin

as referenced in
From Front End to Full Stack with Elixir and Phoenix by Lauren Tan (ElixirConf 2016)

1 Like

I think that the main change is that instead of having objects that themselves are responsible for their capabilities, you have data which can be transformed into other data if it has the correct format.

Thinking with transformations is a lot more extensible and flexible than thinking with a hierarchical model of objects.

In an OOP language (a true one like Ruby. In languages that have a difference between primitive types and objects like Java, you might need to use a.equals(b) instead), a comparison like a == b actually calls a method on object a. Which means that the result might be very different than b == a.
And you will need to define those methods in two places.

In a Functional language, you simply state what the result should be between a comparison of these two kinds of objects. In a single place.

4 Likes

I agree with the above, however I have to say something about the following statement:[quote=“Qqwy, post:10, topic:1771”]
I think that the main change is that instead of having objects that themselves are responsible for their capabilities, you have data which can be transformed into other data if it has the correct format.
[/quote]

In Erlang/Elixir one can think of processes as being objects, in fact when OO was being discussed by Alan Kay (one of the fathers of the idea of object-oriented programming) and Stefan Ram, Alan said the following two statements

I thought of objects being like biological cells and/or individual
computers on a network, only able to communicate with messages

OOP to me means only messaging, local retention and protection and
hiding of state-process, and extreme late-binding of all things. It
can be done in Smalltalk and in LISP. There are possibly other
systems in which this is possible, but I’m not aware of them.

Now this sounds a lot like the processes in OTP. I found the info in this really interesting article by James Edward Gray it’s a nice read. I’ve heard many times OO was about message passing and not Classes but I could not fully grasp that concept until I looked at it through Elixir and OTP.

1 Like

You may find this series worthwhile http://www.ibm.com/developerworks/library/j-ft1/

Why elixir is not purely functional? Please explain with an example.

Thanks

In my programming evolution I went from knowing it all in C/ASM and then proceeded to C++ and other OOP and languages and thought I knew it all. I’m now trying to learn functional programming with a new and correct attitude that I know very little to nothing and I find that attitude helps with the preconceived notions and arrogant feelings of - I already know that. I found once I took the advise of most intro functional books - forget everything you know about imperative/OOP programming before beginning functional programming - I was able to grasp the many, many simple concepts encouraged in functional programming…

Its true. If you can drop all your preconceived notions and proceed with a bare slate then you can move at a steady place in functional programming. If you drag your imperative/OOP practices into functional programming then you can expect a rough ride that will only confuse you.

1 Like

For a funcion to be considerate pure two requirements MUST apply.

  1. there must be absolutely no side-effects.
  2. F(x)=y must always be true for any x. (will explain further down)

The first one is probably the easiest to grasp what it simply means is that a function must get some input do calculations and produce an output without interfering with anything else. If this was always true for Elixir/Erlang we would have to say goodbye to messages. As any message is essentially a side-effect.

F(x)=y means that the function with these specific arguments is essentially equal to its resulted output. Lets say you have the following function
def hello(name), do: "Hello #{name}"
You can replace hello("John") with the string "Hello John" and the program would be working perfectly. However consider the next example.

def greeting(name) do
  cond do
    Time.now.hours > 18 -> "Good evening #{name}"
    Time.now.hours > 12 -> "Good afternoon #{name}"
    Time.now.hours < 6  -> "Good night #{name}"
    true                -> "Good morning #{name}"
  end
end  
## Time.now.hours does not exist and in fact is the exact oposite of a pure function, 
## we can see how using impure function can spread the impurity along

We can easily see that everytime we call greeting("John") there is a big change we get a different output, we cannot simply replace it with any of the strings in the function and be sure its going to work as intended. To make this function pure we would have to supply the date as an argument, like so greeting("John", "20:45") now we could safely replace this call with "Good evening John" and everything would be fine.
Finally consider a function that takes an input sends a message and then returns a tuple.
Considering the function was pure we could replace the function call with the tuple, if we do that however the message would never be sent therefore the function call and its output are not equal.

For a language to be considerate purely functional, it must not only allow the above two requirements but it must enforce them.
While in Elixir/Erlang one can write purely functional programs it is the norm to allow some side-effects for effectiveness.

Other languages like Haskell use monads to address these issues and retain their purity, but you should ask someone else about this since I have only the slightest idea of how it works.

2 Likes

Monads are actually a very simple concept (as the 50000 tutorials state but are still being made, that shows how easy they are! /s), let me try a simple description without using code. It is just a container for carrying state around in an immutable way. Think of an implicit hidden argument being passed around function (in an elixir’ish way or a global ‘this’ in OOP languages) that things can return new versions of.

1 Like

So much hype has grown up around monads that they have become mythical in nature. Monads just bury state in a shallow grave.

This probably the best description of them…

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

2 Likes

José Valim: Beyond Functional Programming with Elixir and Erlang

functional programming is not a goal in the Erlang VM. It is a means to an end.

Erlang (and Elixir) are practical languages and there is nothing wrong with that. If you are interested in the History of Erlang - Joe Armstrong: 26 years with Erlang or How I got my grey hairs:

Here it becomes clear that some of Erlang’s roots actually come from Prolog (that is where all the emphasis on pattern-matching comes from), a declarative, logic programming language that doesn’t even support functions. But the issue of this topic is “Thinking Functional”.

It is often asserted that it is possible to apply “functional practices” in traditional imperative languages but in my personal experience that is not an efficient way towards adopting “functional thinking” because the imperative escape hatch is always so close by. Even in Haskell it is possible to write in an imperative style - the difference is that it typically sticks out like a sore thumb (so you better have a good excuse ready :slight_smile:) - Haskell is functional by default since it is based on lambda calculus. Learning Haskell is a bit like going to the (functional) language immersion school - everybody gives you dirty looks when you revert to your familiar imperative ways.

That being said Haskell is probably too much of a “full frontal assault” if one has had very little exposure to “thinking functionally”. In my personal case Clojure (a Lisp dialect) was the first successful wrecking ball to chip away at my imperative mindset - if one has no Java development background then it may make sense to look elsewhere (however I think it is important not to get too enchanted with Lisp just because on the surface “it does everything I need to do” but one should certainly learn to appreciate and wield it (certainly come in handy with emacs)).

Now I’m no static typing bigot - but in my personal assessment dynamically typed languages like Clojure, Erlang, and Elixir may not push the programmer/designer enough to actively “reason about types” (and their “compositionality”) in the same way strong static typing in Haskell tends to. Of course ultimately this leads down the path to Category Theory for Programmers.

At the very least there seems to be one repeating theme for “things I wish I was told before I started” - “Dialyzer”, e.g. Bernard Duggan: Erlang in production: “I wish I’d known that when I started”

For the time being I simply view concepts like semi-group, monoid, functor, applicative, monad, etc. as “design patterns on steroids”. Actually design patterns from the OO realm (as helpful as they can be) are more like “sloppy laundry lists” compared to these concepts. Basically design a type that strictly observes the identified “laws” (constraints) and enjoy all the other guarantees that go with it by default. Often people get too hung up on one particular instance (e.g. the IO monad) and a particular use case (e.g. dealing with side-effects) and never stick around long enough to understand the full scope of power that these abstractions can yield (on the flip-side dwelling too much on them probably will end in “type” analysis paralysis - but balance is key, as always).

When it comes to “thinking functionally” it may also make sense not get too fixated on one particular language (it’s always handy to have a secondary) but to also have a look at those languages that hang out in the same neighborhood - but are just a little bit different.

Garrett Smith: Why The Cool Kids Don’t Use Erlang

In the case of Elixir you could work with Phoenix on the back end but use something like Elm, PureScript or BuckleScript to further push the envelope of the “functional programming experience” on the front end.

5 Likes

Just on the incorporation of functional programming in languages like java and c#: http://queue.acm.org/detail.cfm?id=2611829 (Erik Meijer: “Mostly functional” programming does not work)

1 Like

There is no 100% pure functional language. You will always need to deal with state and side effects.
But there should be clear separation in code: pure functions vs rest.