7 ms·
Author here, thank you for your kind remarks! You’re right, the backticks surrounding our type level integers are too distracting. The Kotlin grammar [1] requir
by bmc7505 7y ago
Author here, thank you for your kind remarks! You’re right, the backticks surrounding our type level integers are too distracting. The Kotlin grammar [1] requires class names must either start with a letter, or be enclosed by back-ticks. Unless the Kotlin language designers reconsider the identifier scheme [2] (?), we would be better off replacing these with something like T1, T2, ..., TN for readability and to minimize confusion.
Re: Shape Inference. To properly understand how this works, the best place to start is by looking at ToyVectorExample.kt [3]. Once you’re comfortable with that, ToyMatrixExample.kt is a fairly direct generalization. The best way to explain our type system is that we stick to equality checking and perform manual type conversion for tensor contractions and expansions. Haven’t figures out a good way to do concatenation, slicing, or convolution which require type-level arithmetic. This may be feasible for a fixed number set of predefined shapes, but seems to be generally intractable in the Java/Kotlin type system without a significant overhead. But if someone has an idea, I would be very happy to be proven wrong about this!
[1]: https://kotlinlang.org/docs/reference/grammar.html https://kotlinlang.org/docs/reference/grammar.html
[2]: https://github.com/Kotlin/kotlin-spec/blob/master/grammar/src/main/antlr/UnicodeClasses.g4 https://github.com/Kotlin/kotlin-spec/blob/master/grammar/sr...
[3]: https://github.com/breandan/kotlingrad/blob/master/src/main/kotlin/edu/umontreal/kotlingrad/samples/ToyVectorExample.kt https://github.com/breandan/kotlingrad/blob/master/src/main/...
[4]: https://github.com/breandan/kotlingrad/blob/master/src/main/kotlin/edu/umontreal/kotlingrad/samples/ToyMatrixExample.kt https://github.com/breandan/kotlingrad/blob/master/src/main/...
- jillesvangurp 7y agoRegarding the naming, the backtick notation is useful sometimes to allow you to do stuff that goes against normal conventions in Kotlin for identifiers. But generally sticking with naming conventions (that you are also dodging with various annotations top opt out of warnings for non ascii characters) is probably helpful from a code readability and autocomplete predictability point of view; which I would argue is important in an API and DSL. I'd suggest just spelling out what is what instead of relying on names that by themselves are meaningless. So e.g. Dimension1, Dimension2x2, etc. make it clear that 1) it's a class 2) it's intended as syntactic sugar for something else. Could type aliases work here? In any case, there are only so many vector and matrix dimensions you can predefine. Your approach kind of breaks down for larger vectors/matrices and you lose compile time checks for those. Nevertheless, kudos for pushing the type system this far.
- bmc7505 7y agoYou raise some good points about the API readability and discoverability. For identifiers that the user is likely to write often, ASCII and standard naming conventions are usually preferable. While auto-completion is capable of handling unicode symbols, it can easily go overboard and harm usability. Agree that typealias could help, it's something we should explore. Thanks for the suggestions! Indeed you are correct about the finite dimension constraint, a problem we discussed with a recent reviewer [1] in further depth. As you correctly noted, since we have a fixed upper bound for type-level integers, when checking large tensors (i.e. whose width exceeds 1000 in any dimension), we fall back to dynamic shape checking, prior to numerical evaluation. Smaller tensors can be shape checked at compile time. I too, am wary of the "type voodoo" associated with type-level programming, but would argue that the added complexity from our approach (sans type level arithmetic) comes at very little cost to the end user due to type inference. In most cases we can check arrays at compile time. In the worst case, or if the user chooses, we use runtime shape checking or unsafe execution, which is the same as ordinary array programming. Thanks again for your feedback. Please don't hesitate to reach out if you have any further questions or comments! [1]: https://openreview.net/forum?id=SkluMSZ08H¬eId=BJeZ3FkuOr https://openreview.net/forum?id=SkluMSZ08H¬eId=BJeZ3FkuOr