4 ms·
Yes, I'd love to see a revamp of the type system with real interfaces instead of the single inheritance with abstract types. I also think packaging and imports
by bobbylarrybobby 4y ago
Yes, I'd love to see a revamp of the type system with real interfaces instead of the single inheritance with abstract types. I also think packaging and imports need a lot of work — for god's sake, there is no "import adjacent file" mechanism other than a C-style `include`, which just copies and pastes code from another file into the current file.
- contravariant 4y agoNot sure if interfaces work as you'd expect them to in Julia. Values don't have methods for instance, you just define functions for the types. So what would an interface look like? Best I can figure out an interface is equivalent to a requirement that a couple of methods are implemented and that a bunch of fields exist, which sort of gets taken care of by the duck-typing, the only problem is that it's not documented in code. One approach that I'd been thinking about would be defining a method IMyInterface that returns a tuple of fields and methods defined by the interface and saying a type implements that interface if there's an implementation. Technically this performs the same job, but unfortunately it doesn't seem like it'd be easy to use without hefty syntactic sugar. What do you imagine interfaces would look like in Julia?
- bobbylarrybobby 4y agoMost I want to be able to write something like `f(it::Iterable{<:Number})`. The current way to do this is to simply not specify the type and then it let it fail wherever the duck typing fails (e.g., if you try to use a for loop on a non iterable argument). I'd rather it fail when calling f saying no method exists for <passed type>.
- ChrisRackauckas 4y agoI tend to think that this is the one thing that would bring a v2.0. Compile time, startup time, binary building, and native code caching improvements I think take the big priority here (and I describe elsewhere in this thread how those are really all one technical issue), but when that's completed I do think formalizing a traits interface will be the next major semantic change to the language. It could be a v1.x if it does not require a breaking change to the language's semantics, but it's hard (for me at least) to see how to nicely incorporate trait definitions and required dispatches without making a single breaking change.
- contravariant 4y agoI agree that that would be better, I'm just wondering what the definition of an interface would look like. Technically "all" you need is to extend the 'where' keyword a "little": Iterable{T,S} = TIter where { iterate(iter::TIter) <: Tuple{T,S}, iterate(iter::TIter, state::S) <: Tuple{T,S}}
- bobbylarrybobby 4y agoI'm imagining it would look more or less like a struct definition, but with methods instead of fields. Something like interface{S,T} Iterable{T} Next = Tuple{Union{T,Nothing},S} iterate(self::Self)::Next iterate(self::Self, state::S)::Next end This means "Iterable has two type parameters, one of which (T) is named explicitly in the type and the other of which (S) is implicitly used in the definition of the interface but is otherwise not nameable.". I think the real question is how to implement structural sub typing of interfaces -- you wouldn't want to have to list the interfaces a struct implements when defining it because then you're limited to only those traits you (the struct's author) know about. Better (and more Julian) to automatically implement Iterable for any struct with those two iterate methods defined on it, but it seems like a pretty big task to keep track of that at runtime. Especially if you care about matching the return types of the interface's functions since in general those can't be type checked until they're actually called (or at the least compiled, but the whole point of Julia is to not compile the world ahead of time).
- contravariant 4y agoI don't think you really can list the interfaces a struct implements up front, the way I understand Julia you only implement those methods afterwards so you'd have an awkward gap in between the definition of the struct and the part where the definition is actually correct. In theory an interface ought to just be a shorthand for 'this duck-typing works', but in a way that ideally can be verified statically. A static type checker is the only possible (though major) advantage I see. It's debatable if it even makes sense for Julia to check interfaces at runtime, if something doesn't satisfy an interface but the code compiles, then why would it be wrong?