The idiomatic way to write this inner constructor is this following:
type Xyzzy{X,Y} <: AXyzzy
xy::(X,Y)
Xyzzy(x,y) = new((x,y))
end
The only reason you ever need to call new with too few arguments is if you have to mutate an object after creating it in order to completely initialize it. In this case, you definitely don't so you should just pass the one field to new.
Thanks for explaining. Perhaps I am trying to cover too much ground too quickly - part of the reason to post here is to explain what caught my off guard, since it may be a pitfall for others. So I am not going to say how I think it should have been, only explain my reasoning - this can only be done once, while you are still new to the language.
First: yes, the documentation does cover the material, on a second read I went to composite types and methods and missed the separate constructors section, although there are clear references.
Second, I'm still left with a feeling things should work easier - here is my thinking:
There may be good reasons to feed new with arguments, but that shouldn't effect how to match a specific constructor, and in fact, it doesn't changing behavior if I say new((x, y)).
The reason behind the `mknoxyzzy` method is that it was my first attempt, and it didn't make a Xyzzy as I would have hoped. Noting that it would have worked if Xyzzy had no type parameters.
I realize there has to be some magic to derive the Xyzzy type parameter by inference from assignment to _.xy, but even if not, the constructor method missing is still confusing. The exact same parameterized signature works if used as a seperate non-constructor function, that is, if I added {X,Y} to mkxyzzy, that function would work.
mkxyzzy{X, Y}(x::X, y::Y, z::String) = Xyzzy{typeof(x), typeof(y)}(x, y)
The same signature on an inner Xyzzy constructor still won't work unless the method is called with explicity type parameters.
type Xyzzy{X, Y} ...
function Xyzzy{X, Y}(x::X, y::Y)
_ = new((x, y))
#_.xy = (x, y)
return _
end
end
Xyzzy(1,2) results in no method Xyzzy
Xyzzy{Int64, Int64}(1,2) results in Xyzzy instance.
So yes, I can add type parameters, but it seems a bit roundabout to enter typeof(x) etc., at least from my initial inexperienced approach, when the same thing works in other situations.
Now, for parameterized constructors without arguments this is more tricky, as the original post, but not really: If there is only one constructor of zero args, and it assigns a value to a parameterized type on the composite type, inference should be able to work. At least from intuitive thinking.
As to new() parameters, a minor thing is that it is less clear which members are initialized - for example, my tuple (x,y) looks like separate values x, y., and the constructors are prone to errors related to insertion of new fields.
Now, I really appeciate the type system of Julia for many reasons, just explaining what caused me some troubles.