Indeed, measuring compile time is a difficult thing to do. I detailed my misadventures with it in this post.
The runtime of this function is basically instantaneous, which you can confirm using @btime
(a proper measurement will show single-digit nanoseconds)—so even though compile time and runtime are inseparable, the runtime is negligible in this measurement.
I force Base.Fix1
to recompile by redefining the anonymous function every time. You can see that it’s a new function each time:
julia> f = (x,y) -> x+y; (f, typeof(f))
(var"#1#2"(), var"#1#2")
julia> f = (x,y) -> x+y; (f, typeof(f))
(var"#3#4"(), var"#3#4")
julia> f = (x,y) -> x+y; (f, typeof(f))
(var"#5#6"(), var"#5#6")
This makes anonymous functions an excellent stimulus for measuring these compile times, because a new anonymous function will have a different type despite behaving exactly the same as before.
Chain.jl has been a huge inspiration for how this proposal should work. I pretty much copypasted it in imagining the behavior of --
call chain syntax, except that I decided to localize variable scope within the chain using let
statements instead of making unique variables at the parent scope with gensym
. This enables me to use it
as a local keyword, but it makes it difficult to create side-effects except by calling functions which have side-effects.