References to variables: When might precompile fail?


After migrating to Julia 1.0, I started having issues with code hanging when it loads (unless I add @show statements to un-jam Julia somehow).

I suspect the issue might have been triggered either the by the changes in the new package manager, or the changes in the pre-compilation system. My code seems to hang when I @eval(import MyPackage) - unless I @show() something between this call, and the previous import operations.

NOTE: My libraries are typically stored in my work folder, then added to Julia’s LOAD_PATH. I mention this because I have seen a few instances in Juila v1.0 when these libraries do not behave exactly the same as those managed by Julia itself (stored under the ~/.julia directory).

Looking into precompilation

I looked at the Module initialization and precompilation section of the docs.

I never noticed this before, but it appears to say that issues might occur when:

Creating accidental “copies” of global state from another module, by referencing it directly instead of via its lookup path. For example, (in global scope):

#mystdout = Base.stdout #= will not work correctly, since this will copy Base.stdout into this module =#
# instead use accessor functions:
getstdout() = Base.stdout #= best option =#
# or move the assignment into the runtime:
__init__() = global mystdout = Base.stdout #= also works =#


  1. I often prefer creating “aliases” for variables used in other modules. I was wondering if the following was still safe with precompilation:
import Base: stdout
  1. Is there a simpler way to get shorthand aliases for objects in other modules, for example:
import Base: Multimedia.displays as disp

…because I presume we should not do the following anymore from within one of our modules:

const disp = Base.Multimedia.displays
  1. Can we still create shorthand aliases for data types using the following?:
const ADisplay = Base.Multimedia.AbstractDisplay

…I ask, because I often find it useful to create aliases for base data types:

const DataFloat = Float64 #Might want to change this in the future.

don’t know why this is a problem, but why would you do this, as opposed to simply

import ThatPackage


Good point. I tried using import MyPackage instead. I get the same issue.

For the sake of completeness:

I use @eval(import MyPackage) so I can conditionally include my plotting backend, depending on my ~/.juliarc.jl settings.

It should be relatively safe to do this, because it is now evaluated in the user’s own “script” file - not the module that I am distributing.

So, in theory, there is no reason why my own package should not properly precompile/run (I think)… because the conditional code is not being used from a pre-compilable module… and I have now confirmed that I get the same issue when I remove the conditional part, and hard-code the import statement. It was definitely worth testing this.