# Surprising behavior when function contains variable with same name

**URL:** <https://discourse.julialang.org/t/surprising-behavior-when-function-contains-variable-with-same-name/98511>\
**Category:** General Usage\
**Created:** [May 8, 2023, 11:10pm UTC](https://discourse.julialang.org/t/surprising-behavior-when-function-contains-variable-with-same-name/98511 "2023-05-08T23:10:35Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![anodos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anodos/32/212778_2.png) [@anodos](https://discourse.julialang.org/u/anodos)\
**Post date:** [May 8, 2023, 11:10pm UTC](https://discourse.julialang.org/t/surprising-behavior-when-function-contains-variable-with-same-name/98511/1 "2023-05-08T23:10:35Z")

</div>

I have been running into issues with Julia functions whose name matches the name of an internal variable. For example, the following function seems pretty harmless to me:

```julia
function speed(distance,time)
    speed = distance/time
    return speed
end

```

And indeed this function works just fine:

```julia
speed(6,2)
3.0

```

However, I ran into an issue today where referencing the name of the function in the function caused an error. The following is a MWE:

```julia
using DifferentialEquations
function MyCalculation()
    function ImportantParameter(z)
        ImportantParameter = z^2
        return ImportantParameter
    end
    
    function dudz!(dudz,u,p,z)
        dudz[1] = ImportantParameter(z)*u[1]
    end
    
    u0 = [1.0]
    zspan = (0.0, 0.1)
    IVPprob = ODEProblem(dudz!, u0, zspan)
    return solve(IVPprob, Tsit5())
end

MyCalculation()

```

This gives an error:

```julia
MethodError: objects of type Float64 are not callable
Maybe you forgot to use an operator such as *, ^, %, / etc. ?

```

On the other hand, if we change the name of the variable as follows, no error is reported:

```julia
function MyCalculation()
    function ImportantParameter(z)
        ImportantParameter_different_name = z^2
        return ImportantParameter_different_name
    end
    
    function dudz!(dudz,u,p,z)
        dudz[1] = ImportantParameter(z)*u[1]
    end
    
    u0 = [1.0]
    zspan = (0.0, 0.1)
    IVPprob = ODEProblem(dudz!, u0, zspan)
    return solve(IVPprob, Tsit5())
end

MyCalculation()

```

It is surprising to me that changing a local variable name inside a function would affect the behavior of the function in this way. I’m curious if this behavior is expected? It is also strange to me that _sometimes_ using the name of the function as a variable name is harmless, but on other occasions it causes errors; I haven’t figured out a pattern as to when it is safe and when it is not.

Thanks!

---

<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:** [May 9, 2023, 12:12am UTC](https://discourse.julialang.org/t/surprising-behavior-when-function-contains-variable-with-same-name/98511/2 "2023-05-09T00:12:35Z")

</div>

The rule is actually simple: nested local scopes reuse outer local variables by default. In your first example, the outer `speed` is a `const` global variable, so it is not reused in its local scope. In your second example, the outer `ImportantParameter` is a local variable in the scope of `MyCalculation`, so it does get reused by its inner local scope. Unfortunately that reuse is a reassignment from the function to `z^2`, so your first function call costs you access to that very function. To override this default behavior, declare a new local variable `local ImportantParameter = z^2` in the nested scope, though you probably should just `return z^2` in such a simple case or more generally use a different meaningful name.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [May 11, 2023, 4:17am UTC](https://discourse.julialang.org/t/surprising-behavior-when-function-contains-variable-with-same-name/98511/3 "2023-05-11T04:17:05Z")

</div>

Looks like another good reason to implement [this proposal](https://github.com/JuliaLang/julia/issues/47760#issuecomment-1334741784).

---

<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:** [May 11, 2023, 6:37am UTC](https://discourse.julialang.org/t/surprising-behavior-when-function-contains-variable-with-same-name/98511/4 "2023-05-11T06:37:40Z")

</div>

I’m not convinced implicitly `const`ing local function names is a good idea. They don’t even stop reassignments in the global scope now, instead it prints “warning: redefinition of constant” and lets weird things happen. At least throwing “not callable” errors stops it from getting very far. Even if you make `const` variables truly unreassignable, it’d still throw an error when attempting to reassign them. Unless you break the “local scopes reuse outer local variables” rule thus adding even more exceptions to the scoping rules, it’s good to encourage people to make meaningful distinct names.
