ichigolas
ichigolas

Reputation: 7725

Elixir, default keyword list argument

In elixir is possible to use default arguments in function definitions, but I found it impossible to do so with single keyword list arguments like:

def do_stuff(
  success: sucess \\ fn(conn) -> conn end,
  error: error
) do
  # ...
end

Also, I thought about avoiding this kind of "callback passing" style of coding by using something like JS promises but I couldn't find an implementation of promises for Elixir.

Maybe there's something built in right into the language that could help me write better code and closer abide to the elixir standards.

Main question: is possible to use default keyword arguments?

Side question: Is there something Elixir provides to help avoid this "callback passing" style of programming in favor of a more reactive/composable mechanism?

Upvotes: 2

Views: 1493

Answers (1)

whatyouhide
whatyouhide

Reputation: 16781

No, it's not possible to use default keyword arguments as keyword arguments are just syntactic sugar over a single keyword list:

do_stuff(success: ..., failure: ...)

is the same as

do_stuff([success: ..., failure: ...])

So a keyword list is really just a single argument. What you're doing in your function definition is matching on the keyword list passed to do_stuff/1: be sure to watch out for this as well, because your function definition will not match if the order of the keywords is not the same (i.e., do_stuff(failure: ..., success: ...)).

I think a nice way to overcome this is simply use two different arguments for the do_stuff function:

def do_stuff(success \\ fn(conn) -> conn end, failure \\ fn(err) -> err end)

This way default arguments work as expected. If you really need your argument to be a keyword list, then you can handle defaults inside the body of the function:

def do_stuff(options) do
  success = options[:success] || (fn(conn) -> conn end)
  failure = options[:failure] || (fn(err) -> err end)
end

Finally, about the "callback style" you mentioned, I don't know about anything that works much differently than just passing fn for when something is done, unless you start looking into concurrency and message passing.

Upvotes: 6

Related Questions