Macro problem with v0.6

The following macro (which is used in a wrapper for a C library) is no longer working with Julia v0.6. Does anyone have an idea how to fix that?

macro ArrayToVector(ctype, data)
    return :( convert(Vector{$ctype}, vec($data)) )
end

function myfunc(data)
  _data = [ Float32(x) for x in data ]
  println(@ArrayToVector(Float32, _data))
end

data = randn(10,10)
myfunc(data)

The error is:

ERROR: LoadError: UndefVarError: _data not defined
Stacktrace:
 [1] myfunc(::Array{Float64,2}) at /Users/jheinen/Home/Developer/GR.jl/src/t.jl:7
 [2] include_from_node1(::String) at ./loading.jl:532
 [3] include_from_node1(::String) at /usr/local/Applications/Julia-0.6.app/Contents/Resources/julia/lib/julia/sys.dylib:?
 [4] include(::String) at ./sysimg.jl:14
 [5] include(::String) at /usr/local/Applications/Julia-0.6.app/Contents/Resources/julia/lib/julia/sys.dylib:?
 [6] process_options(::Base.JLOptions) at ./client.jl:308
 [7] _start() at ./client.jl:374
 [8] _start() at /usr/local/Applications/Julia-0.6.app/Contents/Resources/julia/lib/julia/sys.dylib:?
while loading /Users/jheinen/Home/Developer/GR.jl/src/t.jl, in expression starting on line 11

Probably it will suffice to escape the arguments, i.e.

macro ArrayToVector(ctype, data)
    return :( convert(Vector{$(esc(ctype))}, vec($(esc(data)))) )
end

This change is required because a macro hygiene bug when a macro is used in its own module has been fixed in 0.6.

@fengyang.wang : Thanks a lot !

Is there a reason not to just use a standard function for this? A macro does not seem to be necessary at a glance.

1 Like

I’m trying to use the same wrapper code vor Julia v0.4, v0.5 and v0.6. This is another example I’m struggling with:

V = randn(10,10)
values = round.(UInt16, (V-minimum(V)) / (maximum(V)-minimum(V)) * (2^16-1))

Works fine with 0.5 and 0.6, but not with 0.4. I tried something like:

values = UInt16[round(UInt16, (_-minimum(_)) / (maximum(_)-minimum(_)) * (2^16-1)) for _ in V]

… but this leads to an InexactError()

This has some bugs (you are computing the minimum and maximum of the individual elements, not of the whole array). I think you want something like

function foo(V)
    m = minimum(V)
    s = typemax(UInt16) / (maximum(V) - m) 
    return [round(UInt16, (v-m) * s) for v in V]
end

Should have taken a closer look - thanks a lot

This is a bit more efficient since it computes the extrema in a single pass:

function foo(V)
    m, M = extrema(V)
    s = typemax(UInt16)/(M-m) 
    return [round(UInt16,(v-m)*s) for v in V]
end

Thanks, Good to know that there is something like extrema()