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
2 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)
3 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.

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.

7 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).

1 Like

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

4 Likes