Oooh, now I think I get it, we use multiple dispatch to make a simple 
wrapper that does the mapping. I went down the path yesterday of trying to 
make my complex setup function into a @generated function (because :new 
isn't available on the first pass at compile time) and ran into too many 
data and type dependencies to be happy. However, in the case that you are 
describing the macro land only occurs in a simple wrapper/mapping function. 
I'll work on prototyping this when I get stuck next on the main part of my 
code.
I actually implemented it by hand (because it is all known ahead of time) 
yesterday afternoon. There are literal walls of assignment statements so I 
need to revisit this.

Thanks 
-Sloan

On Thursday, October 22, 2015 at 8:05:33 AM UTC-7, Yichao Yu wrote:
>
> On Thu, Oct 22, 2015 at 10:55 AM, Dan <get...@gmail.com <javascript:>> 
> wrote: 
> > Oops, random click on post. 
> > So: 
> > function MyType(..) 
> > : 
> > : 
> >     fieldvalues = Any[val1,val2,val3] 
> >   fnames = fieldnames(MyType) 
> >   for i=1:length(fnames) 
> >     setfield!(newobj,fname[i],fieldvalues[i]) 
> >   end 
> >   return newobj 
> > end 
>
> This doesn't work for immutables 
>
> Just to follow up on my mention of @generated in the original issue. 
> Adding a inner constructor like the following (and calling this 
> constructor instead of new) should work (although I also agree it's 
> not a great idea to construct Expr(:new) manually) 
>
> ``` 
> @generated Positive_Vec(args...) = 
>                Expr(:new, Positive_Vec, [:(args[$i]) for i in 
> 1:length(args)]...) 
> ``` 
>
> Also note that apply(f, args) is always equivalent to f(args...) so 
> you don't need to use it in any case. 
>
> > 
> > On Thursday, October 22, 2015 at 5:52:34 PM UTC+3, Dan wrote: 
> >> 
> >> the inner constructor, can separate allocation and initialization of a 
> new 
> >> object. specifically, first do a: 
> >>     newobj = new() 
> >> then you can set the fields. with a loop this can look like: 
> >>   fieldvalues = Any[val1,val2,val3] 
> >> 
> >> 
> >> On Thursday, October 22, 2015 at 4:14:51 PM UTC+3, Sloan Lindsey wrote: 
> >>> 
> >>> I am trying to make some nice inner constructors for an immutable that 
> >>> acts as a nice container. I've run into a bit of a problem with using 
> the 
> >>> new constructor since I wish to have dynamic construction to avoid 
> having to 
> >>> hardcode the hierarchy. 
> >>> 
> >>> 
> >>> #apply new troubles 
> >>> 
> >>> 
> >>> immutable Vec3 
> >>>   x::Float64 
> >>>   y::Float64 
> >>>   z::Float64 
> >>> end 
> >>> 
> >>> 
> >>> immutable Min_Discription 
> >>>   postion::Array{Vec3} 
> >>>   valid::Bool 
> >>>   angry_butter_fly_quotient::Float64 
> >>> end 
> >>> 
> >>> 
> >>> immutable Positive_Vec 
> >>>   position::Array{Vec3} 
> >>>   positive::BitArray 
> >>>   valid::BitArray 
> >>>   angry_butter_fly_quotient::Array{Float64} 
> >>> 
> >>> 
> >>>   function Positive_Vec(elves::Array{Min_Discription}) 
> >>>     size = length(elves) 
> >>>     #automagically initialize all the data! 
> >>>     defaults=((Type{Array{Vec3}},Vec3,null_pos), 
> >>>               (Type{Array{Int}},Int, -1), 
> >>>               (Type{BitArray},Bool,false), 
> >>>               (Type{Array{Float64}},Float64, -Inf)) 
> >>> 
> >>> 
> >>>       data_types = [fieldtype(Positive_Vec,x) for x in 
> >>> fieldnames(Positive_Vec)] 
> >>>       declare_list = Array(Any,length(data_types)) 
> >>> 
> >>> 
> >>>       for i in 1:length(data_types) 
> >>>         for (d_type,primitive, default) in defaults 
> >>>           if d_type == data_types[i] 
> >>>             if d_type != Type{BitArray} 
> >>>               declare_list[i] = Array(primitive, size) 
> >>>               fill!(declare_list[i], default) 
> >>>             else 
> >>>               declare_list[i] = BitArray(size) 
> >>>               fill!(declare_list[i], default) 
> >>>             end 
> >>>           end 
> >>>         end 
> >>>       end 
> >>>       #defaults populated. Now overwrite data passed in 
> >>>       for entry in fieldnames(Min_Discription) 
> >>>         for (name,index) in enumerate(fieldnames(Positive_Vec)) 
> >>>           if entry==name 
> >>>             for (elf,i) in enumerate(elves) 
> >>>               declare_list[index][i]=elf.(entry) 
> >>>             end 
> >>>           end 
> >>>         end 
> >>>       end 
> >>>       #now we worry about a few special cases 
> >>> 
> >>> 
> >>> 
> >>> 
> >>>       for (symbol, index) in enumerate(fieldnames(Positive_Vec)) 
> >>>         name = string(symbol) 
> >>>         if name=="positive"       # set the size of the structure 
> >>>           for i in 1:length(elves) 
> >>>             declare_list[index][i] = elves[i].position.z>0.0 
> >>>           end 
> >>>         end 
> >>>       end 
> >>>       return new(declare_list...)#apply(new, declare_list) 
> >>>     end 
> >>> 
> >>> 
> >>> end 
> >>> 
> >>> 
> >>>   a = Min_Discription(Vec3(0.0,0.0,0.0),true,73.27113) 
> >>>   b = Min_Discription(Vec3(0.0,0.31,1.0),true,892.73165) 
> >>>   c = Min_Discription(Vec3(0.8364,7.4,500.0),true,4.0) 
> >>> 
> >>> 
> >>>   elves = Array(Min_Discription,3) 
> >>>   elves[1],elves[2],elves[3]= a,b,c 
> >>>   Positive_Vec(elves) 
> >>> 
> >>> 
> >>> 
> >>> julia> include("apply_new_troubles.jl") 
> >>> ERROR: LoadError: syntax: ... is not supported inside "new" 
> >>>  in include at boot.jl:261 
> >>>  in include_from_node1 at loading.jl:304 
> >>> 
> >>> trying to use apply(new, declare_list) doesn't work either. 
> >>> 
> >>> I'm being pointed towards making a an expression and doing some macro 
> >>> things over here: 
> >>> https://github.com/JuliaLang/julia/issues/13700#issuecomment-149861728 
> >>> and the developers actually told me this was a use question so I'm 
> here. 
> >>> 
> >>> In summary is there a good way to dynamically describe an inner 
> >>> constructor in julia? 
> >>> 
> >>> Presently, I'm thinking of something to emulate the missing splat 
> >>> functionality (whether it be interpolation or some @generated code), 
> Or even 
> >>> moving the entire generation part into a macro, since all the dynamic 
> parts 
> >>> are known at compile time (I simply wish to avoid a wall of hardcoded 
> >>> variables that will be difficult to maintain). 
> >>> Are there other avenues to follow? I would prefer to keep the 
> functions 
> >>> attached to the constructor as this facilitates code clarity. 
> >>> 
> >>> Any assistance or advice would be appreciated. 
>

Reply via email to