dylan-chong
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
Most Liked
deadbeef
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
gregvaughn
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.
benwilson512
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)







