# Including modules inside blocks vs non-top-level modules

**URL:** <https://discourse.julialang.org/t/including-modules-inside-blocks-vs-non-top-level-modules/74768>\
**Category:** Internals & Design\
**Tags:** question, scope\
**Created:** [January 17, 2022, 7:47pm UTC](https://discourse.julialang.org/t/including-modules-inside-blocks-vs-non-top-level-modules/74768 "2022-01-17T19:47:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [January 17, 2022, 7:47pm UTC](https://discourse.julialang.org/t/including-modules-inside-blocks-vs-non-top-level-modules/74768/1 "2022-01-17T19:47:11Z")

</div>

Suppose I have a file `test.jl`

```julia
mode = "include"
if mode == "include"
    include("mod.jl")
    test.print_hello()
else mode == "direct"
    #module
    # println("HELLO DIRECT")
    #end
end

```

and `mod.jl`

```julia
module test
    function print_hello()
        println("HELLO MOD")
    end
end

```

This works fine, but if I were to un-comment the “direct” mode, I’d get `LoadError: syntax: "module" expression not at top level`.

I’m a little bit confused as to what exactly is going on. On some level, I can understand not allowing to define a module inside an if statement or a loop. On the other hand, the `include` construction is [quite useful](https://github.com/goerz-research/2022-01_Rydberg_Krotov_Spectral_Constraints/blob/74955bbe1368b1653a66d7c1f48eb6affff0740f/src/makerules.jl#L58). Mainly, though, why is `include` different? I was under the impression that `include` is basically, “insert code here”. I guess that’s wrong? Should I read the [docstring of `include`](https://docs.julialang.org/en/v1/base/base/#Base.include)

> Evaluate the contents of the input source file in the global scope of module `m`

to mean that an `include` statement anywhere inside a module basically says, “insert code at the top of the current module”, instead of “insert code where the include statement is”?

I’m still struggling a bit with scoping in Julia, but I suppose scope might be the difference here: a local definition of `module` would be inside the scope of the if-block (not allowed), whereas the `include` is at the scope of the `Main` module (allowed). Is that the correct interpretation?

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 17, 2022, 8:10pm UTC](https://discourse.julialang.org/t/including-modules-inside-blocks-vs-non-top-level-modules/74768/2 "2022-01-17T20:10:20Z")

</div>

> [@goerz](#):
>
> Should I read the [docstring of `include`](https://docs.julialang.org/en/v1/base/base/#Base.include) to mean that an `include` statement anywhere inside a module basically says, “insert code at the top of the current module”, instead of “insert code where the include statement is”?

Yes, exactly: `include` evaluates the file contents in the global scope of the current module, i.e. as if it was written in the top-level of the current module. If you know about C / C++, maybe it helps to emphasize that – although their names are very close – Julia’s `include()` function is not akin to C’s `#include` pre-processing macro in this respect.

If you want the module declaration to work from an `if` / `else` clause, you can wrap it inside `@eval`, which will in this case have more or less the same effect as `include`: evaluate the statement in the global scope of the current module:

```julia
julia> if true
           module Foo
              println("HELLO DIRECT")
           end
       end
ERROR: syntax: "module" expression not at top level
Stacktrace:
 [1] top-level scope
   @ REPL[2]:1

```

```julia
julia> if true
           @eval module Foo
              println("HELLO DIRECT")
           end
       end
HELLO DIRECT
Main.Foo

```

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [January 17, 2022, 8:14pm UTC](https://discourse.julialang.org/t/including-modules-inside-blocks-vs-non-top-level-modules/74768/3 "2022-01-17T20:14:59Z")

</div>

Thanks! My mental model was indeed that of C/C++ `#include`.

Also, thanks for clarifying `@eval`, since I had the same misconception there. I thought it would evaluate in the current scope. But now that you point it out, the [documentation](https://docs.julialang.org/en/v1/base/base/#Base.MainInclude.eval) is actually quite clear that it’s the global scope, not the local scope!

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 17, 2022, 8:16pm UTC](https://discourse.julialang.org/t/including-modules-inside-blocks-vs-non-top-level-modules/74768/4 "2022-01-17T20:16:46Z")

</div>

> [@goerz](#):
>
> a local definition of `module` would be inside the scope of the if-block (not allowed), whereas the `include` is at the scope of the `Main` module (allowed). Is that the correct interpretation?

And this might be nit-picking, but maybe it helps clarifying something here: it’s not entirely a question of _scope_, because `if` blocks don’t introduce local scopes. It’s really about `module` appearing at the _top-level_. (I suspect this has to do with compiler internals, world age issues and such topics, but then we’re speaking of things I don’t really know about)

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [January 18, 2022, 12:57am UTC](https://discourse.julialang.org/t/including-modules-inside-blocks-vs-non-top-level-modules/74768/5 "2022-01-18T00:57:13Z")

</div>

Background on eval and world age:

> **[World Age in Julia: Optimizing Method Dispatch in the Presence of Eval...](https://arxiv.org/abs/2010.07516)**
>
> Dynamic programming languages face semantic and performance challenges in the presence of features, such as eval, that can inject new code into a running program. The Julia programming language introduces the novel concept of world age to insulate...
