Help interpolating a symbol

metaprogramming

#1

I am trying to make a value that does the following

var = :x1
@replace_name var = 4

I am trying to start to figure this out by doing a macro like this:

macro repname(y,body)
       body.args[1] = y
       esc(body)
end

To try and get the expression

@repname :y x = 4
> y = 4

But I can’t even do this! Only @repname y x = 4 works.

Any help in this metaprogramming problem is appreciated. Thanks.


#2
macro repname(y,body)
    body.args[1] = ((typeof(y) == Expr) && (y.head == :quote)) ? y.args[1] : y
    esc(body)
end

julia> @repname y x = 4
4

julia> @repname :y x = 4
4

#3

Thank you! is there any way to access the non-interned string kind of symbol other than by assembling an expression and looking at the arguments?

Any idea how to get to the last step? Of using a variable bound to a symbol to create a new variable?


#4

That case is different, because the AST for it is equivalent to Expr(:quote, :y), which is why you cannot assign a value to it. You have to remove the quote layer to get the Symbol, to which you can assign a value.


#5

There are a few ways you can do it but it is in general not something you should do in a macro. You need to be more specific on why you want to access a variable in the caller’s scope from a macro.


#6

I’m trying to do something for DataFramesMeta, enabling the user to put dataframes commands inside functions.

function dotransformations(df, newvar::Symbol)
    @transfrom(newvar = 100)
end

@transform commands look like this

@transform(df, y #= no symbol, means make a new column in df =# 
          = :x1 + :x2 #= symbols reference columns of df =#). 

I want some sort of small function g() such that when DataFramesmeta examines each keyword argument, if var = :y, it replaces g(var) = :x1 + :x2 with y = :x1 + :x2. The way to do this is to inspect the expression and make a manual replacement when the expression looks like :call, :g, :var etc.


#7

No that’s impossible. The macro cannot access any runtime variables. You need an API that allows you to provide such information at runtime or you can’t do it.


#8

Isn’t DataFramesMeta already doing that though?

If you have a variable that is bound to a symbol, you can do the replacement _I(var) -> :y. And that works. Why is the alternative _g_(var) -> y so much different?


#9

Well, I don’t use those so I don’t know what exactly replacement you are talking about. I’m not saying that what you want can’t be done in a different way. However, you cannot do that by translating into the @transform macro call (edit: or more specifically, the exact thing you asked about original wasn’t possible, that’s exactly why I asked what you actually want to do. Ref https://en.wikipedia.org/wiki/XY_problem) since AFAICT it gets the name from compile time info and your name is only available at runtime. Assuming the @transform macro is just a wrapper for DataFrame you just

In another word, they are not much different, I’m just saying you can’t use one to implement another. Both could be implementable.