Stream: helpdesk (published)

Topic: ✔ Capturing types of variables within a macro


view this post on Zulip Mason Protter (Jun 03 2022 at 23:06):

No, you cannot do this

view this post on Zulip Mason Protter (Jun 03 2022 at 23:07):

The only real way is with a generated function

view this post on Zulip Mason Protter (Jun 03 2022 at 23:08):

e.g.

macro foo(expr)
     some_data = extract_info(expr)
     :($foo($some_data))
end

@generated function foo(some_data::T) where {T}
    # code generation dending on T here
end

view this post on Zulip Brenhin Keller (Jun 03 2022 at 23:24):

Huh, bummer.

view this post on Zulip Brenhin Keller (Jun 03 2022 at 23:24):

It's funny because it doesn't seem that hard

view this post on Zulip Brenhin Keller (Jun 03 2022 at 23:25):

But I guess that explains why the @ccall macro makes you manually annotate the types of everything rather than being able to just figure them out itself

view this post on Zulip Notification Bot (Jun 03 2022 at 23:25):

Brenhin Keller has marked this topic as resolved.

view this post on Zulip Mason Protter (Jun 04 2022 at 02:34):

You can check with @macroexpand.

julia> @macroexpand @code_typed sin(1.0)
quote
    local var"#1263#results" = InteractiveUtils.code_typed(sin, (Base.typesof)(1.0))
    if InteractiveUtils.length(var"#1263#results") == 1
        var"#1263#results"[1]
    else
        var"#1263#results"
    end
end

That is, it just becomes code_typed(sin, (Base.typesof)(1.0))

view this post on Zulip Mason Protter (Jun 04 2022 at 02:34):

I only brought up generated functions because @Brenhin Keller wanted the code generation itself to depend on the types

view this post on Zulip Notification Bot (Jun 04 2022 at 02:35):

Brenhin Keller has marked this topic as resolved.

view this post on Zulip Brenhin Keller (Jun 09 2022 at 07:42):

Ok, so turns out there is also Core.eval, which @static uses in a very similar context... I wonder if anything makes this unsafe:

macro static_types(expr)
    argtypes = ntuple(i->typeof(Core.eval(__module__, expr.args[i+1])), length(expr.args)-1)
    :($argtypes)
end
julia> a,b,c = ones(2), 3.0, false
([1.0, 1.0], 3.0, false)

julia> @static_types f(a,b,c)
(Vector{Float64}, Float64, Bool)

view this post on Zulip Sukera (Jun 09 2022 at 07:44):

unsafe in what regard?

view this post on Zulip Sukera (Jun 09 2022 at 07:44):

that still just looks up the argument in global scope

view this post on Zulip Brenhin Keller (Jun 09 2022 at 07:44):

Dunno, I was just always told "you're not supposed to use evalin a macro"

view this post on Zulip Sukera (Jun 09 2022 at 07:44):

so I think the macro only works in global scope

view this post on Zulip Sukera (Jun 09 2022 at 07:45):

yeah, but that's because evaling the code created by the macro is redundant when you can just return the expression from the macro in the first place

view this post on Zulip Brenhin Keller (Jun 09 2022 at 07:50):

I guess it pretty much has the same limitations @static does

view this post on Zulip Brenhin Keller (Jun 09 2022 at 07:52):

Works fine in a module but only works off variables in the global scope of that module

view this post on Zulip Brenhin Keller (Jun 09 2022 at 07:53):

Still could be useful for some things (the difference from just returning from the macro being you can know earlier in compilation pipeline, so can interpolate into an llvmcall, etc.)

view this post on Zulip Mason Protter (Jun 10 2022 at 01:06):

@Brenhin Keller all the problems with @eval here apply to Core.eval.

view this post on Zulip Mason Protter (Jun 10 2022 at 01:07):

In fact,

julia> @macroexpand1 (@eval Foo bar)
:(Core.eval(Foo, :bar))

view this post on Zulip Mason Protter (Jun 10 2022 at 01:09):

But yeah, there are contexts where eval is fine to use in a macro. Anything that is supposed to be evaluated when the code is parsed and doesn't actually depend on runtime or compile time info is fine. It's just something that's commonly misused

view this post on Zulip Brenhin Keller (Jun 10 2022 at 01:21):

Yeah, that makes sense

view this post on Zulip Brenhin Keller (Jun 10 2022 at 01:21):

thanks!


Last updated: Oct 02 2023 at 04:34 UTC