# How to include into local scope?

**URL:** <https://discourse.julialang.org/t/how-to-include-into-local-scope/34634>\
**Category:** General Usage\
**Created:** [February 14, 2020, 3:58pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634 "2020-02-14T15:58:15Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 14, 2020, 3:58pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/1 "2020-02-14T15:58:15Z")

</div>

In quick and dirty development/testing, the ability to just copy-paste code is very handy. If a snippet is used a lot, it can be elevated to a function later.

Is there a way to evaluate a file in local scope? The `Base.include` function evaluates in the global scope, which is **not** what I want. For a similar discussion, see [Is "include" safe to use inside a function?](https://discourse.julialang.org/t/is-include-safe-to-use-inside-a-function/10867)

For example, say I have some complicated plotting routine in a file `wowPlot.jl`:

```julia
display(x^2)

```

I create some elaborate data and display it:

```julia
x = 5
include("wowPlot.jl")
25

```

Then I want a local scope to not mess with the original data:

```julia
let x = 6
    include("wowPlot.jl")
end
25

```

How to make the last statement display 36?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [February 14, 2020, 4:08pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/2 "2020-02-14T16:08:32Z")

</div>

You can’t. And this is what function/macros are for.

---

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 14, 2020, 4:21pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/3 "2020-02-14T16:21:37Z")

</div>

Is there some fundamental reason why it is not possible? Is it worth requesting this feature? I would find it very useful.

Right now I can’t think of a single language where this is not possible.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 14, 2020, 4:28pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/4 "2020-02-14T16:28:55Z")

</div>

> [@HenrikM](#):
>
> Then I want a local scope to not mess with the original data:

```julia
module LocalScope
    x = 6
    include("wowPlot.jl")
end

```

---

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 14, 2020, 4:31pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/5 "2020-02-14T16:31:48Z")

</div>

You suggest using modules as a super-let? Interesting!

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [February 14, 2020, 4:33pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/6 "2020-02-14T16:33:45Z")

</div>

> [@HenrikM](#):
>
> Is there some fundamental reason why it is not possible?

Yes, `include` is a global scope and you cannot make itt a local scope. Same as that you cannot make `eval` local.

> [@HenrikM](#):
>
> Is it worth requesting this feature?

No, it’s described in the thread you linked.

> [@HenrikM](#):
>
> Right now I can’t think of a single language where this is not possible.

C.

> [@HenrikM](#):
>
> You suggest using modules as a super-let? Interesting!

Module creates a global scope. Yes you can do that but you shouldn’t.

> [@HenrikM](#):
>
> the ability to just copy-paste code is very handy. If a snippet is used a lot, it can be elevated to a function later.

If this is actually you goal, you should just use a function.

---

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 14, 2020, 4:38pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/7 "2020-02-14T16:38:51Z")

</div>

Maybe we are talking past each other here. In C—which the preprocessor is an integral part of—an `#include` does exactly what I want.

Many people are using Julia for many things. Right now I am doing jupyter scripts and this kind of raw paste would be really handy.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [February 14, 2020, 4:39pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/8 "2020-02-14T16:39:25Z")

</div>

Include into local scope, would be the same as `eval` into local scope.  
`eval` into local scope is one of the things that makes code impossible to optimize.  
It is a feature julia very intentionally doesn’t have.

---

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 14, 2020, 4:45pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/9 "2020-02-14T16:45:05Z")

</div>

Yes, I love Julias compiled-language side. But I think interpreted, throwaway scripts are also very important for a modern language. I appreciate that some functions are optimized to the bitter end, but I would also like to have a interpreted interface that is more flexible. Like Python, perhaps.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [February 14, 2020, 4:46pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/10 "2020-02-14T16:46:21Z")

</div>

**I recommend against this,** but I think the following would work:

```julia
macro include(filename::String)
    dir = dirname(string( __source__.file))
    filepath = joinpath(dir, filename)
    source = "quote; " * read(filepath, String) * "; end"
    esc(Meta.parse(source).args[1])
end

```

e.g.

```julia
function foo(x)
    @include "body.jl"
end

```

Which is a close approximation to what C’s `#include` does.  
I feel like it is a **unwise thing** , and I would say the exact same about putting a local `#include` in a C file.

Note that this not catch changes in the file included.

Whats wrong with functions?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 14, 2020, 4:51pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/11 "2020-02-14T16:51:03Z")

</div>

> [@HenrikM](#):
>
> Maybe we are talking past each other here. In C—which the preprocessor is an integral part of—an `#include` does exactly what I want.

Sure, you can do that in Julia too.

```julia
macro include(filename::AbstractString)
    path = joinpath(dirname(String( __source__.file)), filename)
    return esc(Meta.parse("quote; " * read(path, String) * "; end").args[1])
end

```

then

```julia
let x = 5
    @include "wowPlot.jl"
end

```

or

```julia
function f(x)
    @include "wowPlot.jl"
end

```

will do what you expect (i.e. act as if you pasted the included code at that point). (@oxinabox had the same idea and was a bit quicker to post, but I had a chance to test mine and I believe it works.)

(I wouldn’t recommend this from a maintenance/reability standpoint, however! And even for short-term hacks I think it is better to write functions as soon as you find yourself re-using code.)

---

<div class="post-metadata">

**Author:** ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)\
**Post date:** [February 14, 2020, 4:53pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/12 "2020-02-14T16:53:29Z")

</div>

> [@HenrikM](#):
>
> Maybe we are talking past each other here. In C—which the preprocessor is an integral part of—an `#include` does exactly what I want.

Exactly. If you want to do the equivalent to preprorcessor tricks, the analogy in julia is macros - which are safer and more powerful.

However… if you have some reusable code, thee is a 99% chance it is better off in a function in a module than a literal include.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [February 14, 2020, 4:54pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/13 "2020-02-14T16:54:20Z")

</div>

Yes, copy paste is fine. But I don’t see what’s wrong with a function.

---

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 14, 2020, 5:06pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/14 "2020-02-14T17:06:30Z")

</div>

Thank you for your answers.

The consensus seems to be that everything should be packaged into a function. I totally agree.

I will try to describe my use case without actually dumping the code here. I am building a plot that visualises 10 different things. The function would look like

```julia
function wowPlot(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, parameters, more_parameters)

```

This would not be a good function. I hope you agree. Currently in my script I use all those variables and parameters and build a nice plot. Then I modify some variables or some parameters and plot again and compare the difference. Currently I just copy-paste the plotting code to all places in all scripts where I need it. It would be cleaner to be able to simply raw-include into scripts. I you have solved this problem in some other way I would love to hear about it.

---

<div class="post-metadata">

**Author:** ![jbrea](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbrea/32/3879_2.png) [@jbrea](https://discourse.julialang.org/u/jbrea)\
**Post date:** [February 14, 2020, 5:10pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/15 "2020-02-14T17:10:15Z")

</div>

> [@HenrikM](#):
>
> I you have solved this problem in some other way I would love to hear about it.

Can’t you aggregate some arguments into vectors, tuples or namedtuples and pass around those?

---

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 14, 2020, 5:11pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/16 "2020-02-14T17:11:01Z")

</div>

> [@oxinabox](#):
>
> ```julia
> macro include(filename::String)
> dir = dirname(QuoteNode( __source__ ).file)
> filepath = join(dir, filename)
> source = "quote; " * read(filepath, String) * "; end"
> esc(Meta.parse(source).args[1])
> end
> 
> ```

```julia
@include "testInclude.jl"
type QuoteNode has no field file

Stacktrace:
 [1] getproperty(::QuoteNode, ::Symbol) at ./Base.jl:20
 [2] @include(::LineNumberNode, ::Module, ::String) at ./In[1]:2nd_place_medal: 

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [February 14, 2020, 5:13pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/17 "2020-02-14T17:13:07Z")

</div>

> [@HenrikM](#):
>
> This would not be a good function. I hope you agree

Nothing more wrong for this function than doing worse by using including a file.

---

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 14, 2020, 5:14pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/18 "2020-02-14T17:14:03Z")

</div>

> [@jbrea](#):
>
> Can’t you aggregate some arguments into vectors, tuples or namedtuples and pass around those?

Someting like

```julia
t = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, parameters, more_parameters)
wowPlot(t)

```

You mean?

And then unpack inside the function? I think this is just syntax. The semantics of `wowPlot` are still the same and still too broad to be a good function.

---

<div class="post-metadata">

**Author:** ![HenrikM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrikm/32/17975_2.png) [@HenrikM](https://discourse.julialang.org/u/HenrikM)\
**Post date:** [February 14, 2020, 5:16pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/19 "2020-02-14T17:16:55Z")

</div>

> [@yuyichao](#):
>
> Nothing more wrong for this function than doing worse by using including a file.

Are you saying that I should casually write functions with more parameters that can fit on a line? My point is that I want a separation between good and proper functions on one hand and quick and dirty scripting on the other. This post is about making the scripting easier.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 14, 2020, 5:18pm UTC](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634/20 "2020-02-14T17:18:26Z")

</div>

> [@HenrikM](#):
>
> Currently in my script I use all those variables and parameters and build a nice plot.

It sounds like you have default values for those parameters. In that case you can use keyword arguments:

```julia
function wowPlot(; x1=..., x2=...., ....)
   ...
end

```

and then when you call it you only need to pass the parameters you want to change.

[Next page](https://discourse.julialang.org/t/how-to-include-into-local-scope/34634.md?page=2)
