Hacker News new | ask | show | jobs
by m45t3r 2540 days ago
> - dynamic language ( this is the worst part ), working on large code base means problems ahead

IMO, I the fact that Elixir is a dynamic language is not that much a problem thanks to pattern matching.

Elixir's pattern matching is really powerful, allowing for things like:

    def move(_state, _x, _y, kind) when kind not in ~w(forward backwards) do
      {:error, :invalid_move_kind}
    end

    def move(state, x, y, kind) do
      get(state, x, y)
      |> do_move(state, x, y, kind)
    end
In this case, I am asserting that "kind" is either string "forward" or "backwards". If not, I return the an error :invalid_move_kind. I don't need to check if pos is nil or not string, since I can assert using pattern matching that everything with my inputs are right.

Also, there are things like structs:

    defmodule RobotVsDinosaurs.Robot do
      alias RobotVsDinosaurs.Robot

      @enforce_keys [:pos]
      defstruct name: nil, pos: nil

      def set(state, x, y, robot = %Robot{}) do
        case Matrix.elem(state, x, y) do
          %Robot{} -> {:ok, Matrix.set(state, x, y, robot)}
          _ -> {:error, :invalid_type}
        end
      end
    end
What I am saying in the code above is that %Robot{} must have a :name and a :pos entries, and by default they're nil. However, to create a new %Robot{}, :pos must be different them nil. And of course, I can pattern match if my input is actually a %Robot{} and not a simply dict.

You can also do crazy things like pattern matching if a byte array have some specific characteristics, like a magic number.

So while I think it would be nice for Elixir to have types (there is Dialyzer however it is kinda a PITA to use), it is less necessary than Python/Ruby/Javascript thanks to the above.

1 comments

I agree, and what's interesting about this technique is that you can guard against specific values instead of just types.