Changing function head at compile time (named arguments)

Is there an easy way to turn functions like

def create(attrs, by: user_id) do
   # ...
end

into

def create(attrs, user_id) do
  # ...
end

at compile time? I want named arguments, but don’t want to pattern match on lists.

Maybe these functions could be marked with some decorator like @spread?

@spread
def create(attrs, by: user_id) do
  # ...
end

How would I then change the calls to these functions from

# ...
create(attrs, by: user_id)
# ...

to

# ...
create(attrs, user_id)
# ...

during compilation?

def create(attrs, server_id, user_id) do
 create(attrs, server_id: server_id, user_id: user_id)
end

maybe that can help you.

There is still a function with lists being used.

I can indicate the functions calls to which should be transformed at the top of the module.

defmodule SomeModule do
  @spread [:create, ...]
  # ...
end

There are no named arguments, fullstop.

If you do not want pattern match on lists, then do it like this:

def create(attrs, opts) do
  {:ok, user_id} = Keyword.fetch(opts, :by)
  ...
end
2 Likes

There are no named arguments, fullstop.

I guess I’ll implement it then with a library …

Or via:

user_id = opts[:by] || "default_value_else_nil"
1 Like