Well, first things first, in Julia you have explicit modules. Which means that
the vast majority of the files start with the module keyword and end with an
end keyword (NB: blocks in Julia are ended by end).
When one wants to include some external module, one used to have to include the
file containing the module (a.k.a. know where to look) and then import the
module itself. Nowadays if module Foo is contained in the file Foo.jl, the file
inclusion is done automatically (but the module boilerplate is here to stay).
Anyway, the official way to include a module now is by making use of either
using or import. The first one, using Foo is Julia's equivalent to Nim's import
Foo while Julia's import Foo is the equivalent of Nim's from Foo import nil.
Said otherwise, if module Foo is imported by import Foo in Julia, one can
access any symbols from Foo using its full name (e.g. Foo.bar()) whereas using
Foo imports the exportable symbols from the module in the current namespace. In
Nim, you do that by marking any symbol with * while in Julia, there is an
explicit export keyword. Note that there is no concept of privacy in Julia:
exported symbols defines what is imported in the current namespace by using; in
particular, the other symbols are accessible if prefixed by the module name.
In practice, using Foo is almost always used, which can be easily justify by
the fact that most tutorials and the quasi-totality of the examples in the
manual use it exclusively. For Julia demographics, this is not a big problem as
most "technical computing" people tend to write short length/lived scripts
anyway so maintainance and ease of code reading by others is not really a
concern.
As Julia is built on a JIT, most of its analysis is done at runtime. It used to
warn the user about ambiguous definitions at import time but now it does only
when one tries to actually use an ambiguous symbol. This has the extra
advantage (for a JIT-ed language) to use the complete function signature can be
used instead of its name to determine whether or not this is a problem (just as
Nim does).
In addition to the JIT, note that Julia actually allows to pass default values
to functions which makes things even more complicated even when the signatures
do not match to begin with:
function f(x::Int, y::Int=1)
x.+y
end
function f(x::Int)
2.*x
end
What should f(2) give?
>From my perspective, it seems like Julia and Nim has quite a lot in common:
>they are definitely different but they made similar choices in their import
>system which is why I find it relevant to compare the two.