This library implements this functionality, albeit on a peculiar way:
https://hex.pm/packages/defnamed. It suffers from the issues explained by
Marc-André.

On Thu, Oct 27, 2022, 21:05 Marc-André Lafortune <marc-an...@marc-andre.ca>
wrote:

> If I understand your proposal, calling `do_a_thing(old: "older value",
> new: "newer value")` would need to know the signature of `do_a_thing` at
> *compile-time*. Among other things, two modules wouldn't be able to call
> each other's functions this way, as one couldn't be compiled without the
> other... Also there would be no way to know if `do_a_thing` uses named
> function arguments, so any function call using keywords would introduce a
> compile-time dependency.
>
> That being said, I miss Ruby's named arguments, and wish the default
> syntax for Elixir was building maps instead of keywords, but that can't
> change. Having a nice syntax for map arguments with defaults could be
> interesting though.
> On Thursday, 27 October 2022 at 09:59:48 UTC-4 Brandon Gillespie wrote:
>
>> Ordering of arguments is an age-old programming challenge (creating many
>> bugs). Type checking and pattern matching help, but are also limited. We
>> currently have two indirect ways of having named arguments, but both have
>> challenges:
>>
>>    1. Keyword lists — pattern matching must match the exact order of the
>>    listed arguments, which doesn't help the issue here which is ordering, let
>>    alone optional arguments, leading to extraneous in-function calls to
>>    Keyword.get.
>>    2. Maps — while this supports optional arguments, it has the overhead
>>    of creating and destructing a map for a simple function call. Benchmarking
>>    this vs ordered arguments shows it's 1.79x slower than simply using 
>> ordered
>>    arguments. That's an overhead that builds up on every function (I didn't
>>    benchmark keyword lists, sorry).
>>    3. Existing syntax to handle named arguments as keywords should still
>>    be handled, for backwards compatibility, making it harder to do this sort
>>    of thing.
>>
>> To preface the proposal, I realize this may simply not be possible with
>> the limitations of the parser/compiler that we have today.
>>
>> Proposal:
>>
>> Add a compile-time named/pinned argument syntax in the function
>> declaration head, which allows the naming of arguments as if it were a
>> keyword list, but instead, the keys are mapped to the variable names/pins
>> and, if necessary, are rearranged to keep the ordering correct.
>>
>> This will not work with conventional keyword arguments, where one expects
>> a keyword list—if using the named/pinned syntax, keyword arguments may not
>> be used. It's one or the other, not both.
>>
>> If this named syntax exists on a function head, then a calling function
>> may use the `name: value` syntax and it will align the values to the named
>> argument at compile time (no keyword lists are used at runtime).
>>
>> Example:
>>
>> Using `&` as a reference for the naming (or possibly if not that, the
>> asterisk):
>>
>>   def do_a_thing(&new, &old)
>>
>> Would accept any of these calls, and in all cases the variable values
>> within the called function would align properly:
>>
>>   do_a_thing("newer value", "older value")
>>   do_a_thing(new: "newer value", old: "older value")
>>   do_a_thing(old: "older value", new: "newer value")
>>
>> Optional named arguments in the same manner as optional arguments today:
>>
>>   def do_a_thing(&new, &old, &optional \\ "extra info")
>>
>> Optional ideas:
>>
>>
>>    1. If rearranging the arguments at compile time is not easily
>>    feasible, it could simply just raise a compiler error when out of order,
>>    and then strip the names when they are properly ordered.
>>    2. If using named/pinned arguments, always require them to be named
>>    (thus, the first example above would be invalid). However, this comes with
>>    its own challenge, notably what about when using pipelines? Perhaps just
>>    allow that.
>>    3. If it's too challenging to use the same syntax as keyword lists,
>>    another naming convention could be used. It's just ... uglier.  Perhaps if
>>    using `*` instead it would be on both sides (function head, and calling
>>    function), such as:
>>
>>   def do_a_thing(*new, *old)
>>   ...
>>   do_a_thing(*new: "newer value", *old: "older value")
>>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/0928ddde-8ca2-4110-a223-d62b711529a7n%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/0928ddde-8ca2-4110-a223-d62b711529a7n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAKC64%2Bz6yHpK%3DJpN1fd7fgz9Z-m2UmsA0a852obGrjCpXzN1-w%40mail.gmail.com.

Reply via email to