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.

Reply via email to