On Sun, Oct 11, 2015 at 6:54 PM, Andrei Zh <faithlessfri...@gmail.com> wrote:
> I didn't know about such capability, thanks. But I still can't figure out
> how to call this constructor. E.g.:
>
> julia> Bar{Int}()
>  ERROR: MethodError: `convert` has no method matching
> convert(::Type{Bar{Int64}})
>  This may have arisen from a call to the constructor Bar{Int64}(...),
>  since type constructors fall back to convert methods.
>  Closest candidates are:
>    convert{T}(::Type{T}, !Matched::T)
>    Bar{#s6,T}()
>    call{T}(::Type{T}, !Matched::Any)
>   in call at essentials.jl:57
>
> Don't know if it matters, but I also have a different output of
> `methods(Bar{Int})` than you:
>
> julia> methods(Bar{Int})
>  3-element Array{Any,1}:
>   call{#s6,T}(::Type{Bar{#s6}}) at
> /home/<username>/work/playground/contructors.jl:11
>   call{T}(::Type{T}, arg) at essentials.jl:56
>   call{T}(::Type{T}, args...) at essentials.jl:57
>

The error I get (which seems to be different from yours) is

```
julia> type Bar{T}
           x::Array{T,1}
           Bar() = Bar(zeros(T, 10))
       end

julia> Bar{Int}()
ERROR: MethodError: `convert` has no method matching
convert(::Type{Bar{T}}, ::Array{Int64,1})
This may have arisen from a call to the constructor Bar{T}(...),
since type constructors fall back to convert methods.
Closest candidates are:
  call{T}(::Type{T}, ::Any)
  convert{T}(::Type{T}, ::T)
 in call at ./none:3
```

And the issue here is that you cannot call the non-existing default
inner constructor if you provide your own one. I suspect `Foo()` won't
work for you either.

The following works for me

```
julia> type Bar{T}
           x::Array{T,1}
           Bar() = new(zeros(T, 10))
       end

julia> Bar{Int}()
Bar{Int64}([0,0,0,0,0,0,0,0,0,0])
```

>
>
>
>
> On Monday, October 12, 2015 at 1:06:14 AM UTC+3, Yichao Yu wrote:
>>
>> On Sun, Oct 11, 2015 at 5:57 PM, Andrei Zh <faithle...@gmail.com> wrote:
>> > Let's consider 2 types with inner constructors:
>> >
>> > type Foo
>> >     x::Array{Int,1}
>> >
>> >
>> >     Foo() = Foo(zeros(Int, 10))
>> > end
>> >
>> > type Bar{T}
>> >     x::Array{T,1}
>> >
>> >
>> >     Bar() = Bar(zeros(T, 10))
>> > end
>> >
>> > The only difference between them is that `Bar` has type parameter while
>> > `Foo` doesn't. I'd expect their inner constructors behave the same way,
>> > but
>> > `Bar` turns to ignore inner constructor definition:
>> >
>> > julia> methods(Foo)
>> >  3-element Array{Any,1}:
>> >   call(::Type{Foo}) at /home/<username>/work/playground/contructors.jl:5
>> >   call{T}(::Type{T}, arg) at essentials.jl:56
>> >   call{T}(::Type{T}, args...) at essentials.jl:57
>> >
>> >
>> >  julia> methods(Bar)
>> >  2-element Array{Any,1}:
>> >   call{T}(::Type{T}, arg) at essentials.jl:56
>> >   call{T}(::Type{T}, args...) at essentials.jl:57
>> >
>> > Is it a bug or a feature and how to make `Bar` recognize inner
>> > constructor
>> > (outer constructor is not an option here since it uses type parameter
>> > `T` in
>> > constructor body, but not in its constructor)?
>> >
>>
>> As you pointed out, the inner constructor can access the type
>> parameter and therefore the type parameter needs to be specified in
>> order to call it.
>>
>> julia> methods(Bar{Int})
>> 3-element Array{Any,1}:
>>  call{T}(::Type{Bar{T}}) at none:3
>>  call{T}(::Type{T}, arg) at essentials.jl:55
>>  call{T}(::Type{T}, args...) at essentials.jl:56

Reply via email to