Last active
October 18, 2019 06:58
-
-
Save topherhunt/81d81a7b66d061dd600dc85c8b67bec7 to your computer and use it in GitHub Desktop.
Four approaches to expressing nested logic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Sample do | |
# | |
# VERSION 1 | |
# The naive approach: just nest the if/else statements. Pretty readable. | |
# | |
def custom_block(project, label) do | |
# ... validations ... | |
if project do | |
if block = Enum.find(project.custom_blocks, & &1.label == label) do | |
raw block.body | |
else | |
default_block(label) | |
end | |
else | |
default_block(label) | |
end | |
end | |
# | |
# VERSION 2 | |
# I think this is what "with" statements are for, let's try that. Feels clunky and redundant though. | |
# | |
def custom_block(project, label) do | |
# ... validations ... | |
with true <- project != nil, | |
block <- Enum.find(project.custom_blocks, & &1.label == label), | |
true <- block != nil do | |
raw block.body | |
else | |
default_block(label) | |
end | |
end | |
# | |
# VERSION 3 | |
# Pattern-matching to reduce the verbosity of the "with" statement. Still feels weird. | |
# | |
def custom_block(project, label) do | |
# ... validations ... | |
with %Project{} <- project, | |
%CustomBlock{} = block <- Enum.find(project.custom_blocks, & &1.label == label) do | |
raw block.body | |
else | |
default_block(label) | |
end | |
end | |
# | |
# VERSION 4 | |
# Helper function with 2 signatures lets me get rid of the nestedness in the main function. Psew. | |
# | |
def custom_block(project, label) do | |
# ... validations ... | |
if block = find_block(project, label) do | |
raw block.body | |
else | |
default_block(label) | |
end | |
end | |
defp find_block(nil, label), do: nil | |
defp find_block(proj, label), do: Enum.find(proj.custom_blocks, & &1.label == label) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment