Variable scoping in macros: Deprecated syntax `implicit assignment to global variable`


#1

I’m running into a deprecation when running the test/perf/micro benchmarks in 0.7-DEV. The issue is implicit declaration and assignment of global variables in the @timeit macro in test/perf/perfutils.jl. Here it is boiled down to a minimal working example:

ulia> macro timeit(ex)
           quote
               t = Float64[]  # no problem!
               tot = 0.0      # deprecated! 
               i = 0          # deprecated! 
               while i < 5 || tot < 0.0001
                   e = 1000*(@elapsed $(esc(ex)))
                   tot += e
                   if i > 0
                       # warm up on first iteration
                       push!(t, e)
                   end
                   i += 1
               end
               @show tot, t
           end
       end
@timeit (macro with 1 method)

julia> expression = Meta.parse("x=2; y=3; x+y")
:($(Expr(:toplevel, :(x = 2), :(y = 3), :(x + y))))

julia> @timeit(expression)
┌ Warning: Deprecated syntax `implicit assignment to global variable `#2#tot``.
│ Use `global #2#tot` instead.
└ @ nothing none:0
┌ Warning: Deprecated syntax `implicit assignment to global variable `#3#i``.
│ Use `global #3#i` instead.
└ @ nothing none:0
(tot, t) = (0.00020499999999999997, [1.6e-5, 6.3e-5, 2.1e-5, 2.0e-5])
(0.00020499999999999997, [1.6e-5, 6.3e-5, 2.1e-5, 2.0e-5])

julia> versioninfo()
Julia Version 0.7.0-DEV.3234
Commit 2cc82d29e1* (2018-01-02 11:44 UTC)
Platform Info:
  OS: Linux (x86_64-suse-linux)
  CPU: Intel(R) Core(TM) i7-3960X CPU @ 3.30GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, sandybridge)
Environment:

Is there a good way to force a local scope inside the macro in order to suppress the warning? Or should this be accomplished by turning the macro into a function? Or is a macro necessary to avoid overhead in timing the evaluating the expression?

Any help appreciated.


#2

How about wrapping everything in a let block e.g.

quote
    let
        ...
    end
end

Ideally, the perf benchmarks should just be rewritten to use BenchmarkTools though.


#3

That does the job. Thank you. (I’d tried begin ... end and C-style enclosing braces. Still learning Julia basics…)

About updating to BenchmarkTools, should I take that as an order? :slight_smile: I wasn’t sure if the non-use of BenchmarkTools was just historical, or if it was to maximize transparency and similarity to timing algorithms in other languages.