# StackOverflowError with locally defined function

**URL:** <https://discourse.julialang.org/t/stackoverflowerror-with-locally-defined-function/26040>\
**Category:** General Usage\
**Created:** [July 5, 2019, 10:26am UTC](https://discourse.julialang.org/t/stackoverflowerror-with-locally-defined-function/26040 "2019-07-05T10:26:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)\
**Post date:** [July 5, 2019, 10:26am UTC](https://discourse.julialang.org/t/stackoverflowerror-with-locally-defined-function/26040/1 "2019-07-05T10:26:51Z")

</div>

```julia
function main()

    function sub()
        fun(f) = f
        return x -> fun(x)
    end

    fun = sub()
    fun(1)
end

```

A call to `main()` results in a stack overflow. If `sub()` returned `fun` instead of `x -> fun(x)` or the assignment in `main()` was `fun2 = sub()` or `calling sub()(1)` all would be OK.

Is this construct against Julia’s grammar?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 5, 2019, 10:52am UTC](https://discourse.julialang.org/t/stackoverflowerror-with-locally-defined-function/26040/2 "2019-07-05T10:52:21Z")

</div>

> [@mzaffalon](#):
>
> Is this construct against Julia’s grammar?

No, it is parsed fine and I think it is executed correctly.

What happens is that `sub` takes `fun` from the scope of `main`, which you happen to overwrite, so it ends up being recursive.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [July 5, 2019, 12:54pm UTC](https://discourse.julialang.org/t/stackoverflowerror-with-locally-defined-function/26040/3 "2019-07-05T12:54:35Z")

</div>

Interesting that this happens even if `fun` is first assigned/defined after the local function assignment/definition. I would assume that any binding I assign a value inside a local function which does not exist yet in the outer scope will end up being local to the local function, not that it “retroactively” makes the binding in the local function to refer to the binding in the outer scope.

This just happen if `fun` is assigned in the outer scope? It works as I expect if I just try to print the binding in the outer scope.

```julia
function main()

    function sub()
        fun(f) = f 
        return x -> fun(x)
    end 

    show(fun)
    sub()
end

main()

```

In other words, this says `fun` is not defined. Counter-intuitive for me that defining a binding at any point of the scope makes it available before it was defined in some cases (i.e., to be captured by a local function) but not change the answer of `@isdefined`.

```julia
function main()

    function sub()
        fun(f) = f
        return x -> fun(x)
    end

    println(@isdefined(fun))
    fun = sub()
    fun(1)
end

```

This outputs `false` before the stack overflow.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 5, 2019, 1:17pm UTC](https://discourse.julialang.org/t/stackoverflowerror-with-locally-defined-function/26040/4 "2019-07-05T13:17:31Z")

</div>

> [@Henrique\_Becker](#):
>
> Counter-intuitive for me that defining a binding at any point of the scope makes it available before it was defined in some cases

This is the [documented behavior](https://docs.julialang.org/en/v1/manual/variables-and-scoping/): right in the beginning of the relevant chapter, you will find that

> The scope of a variable cannot be an arbitrary set of source lines; instead, it will always line up with one of these blocks.

This is later elaborated with examples.

This is actually a very clean way of thinking about scope: relying on the order of things happening can get chaotic pretty quickly (think of branches, etc).

I think it is best to avoid writing code like this, it can become very hard to reason about.

---

<div class="post-metadata">

**Author:** ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)\
**Post date:** [July 5, 2019, 3:07pm UTC](https://discourse.julialang.org/t/stackoverflowerror-with-locally-defined-function/26040/5 "2019-07-05T15:07:53Z")

</div>

As pointed out by @Tamas_Papp, the [docs](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Local-Scope-1) are explicit about nested functions and their parent’s scope:

> Note that _nested functions_ can modify their parent scope’s _local_ variables:
