Is there a way to do default named parameters

  def fun(options) do
    [parameter1: parameter1, parameter2: parameter2] = Enum.into(options, parameter1: 1, parameter2: 2)

Is there an alternative to the above very boilerplatey code?

Ideally something like this which is not allowed

  def fun(parameter1: parameter1 \\ 1, parameter2: parameter2 \\ 2) do
  end
5 Likes

I have been using something like this…

def fun(options \\ []) do
  default = parameter1: 1, parameter2: 2
  options = Keyword.merge(default, options, fn _k, _v1, v2 -> v2 end)
  ...
end

You don’t need the function to Keyword.merge, what you have there is what it defaults to anyway. Thus you can just have

default = [foo: 1, bar: 2]
options = Keyword.merge(default, options)
4 Likes

Is there any way to reduce the boilerplate?

Only by using individual function parameters. You can default those. You cannot default inner data of parameters.

2 Likes

The subject of the thread suggests a misunderstanding. These are not named parameters. They’re a couple of layers of syntactic sugar. In Elixir the last parameter to a function can implicitly be a keyword list. For example:
def my_fun(param1, param2, option1: v1, option2: v2)
Is literally a function of 3 parameters (my_fun/3). The third parameter is [option1: v1, option2: v2], a keyword list.

Furthermore a keyword list, as displayed above, is syntactic sugar for a list of 2 element tuples:
[{:option1, v1}, {:option2, v2}] which the Keyword module can treat in a very map-like way. They do have their idiosyncrasies in that as a list, pattern matching relies on ordering, and that a key can be duplicated. These and a more generalized form (called proplists) have been used in Erlang long before the BEAM added the map datatype.

8 Likes

Thanks for your response. I am aware that named parameters are just syntactic sugar over keyword lists, however the intended usage of the keyword list is to act like named parameters in a language like kotlin, Which has the concept of named parameters with default values (https://try.kotlinlang.org/#/Kotlin%20Koans/Introduction/Named%20arguments/Task.kt).

2 Likes

Take a look at this package: https://hexdocs.pm/megadef/Megadef.html

I don’t think anyone is using this in real life, but it’s a good example of the power of macros to add little things like “named parameters” easily :slight_smile:

It was my first adventure in “macroland” :slight_smile: I have crazier (and more useful!) things now.

2 Likes

Defnamed — Defnamed v0.1.3 seems interesting.

1 Like

Not to necropost, but I came across this post when searching about default parameters. Posting in-case others come across as well.

Elixir 1.13.0 introduced Keyword.validate/2 (and related Keyword.validate!/2). Which I believe is intended to solve this exact problem.
These functions both ensure the keywords passed are well-known (i.e. fails if any are unlisted keywords) and sets defaults for keywords not passed in.

For the original example, I believe this could be written like:

def fun(opts) do
  opts = Keyword.validate!(opts, [parameter1: 1, parameter2: 2])
end

This goes beyond Keyword.merge/2 since it ensures you won’t have a potential superset of arbitrary, unexpected keywords

16 Likes