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.

Reply via email to