# What is a good way to write methods that help the user not mix up input order?

**URL:** <https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803>\
**Category:** General Usage\
**Tags:** question, argument, dispatch, keywords\
**Created:** [February 17, 2023, 6:29pm UTC](https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803 "2023-02-17T18:29:05Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![philip](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/philip/32/17191_2.png) [@philip](https://discourse.julialang.org/u/philip)\
**Post date:** [February 17, 2023, 6:29pm UTC](https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803/1 "2023-02-17T18:29:05Z")

</div>

I’ve often encountered issues similar to [Keyword argument types - what's going on? - #11 by sijo](https://discourse.julialang.org/t/keyword-argument-types-whats-going-on/75778/11) . I like to write methods with keyword arguments because I find them harder to silently screw up calling than positional arguments. Making up an example, let’s consider a function which gives utility from mean and variance of returns U = E[r] - \frac{1}{2} A \sigma^2:

```
function utility(expected_return, sd_of_returns, risk_aversion)
    expected_return - 1/2 * risk_aversion * sd_of_returns^2
end

```

Suppose a stock has E[r\_s] = 10\% and \sigma\_s = 20\% and an individual’s risk aversion A = 2, then this could be called:

```
julia> utility(0.1, 0.2, 2.0)
0.06

```

Since these are all `Float64`, nothing stops someone from making a mistake such as the following:

```
julia> utility(0.2, 0.1, 2.0)
0.19

```

Of course, the potential mistakes increase in the number of arguments, the complexity of their meaning, etc.

Now. If the function is rewritten to use keyword arguments, there is visually no ambiguity:

```
julia> function utility(;expected_return, sd_of_returns, risk_aversion)
                         expected_return - 1/2 * risk_aversion * sd_of_returns^2
                         end
utility (generic function with 1 method)

julia> utility(0.1, 0.2, 2.0)
ERROR: MethodError: no method matching utility(::Float64, ::Float64, ::Float64)
Stacktrace:
 [1] top-level scope
   @ REPL[2]:1

julia> utility(risk_aversion=2.0, sd_of_returns = 0.2, expected_return = 0.1)
0.06

```

Lovely. But, keyword-argumenting everything seems to be discouraged by the design of the method dispatch system. Furthermore, unlike in this MWE, often I want to write multiple methods that do dispatch differently on types of arguments. But I’d still like to reduce argument order ambiguity.

There are clearly some possible solutions, including:

1. [GitHub - simonbyrne/KeywordDispatch.jl: Dispatch on keyword arguments](https://github.com/simonbyrne/KeywordDispatch.jl) as mentioned in the previously linked post here—but this is currently failing CI and again does not seem to be an encouraged approach
2. Create a bunch of custom types e.g. `struct ExpectedReturn` and then use typing `function utility(expected_return::ExpectedReturn,...); utility(ExpectedReturn(0.1)...)` —but this is overbearing!
3. Similar approach with typing the input itself in a new type (perhaps à la [Parameters.jl](https://github.com/mauro3/Parameters.jl), `@with_kw struct UtilityInput ... end; utility(UtilityInput(expected_return = 0.1, ...))`…but once again this is quite overbearing.

Is strikes me as strange that simply essentially offering the user a “tip” of being able to tell the function/method “here’s the name of the argument I’m trying to pass this value to” needs to break dispatch. What’s so special about argument order? Couldn’t an equivalent ordered-argument method always be present “under-the-hood” for any given named-argument function? (I assume, without being able to understand its source code, that this is what [KeywordDispatch.jl](https://github.com/simonbyrne/KeywordDispatch.jl) tries to achieve.)

TL;DR, is there not a way that combines the elegance, simplicity, and error-preventiveness of keyword arguments with the elegance, power, and stability of positional argument method dispatch?

---

<div class="post-metadata">

**Author:** ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)\
**Post date:** [February 17, 2023, 6:48pm UTC](https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803/2 "2023-02-17T18:48:53Z")

</div>

One thing I do sometimes is to define a function as

```julia
f(a1, a2, a3) = ....
f(; a1, a2, a3) = f(a1, a2, a3)

```

This is generally quite simple to do (just one more line of code) and still allows multiple dispatch by adding methods to `f` based on the type of the arguments.

```julia
julia> utility(expected_return, sd_of_returns, risk_aversion) = expected_return - 1/2 * risk_aversion * sd_of_returns^2
julia> utility(; expected_return, sd_of_returns, risk_aversion) = utility(expected_return, sd_of_returns, risk_aversion)
julia> utility(0.1, 0.2, 2.0)
0.06
julia> utility(risk_aversion = 2.0, sd_of_returns = 0.2, expected_return = 0.1)
0.06
julia> utility(expected_return::Int, sd_of_returns, risk_aversion) = println("No integers, please!")
julia> utility(expected_return = 1, sd_of_returns = 0.2, risk_aversion = 2.0)
No integers, please!

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [February 17, 2023, 6:54pm UTC](https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803/3 "2023-02-17T18:54:52Z")

</div>

Sometimes defining say `f((a,b)::Pair, c) = (; a,b,c)` and thus accepting `f(0.1 => 0.2, 0.3)` helps.

In this case, maybe `utility(0.1 ± 0.2, 0.3)` makes more sense than `=>`. There’s no pre-defined ±, but you could borrow it from Measurements.jl, or you could define your own `struct PlusMinus`.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 17, 2023, 8:07pm UTC](https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803/4 "2023-02-17T20:07:10Z")

</div>

One option is to require a named tuple as the input of the function at the interface. Then you can do whatever you want with the types internally:

```julia
julia> _utility(a::Float64,b::Int) = 1
_utility (generic function with 1 method)

julia> _utility(a::Float64,b::Float64) = 2
_utility (generic function with 2 methods)

julia> utility(input) = _utility(input.a,input.b) # interface function
utility (generic function with 1 method)

julia> input = (a=1.0, b=2.0)
(a = 1.0, b = 2.0)

julia> utility(input)
2

julia> input = (a=1.0, b=2)
(a = 1.0, b = 2)

julia> utility(input)
1

```

The function at the interface can then also check for the types, provide sensible error messages, etc. I usually do this, but instead of a named tuple I use a custom type, `InputData`, or whatever.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [February 18, 2023, 4:22am UTC](https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803/5 "2023-02-18T04:22:31Z")

</div>

> [@philip](#):
>
> a bunch of custom types e.g. `struct ExpectedReturn`

Not unreasonable… add some docstrings and you’re off to the races.

```julia
"`Stonk(expected_return, standard_deviation)`\n\nA fractional digital asset, kinda like an NFT"
struct Stonk{R, S}
    r :: R
    σ :: S
end

"`Investoor(risk_aversion)`\n\nPerson who full-port YOLOs stimmy checks into 0DTE 0.05Δ call options"
struct Investoor{A} 
    a :: A
end

"`utility(stonk, investoor)`\n\nCalculate expected utility for some contrived notion of rationality"
utility(stonk::Stonk, investoor::Investoor) = let (; r, σ) = stonk, (; a) = investoor
    r - (1/2)a*σ^2 
end

```

This allows you to express the utility of _this asset_ to _that person_, which is a bit more meaningful than a bunch of numbers in arbitrary order.

```julia
julia> let TSLA=Stonk(0.1, 0.2), uncle_joe = Investoor(2.0)
           @show u=utility(TSLA, uncle_joe)
           if u > 0; println("TELL UNCLE JOE TO BUY ON 100x MARGIN!! 💎🙌") end
       end
u = utility(TSLA, uncle_joe) = 0.06
TELL UNCLE JOE TO BUY ON 100x MARGIN!! 💎🙌

```

---

<div class="post-metadata">

**Author:** ![philip](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/philip/32/17191_2.png) [@philip](https://discourse.julialang.org/u/philip)\
**Post date:** [February 23, 2023, 2:43am UTC](https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803/6 "2023-02-23T02:43:15Z")

</div>

> [@mbaz](#):
>
> One thing I do sometimes is to define a function as
> 
> ```julia
> f(a1, a2, a3) = ....
> f(; a1, a2, a3) = f(a1, a2, a3)
> 
> ```
> 
> This is generally quite simple to do (just one more line of code) and still allows multiple dispatch by adding methods to `f` based on the type of the arguments.

Very interesting; thanks! I think this is the cleanest and most flexible of the proposals. I will tinker a bit and come back to mark this as the solution after I stress-test the proposal in some harder cases.

> [@lmiq](#):
>
> The function at the interface can then also check for the types, provide sensible error messages, etc. I usually do this, but instead of a named tuple I use a custom type, `InputData`, or whatever.

Also interesting. I think the `InputData` idea is essentially what I wrote as option #3 (`InputData` = `UtilityInput`) but the alternate of using a NamedTuple so one doesn’t have to create a struct is worth considering. My hunch, though, is that it would end up being an unhappy middle–not as rigorous as spelling out what the type `InputData` should be nor as lightweight as just taking unstructured arguments. Thanks for the suggestion!

> [@uniment](#):
>
> This allows you to express the utility of _this asset_ to _that person_, which is a bit more meaningful than a bunch of numbers in arbitrary order.

(Lol.)

But do you think this is an anti-pattern if applied too often? In the case you mentioned, it seems to make sense. But for broader purposes, it seems like it would create “type clutter” to essentially have to have a type that wraps every or vector of primitives before a module’s methods can operate on it. I wasn’t specific enough when I wrote the question, but I think the use case you indicate _is_ better served by having types, but in a sense when those types are already germane to the problem / module. When a method is “naturally” about primitives (numbers), I think @mbaz’s solution feels more natural. But all of this is great food for thought; thanks all.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [February 23, 2023, 3:57am UTC](https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803/8 "2023-02-23T03:57:25Z")

</div>

> [@philip](#):
>
> But do you think this is an anti-pattern if applied too often?

“All things are poison, and nothing is without poison; the dosage alone makes it so a thing is not a poison.” – Paracelsus

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [February 23, 2023, 4:04am UTC](https://discourse.julialang.org/t/what-is-a-good-way-to-write-methods-that-help-the-user-not-mix-up-input-order/94803/9 "2023-02-23T04:04:47Z")

</div>

Another way to check arguments are lined up is to use types or [dimensional analysis](https://painterqubits.github.io/Unitful.jl/stable/). I’m not sure what the dimensions of your example are but you might have a better idea.
