# The death of optional arguments?

**URL:** <https://discourse.julialang.org/t/the-death-of-optional-arguments/7388>\
**Category:** Internals & Design\
**Created:** [November 29, 2017, 3:50pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388 "2017-11-29T15:50:38Z")\
**Posts on this page:** 18\
**Page:** 2

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [November 29, 2017, 6:30pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/22 "2017-11-29T18:30:39Z")

</div>

With many keyword arguments just 1 keyword many times is not enough to tell you what it actually does. Most of the time it does, but there are times where this is not true.

You can just use the documentation string feature using `?` if you forget the argument orders. I think it’s clear from your concerns that this is more in the interactive part of coding, which is perfectly fine to use `?`.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [November 29, 2017, 6:30pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/23 "2017-11-29T18:30:50Z")

</div>

> [@bramtayl](#):
>
> Those aren’t the kind of optional arguments I’m thinking of. I mean optional arguments in the sense of

Yes, I agree with you that your example should be keyword arguments. However, why would that mean optional arguments should be removed from the language and break the examples I am showing? That makes no sense. I’m just showing there’s a use case for both. I also agree with you that optional arguments were abused too much in the past for dispatch, but that doesn’t mean they don’t have a purpose.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 29, 2017, 6:38pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/24 "2017-11-29T18:38:14Z")

</div>

> [@bramtayl](#):
>
> `rstrip(s, chars=mplah_mplah)` is much more readable in case you forget what second argument is supposed to be (number of characters to split? A regex expression?)

I am not sure that’s a particularly good example. Once you know what `rstrip` does, a regex or a number just don’t make sense in that context.

---

<div class="post-metadata">

**Author:** ![bramtayl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bramtayl/32/3614_2.png) [@bramtayl](https://discourse.julialang.org/u/bramtayl)\
**Post date:** [November 29, 2017, 6:38pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/25 "2017-11-29T18:38:54Z")

</div>

Well, I guess I don’t feel super strongly about this. Unless I’m being dense, max isn’t defined using optional arguments in the way I’m thinking about them at all. Maybe a better word for what I’m thinking of is default arguments?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 29, 2017, 6:46pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/26 "2017-11-29T18:46:47Z")

</div>

> [@bramtayl](#):
>
> max isn’t defined using optional arguments in the way I’m thinking about them at all

Is it possible that you are confusing optional and [variadic](https://en.wikipedia.org/wiki/Variadic_function) arguments?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [November 29, 2017, 6:50pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/27 "2017-11-29T18:50:40Z")

</div>

> [@Tamas\_Papp](#):
>
> Is it possible that you are confusing optional and variadic arguments?

I guess I am, but I always see vaiadic arguments as just optional arguments which have a default of `nothing` and are just ignored. In that sense, APIs with `f(x,y=nothing,z=nothing)` are a pretty easy and powerful way to turn off various proceeding steps.

Also, the DiffEq API `sol = solve(prob,alg;kwargs...)` depends on dispatching to specific solvers in different packages via `alg`. I think it would be very difficult to follow if `alg` was turned into some “special keyword argument” that chose which package `solve` would actually call! Instead, it’s quite clear from that `prob` and `alg` do the main dispatch, and the other `kwargs` are just tweaks.

---

<div class="post-metadata">

**Author:** ![Nosferican](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nosferican/32/9275_2.png) [@Nosferican](https://discourse.julialang.org/u/Nosferican)\
**Post date:** [November 29, 2017, 8:24pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/28 "2017-11-29T20:24:26Z")

</div>

I prefer to have only keyword arguments in my coding style. For example, in R I always keyword any and all arguments. One crucial difference though, is that currently keyword arguments have a default value while positional arguments do not.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 29, 2017, 8:55pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/29 "2017-11-29T20:55:29Z")

</div>

It is actually _impossible_ to remove optional arguments from Julia, because they are just syntactic sugar for a particular application of multiple dispatch. For example, `f(x,y=0) = 2x+y` is equivalent to:

```julia
f(x,y) = 2x+y
f(x) = f(x,0)

```

You can get rid of the `f(x,y=0)` sugar, but you can’t get rid of the underlying functionality.

Since the underlying functionality will always be there (and is often useful, as others have pointed out), I don’t see any benefit to getting rid of the sugar.

---

<div class="post-metadata">

**Author:** ![tobias.knopp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobias.knopp/32/7551_2.png) [@tobias.knopp](https://discourse.julialang.org/u/tobias.knopp)\
**Post date:** [November 29, 2017, 9:10pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/30 "2017-11-29T21:10:17Z")

</div>

Maybe the original suggestion of the OP was a little strict. But in general it would be interesting to derive some kind of coding guidelines in context of the new performance behavior. Until now APIs where partially chosen due to the performance bottleneck of kw args. Maybe now one would rethink the API?

---

<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:** [November 29, 2017, 9:55pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/31 "2017-11-29T21:55:55Z")

</div>

> [@bramtayl](#):
>
> I guess I’m in general a fan of readable code. I think that `rstrip(s, chars=mplah_mplah)` is much more readable in case you forget what second argument is supposed to be

But in this example I now need to remember both what the second argument is supposed to be, _and_ what it’s _called_. Is it `chars` or `characters`, or maybe `char`?

Also, verbosity is _bad_.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [November 29, 2017, 11:21pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/32 "2017-11-29T23:21:51Z")

</div>

Could somebody please explain why it would be so desirable to remove a feature like optional arguments from Julia? What is the advantage gained from removing it over keeping it?

---

<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:** [November 30, 2017, 9:37am UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/33 "2017-11-30T09:37:29Z")

</div>

If I understand correctly, it is to promote a clearer, more explicit, programming style, that is easier to read.

I happen to disagree that it’s easier to read (except in cases with many input parameters — more than four, perhaps?), and it’s certainly harder to write. Also, as mentioned by @stevengj, it really cannot be done, without sacrificing multiple dispatch itself.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 30, 2017, 9:47am UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/34 "2017-11-30T09:47:22Z")

</div>

Good point! In fact one can argue that Julia has optional arguments in **any position** , not just trailing. Eg consider

```julia
rand([rng], [S], [dims...])

```

It is just that it has syntactic sugar for **trailing** optional arguments. Perhaps syntax could be introduced for the other kinds, eg

```julia
foo(a = 1, b, c = 3)

```

Of course `foo(4, 5)` is ambiguous, but we already have mechanisms for dealing with that.

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [November 30, 2017, 10:43am UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/35 "2017-11-30T10:43:37Z")

</div>

> [@Tamas\_Papp](#):
>
> Perhaps syntax could be introduced for the other kinds

See [allow default arguments at any place in a function by rfourquet · Pull Request #22460 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/22460) ! But it’s unlikely to get merged, so I’d rather make a package of it.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 30, 2017, 11:07am UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/36 "2017-11-30T11:07:20Z")

</div>

It is similar, except for the square brackets. Why did you introduce them?

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [November 30, 2017, 11:24am UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/37 "2017-11-30T11:24:18Z")

</div>

> [@Tamas\_Papp](#):
>
> It is similar, except for the square brackets. Why did you introduce them?

You are right, it’s not exactly equivalent. I think we could imagine built-in default arguments not only at a trailing position, with the rule that if `m` arguments are missing, the `m` rightmost defaults are used (so in your example, `foo(4, 5)` would be `a=4, b=5, c=3)`. Notice that `n` default values leads to `n+1` methods (once de-sugared).  
I used the square brackets for the case where one wants `2^n` methods for `n` default values in square brackets. For the example you give of `rand([rng], [S], [dims])`, there are indeed `8=2^3` methods available, rather than `4=3+1`, so both ways have their usefulness.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 30, 2017, 11:37am UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/38 "2017-11-30T11:37:13Z")

</div>

While I was initially enthusiastic about having optional arguments on the left side, the more I think about it, the more apparent the disadvantages become clear.

AFAICT not enforcing that methods have the same number of (non-optional) positional arguments is unique to Julia (Common Lip enforces this, and so do multiple dispatch systems descended from CLOS). It allows signatures like we currently have for `Base.show` and `Base.rand`, among other things, but it seems that in practice only a carefully chosen subset of those 2^n combinations is used (except when n is small of course).

Manually writing those methods is not much of a hassle anyway, and is perhaps more clear.

---

<div class="post-metadata">

**Author:** ![jgoldfar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jgoldfar/32/2664_2.png) [@jgoldfar](https://discourse.julialang.org/u/jgoldfar)\
**Post date:** [April 9, 2018, 2:08pm UTC](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388/39 "2018-04-09T14:08:49Z")

</div>

Since there are APIs that make the most sense with or without this language feature, it seems to be a style question. Perhaps off topic, but this could be applied more consistency within a single codebase at a users request by a linter that accepts user-defined rules

[Previous page](https://discourse.julialang.org/t/the-death-of-optional-arguments/7388.md?page=1)
