Quiz 1.12: Interoperability with other languages
Q1: Interfaceable languages
In which of the following languages we can write libraries that can then be used in Julia directly, i.e. without any external package and with a single statement ?
RESOLUTION
Fortran and C shared libraries can be directly called using the 'ccall' function. All of the listed languages can be used in Julia, and many provide C API, but this require writing complex wrappers around their C interface that ended up in language-specific packages: PyCall.jl for Python, CxxWrap.jl for C++, RCall.jl for R, JavaCall.jl for Java, MATLAB.jl for Matlab, MathLink.jl for Mathematica, StataCall.jl for Stata JSExpr.jl for JavaScript (at various level of package maturity).
The correct answers are:
- C
- Fortran
Q2: Interoperativity with C
Assume you have a C shared library whose path address is stored on const myclib
containing the C function extern double getPlusOne(double x);
. You want to use ccall(XXXX)
to call the function with the parameter 10.5
. What should you replace XXXX
with ? Use the type aliases to the C names (e.g. Cint
, Cfloat
, Cdouble
,...), don't use spaces at all (to avoid ambiguous grading of your answer, in real-life coding feel free to use the convention you prefer concerning spaces), and remember that to create a tuple for a single value you still need to use a comma, eg. (x,)
.
RESOLUTION
We need to first specify the tuple function name/library path as the first argument of ccall
, we then specify the return type (Cdouble
) as the second argument, the input types (just Cdouble,
here) as the third argument and finally, we specify 10.5
as the fourth and last argument.
The correct answer is: (:getPlusOne,myclib),Cdouble,(Cdouble,),10.5
Q3: Python interoperativity (theory)
Which of the following statements regarding embedding/using Python code in Julia with 'PyCall.jl' or embedding/using Julia code in Python with 'PyJulia' are correct ?
RESOLUTION
The only wrong statement is the one concerning the environmental variable. If we use ENV["PYTHON"] = ""
we force Julia to use a private version of Python, and so we can't use our default system installation. If we want to use our system default Python installation in Julia we should use ENV["PYTHON"] = "/path/to/python"
instead.
The correct answers are:
- We can use Python code in Julia with the macro
@pyinclude "pythonScript.py"
- We can use Python code in Julia employing the string macro
py"...."
- We can use the syntax
obj.method()
on imported Python objects - We can import Python modules with
pyimport("moduleName")
- In Python, once we have imported the Julia module we want to work with using
PyJulia
, we can call the functions of that module directly asjuliaModule.juliaFunction()
Q4: Calling Python code
Given the following code snippet:
using PyCall
py"""
def getIJElement (matr,i,j):
return matr[i][j]
"""
a = py"getIJElement"([1 2 3; 4 5 6],1,2) # method "a" to call getIJElement()
b = py"getIJElement(XXXX)" # method "b" to call getIJElement()
and assuming the two "methods" return the same value, which of the following sentences are correct?
RESOLUTION
The first method ("a") uses Julia objects that are then "converted" to Python objects. Still the indexing happens in Python and so it uses the Python "rules" and the output is '6'. Method "b" is an evaluation of all Python code, there is no Julia methods there. So we need to write the matrix in the Python way and use Python list syntax (of course, if we don't want to use Numpy arrays instead).
The correct answers are:
- The returned value is
6
XXXX
should be replaced with[[1,2,3],[4,5,6]],1,2
for the assumption to hold- The method "a" calls the Python function with Julia objects that are converted by PyCall
- The method "b" calls the Python function with Python objects
Q5: R interoperativity (theory)
Which of the following statements regarding embedding/using R code in Julia with RCall.jl
or embedding/using Julia code in R with JuliaCall
are correct ?
RESOLUTION
Concerning the wrong answers: (1) The settings for the relevant environmental variables (ENV["PYTHON"]
in Python, ENV["R_HOME"]
for R) to force a private copy or Python or R is the opposite as the ones given in the statement; (2) while Julia objects are automatically converted to R Objects, the opposite requires a passage trough the rcopy()
function; (3) in R, even after we imported a Julia module, we still need to wrap its functions in julia_call("julia_function",args)
calls (or use julia_eval()
).
The correct answers are:
- The objects returned by R must be "converted" to Julia objects explicitly
- On each R session we need to run the
julia_setup
function before we can have access to Julia code