5.3 s

Code structuring and interaction with other languages

Julia workflows

When working with Julia, we can choose between a number of workflows.

Pluto notebook

This ist what you see in action here. After calling pluto, you can start with an empty notebook and add cells.

Jupyter notebook

With the help of the package IJulia.jl it is possible to work with Jupyter notebooks in the browser. The Jupyter system is very complex and Pluto hopefully will be able to replace it.

Classical workflow

Use a classical code editor (emacs, vi or whatever you prefer) in a separate window and edit files, when saved to disk run code in a console window. With Julia, this workflow has the disadvantage that everytime Julia is started, the JIT needs to recompile the packages involved. So the idea is to not leave Julia, but to start a permanent Julia session, and include the code after each change.

The Revise.jl package allows to keep track of changed files used in a Julia session if they have been included via includet (t for "tracked"). In orde to make this work, one should add

if isinteractive()
    try
        @eval using Revise
        Revise.async_steal_repl_backend()
    catch err
        @warn "Could not load Revise."
    end
end

to the startup file ~/.julia/config/startup.jl and to run Julia via julia -i.

Revise.jl also keeps track of packages loaded. It also can be used with Pluto.

Modern workflow

Use an IDE (integrated development environment). Currently the best one for Julia is Visual Studio Code with corresponding extensions.

11.2 μs

Structuring code: modules, files and packages

  • Complex code is split up into several files which can be included

  • Need to avoid name clashes for code from different places

Modules

Modules allow to encapsulate implementation into different namespaces

2.0 ms
Main.workspace3.TestModule
834 μs
"mtest: x=2"
2.9 ms

Packages

  • Packages are modules searched for in a number of standard places

  • Each package is a directory named Package with a subdirectory src

  • The file Package/src/Package.jl defines a module named Package

  • More structures in a package:

    • Documentation resources

    • Test code

    • Metadada: Dependency description, UUID (Universal unique identifier)...

  • Default packages (e.g. the package manager Pkg) are always found in the .julia subdirectory of your home directory

  • The package manager allows to add packages by finding them via the registry and downloading them.

11.6 μs
1.4 ms
26.6 μs
  • After importing a package via the import statement, all functions from a package are available via their name prefixed with the name of the package.

  • The using statement makes these names available without prefix.

4.3 μs

Calling code from other languages

C

  • C language code has a well defined binary interface

    • int Int32

    • float Float32

    • double Float64

    • C arrays as pointers

  • Create a C source file:

9.1 μs
cadd_source
"double cadd(double x, double y) \n{ \n   return x+y; \n}\n"
913 ns
11.0 ms

Compile to a shared object (aka "dll" on windows) using the gcc compiler:

5.1 μs
Process(`gcc --shared cadd.c -o libcadd.so`, ProcessExited(0))
22.5 ms
  • Define wrapper function cadd using the Julia ccall method

    • (:cadd, "libcadd"): call cadd from libcadd.so

    • First Float64: return type

    • Tuple (Float64,Float64,): parameter types

    • x,y: actual data passed

  • At its first call it will load libcadd.so into Julia

  • Direct call of compiled C function cadd(), no intermediate wrapper code

9.1 μs
cadd (generic function with 1 method)
21.6 μs
4.0
2.4 ms
  • Julia and many of its packages use this method to access a number of highly optimized linear algebra and other libraries

3.2 μs

Python

  • Both Julia and Python are homoiconic language, featuring reflection

  • They can parse the elements of their own data structures possibility to automatically build proxies for python objects in Julia

The PyCall package provides the corresponding interface:

1.6 ms
1.6 s

Create a python source file:

21.4 μs
pyadd_source
"def add(x,y):\n    return x+y\n"
948 ns
9.1 ms
pyadd
PyObject <module 'pyadd' from '/home/fuhrmann/Wias/teach/scicomp/scicomp/pluto/pyadd.py'>
373 μs
9.7
15.9 ms
  • Julia allows to call almost any python package

  • E.g. matplotlib graphics - this is the python package behind PyPlot (there are more graphics options in Julia)

  • There is also a pyjulia package allowing to call Julia from python

6.5 μs

Other languages

  • There are ways to interact with C++, R and other langugas

  • Interaction with Fortran via ccall

7.2 μs