I'm working with arrays of immutables each containing several fields. Now 
creating new immutables based on old ones has become a real pain:

old = myarray[i]
myarray[i].foo = myimmutable(old.foo, bar, old.x, old.y, etc.)

imagine this for 15 fields...!

So I made a macro to ease this, it can be used like this:

@set myarray i bar=newbar x=newx

and the rest of the parameters remain the same. See code below.

The problem is that although I can autogenerate the macro for different 
types, I cannot use the same function name @set for all types. Each type 
has to have its own special macro!

The reason is that this macro requires knowledge of the types it is working 
on, something missing at macro "runtime". While stagedfunctions do have 
type information, they miss the array symbol name.

Maybe a "stagedmacro" could help ;)

Do you know how could this be solved? 

Thanks!

immutable IM
    aa::Float64
    bb::Float64
    cc::Float64
    dd::Float64
    ee::Float64
    ff::Float64
    gg::Float64
    hh::Float64
    ii::Float64
    jj::Float64
    kk::Float64
    ll::Float64
end

macro set(ARR, IX, KV...)
    d = [p.args[1]=>p.args[2] for p in KV]
    aa = get(d,:aa,:($ARR[$IX].aa))
    bb = get(d,:bb,:($ARR[$IX].bb))
    cc = get(d,:cc,:($ARR[$IX].cc))
    dd = get(d,:dd,:($ARR[$IX].dd))
    ee = get(d,:ee,:($ARR[$IX].ee))
    ff = get(d,:ff,:($ARR[$IX].ff))
    gg = get(d,:gg,:($ARR[$IX].gg))
    hh = get(d,:hh,:($ARR[$IX].hh))
    ii = get(d,:ii,:($ARR[$IX].ii))
    jj = get(d,:jj,:($ARR[$IX].jj))
    kk = get(d,:kk,:($ARR[$IX].kk))
    ll = get(d,:ll,:($ARR[$IX].ll))
    quote
        @inbounds $ARR[$IX] =
            IM($aa,$bb,$cc,$dd,$ee,$ff,$gg,$hh,$ii,$jj,$kk,$ll)
    end
end

this is used as follows:

a = [IM(1,1,1,1,1,1,1,1,1,1,1,1),
     IM(1,1,1,1,1,1,1,1,1,1,1,1),
     IM(1,1,1,1,1,1,1,1,1,1,1,1),
     IM(1,1,1,1,1,1,1,1,1,1,1,1),
     IM(1,1,1,1,1,1,1,1,1,1,1,1)]

@set a 1 aa=9 ll=9

# a is now:
# [

# IM(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0)
# IM(9.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,9.0)
# IM(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0)
# IM(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0)
# IM(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0)]





Reply via email to