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