On Thu, Oct 22, 2015 at 10:55 AM, Dan <getz...@gmail.com> 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