# Define a function in global scope inside another function

**URL:** <https://discourse.julialang.org/t/define-a-function-in-global-scope-inside-another-function/102597>\
**Category:** General Usage\
**Tags:** scope, function\
**Created:** [August 8, 2023, 11:11am UTC](https://discourse.julialang.org/t/define-a-function-in-global-scope-inside-another-function/102597 "2023-08-08T11:11:08Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Qfl3x](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/qfl3x/32/16227_2.png) [@Qfl3x](https://discourse.julialang.org/u/Qfl3x)\
**Post date:** [August 8, 2023, 11:11am UTC](https://discourse.julialang.org/t/define-a-function-in-global-scope-inside-another-function/102597/1 "2023-08-08T11:11:08Z")

</div>

I want to define a function `a(x)` inside a function `b(a)`, but make `a` in global scope, example:

```julia
a(x) = 3 + x
function b(a)
    global a(x) = a + x
end

```

This gives an error currently:

```julia
ERROR: syntax: Global method definition around REPL[14]:2 needs to be placed at the top level, or use "eval".

```

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [August 8, 2023, 11:16am UTC](https://discourse.julialang.org/t/define-a-function-in-global-scope-inside-another-function/102597/2 "2023-08-08T11:16:11Z")

</div>

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

julia> a(2)
5

julia> function b(a)
           @eval a(x) = $a + x
           return nothing
       end
b (generic function with 1 method)

julia> b(10)

julia> a(2)
12

```

(But likely a bad idea in the first place 😉)

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [August 8, 2023, 11:50am UTC](https://discourse.julialang.org/t/define-a-function-in-global-scope-inside-another-function/102597/3 "2023-08-08T11:50:38Z")

</div>

Likely this is not actually something you want to do, so it would be good if you described the problem you are trying to solve so we avoid [X/Y problems](https://xyproblem.info/).

Otherwise its something we often use a macro for.

---

<div class="post-metadata">

**Author:** ![Qfl3x](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/qfl3x/32/16227_2.png) [@Qfl3x](https://discourse.julialang.org/u/Qfl3x)\
**Post date:** [August 8, 2023, 12:10pm UTC](https://discourse.julialang.org/t/define-a-function-in-global-scope-inside-another-function/102597/4 "2023-08-08T12:10:15Z")

</div>

My problem is this: [Initialize some functions at every remake in PDEProblem](https://discourse.julialang.org/t/initialize-some-functions-at-every-remake-in-pdeproblem/102078)

I’ve thought a possible solution would be to redefine

```julia
Temperature(t,x)

```

by defining a function:

```julia
function pde_solution(Tvec)
    interp = LinearInterpolation(Tvec, [1.,2.,3.,4.,5.])
    global Temperature(t, x) = interp(x)
    solve(prob, TRBDF2())
end

```

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [August 8, 2023, 1:55pm UTC](https://discourse.julialang.org/t/define-a-function-in-global-scope-inside-another-function/102597/5 "2023-08-08T13:55:36Z")

</div>

This is generally not a good idea and won’t work out of the box because the already compiled code won’t see the redefined method until you hit global scope. You’d need to use `Base.invokelatest` inside the solve which is not performant. See [documentation](https://docs.julialang.org/en/v1/manual/methods/#Redefining-Methods).

You could try is pass that function as another parameter into the problem or define some sort of struct where you can then change the values later on.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [August 8, 2023, 5:13pm UTC](https://discourse.julialang.org/t/define-a-function-in-global-scope-inside-another-function/102597/6 "2023-08-08T17:13:48Z")

</div>

Ok, no don’t do this 😉

globals are very difficult to reason about, you are opening yourself up to a lot of potential bugs, and poor performance too.

I don’t totally understand your use case as your code is not a full MWE (e.g. what is `prob`). But you could maybe use a functor ? that’s a struct that can be called like a function:

```julia
struct Temperature{L}
    interp::L
end
(f::Temperature(t, x) = f.interp(x) # But why don't you use `t` ??
interp = Temperature(LinearInterpolation(Tvec, [1.,2.,3.,4.,5.]))

```

---

<div class="post-metadata">

**Author:** ![algunion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algunion/32/51630_2.png) [@algunion](https://discourse.julialang.org/u/algunion)\
**Post date:** [August 8, 2023, 7:06pm UTC](https://discourse.julialang.org/t/define-a-function-in-global-scope-inside-another-function/102597/7 "2023-08-08T19:06:52Z")

</div>

There are two alternative approaches that you can use while avoiding the global `@eval` call.

The best fit depends on your use case:

### A) Your goal is to update/redefine the logic (body) of an existing globally defined function

Take a look at [DynamicExpressions.jl](https://github.com/SymbolicML/DynamicExpressions.jl) package and check if your function logic can be defined this way.

The idea is that you could have a `Ref` inside your original global function body and only update that piece using `DynamicExpressions.jl`.

### B) You are generating multiple functions and want to be able to call them from the global scope.

This scenario is not excluding the usage of `DynamicExpressions.jl` - you might still find the approach feasible.

The alternative is to generate anonymous functions and update a global dictionary:

```julia
const FUNSTORE = Dict{Symbol,Function}()

# from inside some function
FUNSTORE[:myfun] = x -> x + 1
FUNSTORE[:myfun](1) # will produce 2

```
