I parse these kinds of single line function definitions wrong all the time in my head.
Will the syntax Foo{T}(X::T) = Foo{T}(x) continue to work in 1.0? it seems to still work in 0.6
The exact “boilerplate” constructor you mentioned is provided for free whenever no inner constructor is defined.
AFAICT if you need an inner constructor (for an invariant, say) then it is assumed you are an advanced user doing something fancy, and the default outer constructor could potentially get in your way (remember while you can define a method, you can’t really “undefined” one, so as unfortunate as it is I’m not sure a better choice is available).
@andyferris: I am afraid you misunderstand the question. The issue is not whether one is an “advanced user” who can write this, but that one is repeating code unnecessarily.
It is easy to write a macro for this, but the problem is that AFAICT those kinds of macros (eg Parameters.@with_kw, @auto_hash_equals) cannot be combined. Maybe a meta-macro
@struct_meta{with_kw, auto_has_equals, parametric_constructor} struct Foo
...
end
could be the solution, where each expander gets the form struct Foo end and spits out extra code which is then combined.
That allows one to create a type and determine all behaviors. If the default methods were made to exist (invisibly) alongside the specialty type, unexpected interactions can (and do) occur.