Subscribe to access all episodes. View plans →

#195: Shorthand

Published March 24, 2025

Episode Sponsored by FirstDevJob.com


Shorthand

Follow along with the episode starter on GitHub


In this episode let’s explore Shorthand - a handy package that saves time by providing convenience macros to create or match against maps and keyword lists. We’ll add it to this Elixir application that uses Phoenix LiveView to display albums.

Let’s gets started. We’ll go to Hex and grab the shorthand config. With that we can open our application’s Mixfile and add it to our list of dependencies.

mix.exs

...
defp deps do
[
...
{:shorthand, "~> 1.2"},
...
]
end
...

Once it’s added we’ll go to the command line…and download it with mix deps.get.

$ mix deps.get
Resolving Hex dependencies...
Resolution completed in 0.121s
New:
  shorthand 1.2.0
...

Now that we have the package installed, let’s see how we can use shorthand. We’ll start an IEx session with our application.

$ iex -S mix

Then we’ll import Shorthand and let’s create a first_name variable and a last_name. Now if we want to create a map where the keys and values have the same name - and the keys are atoms - we can use the Shorthand m. Great! Our map was returned.

> import Shorthand
Shorthand
> first_name = "Dale"
"Dale"
> last_name = "Cooper"
"Cooper"
> m(first_name, last_name)
%{first_name: "Dale", last_name: "Cooper"}

Now, what if we needed the same map, but now with string keys? To do that we can use the Shorthand sm.

> sm(first_name, last_name)
%{"first_name" => "Dale", "last_name" => "Cooper"}

Shorthand even works with nested maps. Let’s create a couple more variables and we can add them as a nested map with string keys under the “meta” key.

> age = 30
30
> dob = "April 19"
"April 19"
> sm(first_name, last_name, meta: sm(age, dob))
%{
  "first_name" => "Dale",
  "last_name" => "Cooper",
  "meta" => %{"age" => 30, "dob" => "April 19"}
}

It also works for keyword lists using the Shorthand kw.

> kw(first_name, last_name)
[first_name: "Dale", last_name: "Cooper"]

You can also use Shorthand to assign and ignore variables. Let’s create a map with an email and password.

Then let’s use the Shorthand m to get the email and ignore the password.

> m(email, _password) = %{email: "hello@elixircasts.io", password: "topsecret"}
%{pass: "topsecret", email: "hello@elixircasts.io"}

Shorthand works with the pin operator to pattern match against a variable’s existing value.

> email
"hello@elixircasts.io"
> m(^email) = %{email: "hello@elixircasts.io", password: "topsecret"}
%{pass: "topsecret", email: "hello@elixircasts.io"}

Shorthand also makes it easy to create structs. Let’s define a simple %User{} struct and we’ll give it one field email. Then we can use the shorthand st passing in the struct module and then the email.

>   defmodule User do
...>   defstruct [:email]
...>end
> %User{}
%User{email: nil}
> st(User, email)
%User{email: "hello@elixircasts.io"}

Great! Our expected %User{} struct was returned. Now that we know how to use shorthand let’s update a module in our application to use it.

We’ll go to the AlbumLive.Show module and in it we’ll import Shorthand. Then let’s re-write the maps in the module to use Shorthand. It looks like the handle_params callback pattern matches on the params to get the id.

Let’s update that use the Shorthand function sm - since the keys in the params are strings. Below we can update the page_title function to get the artist and title - here we’ll use the Shorthand function m since the keys are are atoms.

defmodule TeacherWeb.AlbumLive.Show do
  use TeacherWeb, :live_view
  import Shorthand

  alias Teacher.Music

  @impl true
  def mount(_params, _session, socket) do
    {:ok, socket}
  end

  @impl true
  def handle_params(sm(id), _, socket) do
    album = Music.get_album!(id)
    {:noreply,
     socket
     |> assign(:page_title, page_title(socket.assigns.live_action, album))
     |> assign(:album, album)}
  end

  defp page_title(:show, m(artist, title)) do
    "#{title} by #{artist}"
  end
end

Great, now we just need to start our server.

$ mix phx.server
...

Perfect! Our application is now updated to use shorthand.

© 2024 HEXMONSTER LLC