# Nothing == absence of keyword argument?

**URL:** https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119
**Category:** General Usage
**Tags:** question, keyword-arguments
**Created:** [December 28, 2023, 7:46am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119 "2023-12-28T07:46:54Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [December 28, 2023, 7:46am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/1 "2023-12-28T07:46:54Z")

</div>

Is there a convenient idiom to indicate that a keyword argument is absent? I imagine that somebody may have already invented a macro or something to do this . . .

There are library functions, typically from graphics packages, that take a large number of optional keyword arguments. Let’s call them “attributes”. If the user doesn’t specify them, such functions return convenient default results. This arrangement is very nice: the user typically needs to customize only a fraction of the attributes.

In this typical situation, how do you _not_ give an attribute?

[In the following examples, `func` is **not** a wrapper to the library function. It just uses the library function as part of its job.]

```julia
# Method 1
function func(; atB = nothing, ...)
   ... do something ...
   if isnothing(atB)
     libraryfunc(;atA=..., atC=..., ...)
   else
     libraryfunc(;atA=..., atB=atB, atC=..., ...)
   end
end

# Method 2
function func(; atB = atB_default, ...)
   ... do something ...
   libraryfunc(; ..., atB=atB, ...)
end

# Method 3: NamedTuple
function func(; atB = (), ...)
   ... do something ...
   libraryfunc(; atB..., ...) # splat atB.
end
func(; atA=..., atB = (atB = somevalue,), atC=...)
func(; atA=..., atC=...)

```

Method 1 quickly becomes impossible if your function has multiple optional attributes.

Method 2 requires that you know the default value. Sometimes there are obvious default values but at other times, you have to consult the documentation, or in the worst case, you have to look at the source code. Moreover, the default value may change in the future. So, a question is, _is there a method to query the default value of an optional keyword argument?_

Method 3 is the only reliable method I’ve found so far. The downsize is that it’s a bit tedious on the caller side: you need to create a NamedTuple. An upside is that you can bundle multiple attributes into a single NamedTuple: `ats = (atB=..., atD=...)`, where you can include or omit arbitrary attributes to `libraryfunc()`.

But, _I wish all library functions regarded_ `nothing` _as equivalent to not giving the argument._ Or, can a macro be constructed in such a way that if the argument’s value is `nothing`, it be removed from the argument list?

---

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [December 28, 2023, 8:00am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/2 "2023-12-28T08:00:28Z")

</div>

Oh and, I should have added that Fortran as this nice `optional` qualifier to arguments:

```fortran
subroutine func(atB)
   real, optional:: atB
   call libraryfunc(atB) ! knows whether atB is present or not.
end
call func()
call func(atB = somevalue)

```

The “presence” or “absence” propagates in Fortran and in `libraryfunc`, you can tell whether the argument is given or not.

---

<div class="post-metadata">

### Author: ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)
#### Post date: [December 28, 2023, 8:59am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/3 "2023-12-28T08:59:51Z")

</div>

If you know the set of possible keyword argument names accepted by `libraryfunc`, you can filter them out of the keyword arguments passed to `func`:

```julia
function func(; kwargs...)
    ... do something ...
    libraryfunc_kwargs = (`atA`, `atB`, `atC`)
    validkwargs = filter(kwargs) do (key, _)
        key in libraryfunc_kwargs
    end
    libraryfunc(; validkwargs...)
end

```

There you don’t need to know the default values, but still have to define the list of keys accepted by `libraryfunc`, in the variable `libraryfunc_kwargs`. Instead of writing them manually as in the example above, you can [get them with `Base.kwarg_decl`](https://discourse.julialang.org/t/get-the-argument-names-of-an-function/32902/6), although if `libraryfunc` has several methods, you need to choose the one that you mean to call (easier if your function is type-stable).

This would become a bit more complicated if `libraryfunc` accepts variable keyword arguments (`kwargs...`). But in that case, probably you don’t even have to filter the ones passed to `func`.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [December 28, 2023, 9:19am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/4 "2023-12-28T09:19:05Z")

</div>

> [@ryofurue](#):
>
> So, a question is, _is there a method to query the default value of an optional keyword argument?_

There is not, though I think `nothing` has exactly the meaning your want. It represents the knowledge that there is no value. Whether that is an appropriate default depends on the function in question though; in general, you can’t really get around “knowing” what the default value is if you implement something that depends on that value.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [December 28, 2023, 9:31am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/5 "2023-12-28T09:31:40Z")

</div>

To do less keyword filtering, the caller function can reserve its `kwargs...` (or some more descriptive name like `barplotkwargs...`) to pass along to the library function call. Shared keywords like `atA`, `atB`, `atC` won’t need to be specified in the caller function header or library function call, and omitting any in the caller function call will let the library function use the default values. Although, if you wanted the caller function to have different defaults, you can specify those keywords, like `atB = new_default`, in ~~the header and pass it by name to~~ the library function call before the `kwargs...` (EDIT: as Salmon demonstrates in the next comment, `kwargs...` containing `atA` overrides the previous `atA=1` instead of causing a repeated keyword syntax error).

If you have multiple library functions with different keyword argument sets, I think the neatest way would be partitioning into reserved `NamedTuple`/`Dict` arguments (could be positional or keyword) for the caller function, defaulting to empty ones.

> [@heliosdrm](#):
>
> although if `libraryfunc` has several methods, you need to choose the one that you mean to call (easier if your function is type-stable).

A healthy library should standardize the keyword arguments, e.g. attributes for a kind of plot.

---

<div class="post-metadata">

### Author: ![Salmon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/salmon/32/22968_2.png) [@Salmon](https://discourse.julialang.org/u/Salmon)
#### Post date: [December 28, 2023, 11:10am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/6 "2023-12-28T11:10:39Z")

</div>

I’m not sure if that’s what you mean but if your function doesn’t explicitly depend on the argument you can just pass optional kwargs to the function.  
Personally, I often do the following:

```julia
function func(a;kwargs...)
  [...]
  libraryfunc(a; atA=1, atC=...,kwargs...)
end

func(1;atB=:green) # passes :green to libraryfunc
func(1) # does not pass any attribute, libraryfunc will use its default
func(1;atA=5) # overwrites the default value atA=1

```

---

<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: [December 28, 2023, 3:23pm UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/7 "2023-12-28T15:23:05Z")

</div>

> [@ryofurue](#):
>
> I imagine that somebody may have already invented a macro or something to do this . . .

I would factor out the choice of defaults to a function, as in eg

```julia
default_atB() = ...

function func(; atB = default_atB(), ...)
    ...
end

```

You can even organize many into a single function in a package, eg

```julia
@inline defaults(s::Symbol) = defaults(Val(s))

defaults(::Val{:atB}) = ...

```

That said, IMO

> [@ryofurue](#):
>
> take a large number of optional keyword arguments

is bad style. Organize them into `struct`s or similar.

---

<div class="post-metadata">

### Author: ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)
#### Post date: [December 28, 2023, 3:37pm UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/8 "2023-12-28T15:37:02Z")

</div>

I usually do a mix – if I have a large number of keyword arguments and want to make it easy for the user to specify them (and not construct a struct themselves) I organise my function all in several levels

First level takes all keyword arguments and calls the struct constructors (these care for good defaults usually), then calls second level

Second level takes struct keywords and does the original work (one could call that the expert interface).

---

<div class="post-metadata">

### Author: ![Salmon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/salmon/32/22968_2.png) [@Salmon](https://discourse.julialang.org/u/Salmon)
#### Post date: [December 28, 2023, 3:58pm UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/9 "2023-12-28T15:58:44Z")

</div>

> [@Tamas\_Papp](#):
>
> That said, IMO
> 
> > [@ryofurue](#):
> >
> > take a large number of optional keyword arguments
> 
> is bad style. Organize them into `struct`s or similar.

Is it always, though?  
plotting packages such as CairoMakie.jl do this all the time, for example:

```julia
scatterlines(1:10;linewidth = 2, marker = '□',linestyle = :dash, colormap = :viridis, color = 1:10,...)

```

Sure, probably these kwargs ultimately end up in a struct somehow, but the user never interacts with them (and thankfully so, the style above is quite easy to use).

One point where I agree with you is that passing kwargs down the callstack makes it hard to see where they actually go or what kwargs are allowed in each function. But this is no issue if there is good documentation of the function.

---

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [December 29, 2023, 2:09am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/10 "2023-12-29T02:09:57Z")

</div>

Thank you all for your inputs! I appreciate them.

> [@Salmon](#):
>
> I’m not sure if that’s what you mean but if your function doesn’t explicitly depend on the argument you can just pass optional kwargs to the function.  
> Personally, I often do the following:
> 
> ```julia
> function func(a;kwargs...)
> [...]
> libraryfunc(a; atA=1, atC=...,kwargs...)
> 
> ```

Yes, I would do the same when that works. I said that `func` is not a wrapper to `libraryfunc`, by which I meant that `func` takes other keyword arguments that have nothing to do with `libraryfunc`. I should have been clearer.

> [@Tamas\_Papp](#):
>
> That said, IMO
> 
> > [@ryofurue](#):
> >
> > take a large number of optional keyword arguments
> 
> is bad style. Organize them into `struct`s or similar.

I don’t think that that is always better than giving the user access to individual attributes. For example, I sometimes want to change only the line width:

```julia
plotgraph!(xs, ys; linewidth=3)

```

where `plotgraph!()` has a large number of attributes. I’m actually annoyed when such a function demands a `struct` or tuple

```julia
# lineattributes=(type, width, color, withsymbols)
plotgraph!(xs, ys; lineattributes=(:solid, 3, :auto, false))

```

You are giving more burden to the user. To avoid this burden, do you use NamedTuple?

```julia
plotgraph!(xs,ys; lineattributes=(linewidth = 3, ))

```

but of course, this isn’t better than `plotgraph!(xs, ys; linewidth=3)`.

---

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [December 29, 2023, 2:32am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/11 "2023-12-29T02:32:45Z")

</div>

Reading through the responses, I’ve gotten the impression that there is no “easy” and “obvious” solution for the user _because there is no “easy” and “obvious” method for library writers._

I wish that the language (or a macro) provided a mechanism _that removes the attribute from the list when its value is_ `nothing` or something equivalent or cleverer.

By design, `nothing` _should_ be the universal signal of absence, but currently it’s not, which is likely because it’s tedious to always have to deal with `nothing` on the part of the library writers.

Actually, I was thinking of submitting to `Makie` a feature request that `nothing` be always treated as equivalent to absence, but then I immediately started to wonder why `nothing` isn’t already used like that.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [December 29, 2023, 3:56am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/12 "2023-12-29T03:56:03Z")

</div>

> [@ryofurue](#):
>
> I said that `func` is not a wrapper to `libraryfunc`, by which I meant that `func` takes other keyword arguments that have nothing to do with `libraryfunc`. I should have been clearer.

If `func`’s keywords don’t need a `kwargs...`, then you can just reserve it for `libraryfunc` like how Salmon does it. If you can’t, you can pass `libraryfunc`’s keyword arguments in a `NamedTuple` in 1 argument of `func`’s call, defaulting to an empty `NamedTuple()`, and it’ll look just like putting parentheses around keyword arguments. Following Salmon’s example:

```julia
function func(a, libraryfunckwargs = NamedTuple())
  #=... V these act like func-specific defaults=#
  libraryfunc(a; atA=1, atC=2, libraryfunckwargs...)
end

func(1, (atB=:green,)) # passes :green to libraryfunc
func(1) # does not pass any attribute, libraryfunc will use its default
func(1, (atA=5,)) # overwrites the default value atA=1

```

Seems simple enough.

> [@ryofurue](#):
>
> By design, `nothing` _should_ be the universal signal of absence

That’s a different notion of “absence.” This is what its docstring says:

> The singleton instance of type Nothing, used by convention when there is no value to return (as in a C void function) or when a variable or field holds no value.

`atB = nothing` is definitely not an absent keyword argument, so the instance `nothing` will normally override a default value. You’re effectively suggesting `nothing` to become a sentinel value for default values, which is very much not absent, and `nothing` was never designed to do that.

---

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [December 31, 2023, 7:15am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/13 "2023-12-31T07:15:13Z")

</div>

> [@Benny](#):
>
> Following Salmon’s example:
> 
> ```julia
> function func(a, libraryfunckwargs = NamedTuple())
> #=... V these act like func-specific defaults=#
> libraryfunc(a; atA=1, atC=2, libraryfunckwargs...)
> end
> 
> func(1, (atB=:green,)) # passes :green to libraryfunc
> func(1) # does not pass any attribute, libraryfunc will use its default
> func(1, (atA=5,)) # overwrites the default value atA=1
> 
> ```

That’s what I meant by “Method 3” in my initial example and it’s what I currently use in my actual programs. I should have written my Method 3 as you show above.

> [@Benny](#):
>
> > [@ryofurue](#):
> >
> > By design, `nothing` _should_ be the universal signal of absence
> 
> That’s a different notion of “absence.” This is what its docstring says:
> 
> > The singleton instance of type Nothing, used by convention when there is no value to return (as in a C void function) or when a variable or field holds no value.
> 
> `atB = nothing` is definitely not an absent keyword argument, so the instance `nothing` will normally override a default value. You’re effectively suggesting `nothing` to become a sentinel value for default values, which is very much not absent, and `nothing` was never designed to do that.

You mix up two things:

1. “What `nothing` is”, and
2. “How a library function should treat it.”

You are correct that

> `atB = nothing` is definitely not an absent keyword argument,

You describe “what” `nothing` is not.

My argument is that a library function should treat `nothing` as equivalent to the absence of the argument. I want to draw your attention to “by convention” in the sentence from the documentation you quote. How useful `nothing` is depends on “how” you use it.

`nothing` should be viewed as a signal that the variable “holds no value” (from the sentence from the documentation you quote). Then the _real_ question is

What should a library function do if the optional keyword argument “holds no value”?

This is not a question about “what” `nothing` is. It is a question about what’s the best use of `nothing`. What should the library function do when the given variable “holds no value”?

Currently there are a lot of library functions that result in error if a given optional keyword argument is `nothing`. Is that the best design?

In many cases, treating `nothing` as if the optional argument were absent would be better than resulting in error.

To summarize, I think “we” should agree that “by convention”, an optional keyword argument should be regarded as absent if it’s given a `nothing` value. I think it agrees with “the spirit of `nothing`”.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [December 31, 2023, 8:10am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/14 "2023-12-31T08:10:07Z")

</div>

> [@ryofurue](#):
>
> To summarize, I think “we” should agree that “by convention”, an optional keyword argument should be regarded as absent if it’s given a `nothing` value. I think it agrees with “the spirit of `nothing`”.

When I manually assign a variable an instance, I expect that it isn’t reassigned automatically. Keyword arguments are not an exception in practice, and what happens with `nothing` arguments vary case by case. Sometimes it’s used to branch to different code with no default value to replace it, which is also a “spirit of `nothing`”, perhaps even more so. You could implement your desired default value behavior for your callers by `filter`ing out `nothing` values from the `NamedTuple` of keyword arguments before passing into your library function, no need to instantiate defaults in callers.

---

<div class="post-metadata">

### Author: ![axsk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/axsk/32/1952_2.png) [@axsk](https://discourse.julialang.org/u/axsk)
#### Post date: [June 13, 2025, 10:29am UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/15 "2025-06-13T10:29:43Z")

</div>

Just came here with the same issue but must see that there is no satisfactory/simple solution for the simple (and I believe common) problem to distribute kwargs from `func` to different `libraryfunc`s and inheriting `libraryfunc`s default values.

In my eyes the suggested behavior of treating `nothing` as placeholder for “plug in a default if available” is pretty simple and clear, except for arguments about the meaning of `nothing`. So maybe we should call that value `optional` or `default`.

This should be doable with a macro

```julia
@defaults func(; atA=default, atB=default) 
  libraryfuncA(; atA)
  libraryfuncB(; atB)
...
end

```

rewritten to use the namedtuple trick on all call-sites inside `func`, right?  
Possibly we can even leave out the `=default` part?

Guess its time to pull up the metasleeves!

Whereas I love where Julia went with kwargs expansion so far, I would still love if the language supported this behavior itself 🙂  
Missing the experience I am also wondering if this is something that would be handled elegantly through pattern-matching for function arguments (without really knowing what I mean here, happy for read-up suggestions :))

Edit: Alternatively we could have a macro for filtering kwargs for `atA, atB` on the call site only. That might be simpler and more robust..

---

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [June 13, 2025, 1:35pm UTC](https://discourse.julialang.org/t/nothing-absence-of-keyword-argument/108119/16 "2025-06-13T13:35:30Z")

</div>

Thank you for your thoughts. Here is a meta-discussion (or rambling) from me . . .

I found that the root cause of this kind of problem in Julia is that almost everything is “convention”, “library” or package. The pure, true core of Julia is very small. Even `nothing` is used as and by “convention”. Therefore, what to do with `kwarg = nothing` is up to the library writer.

It is in contrast with Fortran. There, the notion that “no argument is given” is defined by the language standard. If you don’t give an optional argument to a function, the fact that it’s not given propagates down, just as your `default` does. In your function in Fortran, you can examine whether the argument is given or not using a standard query function. If you fail to examine it and use it when it’s not given, the runtime catches the error.

Your macro solution would be excellent, _ **if everybody and every package used it** _.

I guess that the only practical solution is to decide on a convention, write it down, post it as part of the official documentation, and strongly encourage everybody to follow it.

In the present case, the convention I would like to see is that: “If `kwarg = default`, the function should behave as if `kwarg` is not given.”
