# Make function arguments positional or keyword

**URL:** <https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984>\
**Category:** General Usage\
**Tags:** functions, keyword-arguments\
**Created:** [March 31, 2017, 1:45pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984 "2017-03-31T13:45:04Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [March 31, 2017, 1:45pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/1 "2017-03-31T13:45:04Z")

</div>

How do I create a function that can take either positional or keyword arguments? Right now, I have a function that takes keyword arguments. But, I would to revise it to take either positional or keyword arguments. Thanks.

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [March 31, 2017, 1:52pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/2 "2017-03-31T13:52:13Z")

</div>

You can overload this function, e.g.:

```julia
julia> foo(x) = println(x)
foo (generic function with 2 methods)

julia> foo(;x=1) = foo(x)
foo (generic function with 2 methods)

julia> foo(42)
42

julia> foo(x=42)
42

```

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [March 31, 2017, 1:59pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/3 "2017-03-31T13:59:06Z")

</div>

Is it possible to do that without passing default values in optional arguments? The function I have is for a stats model and I do not want to pass default values.

@ChrisRackauckas

---

<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:** [March 31, 2017, 2:45pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/4 "2017-03-31T14:45:22Z")

</div>

> [@sbohor3](#):
>
> Is it possible to do that without passing default values in optional arguments? The function I have is for a stats model and I do not want to pass default values.

Julia does dispatching on default values. So what you can do is:

```julia
function f(x,y=nothing;z=:SomeOption)
  if y == nothing
    return 5
  else # y is some number
    if z == :SomeOption
      return x+2y
    else
      return x+3y
    end
  end
end

```

Via dispatch, it will compile a different function when `y` is a number, so you don’t need to worry about the internal checks. To see this, notice that when `y` is not given, all of the other logic compiles away:

```julia
julia> @code_llvm f(2)

; Function Attrs: uwtable
define i64 @julia_f_68264(i64) #0 !dbg !5 {
top:
  ret i64 5
}

```

and thisis just a function which returns 5. In the other case:

```julia
julia> @code_llvm f(2,3)

; Function Attrs: uwtable
define i64 @julia_f_68300(i64, i64) #0 !dbg !5 {
top:
  %2 = call i8 **** @jl_get_ptls_states() #4
  %3 = alloca [7 x i8**], align 8
  %.sub = getelementptr inbounds [7 x i8**], [7 x i8**]* %3, i64 0, i64 0
  %4 = getelementptr [7 x i8**], [7 x i8**]* %3, i64 0, i64 2
  %5 = bitcast i8*** %4 to i8*
  call void @llvm.memset.p0i8.i32(i8* %5, i8 0, i32 40, i32 8, i1 false)
  %6 = bitcast [7 x i8**]* %3 to i64*
  store i64 10, i64* %6, align 8
  %7 = getelementptr [7 x i8**], [7 x i8**]* %3, i64 0, i64 1
  %8 = bitcast i8 **** %2 to i64*
  %9 = load i64, i64* %8, align 8
  %10 = bitcast i8*** %7 to i64*
  store i64 %9, i64* %10, align 8
  store i8 ***%.sub, i8**** %2, align 8
  %11 = getelementptr [7 x i8**], [7 x i8**]* %3, i64 0, i64 6
  %12 = getelementptr [7 x i8**], [7 x i8**]* %3, i64 0, i64 5
  %13 = getelementptr [7 x i8**], [7 x i8**]* %3, i64 0, i64 4
  %14 = getelementptr [7 x i8**], [7 x i8**]* %3, i64 0, i64 3
  store i8**inttoptr (i64 2147434592 to i8**), i8*** %4, align 8
  store i8**inttoptr (i64 71900760 to i8**), i8*** %14, align 8
  store i8**inttoptr (i64 2147434584 to i8**), i8*** %13, align 8
  %15 = call i8** @jl_box_int64(i64 signext %0)
  store i8 **%15, i8*** %12, align 8
  %16 = call i8** @jl_box_int64(i64 signext %1)
  store i8 **%16, i8*** %11, align 8
  %17 = call i8**@jl_invoke(i8** inttoptr (i64 2271350544 to i8**), i8*** %4, i32 5)
  %18 = bitcast i8** %17 to i64*
  %19 = load i64, i64* %18, align 16
  %20 = load i64, i64* %10, align 8
  store i64 %20, i64* %8, align 8
  ret i64 %19
}

```

it compiles to a function which has to do a check on symbols and branch etc.

A better way, sometimes, is to use dispatch:

```julia
f(x;z=:SomeOption) = 5
function f(x,y;z=:SomeOption)
   if z == :SomeOption
     return x+2y
   else
     return x+3y
   end
end

```

this is equivalent to the code above but may organize your code better in some cases. You can think of this as the “no default values” case.

A very common way to use this is, if you have a lot of code that you want to share, have an internal function named `_f` that does the big calculations. Then you have your different dispatches do setup and call `_f`. This organizes by dispatch but still re-uses most of the internal code.

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [March 31, 2017, 2:58pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/5 "2017-03-31T14:58:28Z")

</div>

@ChrisRackauckas: Thanks. I thought it would be helpful to share part of the function I wrote which shows the parameter types as well. With using someOption works, but I can still declare the parameter types right?  
For e.g.  
`function squared(;x=:SomeOption::Int)`

Here is what my fuction looks like

```julia
function sAUC(; x::DataFrames.Formula = nothing, treatment_group::Symbol = nothing, data::DataFrames.DataFrame = nothing)
...

```

I would like to revise this function so it can take either all positional or keyword arguments. Thanks.

---

<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:** [March 31, 2017, 3:04pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/6 "2017-03-31T15:04:42Z")

</div>

> [@sbohor3](#):
>
> With using someOption works, but I can still declare the parameter types right?

`function squared(;x::Int=1)`

But note that keyword arguments do not do dispatch yet, so this is actually a type assertion instead of normal dispatch. That should change before 1.0 is out:

> <https://github.com/JuliaLang/julia/pull/16580>
>
> I tried a couple approaches for kwargs but this one I like.
> It introduces a stru…ctural named-fields counterpart to tuple types (unimaginatively called \`Struct\`). You can make a \`Struct(x = 1.0, y = 2.0)\` and it has type \`Struct{(:x,:y),Tuple{Float,Float}}\` with fields \`x\` and \`y\`.
> 
> There is a couple functions to merge or diff them and it uses that as the basis for kwargs splatting and unpacking.
> 
> This PR is not ready yet and is up here mostly to discuss the implications. The problematic one are probably over-specialization and the use of staged functions in the implementation (as always).
> 
> Assuming we want this, here are a few points I'm wondering about :
> \- Should we aim to merge those things with \`Tuple\` so that we have only one kind of structural type. We'd get dispatch-on-kwargs for "free" (== retrofit all code that touches tuple types ... hem). This is probably a long term question and keeping them separate is a decent first step in that direction anyway.
> \- Should they be covariant ? I'm guessing yes.
> \- Should they have vararg forms ? I'm guessing yes too, so you could match on "at least those fields with those types"
> \- Should they have an optional-field form ? Like \`{x::Int, y?::Int}\` that has \`{x::Int,y::Int}\` and \`{x::Int}\` as subtypes. I tink this is necessary if we want to express our current kwarg semantics using only normal dispatch and avoid generating a lot of methods.
> \- Should we always sort fields ? For now \`Struct\` types take ordering into account but the kwarg lowering/merging/diffing always keeps them sorted to avoid generating a specialization for every permutation.
> 
> Other than that, it currently seem to work when used as a replacement for our current kwarg lowering and we get specialization, inlining, inference etc.
> Going forward with this we can probably remove a bit of the \`kwfunc\` business but for now I only did minimal integration.
> 
> I feel that the \`Struct\` type is interesting in itself anyway.

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [March 31, 2017, 3:11pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/7 "2017-03-31T15:11:16Z")

</div>

> [@ChrisRackauckas](#):
>
> ```julia
> function f(x,y=nothing;z=:SomeOption)
> if y == nothing
> return 5
> else # y is some number
> if z == :SomeOption
> return x+2y
> else
> return x+3y
> end
> end
> end
> 
> ```

@ChrisRackauckas: Can we make this function to take `:SomeOption` in all parameters?  
Thanks.

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [March 31, 2017, 3:13pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/8 "2017-03-31T15:13:55Z")

</div>

> [@sbohor3](#):
>
> I would like to revise this function so it can take either all positional or keyword arguments.

What is the reason for this? This R-coding style is not idiomatic in Julia.

---

<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:** [March 31, 2017, 3:18pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/9 "2017-03-31T15:18:06Z")

</div>

> [@sbohor3](#):
>
> @ChrisRackauckas: Can we make this function to take :SomeOption in all parameters?

I don’t know what you mean. What are parameters? That’s not a Julian word for this, and we need to use specifics here since the details can be subtle.

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [March 31, 2017, 3:20pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/10 "2017-03-31T15:20:56Z")

</div>

@mkborregaard: Thanks. Do you mean that we can only do either positional or keyword arguments, but not both in Julia?

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [March 31, 2017, 3:31pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/11 "2017-03-31T15:31:16Z")

</div>

Yes, exactly (or to be exact, each argument should be either a keyword or a positional argument - you can combine both types in the same call). They are very different in Julia, as (at the moment) positional arguments are used to dispatch, keywords aren’t.

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [March 31, 2017, 3:34pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/12 "2017-03-31T15:34:15Z")

</div>

@mkborregaard @ChrisRackauckas: I am deleting this response because it is still being tested.

@mkborregaard: you are correct about the following statement. Thanks. Is there any plan to allow both keyword and a positional argument in the future? Thanks a lot.

> Yes, exactly (or to be exact, each argument should be either a keyword or a positional argument - you can combine both types in the same call).

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [March 31, 2017, 3:42pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/13 "2017-03-31T15:42:41Z")

</div>

> [@ChrisRackauckas](#):
>
> I don’t know what you mean.

I meant to say if we can use `:SomeOption` for all parameters. It looks like we can. Thanks.

```julia
function squared(;x =:SomeOption::Int64, y =:SomeOption::Int64)
  return x+y
end

```

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [March 31, 2017, 6:42pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/14 "2017-03-31T18:42:53Z")

</div>

@mkborregaard @ChrisRackauckas: Here is a workaround to the above problem. Any advice/comments? Thanks a lot.

```julia
function tryFunction(; x::Int64=nothing,y::Int64=nothing)
  if x == nothing || y == nothing
    error("Specify arguments")
  end
  tryFunction(x::Int64, y::Int64)
end

function tryFunction(x::Int64,y::Int64)
  return(x + y)
end

tryFunction(x=2,y=7)
tryFunction(2,7)
tryFunction(y=2,x=7)  

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 31, 2017, 7:02pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/15 "2017-03-31T19:02:45Z")

</div>

Since the argument defaults get evaluated at call time, you can actually have the default itself be an expression that throws an error:

```julia
julia> f(;x::Int=throw(ArgumentError("missing x"))) = x
f (generic function with 1 method)

julia> f(x=2)
2

julia> f()
ERROR: ArgumentError: missing x
 in f() at ./REPL[1]:1

```

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [March 31, 2017, 7:21pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/16 "2017-03-31T19:21:30Z")

</div>

@mbauman:  
@mkborregaard: Thanks. How do I combine this with the function so it takes positional arguments as well to fit into the `tryFunction` I wrote above?

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [April 1, 2017, 12:24am UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/17 "2017-04-01T00:24:51Z")

</div>

@mbauman: I tried to replicate the same function in Atom.But, it did not run. Any idea? Thanks.

```julia
f(; x::Int=throw(ArgumentError("missing x")))
  return(x)
end

```

I got this error message;

` syntax: keyword argument is not a symbol: "x::Int" in include_string(::String, ::String) at loading.jl:441 in include_string(::String, ::String, ::Int64) at eval.jl:28 in include_string(::Module, ::String, ::String, ::Int64, ::Vararg{Int64,N}) at eval.jl:32 in (::Atom.##53#56{String,Int64,String})() at eval.jl:40 in withpath(::Atom.##53#56{String,Int64,String}, ::Void) at utils.jl:30 in withpath(::Function, ::String) at eval.jl:46 in macro expansion at eval.jl:57 [inlined] in (::Atom.##52#55{Dict{String,Any}})() at task.jl:60`

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [April 1, 2017, 5:37am UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/18 "2017-04-01T05:37:59Z")

</div>

You’re missing the `function` (or to do like the example, where the function was defined in a short form using `= x`).

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [April 1, 2017, 5:40am UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/19 "2017-04-01T05:40:55Z")

</div>

This `tryFunction` approach works, of course. There is nothing wrong with it 🙂 I was just curious of why you wanted to achieve this design.

---

<div class="post-metadata">

**Author:** ![sbohor3](https://avatars.discourse-cdn.com/v4/letter/s/b9bd4f/32.png) [@sbohor3](https://discourse.julialang.org/u/sbohor3)\
**Post date:** [April 1, 2017, 6:51pm UTC](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984/20 "2017-04-01T18:51:06Z")

</div>

@mkborregaard: oh, my bad. So, that works without function in REPL , but in ATOM?? Thanks.

[Next page](https://discourse.julialang.org/t/make-function-arguments-positional-or-keyword/2984.md?page=2)
