Programming Elixir Chapter 6 Notes


Modules and Named Functions

It takes awhile to get used to not seeing function return statements. Drives home the point that everything is an evaluation.

  1. If you define an anonymous function within a module it must either be used or start with the underscore (_) character.

    defmodule Test do
      hello = fn -> "hello" end
    end
    
    warning: variable "hello" is unused...prefix it with an underscore

  2. Declaring named functions with and without syntactic sugar. Chapter 6 tends to use without syntactic sugar for short functions.

    # With syntactic sugar
    defmodule Ex do
      def double(n) do
        n * 2
      end
    
      # Without syntactic sugar
      def treble(n), do: n * 3
    end
    
    Ex.double 3
    Ex.treble 3

  3. Elixir pattern matching is depending on code order, runs from the top down.

  4. I seem to have missed the discussion on how to handle list iteration. Had to look up how to split list into first/rest. (CAR/CDR anyone?)

    def sumit([first | rest]), do: ...

  5. I found the explanation of using a function head and default parameters confusing, but the Params example is clarifying.

  6. Ranges are maps. There doesn’t seem to be a way to check that a map is specifically a range.

  7. My solution to the Chopped exercise.

    defmodule Chopped do
    
      def guesser(actual, guessed, _min, _max) when actual == guessed do
        IO.puts("Final Guess: #{guessed}\n\n")
      end
    
      def guesser(actual, guessed, min, max) when actual > guessed do
        IO.puts("Actual > guessed: #{actual} > #{guessed}")
        guessed = min + div(max - min, 2) + 1
        min = Enum.min([guessed, actual])
        IO.puts("guessed/min/max-> #{guessed}/#{min}/#{max}\n")
        guesser(actual, guessed, min, max)
      end
    
      def guesser(actual, guessed, min, max) when actual < guessed do
        IO.puts("Actual < guessed: #{actual} < #{guessed}")
        guessed = min + div(max - min, 2) + 1
        max = Enum.max([guessed, actual])
        IO.puts("guessed/min/max-> #{guessed}/#{min}/#{max}\n")
        guesser(actual, guessed, min, max)
      end
    
      def guess(actual, min..max) when is_integer(actual) and min == actual and max == actual do
        actual
      end
    
      def guess(actual, min..max) when is_integer(actual) and min <= actual and max >= actual do
        # Make max the first guess.
        IO.puts("First guess: #{max}")
        guesser(actual, max, min, max)
      end
    
      def guess(actual, min..max) when is_integer(actual) do
        IO.puts("#{actual} is not in the range #{min}..#{max}")
      end
    end
    
    Chopped.guess(10, 1..88)

    Actual > guessed: 10 > 8
    guessed/min/max-> 6/6/10
    
    Actual > guessed: 10 > 6
    guessed/min/max-> 9/9/10
    
    Actual > guessed: 10 > 9
    guessed/min/max-> 10/10/10
    
    Final Guess: 10
    :ok

All notes and comments are my own opinion. Follow me at @rgacote@genserver.social