Hi Tim,

That's a shame, I was hoping that doing the above would let me create 
several different concrete PhylogenyNode and PhylogenyEdge types, that can 
be used together. I guess since this is an abuse I have to pair one 
concrete PhylogenyEdge type with one concrete PhylogenyNode type? I 
wondered is a valid alternative to do something like this:

abstract AbstractNode
abstract PhylogenyNode <: AbstractNode
abstract NetworkNode <: AbstractNode
abstract AbstractEdge
abstract PhylogenyEdge <: AbstractEdge
abstract NetworkEdge <: AbstractEdge

type Branch <: PhylogenyEdge
   from::PhylogenyNode
   to::PhylogenyNode
   length::Float64

    function Branch()
       x = new()
       length!(x, -1.0)
       return x
   end
end

type Clade <: PhylogenyNode
   from::PhylogenyEdge
   to::Vector{PhylogenyEdge}
   confidence::Float64

    function Clade()
       x = new()
       x.to = Vector{PhylogenyEdge}()
       confidence!(x, -1.0)
       return x
   end
end

And define getters and setters in such a way that type assertions make 
things certain for the compiler?
I saw that Jeff proposed a similar solution in julia issue #269 to handle 
circular type declarations.




On Wednesday, August 24, 2016 at 4:11:06 PM UTC+1, Tim Holy wrote:
>
> I don't think that's type-stable. Since each node of each tree will also 
> be a 
> different type, I also think you'll end up hating life due to compile 
> times. 
> There's some (peripherally) relevant discussion at http://docs.julialang.org/ 
>
> en/latest/manual/performance-tips/#the-dangers-of-abusing-multiple-dispatch- 
>
> aka-more-on-types-with-values-as-parameters 
> <http://docs.julialang.org/en/latest/manual/performance-tips/#the-dangers-of-abusing-multiple-dispatch-aka-more-on-types-with-values-as-parameters>
>  
>
> Best, 
> --Tim 
>
> On Tuesday, August 23, 2016 3:28:17 PM CDT Ben Ward wrote: 
> > I'm doing some development and wondered if this kind of pattern is 
> > problematic: 
> > 
> > abstract AbstractNode 
> > abstract PhylogenyNode <: AbstractNode 
> > abstract NetworkNode <: AbstractNode 
> > abstract AbstractEdge 
> > abstract PhylogenyEdge <: AbstractEdge 
> > abstract NetworkEdge <: AbstractEdge 
> > 
> > type Branch{N <: PhylogenyNode} <: PhylogenyEdge 
> >     from::N{Branch} 
> >     to::N{Branch} 
> >     length::Float64 
> > 
> >     function Branch{N}(::Type{N}) 
> >         x = new() 
> >         length!(x, -1.0) 
> >         return x 
> >     end 
> > end 
> > 
> > type Clade{E <: PhylogenyEdge} <: PhylogenyNode 
> >     from::E 
> >     to::Vector{E} 
> >     confidence::Float64 
> > 
> >     function Clade{E}(::Type{E}) 
> >         x = new() 
> >         x.to = Vector{E}() 
> >         confidence!(x, -1.0) 
> >         return x 
> >     end 
> > end 
> > 
> > 
> > 
> > As you can see both concrete types are parametric, and as a result there 
> is 
> > a certain circularity to it 
> > Clade{Branch{Clade{Branch{Clade{Branch}}}}}.... That ultimately ends in 
> > something like Clade{Branch{N<:PhylogenyNode}}. I'd like to know if this 
> is 
> > type-certain or not - the fact it terminates in N<:PhylogenyNode or 
> > E<:PhylogenyEdge makes me doubt it. 
>
>
>

Reply via email to