# What is the difference between a variable that contains a function an a function?

**URL:** https://discourse.julialang.org/t/what-is-the-difference-between-a-variable-that-contains-a-function-an-a-function/111652
**Category:** New to Julia
**Tags:** functions
**Created:** [March 15, 2024, 9:19am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-a-variable-that-contains-a-function-an-a-function/111652 "2024-03-15T09:19:49Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![AwesomeQuest](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/awesomequest/32/38910_2.png) [@AwesomeQuest](https://discourse.julialang.org/u/AwesomeQuest)
#### Post date: [March 15, 2024, 9:19am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-a-variable-that-contains-a-function-an-a-function/111652/1 "2024-03-15T09:19:49Z")

</div>

Why is there a difference between

```julia
f = x->5

```

and

```julia
f(x) = 5

```

Why does the compiler treat these differently?  
Since if you run both of the above you get

```julia
ERROR: cannot define function f; it already has a value

```

But they both behave the same, as in:

```julia
julia> f(1)
5

```

Maybe I’m asking why should these two be treated differently?

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [March 15, 2024, 9:30am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-a-variable-that-contains-a-function-an-a-function/111652/2 "2024-03-15T09:30:40Z")

</div>

The assignment-form syntax `f(x) = 5` and the equivalent `function ... end` syntax both implicitly declare `f` a `const` name in the definition’s global scope. This also occurs for `struct` definitions. A `const` name means that reassignment is undefined behavior or an error. Conversely, a non-`const` name cannot be made into a `const` name afterward; this threw the error you saw. Note that adding methods to an existing function or type like `f() = 0` or replacing a method `f(x) = 7`, is _not_ reassigning `f`. You’d need actual assignment syntax `f = ...` to try that.

The compiler can do some great optimizations when accessing `const` names; they’re actually necessary to let function calls and type instantiations be optimized at all. For example, if you defined `f = x->5` and `g(x) = f(x)`, `g` cannot assume `f` will be the same function and cannot be optimized much. You can get around this with some higher order functions like `g(foo::Function, x) = foo(x)`, but you probably prefer to access global names rather than pass every function and type through the arguments like `g(f, x)`.

---

<div class="post-metadata">

### Author: ![Alseidon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alseidon/32/207775_2.png) [@Alseidon](https://discourse.julialang.org/u/Alseidon)
#### Post date: [March 15, 2024, 9:37am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-a-variable-that-contains-a-function-an-a-function/111652/3 "2024-03-15T09:37:21Z")

</div>

If you write

```julia-repl
julia> f = x->5
#3 (generic function with 1 method)

julia> g(x) = 5
g (generic function with 1 method)

julia> supertypes(typeof(f))
(var"#3#4", Function, Any)

julia> supertypes(typeof(g))
(typeof(g), Function, Any)

```

Indeed they are both functions. The difference is, the name `g` is now assigned to the function, whereas `f` is just a variable which currently stores the address to the anonymous function “`#3`” (you couldn’t call it with #3(2)` though).

```julia-repl
julia> g = 2
ERROR: invalid redefinition of constant Main.g
Stacktrace:
 [1] top-level scope
   @ REPL[16]:1

julia> f = 2
2

```

I hope this clears it up for you! You can also take a look at [the docs](https://m3g.github.io/JuliaNotes.jl/stable/anonymous/) about this.

On a side-note, this seems to induce performance issues:

```julia-repl
julia> using BenchmarkTools

julia> @btime f(2)
  8.603 ns (0 allocations: 0 bytes)
5

julia> @btime g(2)
  1.060 ns (0 allocations: 0 bytes)
5

```

Not sure why exactly this is the case, probably because `g` is a constant.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [March 15, 2024, 9:41am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-a-variable-that-contains-a-function-an-a-function/111652/4 "2024-03-15T09:41:21Z")

</div>

Try `@btime $f(2)`? BenchmarkTools’ `$`-interpolation is needed for non-`const` globals generally.

---

<div class="post-metadata">

### Author: ![Alseidon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alseidon/32/207775_2.png) [@Alseidon](https://discourse.julialang.org/u/Alseidon)
#### Post date: [March 15, 2024, 9:44am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-a-variable-that-contains-a-function-an-a-function/111652/5 "2024-03-15T09:44:11Z")

</div>

Got it! I forgot `f` was indeed a non-const variable, even though I said it before…

```julia-repl
julia> @btime $f(2)
  1.059 ns (0 allocations: 0 bytes)
5

```
