I'd like to reflect on what I've learned this week. There aren't any specific concepts that are of focus, this is essentially the net of what I googled throughout the week.
Pattern matching on an empty map
Suppose you have a map that contains the following properties
foo = %{:bar: "baz"}
Suppose that you want to apply a function to the map foo
. If you want to check whether or not the map foo
is empty, naively you would want to write a function declaration of the following
def some_fun(%{}) do
# ... do some stuff
end
def some_fun(%{bar: bar} = some_args) do
# ... do some other stuff
end
You would think that passing foo
into some_fun
that the first declaration would be called if foo
were empty. Well, nope, that's not the case. Instead the first function declaration would match on any parameter that is of type map
even if it were empty. Instead to write a function declaration that would match empty maps you would need to leverage a guard statement in the function declaration.
def some_fun(some_args) when some_args == %{} do
# ... do some stuff
end
Anonymous functions don't need an explicit parameter
I was surprised by this, but anonymous functions also support pattern matching that doesn't require an explicit parameter. This seems like a nice way to get reusable case statements.
handle_result = fn
{:ok, result} ->
# do some work
{:error, error} ->
# do some work
end
Here you could reuse this in a set of statements that have common logic.
iex
iex is an interactive repl that allows you to work with your application without the overhead of running your application in full.
Prototyping
Prototyping in elixir is a breath of fresh air. You don't need to worry about setting break points in your code in order to interact with the current program state. Instead you can use iex to load in all of your elixir applications to work with functions and application state all from within a repl.
Running iex -S mix
allows you to load all of your application into memory. From there you can run any functions defined in modules of your applications that are loaded by your mix.exs
.
For the project I work on at Vetspire, we utilize Phoenix. Phoenix is a web framework written for elixir. Suppose there's an in memory cache that I want to introspect after making a call to an API in the app that's run by Phoenix. I could set a debugger statement at the point in which we modify the API and review the cache while the breakpoint is being hit, or I could simply run the application, make a call to the API and then invoke a get function in the iex repl.
# Load run the Phoenix application and begin an interactive repl session
iex -S mix phx.server
# Make a call to the API externally
iex(0)> MyApp.SomeCache.list_all() # get a listing of entries that were added to the cache.
I don't know about you, but I find this changes the way that I look at building applications. Normally while going through early prototyping phases you have to make changes to the code, wait for a new compilation phase and then make a call to the corresponding API from the client application to test those changes. Instead I can make direct calls to application code while the application is being run.
Libraries
Timex
If you're looking for a good datetime library, this seems to be the way to go. I especially like the fact that the goal of the library is to get the work merged into the standard language of elixir.
Memento
If you need to work with persistent and in memory databases, Memento makes that much easier to do. It adds a nice api to working with both :ets
and mnesia
, in memory and distributed persistent databases that are provided by erlang respecitvely.
Quantum
If you need simple cron behaviors for jobs in your app, This is the way to go.