# Redefinition of functions sometimes possible?

Hi!

I noticed some unexpected (at least for me) behavior when redefining functions.

``````julia> foo(x) = x + 1
foo (generic function with 1 method)

julia> foo(x) = x + 2
foo (generic function with 1 method)

julia> foo = x -> x + 1
ERROR: invalid redefinition of constant foo
Stacktrace:
 top-level scope
@ REPL:100:
``````

and

``````julia> bar = x -> x + 1
#3 (generic function with 1 method)

julia> bar = x -> x + 2
#5 (generic function with 1 method)

julia> bar(x) = x + 1
ERROR: cannot define function bar; it already has a value
Stacktrace:
 top-level scope
@ none:0
 top-level scope
@ REPL:1
``````

Can someone explain why this happens? Are `f(x) = x + 1` and `f = x -> x + 1` fundamentally different?

Yes. The former is a function named `f`. The latter is a pointer to an anonymous function. In a sense, the two are akin to

``````g(x) = x+1

f(x) = g(x) # the first one
f = g # the second
``````
3 Likes

In particular the most important difference for this question is that `f = x -> x + 1` creates a global variable biniding, whereas `f(x) = x + 1` creates a global constant binding.

If you make is a constant then you also can’t change it:

``````julia> const g = x -> x + 1
#4 (generic function with 1 method)

julia> const g = x -> x + 2
ERROR: invalid redefinition of constant g
Stacktrace:
 top-level scope
@ REPL:1
``````
5 Likes

Thank you both!

Why can I change `f(x) = x + 1` to `f(x) = x + 2` when it is a constant variable? Are functions in some way mutable?

`f(x) = x + 1` creates a constant binding from the variable `f` to a function. However, the function itself is a mutable bag of methods. What you did was actually overwrite one of it’s methods. We can do this same with your other example:

``````julia> const g = x -> x + 1
#4 (generic function with 1 method)

julia> (::typeof(g))(x) = x + 2

julia> g(1)
3
``````
4 Likes

When you write

``````f(x) = x + 1
``````

you can think of this as ‘special syntax’ for something more like

``````struct var"typeof(f)" end
const f = var"typeof(f)"()
(::typeof(f))(x) = x + 1
``````

Here’s that in action:

``````julia> struct var"typeof(f)" end

julia> const f = var"typeof(f)"()
var"typeof(f)"()

julia> (::typeof(f))(x) = x + 1

julia> f(1)
2
``````

In julia, methods can be attached to any object. Functions are just a type of singleton object that have special syntax to make it easier to add methods to them.

4 Likes

What is displayed if you just write `g` after adding that method? (On my phone, can’t check)

``````julia> g
#4 (generic function with 1 method)
``````
2 Likes