@@ -265,6 +265,119 @@ Julia its ability to abstractly express high-level algorithms decoupled
265265from implementation details, yet generate efficient, specialized code to
266266handle each case at run time.
267267
268+ Redefining Methods
269+ ------------------
270+
271+ When redefining a method or adding new methods,
272+ it is important to realize that these changes don't take effect immediately.
273+ This is key to Julia's ability to statically infer and compile code to run fast,
274+ without the usual JIT tricks and overhead.
275+ Indeed, any new method definition won't be visible to the current runtime environment,
276+ including Tasks and Threads, or any previously defined ``@generated `` functions.
277+ Let's start with an example to see what this means::
278+
279+ julia> function tryeval()
280+ @eval newfun() = 1
281+ newfun()
282+ end
283+ tryeval (generic function with 1 method)
284+
285+ julia> tryeval()
286+ ERROR: MethodError: no method matching newfun()
287+ The applicable method may be too new: running in world age xxxx1, while current world is xxxx2.
288+ Closest candidates are:
289+ newfun() at none:1 (method too new to be called from this world context.)
290+ in tryeval() at none:1
291+ ...
292+
293+ julia> newfun()
294+ 1
295+
296+ In this example, observe that the new definition for ``newfun `` has been created,
297+ but can't be immediately called. Future calls to ``newfun `` from the REPL work as expected.
298+ But future calls to ``tryeval `` will continue to see the definition of ``newfun `` as it was
299+ *at the previous statement at the REPL *. You may want to try this for yourself to see how it works.
300+
301+ The world age counter is a monotonically increasing value that tracks each delayed operation.
302+ This allows describing "the set of method definitions visible to a runtime environment"
303+ as simply a number.
304+ It also allows comparing the methods available in two worlds just by comparing their ordinal value.
305+ In the example above, we see that the "current world" (in which the method ``newfun() `` exists),
306+ is one greater than the runtime world that was fixed when the execution of ``tryeval `` started.
307+
308+ Sometimes it is necessary to get around this (for example, if you are implementing the above REPL).
309+ Well, don't despair, since there's an easy solution: just call ``eval `` a second time.
310+ For example, here we create a zero-argument closure over ``ans `` and ``eval `` a call to it:
311+
312+ .. doctest ::
313+
314+ julia> function tryeval2()
315+ ans = (@eval newfun2() = 1)
316+ res = eval(Expr(:call,
317+ function()
318+ return ans() + 1
319+ end))
320+ return res
321+ end
322+ tryeval2 (generic function with 1 method)
323+
324+ julia> tryeval2()
325+ 2
326+
327+ Finally, let's take a look at some more complex examples where this rule comes into play.
328+
329+ .. doctest ::
330+
331+ julia> # initially f(x) has one definition:
332+
333+ julia> f(x) = "original definition";
334+
335+ julia> # start some other operations that use f(x):
336+
337+ julia> g(x) = f(x);
338+
339+ julia> t = @async f(wait()); yield();
340+
341+ julia> @generated gen1(x) = f(x);
342+
343+ julia> @generated gen2(x) = :(f(x));
344+
345+ julia> # now we add some new definitions for f(x):
346+
347+ julia> f(x::Int) = "definition for Int";
348+
349+ julia> f(x::Type{Int}) = "definition for Type{Int}";
350+
351+ julia> # and compare how these results differ:
352+
353+ julia> f(1)
354+ "definition for Int"
355+
356+ julia> g(1)
357+ "definition for Int"
358+
359+ julia> wait(schedule(t, 1))
360+ "original definition"
361+
362+ julia> t = @async f(wait()); yield();
363+
364+ julia> wait(schedule(t, 1))
365+ "definition for Int"
366+
367+ julia> gen1(1)
368+ "original definition"
369+
370+ julia> gen2(1)
371+ "definition for Int"
372+
373+ julia> # each method of a generated function has its own view of defined functions:
374+
375+ julia> @generated gen1(x::Real) = f(x);
376+
377+ julia> gen1(1)
378+ "definition for Type{Int}"
379+
380+
268381Method Ambiguities
269382------------------
270383
0 commit comments