Skip to content

Instantly share code, notes, and snippets.

@WLSF
Created January 11, 2023 15:28
Show Gist options
  • Save WLSF/394c7bf907805d0e52c7de71e098be6c to your computer and use it in GitHub Desktop.
Save WLSF/394c7bf907805d0e52c7de71e098be6c to your computer and use it in GitHub Desktop.
Let's write some Elixir.
defmodule FooBar do
def foo(a) do
if a < 0 do
bar(a, -1)
else
bar(a, 1)
end
end
defp bar(a, b) do
IO.inspect(a * b)
end
end
Not very useful, but that's good enough for our purpose.
I like Elixir, but I think most of the time it just looks like functional Ruby. I want to make this code look like Elixir.
First, this code is lacking every Elixir developer's best friend: |>. Let's add some |>s.
defmodule FooBar do
def foo(a) do
if a < 0 do
a |> bar(-1)
else
a |> bar(1)
end
end
defp bar(a, b) do
(a * b) |> IO.inspect()
end
end
Meh. It's definitely better, but I mean, that's only 3 |>s. I want more |>s.
We have an if in there, so maybe we can do something with it?
defmodule FooBar do
def foo(a) do
(a < 0) |> if do
a |> bar(-1)
else
a |> bar(1)
end
end
defp bar(a, b) do
(a * b) |> IO.inspect()
end
end
We sure can! That's one more |>. Can we do better than this?
Well... > and * are Kernel functions, so maybe...
defmodule FooBar do
def foo(a) do
a |> Kernel.<(0) |> if do
a |> bar(-1)
else
a |> bar(1)
end
end
defp bar(a, b) do
a |> Kernel.*(b) |> IO.inspect()
end
end
This is great, can we keep going?
The Elixir docs say defmodule is just a macro. Does that mean I can just |> into defmodule?
FooBar |> defmodule do
def foo(a) do
a |> Kernel.<(0) |> if do
a |> bar(-1)
else
a |> bar(1)
end
end
defp bar(a, b) do
a |> Kernel.*(b) |> IO.inspect()
end
end
Yes you can!
def and defp are macros too right?
FooBar |> defmodule do
a |> foo() |> def do
a |> Kernel.<(0) |> if do
a |> bar(-1)
else
a |> bar(1)
end
end
a |> bar(b) |> defp do
a |> Kernel.*(b) |> IO.inspect()
end
end
So many pipes! �?
We're getting somewhere, but something still doesn't feel right. This module really isn't doing much, so maybe it should not be that long? Also, I think we need more :. Atoms are very Elixir-y, so let's do more of that:
FooBar |> defmodule(do: (
a |> foo() |> def(do: a |> Kernel.<(0) |> if(do: a |> bar(-1), else: a |> bar(1)))
a |> bar(b) |> defp(do: a |> Kernel.*(b) |> IO.inspect())
))
We're :doing great!
You know what's also very Elixir-y? Lists. Lists and tuples.
FooBar |> defmodule([{:do, (
a
|> foo()
|> def([{:do, a |> Kernel.<(0) |> if([{:do, a |> bar(-1)}, {:else, a |> bar(1)}])}])
a |> bar(b) |> defp([{:do, a |> Kernel.*(b) |> IO.inspect()}])
)}])
Who's going to say this looks like Ruby now? ⚗�?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment