Learning Elixir: Part 1

Hi All, This should be the first in a series of "Sam learns Elixir" type blog posts I plan on writing as I learn bits of Elixir.

logo

logo

Motivations

I thought it'd be time to branch out from iOS for a bit and learn something completely new. At work, some of our team wrote a job processing system in Elixir and I'd like to be able to understand what the code actually does and be able to help the team where necessary.

What is Elixir?

Elixir is a functional programming language written on the BEAM VM. This is the same VM as Erlang uses. Erlang was written ages ago by Ericsson (the phone company, as in Sony Ericsson) to be highly fault tolerant and massively scaleable. So while the tech isn't new, Elixir is, and brings with it a trendier ruby-like syntax and features like Meta-programming.

First Experiment

So to start with, I watched this talk by Peter Broderick. My goal of this first session was to reproduce the code he wrote in the demo to a working level, and fix that code he couldn't at the end (under pressure, live coding sucks, definitely not judging him!).

SO, brew install elixirand let's go!

The command iexstarts a shell and you can start to play around with it.

Screen Shot 2016-05-09 at 7.53.35 AM

Screen Shot 2016-05-09 at 7.53.35 AM

Some interesting things to note here are that tuples ({1, 2, 3}) are indexable but lists ([1,2,3]) are not. Lists are in fact implemented as Linked Lists, similar to those in Clojure/Lisp so you can get the head of the list and the "rest" of the list as I have done. Of course, Elixir has string and even a concept of symbols - but I'll probably explore both of those at a later time.

Another interesting thing here is the = operator which is actually doing pattern matching, not assignment, which is why I could write [head | tail] = [1,2,3]. Ultimately the same effect if you did something similar in python.

Second Experiment: Mix

Mix is the build tool in Elixir. It is similar to tools you may have used in Ruby/Rails land like bundler, the generators, gems etc where you can generate project and scaffolding files. I used it with the --bare switch to get a reasonably blank project.

Screen Shot 2016-05-09 at 8.08.17 AM

Screen Shot 2016-05-09 at 8.08.17 AM

As you can see, out of the box, you'll get a bunch of sensible files and a test that passes. Then I implemented a few functions to try out the testing suite.

https://gist.github.com/samjarman/a92ecc08e4d22161f15615d9e33d7466

Additionally, similar to Python, Elixir has doc tests which I think are super cool. You can show the doctest how to interact with it as if you were in the shell and then it asserts the output. Neato.

https://gist.github.com/samjarman/ccf4561bedc0b2d8860c3ff50c3d97f5

Experiment 3: Recursion and Private Methods

After this, it was best to get my hands wet with some good ol' fashioned functional programming. So let's create a function which sums some numbers. In imperative programming languages, you could achieve this with a total variable and a loop, but that's a big no no in functional, so we'll use recursion instead.

https://gist.github.com/samjarman/e76d1eb0bfa17834577712109dd994a3

We start off with one public function and two other, private functions (notice the defp). First we can define a function that takes a list and a total variable, where the list is pattern matched into some variables already (see the shell commands above). We'll have for use in this function a tail, a head and total.

For example, calling _sum([1,2,3], 0) would make the variables of head be 1, tail be [2, 3] and total to be 0.

We simply recurse and add it up and continue. The base case is defined above - if we're at an empty list (because the previous calls tail was an empty list) then we can stop and return the total. Sure, a bit complicated, but like all recursive programming it looks pointless on simple examples but looks amazing on harder examples, like tree traversal.

Add a few doctests, run mix test again and we see it works. Boom.

Also it seems that as a naming conventions, private functions are prefixed with _. (Update: Maybe not! Eduardo points out that a lot of Elixir is written in Elixir so that's where the conventions should come from!) Generally I find it a great idea to learn naming conventions alongside everything else with new programming languages. This'll stop the better developers cringing at your code when you inevitably ask for help :P

Experiment 4: Concurrency and Messaging

So I thought it was about time we get to the bit that makes Elixir cool, which is its concurrency model. Long story short, you can spin off threads (except don't call them that, call them Erlang or BEAM processes) trivially and send messages between them. Each process has a "mailbox" and processes communicate by sending messages to each other. Seems simple enough conceptually but obviously we're only scratching the surface of the surface :P

So let's create another process and get it to send us something.

First, we'll get a reference to the current process, by assigning it to a variable called me.

Screen Shot 2016-05-10 at 7.47.09 AM

Screen Shot 2016-05-10 at 7.47.09 AM

Next we'll define a function that uses the send function to send me a tuple with the symbol :hello and the string "hello".

We'll the spawn a process with the spawn command, giving it that function. The process will die once the function has ran. And it's done. It's sent a message. We can check the contents of our main processes' inbox with the flush command.

But now we want to explicitly receive it, so we run it again to get another message in the inbox (previously made empty by flush) and we use a receive block to declare what to do with it. Again here, you see pattern matching taking place that assigns str to the second item of the tuple, if the first item is :hello. We can then print it by using IO.puts strand you see it in the output. Boom. From here you could imagine more complex send functions and receive blocks for many messages, although I'm not yet too sure on how simple they are kept in practice.

That's probably enough for today! There was a bit more in the video, and I did manage to fix Peter's code but I feel this is enough for a single post.

Where to from here? Let me know. Do you know any good learning resources... I'd love to hear about them. Ping me on twitter!

Apps are Making us Better People

A role of an actor is to capture the essence of the character they're trying to play. If you think of the trope of "actors trying to make it", you'll often see them showing their "range", which is a typically done with a series of photographs showing various emotional states. Typically, actors would work for years to get this right, developings these expressions in front of a the mirror. However, times have changed. Now everyone has a decently quality forward-facing camera in their pocket. And boy do we know it. As a society in recent years, we've been obsessed with that small camera. The one tiny technological change that will define a generation. "Selfies" are so commonplace, that even those quotes around the word were perhaps unnecessary. These photos of one's own expression, typically reacting to a situation are now so commonplace, even my parents are beginning to take them.

But it doesn't just stop with the camera app built into your smartphone. Snapchat, an app that's come almost out of nowhere (since ~2014) promoted selfies and reactions that can be read in a small timeframe. The metric for a great snapchat is being able to understand it fully before the timer runs out. It's not just Snapchat, one could argue Vine and YouTube did this as well. Another great example is Musical.ly, an app for recording yourself lip syncing – How is it we can convey so much with just a silent movement of our lips?

I believe a generation of kids and young adults are now training themselves in the fine art of expression. Expression is a cornerstone of society, a way to tell someone what you're feeling without saying a single word. It's so deeply important for interpersonal communication and relationships, but often overlooked by its inherent subtlety.  These are the very reasons why actors have to get it right – they have to be able to match society and play characters, down to the musty subtle of details.

Social apps are often bashed for pulling people apart with the common example coming to mind of a group of friends out for dinner, ignoring each other for the allure of an unread twitter feed. While that may be true to an extent, the video and picture messaging apps are having quite the opposite effect.

A generation is being trained to produce and better recognise expression. The consequence of this being that these people will be able to communicate better, feel more in sync and have more meaningful and deeper connections.

So next time you see a young person taking a selfie, don't smirk. Think. Be envious. That person will most likely relationships better than most of us can ever dream. And who knows, perhaps they'll win an Oscar one day.

 

Quick Tip: Listen to All the Notifications

Quick Tip - You can listen to all the Notifications being sent around by passing in nil as the name to addObserverForName:* methods on a NSNotificationCenter instance.

This is particularly useful for snooping on other frameworks and around the many system notifications that get sent. Obviously, remove once you've found anything you're looking for :)


This has been a "Quick Tip" style post. Short, simple and to the point. What are  your thoughts on this style? Tell me on Twitter!