roman

roman

Using a literal parameter to choose between multiple function heads

Hi,
Imagine we have a code like this in a language that doesn’t support functions with multiple heads:

def parse_date(format, value) do
  case format do
  :iso8601 -> Date.from_iso8601(value)
  :american -> value |> String.split("/") |> …
  end
end

If we always pass the format as an atom literal, i.e. parse_date(:iso8601, value), this is considered an anti-pattern (https://martinfowler.com/bliki/FlagArgument.html).

In Elixir, however, this is not so clear, because the implementations are more separated and there’s no explicit branching:

def parse_date(:iso8601, value) do
  Date.from_iso8601(value)
end

def parse_date(:american, value) do
  value |> String.split("/") |> …
end

Do you consider this an anti-pattern in Elixir as well, and we should have differently named functions? Or does this approach fit the general pattern-matching style of Elixir?

Most Liked

LostKobrakai

LostKobrakai

I’ve looked into the arguments of martin fowler:

Tangled Implementation

This can happen, but given in elixir we usually write different function bodies like he does for two different functions I feel this is is not more of an issue then for his proposed solution.

Deriving the flag

Given we’re not in oop land, somewhere some functions needs to decide for which “flag” to use – only then parse_date is called. So most of the discussion is not applicable to elixir. But I’m with martin that boolean flags are bad. I don’t want to see calls like parse_date(true, date) vs. parse_date(false, date) to differenciate :america | :iso8601. Either use atoms describing the flag or if it’s truely boolean use a keyword list: parse_date(value, time_only: true)

al2o3cr

al2o3cr

An initial style note: the first argument position is usually reserved for the “subject” - value here - so that pipes work nicely:

some
|> chain()
|> of_expressions(that: return_a_string_shaped_like_a_date)
|> parse_date(:american)

Whether this is better as |> parse_date(:american) or parse_date_american() depends on usage; is the format always hard-coded or is it driven by data (for instance, from a user preference)?

Another deciding factor might be the implementation: are the two function heads independent, or do they rely on common private functions?

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
kostonstyle
Hi all I want to have a unix time, from the current time plus 1 hour. DateTime.now + 1 hour How to get it in elixir? Thanks
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement