Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save collegeimprovements/a3a8258a88a0bfb0163b7cde01ae3deb to your computer and use it in GitHub Desktop.
Save collegeimprovements/a3a8258a88a0bfb0163b7cde01ae3deb to your computer and use it in GitHub Desktop.
I have heard it said in the Erlang world that you start out writing functions to process lists using tail recursion, because that's what the books talk about. Then you realize that you can use functions in the standard library e.g. :lists.map. Then you realize that the syntax for list comprehensions is nicer for common cases. Then you come full circle and write functions which handle control flow, like Plug or "railway oriented programming"
Elixir has more powerful comprehensions with nicer syntax, and there are more patterns in Enum, and there are macros, but it's generally the same kind of progression
Pipe chains are generally best when you can organize things to have a consistent first argument style. It can conflict with the pattern of returning {:ok, value} or {:error, reason}, which is generally a good thing
So pipes are nice when they happen more or less naturally, but don't force things.
So if you have a series of transformations on data which basically can't fail, then great. Otherwise, maybe not.
And some people use pipes when a simple function call would be fine, e.g.
COPY
state
|> Map.put(:sequence_token, next_sequence_token)
|> flush(opts)
is better written as
COPY
flush(%{state | sequence_token: next_sequence_token}, opts)
And then there is this:
COPY
{{years, months, days}, {hours, minutes, seconds, milliseconds}} = timestamp
timestamp = :calendar.datetime_to_gregorian_seconds({{years, months, days}, {hours, minutes, seconds}})
|> Kernel.-(@epoch)
|> Kernel.*(1000)
|> Kernel.+(milliseconds)
@collegeimprovements
Copy link
Author

Jake Morrison - Elixir

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment