# Naming positional arguments at call site

**URL:** <https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526>\
**Category:** Internals & Design\
**Created:** [September 4, 2023, 7:07pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526 "2023-09-04T19:07:20Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![GregVernon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregvernon/32/5611_2.png) [@GregVernon](https://discourse.julialang.org/u/GregVernon)\
**Post date:** [September 4, 2023, 7:07pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/1 "2023-09-04T19:07:20Z")

</div>

> [@What steps should the Julia community take to bring Julia to the next level of popularity?](https://discourse.julialang.org/t/what-steps-should-the-julia-community-take-to-bring-julia-to-the-next-level-of-popularity/101389/604):
>
> The inability to use positional arguments with keywords

I would _love_ to be able to use keywords with positional arguments. It’s one of my favorite “code should be self-documenting” features.

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [September 4, 2023, 7:17pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/2 "2023-09-04T19:17:30Z")

</div>

> I would _love_ to be able to use keywords with positional arguments. It’s one of my favorite “code should be self-documenting” features.

When I started out with Julia, I also thought that was a missing feature (especially coming from Python), but the idea is really not compatible with multiple dispatch: different methods can use different names for the positional arguments. So, allowing keywords for positional argument would be _very_ breaking, and thus won’t happen.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 4, 2023, 7:21pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/3 "2023-09-04T19:21:59Z")

</div>

> [@What steps should the Julia community take to bring Julia to the next level of popularity?](https://discourse.julialang.org/t/what-steps-should-the-julia-community-take-to-bring-julia-to-the-next-level-of-popularity/101389/604):
>
> The inability to use positional arguments with keywords

This would be a grotesque mis-feature. I fervently hope that nightmare vision will never torment my soul again.

---

<div class="post-metadata">

**Author:** ![ParadaCarleton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paradacarleton/32/20005_2.png) [@ParadaCarleton](https://discourse.julialang.org/u/ParadaCarleton)\
**Post date:** [September 4, 2023, 7:23pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/4 "2023-09-04T19:23:06Z")

</div>

> [@goerz](#):
>
> When I started out with Julia, I also thought that was a missing feature (especially coming from Python), but the idea is really not compatible with multiple dispatch:

That’s fine; it just means the positional argument names you use have to be the ones allowed by the method you’re calling. It works just the same as with keyword arguments.

---

<div class="post-metadata">

**Author:** ![ParadaCarleton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paradacarleton/32/20005_2.png) [@ParadaCarleton](https://discourse.julialang.org/u/ParadaCarleton)\
**Post date:** [September 4, 2023, 7:23pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/5 "2023-09-04T19:23:31Z")

</div>

> [@DNF](#):
>
> This would be a grotesque mis-feature.

Then don’t use it. But many of us like self-documenting code like we’re used to in Python. I personally can never remember the right order for the arguments in functions like `Turing.sample`.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 4, 2023, 7:25pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/6 "2023-09-04T19:25:42Z")

</div>

That’s not how it works. If this were ever implemented, _everyone_ would be forced to deal with it, that’s one of the things that makes it so evil.

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [September 4, 2023, 7:28pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/7 "2023-09-04T19:28:27Z")

</div>

You can always add a method accepting only keyword arguments and forwarding those to positional arguments. I’ve certainly done that on occasion in my own packages. You could even do something crazy like dynamically inspecting the methods table and selecting a method based on matching names (although I wouldn’t recommend it). But the compiler just isn’t going to be able to help you with any of this: you’ll always end up with runtime-dispatch.

---

<div class="post-metadata">

**Author:** ![ParadaCarleton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paradacarleton/32/20005_2.png) [@ParadaCarleton](https://discourse.julialang.org/u/ParadaCarleton)\
**Post date:** [September 4, 2023, 7:31pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/8 "2023-09-04T19:31:22Z")

</div>

> [@goerz](#):
>
> But the compiler just isn’t going to be able to help you with any of this: you’ll always end up with runtime-dispatch.

The compiler could handle it easily (see KeywordCalls.jl, which gives 0-cost keyword dispatch). The fact that keywords force runtime dispatch is because of a heuristic in the Julia compiler: the compiler assumes keyword arguments are unimportant, so it doesn’t need to compile separate methods for every possible keyword.

---

<div class="post-metadata">

**Author:** ![ParadaCarleton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paradacarleton/32/20005_2.png) [@ParadaCarleton](https://discourse.julialang.org/u/ParadaCarleton)\
**Post date:** [September 4, 2023, 7:34pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/9 "2023-09-04T19:34:08Z")

</div>

> [@DNF](#):
>
> _everyone_ would be forced to deal with it

It’s evil to have to read

```julia
sample(rng=Xoshiro(0), sampler=NUTS(), model=my_loglikelihood)

```

instead of

```julia
sample(Xoshiro(0), NUTS(), model)

```

?

Even if you don’t like it, then just don’t allow it in your style guide. All I’m saying is that you’re never going to get people to switch over from Python if this feature is missing; it makes Julia code substantially less _readable_ than Python. _Readable_ isn’t the same thing as _pretty_. _Readable_ requires users to be _explicit_ about what they’re doing. Using kwargs, instead of positional arguments, forces users to document their code.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [September 4, 2023, 7:37pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/10 "2023-09-04T19:37:56Z")

</div>

> [@ParadaCarleton](#):
>
> All I’m saying is that you’re never going to get people to switch over from Python if this feature is missing;

of all the things I’ve read someone claim will doom Julia, this is one of the silliest. besides being IMO a much more confusing misfeature than status quo, it’s also largely irrelevant

I also just don’t really understand your argument. why would `kwargs` be synonymous, or even correlated, with documentation?

do you really want to write `subset(table=df, label=:day, value="Sunday")` ?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 4, 2023, 7:41pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/11 "2023-09-04T19:41:28Z")

</div>

> [@ParadaCarleton](#):
>
> It’s evil to have to read

You choose an example where keywords read well, but most functions have variables that don’t _have_ any reasonable names. It’s evil to have to read

```julia
+(x=1, y=2)

```

because that’s the can of worms you are opening. Every arbitrarily named argument is now part of the user interface. And every change you want to make for the sake of internal implementation reasons is now a breaking change.

---

<div class="post-metadata">

**Author:** ![GregVernon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregvernon/32/5611_2.png) [@GregVernon](https://discourse.julialang.org/u/GregVernon)\
**Post date:** [September 4, 2023, 7:42pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/12 "2023-09-04T19:42:18Z")

</div>

Interesting, thanks for your insight here – it’s the first answer to this question of mine I’ve seen, so bear with me as I ask a few clarifying follow-up questions:

1. Is the “different methods can use different names” just an issue when namespace clashes exist, such as

```julia
using Krylov
using IterativeSolvers

# stiff_matrix = ..., force_vector = ..., etc.
cg( A=stiff_matrix, b=force_vector )

```

Where we _pretend_ for this question’s purpose that the `cg` method from `Krylov.jl` and `IterativeSolvers.jl` have different names for those arguments.

1. In the actual case, where both `Krylov.jl` and `IterativeSolvers.jl` have the same names and amount of positional arguments, it would seem like this wouldn’t be “the” issue.

2. Are the “methods” you’re referring to from multiple dispatch of a single package’s method? It would seem to me that Julia could simply “ignore” the keyword on positional arguments. For example, it’s not clear to me how:

```julia
import LinearAlgebra

# stiff_matrix = ..., mass_matrix = ..., etc
e = LinearAlgebra.eigvals( A = stiff_matrix, B = mass_matrix )[0]

```

would have issues doing multiple dispatch.

---

<div class="post-metadata">

**Author:** ![rdavis120](https://avatars.discourse-cdn.com/v4/letter/r/b5a626/32.png) [@rdavis120](https://discourse.julialang.org/u/rdavis120)\
**Post date:** [September 4, 2023, 7:43pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/13 "2023-09-04T19:43:45Z")

</div>

It can also be a safer work process in terms of entering argument names when writing code. For example, in Rstudio when you work with a multiple dispatch method like print(), if you hit the tab key it shows you all of the arguments and their corresponding documentation. This will only show you the arguments for print.POSIXct. You can write a fair amount of code in a dynamic language with multiple dispatch, with just the tab key.

```r
d = Sys.time()
print(d, <hit tab and select documented arguments>

```

---

<div class="post-metadata">

**Author:** ![GregVernon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregvernon/32/5611_2.png) [@GregVernon](https://discourse.julialang.org/u/GregVernon)\
**Post date:** [September 4, 2023, 7:53pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/15 "2023-09-04T19:53:37Z")

</div>

> [@adienes](#):
>
> do you really want to write `subset(table=df, label=:day, value="Sunday")` ?

Yes. See arguments of:

> [Code is read much more often than it is written, so plan accordingly - The Old New Thing](https://devblogs.microsoft.com/oldnewthing/20070406-00/?p=27343)

> "Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …[Therefore,] making it easy to read makes it easier to write  
> [Quote by Robert C. Martin: “Indeed, the ratio of time spent reading versus ...”](https://www.goodreads.com/quotes/835238-indeed-the-ratio-of-time-spent-reading-versus-writing-is)

I’m not saying that I would want it to be _required_ (wouldn’t want to force my worldview on others) but rather _supported_ as an option.

This is similar to my annoyance with devs using `from numpy import *` or `using LinearAlgebra` or `using namespace std;`, _especially_ in documentation / tutorials. It makes it difficult for a new-user, or a different developer three years later, to know what functions come from which packages. I prefer being explicit, if not pedantic, when I write code.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [September 4, 2023, 7:54pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/16 "2023-09-04T19:54:33Z")

</div>

> [@GregVernon](#):
>
> Yes. See arguments of:

I’m not disputing that code should be optimized for readability

I’m disputing that this proposal achieves that aim

> [@GregVernon](#):
>
> `using LinearAlgebra` or `using namespace std;`, _especially_ in documentation / tutorials. It makes it difficult for a new-user, or a different developer three years later, to know what functions come from which packages. I prefer being explicit, if not pedantic, when I write code.

yes, now this is a major problem I have as well. I agree that the magic namespace loading paradigm is not good for readability. I think it is a completely independent issue though to this named positional arg thing. I don’t think the two are remotely similar

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [September 4, 2023, 7:54pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/17 "2023-09-04T19:54:49Z")

</div>

We’re really going on a tangent here… Someone should probably move this to a new thread.

But no, this has nothing to do with namespace clashes. It’s very likely that the same package will define multiple methods for the same function, using different names for the positional arguments.

Or, other packages will extend an existing function and use different names. For example, I’m usually writing packages in the context of quantum mechanics, so if I define a type that represents a Hamiltonian operator, I’ll most likely define a method

```julia
LinearAlgebra.eigvals(H; kwargs...)

```

for it. Or, maybe in another part of the library, it’s a data structure for a Liouvillian, and I’ll have `LinearAlgebra.eigvals(L; kwargs...)`.

Obviously, people should be able to call `eigvals(A)` without having to worry about what the type of `A` is and whether the author extending it used `A` or `H` or `L` or something else. It would be quite limiting if `eigvals(A)` / `eigvals(A=object)` extended only to methods that used `A`. I mean, sure, you could design a language like that, but it would be very different from how it works in Julia.

In any case, this would be a very breaking change to the fundamental design of the Julia, and thus won’t happen (since there’s no breaking 2.0 version planned, and I doubt even a 2.0 would touch anything so fundamental)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 4, 2023, 8:02pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/18 "2023-09-04T20:02:06Z")

</div>

> [@GregVernon](#):
>
> I’m not saying that I would want it to be _required_ (wouldn’t want to force my worldview on others) but rather _supported_ as an option.

The answer to your wish is to improve the performance of kwargs.

But how readable will this be when you want to mix four libraries with related functionalities that all use different naming schemes for the same kind of argument? Perhaps this works for monoliths like SciPy, but I doubt it will be either pretty or readable, but rather extremely confusing in an ecosystem of many small packages.

---

<div class="post-metadata">

**Author:** ![ParadaCarleton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paradacarleton/32/20005_2.png) [@ParadaCarleton](https://discourse.julialang.org/u/ParadaCarleton)\
**Post date:** [September 4, 2023, 8:03pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/19 "2023-09-04T20:03:39Z")

</div>

> [@adienes](#):
>
> of all the things I’ve read someone claim will doom Julia, this is one of the silliest.

This is one of the top 3 or 4 complaints about the issue that I hear people bring up, and probably the single biggest feature I miss when I use Turing instead of PyMC (along with the closely related array-labeling ecosystem). Those _definitely_ take up a substantial amount of time. I think it takes me about 50% longer to write a model in Turing than it does in PyMC because of this one issue. I just spend _so_ much more time chasing down bugs in Julia that would be extremely obvious if everything could be clearly labeled.

It seems like Julia devs still haven’t learned the lessons of TensorFlow. TensorFlow/Keras blew a 4-year lead to PyTorch because PyTorch was slightly more readable, despite TensorFlow being orders of magnitude faster under some circumstances. I originally learned Julia because macros let me write more readable/obvious/explicit code (`y ~ Normal()` instead of `y = pymc.normal()`), not for any performance reason.

---

<div class="post-metadata">

**Author:** ![xiaoxi](https://avatars.discourse-cdn.com/v4/letter/x/a9adbd/32.png) [@xiaoxi](https://discourse.julialang.org/u/xiaoxi)\
**Post date:** [September 4, 2023, 8:05pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/20 "2023-09-04T20:05:16Z")

</div>

> [@ParadaCarleton](#):
>
> It’s evil to have to read
> 
> ```julia
> sample(rng=Xoshiro(0), sampler=NUTS(), model=my_loglikelihood)
> 
> ```
> 
> instead of
> 
> ```julia
> sample(Xoshiro(0), NUTS(), model)
> 
> ```
> 
> ?

The LSP server could provide that information. For instance, the TypeScript LSP server does it:

![image](https://global.discourse-cdn.com/julialang/original/3X/b/3/b3ea6a844f2ac602d3ca3010d3a41a34ddd62b2e.png)

---

<div class="post-metadata">

**Author:** ![ParadaCarleton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paradacarleton/32/20005_2.png) [@ParadaCarleton](https://discourse.julialang.org/u/ParadaCarleton)\
**Post date:** [September 4, 2023, 8:06pm UTC](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526/21 "2023-09-04T20:06:19Z")

</div>

> [@DNF](#):
>
> The answer to your wish is to improve the performance of kwargs.

The only way to do that would be to make TTFP explode by having us compile methods for every possible combination of keyword arguments. Then, we would have to replace positional arguments for every function in Julia with keyword arguments.

[Next page](https://discourse.julialang.org/t/naming-positional-arguments-at-call-site/103526.md?page=2)
