# Typing optional arguments

**URL:** https://discourse.julialang.org/t/typing-optional-arguments/1010
**Category:** New to Julia
**Tags:** question
**Created:** [December 17, 2016, 6:04pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010 "2016-12-17T18:04:58Z")
**Posts on this page:** 16
**Page:** 1

<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 17, 2016, 6:04pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/1 "2016-12-17T18:04:58Z")

</div>

I’m still struggling with (hard) typing and performance; this time consider the following code  
it’s not so important what it does (while that also takes some allocations…but not the most for now)

```julia
abstract myAbsT
immutable myT <: myAbsT
  v::Float64
end

function myFun{T <: myAbsT, S<: Number}(f::Array{T}, α::Array{S,1};
       MaxIterations::Int64=500, myMask::Array{Bool} = Array(Bool,0)
    )::Array{T}
  iter::Int64 = 1
  if (length(myMask) == 0)
    myMask = falses(f)
  end
  x = f;
  while ( iter < MaxIterations )
    iter = iter+1
    for i in eachindex(x)
      if ~myMask[i]
      x[i] = T(x[i].v+α[1])
      end
    end
  end
  return x
end

preF = ones(2^9,2^9)
@time myFun(myT.(preF), [0.2])
@code_warntype myFun(myT.(preF), [0.2])
@time myFun(myT.(preF), [0.2]; MaxIterations=1000)
@code_warntype myFun(myT.(preF), [0.2]; MaxIterations = 1000)

```

There’s something really interesting in the `warntypes` (i happily learned here, they are very helpful).  
When running the first `@code_warntype` one gets  
3.809560 seconds (130.57 M allocations: 1.948 GB, 2.27% gc time)  
This is still a lot of allocations I don’t know completely where they come from but the body gets shorten tremendously in the profiles. Most interestingly for the second `@code_warntype`

8.382499 seconds (261.38 M allocations: 3.897 GB, 2.28% gc time)

The number doubles and the time gets quite bad. Looking at the variables, there’s `#temp#@_12::Any`.  
I even started from a larger example and coulnd’t get it smaller than this but still, i can’t find the reason this temporary variable of type any is used and why for this case even the body is not shortened and contains some red types for example the `Array{Bool,N}` (of course myMask is a bool for every ntry in `f` but how to fix that?). What’s the reason? I didn’t even touch the mask yet, just set the optional iterations parameter. Coulnd’t figure out what’s happening here. What am I missing here in the typing tricks of Julia?

---

<div class="post-metadata">

### Author: ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)
#### Post date: [December 17, 2016, 11:40pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/2 "2016-12-17T23:40:48Z")

</div>

If I understand your code correctly the reason is that `falses(f)` produces `BitArray` not `Array{Bool}` so the type of variable `myMask` changes in your function and this causes the allocations.

If you changed the function definition to:

```julia
function myFun{T <: myAbsT, S<: Number}(f::Array{T}, α::Array{S,1};
    MaxIterations::Int64=500, myMask::BitArray = falses(f))::Array{T}

```

then the code works fast.

However, this shows that type declaration for keyword arguments is not enforced in function body (if it was enforced your code would throw an error).

---

<div class="post-metadata">

### Author: ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)
#### Post date: [December 17, 2016, 11:46pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/3 "2016-12-17T23:46:24Z")

</div>

> [@bkamins](#):
>
> However, this shows that type declaration for keyword arguments is not enforced in function body (if it was enforced your code would throw an error).

Assuming I’ve understood what you meant (which I’m not sure I have), the declared type of a function argument is never a property of the resulting binding. Code like the following is always fine, so keyword arguments aren’t special in this regard:

```julia
function foo(x::Array{Int})
    x = [1.0]
    return x
end

```

Put another way: the type declaration in the method definition says that this method will be called when the values of the arguments (up to specificity) match the types of the declaration. But within the function’s body, there are no constraints of any sort on the type of the binding for `x` unless you add those constraints in through another mechanism.

---

<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 18, 2016, 8:04am UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/4 "2016-12-18T08:04:40Z")

</div>

Oh, interesting, i wasn’t even aware that there are two different kind of types for something I would just call `boolean`.

and @johnmyleswhite thanks for the example and yes I think that’s sadly what I’m doing and of course one should not change type of a variable.

However, interestingly, I’m still left with some internal variable of type `Any` in the second call and i am not able to find that even If I change the `myMask` to BitArray

---

<div class="post-metadata">

### Author: ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)
#### Post date: [December 18, 2016, 4:37pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/5 "2016-12-18T16:37:03Z")

</div>

I haven’t found the source of the `Any`, but one problem is that you change the types of some variables between concrete and non-concrete types.

For example, you have `myMask::Array{Bool} = Array(Bool,0)`, but you really want `myMask::Vector{Bool} = Array(Bool,0)` if you intend to latter assign `myMask = falses(f)`.

Note that I’m using `Vector{Bool}` which is an alias for `Array{Bool, 1}`, whereas your code effectively has `Array{Bool, N}`. One way to get used to Julia’s types is to make a habit of writing out all type parameters explicitly. This is probably a bad habit in the long run (since there’s no reason you need those parameters in general), but the explicitness can help you understand what you’re declaring versus what the compiler is inferring.

---

<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 18, 2016, 4:49pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/6 "2016-12-18T16:49:16Z")

</div>

That’s intended, because my data is an array, in the example 2D (`ones2^9,2^9)` and that should also be possible to use `ones(2^8,2^7,4)`). And that indeed works fine with `BitArray`, though the BitArray still is merked in Red due to its unknown dimension `N`. And I definetly want to have 1,2,3,4,…dimensional data.

---

<div class="post-metadata">

### Author: ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)
#### Post date: [December 18, 2016, 10:00pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/7 "2016-12-18T22:00:04Z")

</div>

You could also introduce array dimension N:

```julia
function myFun{T<:myAbsT, S<:Number, N}(f::Array{T,N}, α::Array{S,1};
        maxIterations::Int=1000, myMask::BitArray{N}=falses(f)
    )::Array{T,N}

```

---

<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 19, 2016, 6:18am UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/8 "2016-12-19T06:18:20Z")

</div>

Thanks Greg,  
that’s a neat way to solve the `@code_warntypes` of the `BitArrays`. So my code now looks like

```julia
function myFun{T <: myAbsT,N}(
      f::Array{T,N}, α::Array{Float64,1};
       MaxIterations::Int64=500,
       myMask::BitArray{N} = falses(f)
      )::Array{T,N}
  iter::Int64 = 1
  x::Array{T,N} = f;
  while ( iter < MaxIterations )
    iter = iter+1
    @fastmath @inbounds for i in eachindex(x)
      if ~myMask[i]
      x[i] = T(x[i].v+α[1])
      end
    end
  end
  return x
end

preF = ones(2^9,2^9)
@time myFun(myT.(preF), [0.2])
@code_warntype myFun(myT.(preF), [0.2])
@time myFun(myT.(preF), [0.2]; MaxIterations=1000)
@code_warntype myFun(myT.(preF), [0.2]; MaxIterations = 1000)

```

And calling it without the optional argument works fine (though there are still a few allocations; 46 k; and your tips where very helpful to learn using the code warnings. However I’m still stuck with one `Any` variable and one union. Let me just take some lines from `@code_warning`

```julia
Variables:
  #unused#::#kw##myFun
  #temp#@_2::Array{Any,1}
  ::#myFun
  f::Array{myT,2}
[...]
  #temp#@_11::Int64
  #temp#@_12::Any

Body:
  begin
[...]
      unless (#temp#@_12::Any === :myMask)::Bool goto 20
[...]
      unless (#temp#@_12::Any === :MaxIterations)::Bool goto 24
[....]
      SSAValue(12) = f::Array{myT,2}
      SSAValue(13) = α::Array{Float64,1}
      (Base.throw)($(Expr(:new, :(Base.MethodError), :((Core.getfield)((Core.getfield)((Core.getfield)(#myFun,:name)::TypeName,:mt),:kwsorter)), :((Core.tuple)(#temp#@_2,SSAValue(11),SSAValue(12),SSAValue(13))::Tuple{Array{Any,1},#myFun,Array{myT,2},Array{Float64,1}}))))::Union{}

```

So somehow this dangling 12th temporary variable is for typechecks of the two optional arguments, am I reading the first two lines I left in the body correctly?  
And: Does anybody know there the `::Union` comes from? I think (by the two lines before) that might be the `x[i] = ...` causing that; but why?

Thanks again for all the help, Julia seems somehow a little tricky but fun to find out how it works 🙂

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [December 19, 2016, 12:41pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/9 "2016-12-19T12:41:36Z")

</div>

I think you may be hitting issues of keyword functions: keyword-arguments defy inference (there are open issues about it). Consider:

```julia
julia> f(x; y::Int=1) = x+y # the ::Int helps some but not all the way
f (generic function with 1 method)

julia> @code_warntype f(5) # it's fine if no key-words are specified
Variables:
  #self#::#f
  x::Int64

Body:
  begin
      return (Base.box)(Int64,(Base.add_int)(x::Int64,1))
  end::Int64

julia> @code_warntype f(5,y=1)
Variables:
  #unused#::#kw##f
  #temp#@_2::Array{Any,1}
  ::#f
  x::Int64
  y::Int64
  #temp#@_6::Int64
  #temp#@_7::Int64
  #temp#@_8::Int64
  #temp#@_9::Any
...

```

Also benchmarking those two function calls, `f(5)` takes 1ns whereas `f(5,y=1)` takes 40ns.

So, moral of it: don’t use keywords in functions which are called in performance critical code.

---

<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 19, 2016, 12:55pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/10 "2016-12-19T12:55:46Z")

</div>

Very interesting! And I thought it was my fault, because I also narrowed my larger example down to the only thing being different are the optional parameters!  
Your short example has the same last \_any parameter as mine.

Is there any other way to make them optional? I’d like to use them really as optional ones…even in performance critical code. Of course i could do a wrapper around that, hm.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [December 19, 2016, 1:01pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/11 "2016-12-19T13:01:37Z")

</div>

You can make a convenience keyword-wrapper. Also you can use default positional arguments, those are fine.

---

<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 19, 2016, 5:07pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/12 "2016-12-19T17:07:32Z")

</div>

Thanks, but i fear i didn’t get the wrapper idea right, doing just `; kwargs...)` and making an dictionary out of that, i.e.

```julia
      kwargs_dict = Dict(kwargs);
      MaxIterations::Int64=get(kwargs_dict, "MaxIterations", 500)

```

doesn’t seem to do the trick; it’s still slow it still has the 12th temp `::Any` variable. And i don’t want to go into optional positional arguments, because already in this small example i fond’t want to fix the order in which eventually leave them open, so I would like to get to something dictionary like. Without that, some  
of my more complicated algorithms would just be unusable.

That said: How can I then use something like keywords in such functions as my example while not loosing performance?

---

<div class="post-metadata">

### Author: ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)
#### Post date: [December 19, 2016, 5:42pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/13 "2016-12-19T17:42:42Z")

</div>

> That said: How can I then use something like keywords in such functions as my example while not loosing performance?

Honestly, the real answer is that you don’t. The performance issues with keyword arguments will get fixed one day, but it’s not fixed yet and long-term Julia developers have learned to tolerate this as a weakness of the current implementation of the language.

In this specific example, the use of a dictionary can’t fix things because it’s a total black-box to the type system. You can easily convince yourself of this fact by figuring out why the dictionary can’t possibly know the concrete type of all possible values returned by indexing into the dictionary given arbitrary keys.

One way to handle this is the following:

- Create a new immutable type that specifies the names and types of the arguments you want to make into keyword arguments.
- Create a wrapper function that takes in keyword arguments and places those keyword arguments into the immutable type you created before.
- Pass the immutable type wrapping your keywords to a fast inner function that has clear and enforced types for all arguments.

Of course, you can also avoid the wrapper entirely and just do things by passing the keyword arguments to an inner function. The important thing is that keyword arguments sabotage the type system at present, so you have to use indirection to fix this.

---

<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 19, 2016, 6:01pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/14 "2016-12-19T18:01:34Z")

</div>

Thank you for the clarification. I think I’ll stick to a wrapper function handling all keyword arguments and calling an inner function having all parameters fixed, so for the above example a function having bot optional arguments as fixed ones, and a wrapper passing onto that function.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [December 19, 2016, 7:25pm UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/15 "2016-12-19T19:25:46Z")

</div>

This seems like a fine occasion to advertise my [Parameters.jl](https://github.com/mauro3/Parameters.jl) package. It gives you some handy tools for some of the options John described:

```julia

using Parameters

function f(x,y;
           a=1, b=2, c=3)
    x+y+a+b+c
end

# using Parameters.jl

@with_kw immutable MT
    a::Int=1
    b::Int=2
    c::Int=3
end

function fw(x,y,
           opts=MT()) # positional-default, constructs MT(1,2,3)
    @unpack a,b,c = opts
    x+y+a+b+c
end

fw(1,1) # =>8

# calling with non-defaults
op = MT(c=99)
fw(1,1,op) # => 104

```

---

<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 20, 2016, 7:32am UTC](https://discourse.julialang.org/t/typing-optional-arguments/1010/16 "2016-12-20T07:32:27Z")

</div>

Thanks mauro for the idea; it looks neat; though I personally like the optional parameters with `;`better, but that’s just a personal taste; I wrote a wrapper for that, and this part now seems to work fine.

Interestingly combining this solution here with one from my previous questions yields a further point I can’t get my mind to (still learning all this stuff though). When indexing an neighbor index, as I learned [here](https://discourse.julialang.org/t/struggling-with-indexing-a-neighbor-index-in-an-array/825), i adapted

```julia
abstract myAbsT
immutable myT <: myAbsT
  v::Float64
end

function myFun{T <: myAbsT,N}(
      f::Array{T,N}, α::Array{Float64,1},MaxIterations,myMask::BitArray{N}=falses(f))::Array{T,N}
  iter::Int64 = 1
  x::Array{T,N} = f
  R = CartesianRange(size(f))
  while ( iter < MaxIterations )
    iter = iter+1
    for d = 1:ndims(f)
      unitOffset::CartesianIndex{N} = CartesianIndex{N}(ntuple(i::Integer->i::Integer==d ? 1: 0, N))
      for i in R
        i2 = i+unitOffset
        if (i2 in R) && (~myMask[i])
          x[i] = T(x[i2].v+x[i].v)
        end
      end
    end
  end
  return x
end

preF = ones(2^9,2^9)
@time myFun(myT.(preF), [0.2],200)
@code_warntype myFun(myT.(preF), [0.2],200)
@time myFun(myT.(preF), [0.2],200,falses(preF))
@code_warntype myFun(myT.(preF), [0.2],200,falses(preF))

```

While the first call/warntype works completely fine (maybe because the mask even gets eliminated in optimization), for the second call (well it’s the same values) the `d` iterate gets `Core.Box` as a type. Still for this example (not for my larger run on the productive code) both are qually fast and the second oneeven uses only 1.6k allocations while the first requires 39k. Can anyone explain why?

I know I’m asking a lot of questions, for now I’m still trying to understand such details of Julia (coming from Matlab, Mathematica, and such).
