If Julia already makes an automatic default inner constructor, wouldn't it
be a good idea to also make an automatic default outer constructor like
this:
julia> abstract Foo
julia> type Bar{T<:Number} <: Foo
x::T
Bar(x::T) = new(x)
end
julia> Bar{T<:Number}(x::T) = Bar{T}(x)
Bar{T<:Number} (constructor with 1 method)
julia> Bar(5), Bar(5.5), Bar(3//5), Bar(big(5.3))
(Bar{Int32}(5),Bar{Float64}(5.5),Bar{Rational{Int32}}(3//5),
9999999999982236431605997495353221893310546875e+00 with 256
julia> Bar(5), Bar(5.5), Bar(3//5)
(Bar{Int32}(5),Bar{Float64}(5.5),Bar{Rational{Int32}}(3//5))
Or what's the advantage in doing it the way it is now?
El martes, 17 de febrero de 2015, 12:59:00 (UTC-6), Ismael VC escribió:
>
> Why can't I create an instance of this `Bar` type with the following
> enforced invariants?
>
> julia> versioninfo()
> Julia Version 0.4.0-dev+3353
> Commit 0179028* (2015-02-14 17:08 UTC)
> Platform Info:
> System: Windows (x86_64-w64-mingw32)
> CPU: Intel(R) Core(TM) i3 CPU M 350 @ 2.27GHz
> WORD_SIZE: 64
> BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Nehalem)
> LAPACK: libopenblas
> LIBM: libopenlibm
> LLVM: libLLVM-3.3
>
> julia> abstract Foo
>
> julia> type Bar{T<:Number} <: Foo
> value::Nullable{Complex{T}}
> x::Int
> y::Int
>
> function Bar(x::Int, y::Int)
> x < 0 || y < 0 && error()
> x < y ? new(Nullable{Complex{T}}(), x, y) : error()
> end
> end
>
> julia> Bar{T<:Number}(value::T, x::Int, y::Int) =
> Bar(Nullable(complex(value)), x, y)
> Bar{T<:Number}
>
> julia> methods(Bar)
> 2-element Array{Any,1}:
> call{T<:Number}(::Type{Bar{T<:Number}},value::T<:Number,x::Int64,y::Int64)
> at none:1
> call{T}(::Type{T},args...) at base.jl:36
>
> julia> Bar(1, 8)
> ERROR: MethodError: `convert` has no method matching
> convert(::Type{Bar{T<:Number}}, ::Int64, ::Int64)
> This may have arisen from a call to the constructor Bar{T<:Number}(...),
> since type constructors fall back to convert methods.
> Closest candidates are:
> convert{T}(::Type{T}, ::T)
>
> in call at base.jl:36
>
> julia> Bar(5.7, 1, 8)
> ERROR: MethodError: `convert` has no method matching
> convert(::Type{Bar{T<:Number}}, ::Nullable{Complex{Float64}}, ::Int64,
> ::Int64)
> This may have arisen from a call to the constructor Bar{T<:Number}(...),
> since type constructors fall back to convert methods.
> Closest candidates are:
> convert{T}(::Type{T}, ::T)
>
> in call at none:1
>
> How could I implement the this type's constructors? I don't understand the
> new `call` constructors! :'(
>
>