Learn functional programming

I’ve spent some time recently organizing material for people who: 1) don’t know Elixir and want to try it and/or 2) for those who want to learn functional programming concepts.

It started out as information I shared at a meetup last week (http://www.meetup.com/dev-coop/events/229536722/) and I decided to take it further and organize the content.

I’d love feedback (or even better, contributions) to make it better. I’m looking for content-editing for correctness as well as contributions of examples for each category.

Thank you!

25 Likes

Looks great Karmen :023:

Reckon you should turn it into a screencast series :003:

4 Likes

:thumbsup:

I’ve always felt the problem with OO is that people don’t use OO methodologies. Hence code smells like God objects or Combinitorial Explosion are seen everywhere.

Is there such a thing as code smell in elixir or is it inherently impossible due to the nature of the language?

1 Like

You can’t guarantee the absense of code smells by the language. Programmers will always find ways to write smelly or even stinky code.

One of the most common smells in FP I’ve seen so far is to not use the folds/reduce of the stdlib, but “writing them out” instead. I have seen this behaviour in beginners as well as in professionals code. I really consider this a code smell.

In general very often, imperativ concepts are tried to carried over to FP, just because most programmers do begin with imperativ languages and it is hard to lay down old behaviours. Regardless of how good/idiomatic/useful or professional these techniques, patterns and habbits were in imperative languages, they do smell in FP.

Of course this is also true for the other way around. There are concepts in FP which you can’t transfer to imperativ coding without smelling there.

6 Likes

You should try you check:


https://www.reddit.com/r/functionalprogramming/
Slack FP

This is on my todo list

As my journey started from:
Scala language
Functional Programming in Scala
Clojure language
Elixir language
now I am starting reading

From my perspective some concepts are common but some are unique between languages. For example Elixir does not have Currying

Maybe not related but there is interesting concept of Reactvie Programming. You build program like a graph, You have input nodes and output nodes. You react to stream of data/events from inputs. Example of implementation ReactiveX

5 Likes

@mkunikow Thanks for the links and info! I’dd them.

For currying, I was actually going to add some Elm and/or Haskell examples. :thumbsup:

1 Like

You still can curry manually:

defmodule Curried do
  def add(a, b), do: a + b
  def add(a), do: &add(a, &1)
  def increment(n), do: add(1).(n)
  def decrement(n), do: add(-1).(n)
end

This is untested, but should work. AFAIR I’ve already seen a WIP package which creates curried functions with the help of macros, but can’t find it right now. But I have to admit, the syntax in Elm or Haskell is much nicer than what you get with elixir :wink:

3 Likes

@NobbZ

yea, you can do some manual currying but it will eventually get unwieldy. :frowning:
I know my examples started out in Elixir but I want to be open to using other languages that best exemplifies certain functional programming concepts. :slight_smile:

1 Like

To explain functional concepts one should probably use Haskell or ML syntax to explain, these are the most pure syntaxes (is this the plural of syntax?) in FP. “Pure” FP doesn’t really know about sequences as Elixir and Erlang do, but have composition (as in Haskells (.)).

Also I do have some thoughts about your post there, but I’ll comment on GH directly.

Thanks for the suggestions! Please do comment on GH.

My goals, as mentioned on GH, are to 1) expose a person who has not done functional programming before to functional concepts, 2) encourage exploration of functional aspects of their existing language, 3) eventually deep-dive into a functional language like Haskell, Elixir, etc.

You see it’s not set up for one ready to deep dive just yet. I presented this material at a meetup full of developers using Javascript, Ruby, Java, Python, C#. Most have no idea about functional programming.

I hope that explains better where I’m coming from. :slight_smile:

OK, for explaining FP to someone coming from an imperativ language, Elixir might be much more suitable. Im in FP since Winter '13 and still trying to wrap my head around the M-word :wink:

I really had appreciated it, if my prof had used Erlang or Elixir back then to introduce core concepts of FP and then in another course would have introduced the higher concepts…

But I have to be honest… It was funny to see, how all the “programming virgins” did grasp most of the FP stuff much faster than the group of students that already knew some imperativ languages :wink:

So I’ll keep my comments for me for now, since these comments were targetting another audience.

3 Likes

It took me some time back in the day to make the leap from things such as 6502 assembly and Ansi-C to OO. It’s been a similar event for FP. For awhile I only though of FP’s benefit as being less verbose, having been exposed to lambdas replacing anon functions in Java.

The breakthrough for me was when I realized how similar FP was to things I already did for decades in the shell, such as piping ps -aux through grep and awk then throwing the result in an outfile. Watching a Dave Thomas video on Elixir helped me make that connection.

Pattern matching I groked as akin to interface overloading.

Turned out I knew most of the concepts already but just hadn’t realized it.

1 Like

Thx to your code I manage to implement ListAndRecursion-8.exs from programming elixir book :smiley:

  def calculate_total_amount(tax_rates, orders) do
    Enum.map(orders, set_order_total_amount(tax_rates))
  end

  def set_order_total_amount(tax_rates), do: &set_order_total_amount(tax_rates, &1)

  def set_order_total_amount(tax_rates, [id: _, ship_to: ship_to, net_amount: net_amount] = order) do
    tax = Keyword.get(tax_rates, ship_to, 0)
    Keyword.put_new(order, :total_amount, net_amount + tax)
  end
1 Like

You could even inline the syntax used into the Enum.map/2. This will save you one reduction per item in the list (function call) and reductions are the primary measure for the scheduler to switch processes. So the less reductions you have the longer is the time you get.

Something like this?

def calculate_total_amount(tax_rates, orders) do
    set_order_total_amount_f = set_order_total_amount(tax_rates)
    Enum.map(orders, set_order_total_amount_f)
 end

@kblake I found this video
###Basics of functional Programming by Siddharth Kulkarni

4 Likes

@kblake it is awesome.

1 Like

@mkunikow Cool! I’ll watch it soon! Thanks!

No, this is not what I meant. You actually don’t even need set_order_total_amount/1, you can pass set_order_total_amount/2 directly to Enum.map/2 using the exact same syntax as you used, to return that function on line 5 of your origninal code.