World Age Problem Explanation


#1

Hello.

Recently I have faced the “world age problem” several times. That means, after searching for my problems, this website came up with themes like “world age workaround” or “How to Bypass the World Age Problem”.
I am not a computer scientist, so maybe this is a stupid question, but I have not found a explanation of this problem; where can I get information what actually happens there? Or, more clearly, what is the “World Age Problem”?
As you can imagine, if I google this, I get a lot of information about our Earth’s age…

I am not absolutely sure, if this topic fits the “Usage” category. So if I should have decided another part of this board, I apologize for this.

Thank you in advance.
LS64


#2

How to Bypass the World Age Problem does have some information
Seems to be to do with redeclaring functions and/or the order they are defined in, and using eval / @eval


#3

Thank you for this information. I’ve read some pages and maybe, I get an idea.

But I need a starting point to understand this issue completely and want to be sure, that I’ve understood this correctly. Can someone please revise or confirm the following?

Every compilation of a function gets a “time stamp”, here known as world age. If I change dependencies to already compiled functions in a new world and execute my code, I get these errors? (In my case, these functions are parts of packages (e.g. Plots), which heightens the level of complexity to me.)
So, in the end, it is precompilation/recompilation problem, which I can solve by using eval, because @eval forces a new compilation in the latest world (by letting jl_toplevel_eval_flex() decide again, what to do)?


#4

The reason for worlds is because of optimizations. If functions can be defined (and redefined) at arbitrary points (and instantly take effect), then that would limit the possible optimizations that can be made. Therefore, new functions are only made visible to the system (become usable) after hitting toplevel. If you try to call a new function before this, then you get a world error.

In some cases (like if you are writing a REPL), you do actually want to call your newly defined function without hitting toplevel. This can be done by using Base.invokelatest(f, args...) but it will of course prevent certain optimizations in the scope where f is called (it can pretty much not be reasoned about at all, so no inlining or inference).


#5

Check out "running in world age X, while current world is Y" errors for another explanation.


#6

You might also want to share a minimal working example (MWE) of your code. In my experience, world age issues are rather uncommon and perhaps you are using eval in cases where you shouldn’t.


#7

Thank you very much for your answer, kristoffer.carlsson. This helps me a lot.

I will take a closer look at this whole theme on the weekend; especially at your link, mbauman.

If errors related to world age continue to appear, I will let you know and share my code. At the moment, I just want to understand the point in general.

Thank you all!


#8

I would add that requiring modifications to dispatch to take effect immediately is one of those classic behaviors in dynamic languages that makes them hard/impossible to compile without heroic efforts (along with reified local scopes, the ability to add state to objects dynamically at any point, etc. – we should make a list some time). In Julia we’re nipping that one in the bud by defining the language to work in a way that can be implemented in the presence of compilation without insane contortions, namely with world ages that only take effect at the top-level, just the way that @kristoffer.carlsson described.


#9

Seel also here for a detailed explanation, and here for an explanation of invokelatest.

It would be nice to have something about this in the manual at some point…