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.
Looks great Karmen
Reckon you should turn it into a screencast series
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?
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.
You should try you check:
This is on my todo list
As my journey started from:
Functional Programming in Scala
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
@mkunikow Thanks for the links and info! I’dd them.
For currying, I was actually going to add some Elm and/or Haskell examples.
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)
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
yea, you can do some manual currying but it will eventually get unwieldy.
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.
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.
I hope that explains better where I’m coming from.
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
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
So I’ll keep my comments for me for now, since these comments were targetting another audience.
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.
Thx to your code I manage to implement ListAndRecursion-8.exs from programming elixir book
def calculate_total_amount(tax_rates, orders) do
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)
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)
@kblake I found this video
###Basics of functional Programming by Siddharth Kulkarni
@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.