# Import Once in Julia

### Background

I’m reading Think Julia to repick the language again.

• To import a package/module, we using Foo.
• To run a script within the REPL, we include("foo.jl").

This is useful for user-defined functions, which are usually multi-line.

### Problem

How to avoid importing a module/including a file twice?

### Solution

Here’s a modified code from the book to give an example.

1. polygon.jl depends on the module :ThinkJulia, and it defines a function which moves the object t along a polygon-shaped closed loop.
2. circle.jl depends on the script polygon.jl, and it attempts to move the object t along a “circle”.
# polygon.jl
if !isdefined(Main, :ThinkJulia)
using ThinkJulia
end

function polygon(t, n, len)
angle = 360 / n
for i in 1:n
forward(t, len)
turn(t, -angle)
end
end

# circle.jl
if !(@isdefined polygon) || !(typeof(polygon) <: Function)
include("polygon.jl")
end

function circle(t, r)
circumference = 2 * π * r
n = 50
len = circumference / n
polygon(t, n, len)
end


### Notes

1. <:(T1, T2) -> Bool is a function that returns true if T1 is a subtype of T2.
2. isa(x, type) -> Bool is a function, e.g. :foo isa Symbol.
3. eval() evaluates the expression inside. This can be used to get an object of type Module. Say typeof(:Main) is Symbol, but typeof(eval (:Main)) is Module.
4. filter((x) -> f(x), arr) filters element from arr using the predicate f.

Reference: https://stackoverflow.com/q/37823591