# \`foo = () -\> 3\` vs. \`foo() = 3\`

**URL:** <https://discourse.julialang.org/t/foo-3-vs-foo-3/59710>\
**Category:** New to Julia\
**Tags:** functions\
**Created:** [April 21, 2021, 4:34am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710 "2021-04-21T04:34:33Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [April 21, 2021, 4:34am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/1 "2021-04-21T04:34:33Z")

</div>

I saw the following line in one of the [Flux.jl examples](https://github.com/FluxML/model-zoo/blob/master/text/char-rnn/char-rnn.jl)

```julia
evalcb = () -> @show loss(tx, ty)

```

In my mind, this is identical to

```julia
evalcb() = @show loss(tx, ty)

```

which I find more legible.

An even more minimal example:

```julia
julia> foo = () -> 3
#1 (generic function with 1 method)

julia> bar() = 3
bar (generic function with 1 method)

julia> foo()
3

julia> bar()
3

help?> foo
search: foo floor pointer_from_objref OverflowError RoundFromZero unsafe_copyto! functionloc StackOverflowError

  No documentation found.

  foo is a Function.

  # 1 method for anonymous function "#1":
  [1] (::var"#1#2")() in Main at REPL[1]:1

help?> bar
search: bar baremodule SubArray GlobalRef clipboard BitArray backtrace BitMatrix catch_backtrace AbstractRange

  No documentation found.

  bar is a Function.

  # 1 method for generic function "bar":
  [1] bar() in Main at REPL[2]:1

```

The only difference is that `(::var"#1#2")` appears in the help description where I would expect to see `foo`.

**What is the purpose of a construction like `evalcb = () -> @show loss(tx, ty)`?**

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [April 21, 2021, 5:39am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/2 "2021-04-21T05:39:49Z")

</div>

They are different objects with different behaviour in regards to optimization, scope rules and so on.

Compare these two definitions

```julia
function f1(x)
    if x == 1
        g() = 3
    else
        g() = 4
    end

    return g
end

function f2(x)
    if x == 1
        g = () -> 3
    else
        g = () -> 4
    end

    return g
end

julia> f1(1)()
4

julia> f2(1)()
3

```

In the first function `g` is defined only once (probably you may say it is “global” to the scope of the function). But in the second function these are two different and independent objects.

It probably does not explain why in this particular example of the Flux.jl the second form was chosen, but probably due to the nature of the operations that happen in Flux.jl it is safer to use it always, so you wouldn’t run into some unexpected corner cases.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [April 21, 2021, 5:43am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/3 "2021-04-21T05:43:21Z")

</div>

I can only think of one difference that isn’t a clear advantage to the non-anonymous version:

```julia
foo = () -> bar()
foo = 3 # legal

foo() = bar()
foo = 3 # illegal

```

Hardly anything I would consider that beneficial though.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [April 21, 2021, 7:05am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/4 "2021-04-21T07:05:30Z")

</div>

> [@Skoffer](#):
>
> In the first function `g` is defined only once (probably you may say it is “global” to the scope of the function).

Could you explain a bit more about this?  
I wonder, why it is the second `g()=4` which is the only once definition?

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [April 21, 2021, 7:20am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/5 "2021-04-21T07:20:43Z")

</div>

Well, it turns out that this is more of a bug than feature.

Discourse discussion: [Confused by behaviour of nested functions](https://discourse.julialang.org/t/confused-by-behaviour-of-nested-functions/20576)

And related github issue: [disallow methods of local functions in different blocks · Issue #15602 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/15602)

I think in an issue it is explained better than I can do.

---

<div class="post-metadata">

**Author:** ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)\
**Post date:** [April 21, 2021, 7:25am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/6 "2021-04-21T07:25:00Z")

</div>

I think it’s because Julia evaluates `g() = 3` and then overrides it by evaluating `g() = 4` (even if the condition is not hit). So regardless of the value of `x`, `f1(x)()` will call `g()`, which will always return `4`.

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [April 21, 2021, 7:27am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/7 "2021-04-21T07:27:05Z")

</div>

Glad I’m not the only one baffled by the behavior of your `f1`. I have gotten away with the assumption that if an `if` condition is met, then the material inside of an `else` condition will never have any effect.

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [April 21, 2021, 7:58am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/8 "2021-04-21T07:58:30Z")

</div>

Just for completeness, another small difference is how they’re serialized. For the anonymous version, the function definition is actually serialized, where as the non-anonymous one just the name is serialized. The niche place where this might come up is when using Distributed’s auto-global shipping, so e.g. this works,

```julia
foo = () -> 3
@fetch foo() # foo definition shipped to worker, run there, answer returned

```

whereas the non-anonymous version you need to have `foo` actually defined on all workers (since only its name is serialized), which ammounts to an `@everywhere`

```julia
foo() = 3
@fetch foo() # error

@everywhere foo() = 3
@fetch foo() # works

```

---

<div class="post-metadata">

**Author:** ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)\
**Post date:** [April 21, 2021, 8:51am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/9 "2021-04-21T08:51:21Z")

</div>

> [@maxkapur](#):
>
> `evalcb = () -> @show loss(tx, ty)`

I think one should not do that without reason. It declares a [global variable](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-global-variables) and there will be an overhead in calling it in respect to a declared function.

If one uses [anonymous functions as intended](https://docs.julialang.org/en/v1.6/manual/functions/#man-anonymous-functions):

> The primary use for anonymous functions is passing them to functions which take other functions as arguments.

… there is no such overhead.

Maybe in an example this is not so important. It doesn’t seem to me that [the context](https://fluxml.ai/Flux.jl/stable/utilities/#Flux.throttle) demands it.

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [April 21, 2021, 8:55am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/10 "2021-04-21T08:55:50Z")

</div>

That definition of `evalcb` is itself wrapped inside a function. Is it still correct to say it declares a global variable in this case?

---

<div class="post-metadata">

**Author:** ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)\
**Post date:** [April 21, 2021, 9:02am UTC](https://discourse.julialang.org/t/foo-3-vs-foo-3/59710/11 "2021-04-21T09:02:34Z")

</div>

you are right. Inside a function it is not a global variable and it doesn’t make a difference. I was confused.
