Thanks, lots of helpful stuff here. It's nice that this was being
considered for inclusion by default. I will investigate not using abstract
field types. I also like the idea to just use multiple subtypes, which
would be good for organization especially if the model got more complex.
Greg, I like your macro. It helped me understand metaprogramming some more.
Also, the use of a function which defines the parameters explicitly is very
similar to how I do this in MATLAB.
I do have one question on your code for the macro. You write [ :($field)
for field in names(eval(T)) ]. I played around with this and got
In [225]:
[ :($field) for field in names(eval(Parameters)) ]
Out[225]:
6-element Array{Any,1}:
:sigma
:xi
:eta
:beta
:rho
:agrid
In [226]:
[ field for field in names(eval(Parameters)) ]
Out[226]:
6-element Array{Any,1}:
:sigma
:xi
:eta
:beta
:rho
:agrid
In [231]:
names(eval(Parameters))
Out[231]:
6-element Array{Symbol,1}:
:sigma
:xi
:eta
:beta
:rho
:agrid
Is there a reason you went through the trouble of using a comprehension? I
think just
expressions = names(eval(T))
does the same thing.
On Saturday, January 17, 2015 at 6:08:42 PM UTC-5, Greg Plowman wrote:
>
>
> Not sure if this is helpful.
> Not sure if it is a good idea in general.
> Certainly unsure if it is Julian.
>
> However, I find it useful because I can change fields of my type (reorder,
> add, remove, rename etc) quite easily.
>
>
> macro CallDefaultConstructor(T)
> expressions = [ :($field) for field in names(eval(T)) ]
> return Expr(:call, T, expressions...)
> end
>
> type Parameters
> sigma::Real
> xi::Real
> eta::Real
> beta::Real
> rho::Real
> agrid::FloatRange
> end
>
> function Parameters()
> eta = 3
> sigma = 1
> rho = 5
> xi = 2
> agrid = linrange(1,10,10)
> beta = 4
>
> @CallDefaultConstructor Parameters
> end
>
> p = Parameters()
>
>
>
>
>
>
> On Saturday, January 17, 2015 at 11:34:19 AM UTC+11, Andrew wrote:
>
>> Suppose I have a model which contains many parameters. I'd like to store
>> my parameters in a type, for example
>>
>> type Parameters
>> sigma::Real
>> xi::Real
>> eta::Real
>> beta::Real
>> rho::Real
>> agrid::FloatRange
>> end
>>
>>
>> and then I need to assign some values to my parameters. The natural way I
>> see to do this is
>>
>> params = Parameters(1,2,3,4,5,linrange(1,10,10))
>>
>>
>>
>> or something like that. However, the fact that I need to remember the
>> order in which I defined these parameters means there is some chance of
>> error. In reality I have about 20 parameters, so defining them this way
>> would be quite annoying.
>>
>> It would be nice if there was a constructor that would let me use keyword
>> arguments, as in
>>
>> params = Parameters(sigma=1,xi=2,eta=3,beta=4,rho=5,agrid=linrange(1,10,
>> 10)) .
>>
>>
>>
>> I know I could write my own constructor and use keyword arguments, but
>> then I think I'd still need to use the ordered constructor to write that
>> one.
>>
>> Is there an easy way to do this? Maybe a macro that could automatically
>> define a constructor with keyword arguments?(I don't know much about
>> metaprogramming). Alternatively, is there is a cleaner way to store
>> parameters that doesn't use types?
>>
>> ---
>> I did find a related post here.
>> https://groups.google.com/forum/#!searchin/julia-users/constructor$20keyword$20arguments/julia-users/xslxrihfO30/jV2awP5tbpEJ
>>
>> . Someone suggests that you can define a constructor like,
>> Foo(;bar=1, baz=2) = new(bar, baz)
>>
>> which does what I want. Is there a way to macro that so that it's
>> automatically defined for every field in the type?
>>
>