Data Abstractions

Elixir in Action: Chapter 4

I found that typing and testing all the small code snippets added to my Elixir “muscle memory” and seeing what standard practices look like. For example, when updating the todo list example, I would not have thought of passing a lambda function for the update vs. just passing new data. The lambda function provides much more flexibility at the cost of some slight complexity increase (at least I’m still seeing it as a complexity increase at this stage).

I need to get more comfortable with updating structures. Spending a lot of time staring at this code before comprehending it.

def delete_entry(todo_list, entry_id) do
    %TodoList{todo_list | entries: Map.delete(todo_list.entries, entry_id)}
  end

CSV Import Exercise

My solution was functionally identical to Saša’s except I tried to do everything inline in a single pipe. Saša broke out the pipelined actions into two functions (read_lines and create_entries). Also used a multi-step anonymous function in a Stream.map. I need to remember that anonymous functions don’t need to be simple one-liners.

Notable Notes and Quotes

[Read More]

Control Flow

Elixir in Action: Chapter 3

Chapter 3 opens with an introduction to pattern matching, with details on tuples, lists, maps, bitstrings, binaries, and of course functions, then delves into function guards to implement extended pattern matching in functions.

Multi-clause anonymous functions were new to me:

test_num =
          fn
            x when is_number(x) and x < 0 -> :negative
            x when x == 0 -> :zero
            x when is_number(x) and x > 0 -> :positive
          end

In Elixir, recursion is efficient. Nothing is pushed on the stack when the last thing a function does is call another function, or itself. This is called tail call optimization.

Notable Notes and Quotes

[Read More]