# Conditional functions within functions

**URL:** <https://discourse.julialang.org/t/conditional-functions-within-functions/5228>\
**Category:** General Usage\
**Created:** [August 4, 2017, 6:34pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228 "2017-08-04T18:34:23Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 4, 2017, 6:34pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/1 "2017-08-04T18:34:23Z")

</div>

consider the following code:

```julia
function foo(x::Int; d=:out)
    myfn = (d == :out) ? fn1 : fn2
    z = 0
    for i = 1:x 
        z += myfn(i)
    end
end

```

I understand the inefficiency that results from the compiler not being able to tell that `myfn` won’t change within the loop. Is there a way to do this efficiently that preserves the simplicity of the function? I tried wrapping the loop inside a `let myfn = (d == :out) ? fn1 : fn2` block but that didn’t show any benchmarking improvements.

---

<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:** [August 4, 2017, 6:37pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/2 "2017-08-04T18:37:11Z")

</div>

Try using a barrier function?

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 4, 2017, 6:38pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/3 "2017-08-04T18:38:05Z")

</div>

@mauro3 - yeah, @ChrisRackauckas suggested that as well but it violates the “preserves the simplicity” goal.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 4, 2017, 6:39pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/4 "2017-08-04T18:39:56Z")

</div>

[https://github.com/JuliaLang/julia/issues/21925](https://github.com/JuliaLang/julia/issues/21925)

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [August 4, 2017, 6:43pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/5 "2017-08-04T18:43:55Z")

</div>

I believe the usual solution is to use functions as values:

```julia
function foo(x::Int, myfn=fn1)
    z = 0
    for i = 1:x 
        z += myfn(i)
    end
    return z
end

```

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 4, 2017, 6:44pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/6 "2017-08-04T18:44:40Z")

</div>

does this work if `myfn` is a keyword argument?

---

<div class="post-metadata">

**Author:** ![adamslc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamslc/32/3452_2.png) [@adamslc](https://discourse.julialang.org/u/adamslc)\
**Post date:** [August 4, 2017, 7:09pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/7 "2017-08-04T19:09:07Z")

</div>

I would assume not because the keyword argument would not be specialized on. You could write two copies of the function: one with positional arguments, and the other with keyword arguments.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 4, 2017, 7:10pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/8 "2017-08-04T19:10:45Z")

</div>

I think I’m going to go with this:

```julia
foo(x::Int; d=:out) = (d == :out) ? _foo(x, fn1) : _foo(x, fn2)
function _foo(x::Int, myfn::Function)
  ...
end

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 4, 2017, 7:29pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/9 "2017-08-04T19:29:36Z")

</div>

> [@adamslc](#):
>
> keyword argument would not be specialized on

Who said that?

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 4, 2017, 7:30pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/10 "2017-08-04T19:30:48Z")

</div>

I think it’s true (that kwargs aren’t specialized on):

```julia
julia> foo(x::Int; d::Float64=2.0) = 1
foo (generic function with 1 method)

julia> foo(x::Int; d::Int=2) = 2
foo (generic function with 1 method)

julia> foo(2)
2

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 4, 2017, 7:31pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/11 "2017-08-04T19:31:33Z")

</div>

> [@anon94023334](#):
>
> I think it’s true:

What’s true? You are just showing that you cannot dispatch on keyword argument. It has nothing to do with specialization.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 4, 2017, 7:32pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/12 "2017-08-04T19:32:21Z")

</div>

> [@yuyichao](#):
>
> It has nothing to do with specialization.

Then I guess I’m confused as to what specialization is (as opposed to dispatch). Never mind.

---

<div class="post-metadata">

**Author:** ![adamslc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamslc/32/3452_2.png) [@adamslc](https://discourse.julialang.org/u/adamslc)\
**Post date:** [August 4, 2017, 7:32pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/13 "2017-08-04T19:32:26Z")

</div>

You’re right; I was a little sloppy with my language. The types of keyword arguments are not specialized on, which is what is important for this question.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 4, 2017, 7:33pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/14 "2017-08-04T19:33:29Z")

</div>

> [@adamslc](#):
>
> You’re right; I was a little sloppy with my language. The types of keyword arguments are not specialized on

Then language you use does mean that but it’s not the case (i.e. what you are claiming is wrong). If you read it somewhere in the doc then the doc must be corrected.

---

<div class="post-metadata">

**Author:** ![adamslc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamslc/32/3452_2.png) [@adamslc](https://discourse.julialang.org/u/adamslc)\
**Post date:** [August 4, 2017, 7:34pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/15 "2017-08-04T19:34:16Z")

</div>

> [@anon94023334](#):
>
> Then I guess I’m confused as to what specialization is (as opposed to dispatch). Never mind.

I think that I am confused too. @yuyichao, would you mind defining those two terms for me?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 4, 2017, 7:35pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/16 "2017-08-04T19:35:07Z")

</div>

Dispatch means picking a method, specialize means optimizing/compiling a method/function for a given (set of) input type(s).

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 4, 2017, 7:36pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/17 "2017-08-04T19:36:53Z")

</div>

In fact, the document explicitly mentioned that [the keyword arguments are being specialized on](https://docs.julialang.org/en/latest/manual/performance-tips/#Declare-types-of-keyword-arguments-1):

> Functions are specialized on the types of keyword arguments

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 4, 2017, 7:39pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/18 "2017-08-04T19:39:09Z")

</div>

> [@yuyichao](#):
>
> Dispatch means picking a method, specialize means optimizing/compiling a method/function for a given (set of) input type(s).

But only one method/function is compiled in my example above (see the “generic function with 1 method” output after the second line), even though the kwarg has a different type. This implies that the type of the kwarg is ignored when determining the set of input types, right?

```julia
julia> foo(2; d=3.3)
ERROR: TypeError: #foo: in typeassert, expected Int64, got Float64

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 4, 2017, 7:41pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/19 "2017-08-04T19:41:33Z")

</div>

> [@anon94023334](#):
>
> But only one method/function is compiled in my example above

No, only one method is added to the function, which is unrelated to the number of specilizations. FWIW, your `_foo` also has only one method.

> [@anon94023334](#):
>
> This implies that the type of the kwarg is ignored when determining the set of input types, right?

No, it implies that the keyword are being ignored for dispatch (i.e. picking method), which, again, has nothing to do with specialization.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [August 4, 2017, 7:42pm UTC](https://discourse.julialang.org/t/conditional-functions-within-functions/5228/20 "2017-08-04T19:42:38Z")

</div>

We’re way off topic here, I think, and I’m utterly confused, so I’ll bow out at this point. Thanks.

[Next page](https://discourse.julialang.org/t/conditional-functions-within-functions/5228.md?page=2)
