Newbie question on search path


#1

I should preface the question by saying I’m a Julia pre-newbie…I’ve read a bunch but haven’t written my first real program yet. (But I have 50 years of programming experience and write mostly in Matlab nowadays.) So please be gentle.

When I write in Matlab I break up my problem into small functions, one to a source file. For a given project all the functions go into one directory. I point Matlab at that directory and it knows to search for a function there first.

So what’s the equivalent in Julia. Is there a way to tell Julia where to look for files containing functions? Do I have to preface everything with a long list of #includes? Or is there just a different way to think about things in Julia? (I’m not writing large projects nor do they generally get used anywhere except on my desk.)

Thanks in advance.


#2

Welcome!

Julia code typically uses more, smaller functions, with many functions living within a single file. You don’t have to do that, but I find that short functions are easier to describe, understand, and test. The fact that MATLAB only allows a single exported function per file, is, in my opinion, a significant downside to the language.

Since Julia code tends to have many functions, we need some way to organize them. The way we do that is with Modules. You can read about Modules in the manual here: https://docs.julialang.org/en/stable/manual/modules/

For example, you can make a module by creating a file called Foo.jl and adding the following:

module Foo

function f(x)
  println(x)
end

function g(x, y)
  x + y
end

end

To use the module you’ve just defined, you need to tell Julia where to look for it. See: https://docs.julialang.org/en/stable/manual/modules/#Module-file-paths-1 All you need to do is add the folder containing Foo.jl to your LOAD_PATH variable with push!(LOAD_PATH, "/path/to/folder"). Then you can load your module with:

using Foo

Foo.f(1.0)

Note that the name of the module matches the name of the file: module Foo is in Foo.jl. The filename matters, and when you do using Foo Julia will expect to find Foo.jl or Foo/src/Foo.jl somewhere in LOAD_PATH.

If you want to call the f function without the Foo. prefix, you can modify your module:

module Foo

export f

function f(x)
  println(x)
end

function g(x, y)
  x + y
end

end

Then you can do:

using Foo
f(1.0)

If you don’t want to do the push!(LOAD_PATH, ...) every time you start Julia, you can either set the JULIA_LOAD_PATH environment variable, or you can just add that push! statement to your ~/.juliarc.jl file. For more info see: https://docs.julialang.org/en/stable/manual/getting-started/#Getting-Started-1

If your module starts to get too big to comfortably remain in a single file, you can split it up into files however you like. See: https://docs.julialang.org/en/stable/manual/modules/#Modules-and-files-1

Finally, as your code matures to the point where you’d like to share it with other people, you can turn it into a package, which other people will be able to install with Pkg.add() or Pkg.clone(). For more info see https://docs.julialang.org/en/stable/manual/packages/


#3

rdeits,

That’s a very clear answer and is much appreciated.

Let me ask if there is a Julia-ism that would effectively say

using _all-modules-in-directory-such-and-such_

#4

I was just looking at this. I think you want to use pushfirst! so that your project or local path is searched first.

EDIT: or unshift! on Julia v0.6


#5

No, there’s no command to do that. You could write a function that would list the directory’s contents and then load each module that it finds, but I’m not aware of such a function existing already.

Instead, if you have a collection of modules that are used together, you can just create them as nested modules inside another module. For example:

module MyProject

module Solvers

 f(x) = ...

end

module Visualization

g(x) = ...

end

end

Then you can do using MyProject and all of the modules inside it will be loaded. You can also put those inner modules in separate files and/or folders and include() them within your MyProject.jl.

A single module with several other modules inside it is very common in Julia packages, since it makes it easy to gather a bunch of related code while still keeping some logical separation between the various pieces.


#6

Hadn’t thought of that. Thank you.


#7

I see. This is helpful for me learning to think in Julia rather than just translating from Matlab. Thanks.


#8

Be aware that in 0.7:
The ~/.juliarc.jl file has been moved to ~/.julia/config/startup.jl and /etc/julia/juliarc.jl file has been renamed to /etc/julia/startup.jl (#26161).