> something's probably wrong. Like this macro assuming you want to disable optimization of your code and only work in the global scope without modules.
I maintain my recommendation of using an immutable type (which allows llvm to do some additional optimizations) and making a single local variable with a shorter name for typing repeatedly. The only feature somewhat unique to Visual Basic that I liked is the with block , which is similar to what you are asking. I would love to have this syntax in Julia too, but I'm not sure it is possible/a good idea. Since it is just a source transform, it should avoid Stefan's note about the compile/runtime distinction error. On Monday, June 9, 2014, Stefan Karpinski <[email protected]> wrote: > Any time there's an eval in what your macro emits, something's probably > wrong. In this case, however, you can't really avoid it – largely because > you can't do this correctly. The trouble is that the type of the object you > want to bind the fields of is a runtime property, but you want to bind > variables based on it – which is a compile-time property. > > > On Mon, Jun 9, 2014 at 12:55 PM, Nathaniel Nicandro < > [email protected] > <javascript:_e(%7B%7D,'cvml','[email protected]');>> wrote: > >> Oh, yes I see that now. Then what you could do is quote the call to >> names() in your macro expression so the names call is executed in the >> calling environment. >> >> macro fetch(p) >> return quote >> local vars = names($p) >> local ex = Expr(:block) >> append!(ex.args, [:($v = $p.$v) for v in vars]) >> eval(ex) >> end >> end >> >> This is similar to what yo have done at the REPL but it quotes the >> names() call so it can get evaluated in the macro calling environment >> instead of within the macro itself. ex = Expr(:block) is just another >> quote block with a list of expressions to evaluate in ex.args. Note that >> there is no need to use esc() here because the eval() call happens in the >> calling environment. >> >> >> On Monday, June 9, 2014 10:18:13 AM UTC-5, Andrew Simper wrote: >>> >>> Yes thanks for pointing that out, but if you look at this thread I >>> already got some help with the |> esc for this type of thing over on >>> another thread https://groups.google.com/forum/#!topic/julia-users/ >>> UvBff9QVKaA , but I started this thread specifically to find out how to >>> get write a macro using names(obj) to do the work instead of having to >>> write a new fetch macro manually every time I create a new type. >>> >>> On Monday, June 9, 2014 11:04:12 PM UTC+8, Nathaniel Nicandro wrote: >>>> >>>> You can use the esc >>>> <http://julia.readthedocs.org/en/latest/stdlib/base/?highlight=esc#Base.esc> >>>> function >>>> that can introduce variables in the calling environment >>>> >>>> julia> type Point >>>> x >>>> y >>>> end >>>> >>>> julia> macro fetch(p) >>>> variables = quote >>>> x = $p.x >>>> y = $p.y >>>> end >>>> return esc(variables) >>>> end >>>> >>>> julia> p = Point(5, 10) >>>> Point(5,10) >>>> >>>> julia> x >>>> ERROR: x not defined >>>> >>>> julia> y >>>> ERROR: y not defined >>>> >>>> julia> @fetch p; >>>> >>>> julia> x >>>> 5 >>>> >>>> julia> y >>>> 10 >>>> >>>> >>>> >>>> On Saturday, June 7, 2014 2:35:59 AM UTC-5, Andrew Simper wrote: >>>>> >>>>> A lot of the time it is good to copy a structure to local variables >>>>> and then process on those for efficiency before storing the local values >>>>> back to a structure. To help out with this I'm trying to write a macro, >>>>> so >>>>> this is what I would like the end result to be: >>>>> >>>>> Point >>>>> x::Float64 >>>>> y::Float64 >>>>> end >>>>> >>>>> function process (p::Point) >>>>> local x = p.x; >>>>> local y = p.y; >>>>> # do some processing on x and y >>>>> p.x = x >>>>> p.y = y >>>>> end >>>>> >>>>> and I would like write a macro that does this so the end code would >>>>> like like: >>>>> >>>>> function process (p::Point) >>>>> @fetch p >>>>> # do some processing on x and y >>>>> @store p >>>>> end >>>>> >>>>> So far I've got this working at the REPL using: >>>>> >>>>> point = Point (1, 2) >>>>> map (eval, ([:($name = point.$name) for name in names(point)])) >>>>> println("x=$(x) y=$(y)") >>>>> >>>>> which prints out: x=1.0 y=2.0 >>>>> >>>>> Can someone please help out turning this into a macro? >>>>> >>>>> >
