Thanks a lot Spencer,

So when I create a type I should first think which fields are going to be 
initialized in the constructor. It makes sense. 

Best,
Alex




On Thursday, May 7, 2015 at 4:17:20 PM UTC-4, Spencer Lyon wrote:
>
> Uninitialized fields need to be declared last because the way you 
> construct an incompletely initialized type is to call `new` with less than 
> the total number of fields. Then, elsewhere (preferably via a function call 
> later in the constructor) you will fill in the fields that didn't make it 
> into `new`.
>
> Your question about why `a` was given the value `3` instead of `b` in your 
> example is a confusion about how he `new` function works. The `new` 
> function takes only *positional* arguments, not *keyword* arguments. This 
> means that no matter what the variable is named locally when you call `new` 
> from an inner constructor, the first argument to `new` will always fill in 
> the value for the first field listed when you declared all the types on the 
> field. In your example you assigned `b=3`locally in the function, then 
> passed `b` as the first argument to `new` which made assigned it to be the 
> value of the first field in your type (the `a` field).
>
> So to me, this comment:
>
> >  it seems complicated to place uninitialized fields last. Why is this? 
> The field have names and when calling *new() *you are using these names
>
> is actually more salient in reverse: you list the fields in the order you 
> create them within a constructor, then whenever you are actually using the 
> type (e.g. not in the constructor) you (most commonly) refer to fields by 
> name so the order in which they were declared doesn't matter. 
>
>
> On Thursday, May 7, 2015 at 2:04:36 PM UTC-4, Alexandros Fakos wrote:
>>
>> If I don't want to leave fields uninitialized what is the easiest and 
>> most correct way to initialize them? Put them all zero with an inner 
>> constructor?
>>
>> Thanks a lot,
>> Alex
>>
>> On Thursday, May 7, 2015 at 12:56:35 PM UTC-4, Alexandros Fakos wrote:
>>>
>>> Andrew,
>>>
>>> I found your suggestion very helpful. However, it seems complicated to 
>>> place uninitialized fields last. Why is this? The field have names and when 
>>> calling *new() *you are using these names.
>>>
>>> For example:
>>>
>>> *julia> type foo*
>>> *       a :: Int64*
>>> *       b :: Int64*
>>> *       function foo()*
>>> *       b=3*
>>> *       return new(b)*
>>> *       end*
>>> *       end*
>>>
>>> *julia> var = foo()*
>>> *foo(3,0)*
>>>
>>> *julia> xdump(var)*
>>> *foo *
>>> *  a: Int64 3*
>>> *  b: Int64 0*
>>>
>>> Even if I ask b to be initialized, a is initialized instead. Why is 
>>> this? 
>>>
>>>
>>>
>>> On Sunday, April 20, 2014 at 10:51:29 AM UTC-4, andrew cooke wrote:
>>>>
>>>> yes, you can do this.  just place those fields last and use an internal 
>>>> constructor to define everything else.
>>>>
>>>> its described at 
>>>> http://julia.readthedocs.org/en/latest/manual/constructors/#incomplete-initialization
>>>>  
>>>> (types are so important in julia that the info is in several chapters - 
>>>> you 
>>>> need to read the types and the constructors chapters to get a good 
>>>> understanding).
>>>>
>>>> andrew
>>>>
>>>>
>>>> On Saturday, 19 April 2014 21:50:05 UTC-3, Spencer Lyon wrote:
>>>>
>>>>> Say I have a type that defines a model. Something like this:
>>>>>
>>>>> abstract Model
>>>>>
>>>>> type Results
>>>>> # Details not shown here
>>>>> end
>>>>>
>>>>> type IFP{T <: FloatingPoint} <: Model
>>>>>     # Model parameters
>>>>>     rho::T
>>>>>     beta::T
>>>>>     r::T
>>>>>     R::T
>>>>>     gamma::T
>>>>>
>>>>>     # Grid parameters for a
>>>>>     n_a::Integer
>>>>>     a_max::T
>>>>>     a::Vector{T}
>>>>>
>>>>>     # Parameters for y
>>>>>     n_y::Integer
>>>>>     y::Vector{T}
>>>>>     P::Matrix{T}
>>>>>
>>>>>     Sol::Results
>>>>>
>>>>> end
>>>>>
>>>>> I would like to be able to initialize an object of type IFP, work with 
>>>>> it for a while, pass it to a solution routine, and then fill in the 
>>>>> Sol field at a later time.
>>>>>
>>>>> Is there a way to leave Sol as an uninitialized field and then fill 
>>>>> it in after the solution has been determined (which will be after 
>>>>> constructing the IFP object and playing around with it for a while)? 
>>>>> I suppose one way would be to have the inner constructor directly call 
>>>>> the 
>>>>> solution routine to get the Sol object. However, I want to avoid that 
>>>>> because I may want to manipulate IFP between its construction and 
>>>>> actually solving the model it describes.
>>>>> ------------------------------
>>>>>
>>>>> One more note. In this specific use case Sol could effectively be 
>>>>> replaced by two other fields:
>>>>>
>>>>> c::Matrix{T}
>>>>> ap::Matrix{T}
>>>>>
>>>>> Would that be an easier way to work with them as uninitialized fields? 
>>>>> If so, why?
>>>>>
>>>>

Reply via email to