Replies: 12 comments
-
|
Thank you for your comment! You're right, it's technically just as expressive - with the downside of having to modify the dispatch into a much more complicated, potentially N-ary dispatch that also needs to be modified every time you want to add a new trait (IF the original maintainer is around to do that!). I wouldn't call that pattern "basic" anymore though, since you now also have to modify
The " |
Beta Was this translation helpful? Give feedback.
-
|
Correct. I think (not sure) some of the traits packages (probably WhereTraits) support extending with new traits: you can do this automatically with BUT there are huge downsides to this:
For those reasons, I personally don't see ever supporting an extensible (in the sense of adding new independent) traits system in Julia; I think there would have to be some social consensus about what traits are needed, and the "depot function" that computes the trait-values would live in some small package (like |
Beta Was this translation helpful? Give feedback.
-
|
Right - extending existing struct types with new traits from the outside is questionable at best, and I wrote as much in the doc page. I'm definitely not talking about deleting methods or anything like automatic method rewriting - I'm not sure how WhereTraits.jl and its mechanism for having predicates to limit dispatch relates to what I discuss in the philosophy page. Could you elaborate? I don't personally see how that gets in the way of treating abstract types as trait-like dispatches directly. To be clear - I really want to get rid of the "depot" function entirely. From my POV, it's just an additional dispatch layer that's been introduced to work around the limitation of not being able to subtype more than one abstract type. That's why I keep saying that abstract types are exactly the traits we're looking for, were we able to explicitly subtype more than one of them. |
Beta Was this translation helpful? Give feedback.
-
|
I think the non-dispatch solution still amounts to the same thing: you have to invalidate everything that was compiled in a world where it didn't know about the new trait. |
Beta Was this translation helpful? Give feedback.
-
|
Right, but that's something shared across every form of trait implementation, no? Even Holy Traits, since all that's happening there is moving the dispatch one layer in to the "depot function", as you call it - the invalidations still happen just the same, if I'm not mistaken, by lieu of invalidating the |
Beta Was this translation helpful? Give feedback.
-
|
Right, that exactly my point. We have to choose between "extensible traits" and other good things like having precompilation that works. I'm strongly in the camp of keeping precompilation working, even if it means we can never have extensible traits. Maybe I'm misunderstanding your point, but I interpreted
to indicate that you thought a |
Beta Was this translation helpful? Give feedback.
-
|
I guess I'm confused by what exactly you mean with "extensible traits". Do you mean having some way to declare an object implementing a trait? Because that is what I mean with subtyping an abstract type - you have to implement the methods required of an abstract type either way already. My point with |
Beta Was this translation helpful? Give feedback.
-
|
Using the syntax of WhereTraits but inspired by the example of Traitor: PkgA declares foo(A::AbstractArray) where {Size(A)<:Big} = 1but then PkgB declares PkgA.foo(A::AbstractArray) where {Odor(A)<:Smelly} = 2 |
Beta Was this translation helpful? Give feedback.
-
|
I don't understand. That is not at all what I'm talking about, or what RequiredInterfaces.jl would do, even if implemented in Base. With RequiredInterfaces.jl, you'd have At least, that's what I take the entire concept of a type to mean, both theoretically and practically in Julia. Are you suggesting we should create some different dispatch mechanism bespoke to this..? That seems a bit redundant to me, like creating a second way of expressing types in Julia. |
Beta Was this translation helpful? Give feedback.
-
OK. I don't think I can answer your question because I've lost sight of what you mean by
That's the objection I was answering. My point is that dynamic trait/multiple inheritance may require old code to be thrown away regardless of the implementation. At the end of the day, if method calls would dispatch differently in the new world you've created, you're going to have to recompile code (because the dispatches are hard-wired). |
Beta Was this translation helpful? Give feedback.
-
|
I'm talking about your comment that you can just add the new trait to the depot function here: And while that indeed works, if you now want to add another trait
Right - my question is about what you mean with "dynamic trait". If you're talking about WhereTraits style "match any boolean predicate" style of traits, I wholeheartedly agree, that's not going to be scaling well - particulalry as it'll require SAT and/or SMT solving to be able to even say if a given method matches. That's certainly not what I want, hence my focus on making our existing abstract types more expressive/semantically meaningful, with the smallest possible addition to the type system that allows the same behavior. |
Beta Was this translation helpful? Give feedback.
-
|
I'm converting this to a discussion, since there isn't really anything actionable in here - well, and that's what the OP was opened with :) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Thanks for doing this! One specific discussion point:
Not true. The "depot" function should just compute both traits:
and the underscore versions take all 3 args. I think it's basically the same as
Meet(with all the same strengths and weaknesses), albeit with far uglier syntax.Beta Was this translation helpful? Give feedback.
All reactions