-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Random: Uniqueness Types? #401
Comments
Great question. We've toyed with linear types in Dex (you can see some vestigial lollipops,
newtype Random a = Random { runRandom :: Key -> a }
instance Monad Random where
f >>= g = Random $ \k ->
let (k1, k2) = splitKey k
in runRandom (g $ runRandom f k1) k2
return x = Random $ const x
The problem is that it breaks the law! We don't even have
linearize : (a -> b) -> a -> (b & a --o b)
transposeLinear : (a --o b) -> (b --o a)
vjp : (a -> b) -> a -> (b & b --o a) = They used to be checked but they're currently just documentation. The advantage of actually checking them is that it lets you safely expose Hope that gives some context. The summary is: linear types could have many applications in Dex but we don't have concrete plans for them yet. |
This is extremely interesting! Thanks so much for taking the time to write it up. |
One more question @dougalm . I think I am missing something basic in your point 3. Am I right to assume that in Dex I can't think of any usability reason why a linear function would need to have the Linear typing restriction as well? (Although maybe there are some ways to exploit that for efficiency? https://www.cl.cam.ac.uk/~nk480/numlin.pdf) |
This looks resolved, so I'll close it. Can't seem to find the button to convert the issue to a discussion for some reason 😕 |
Oh, and answering your question @srush: yes, it is a different notion of linearity. For example, |
Sorry, I meant to respond to this earlier.
Actually, it is meant to imply that it is linearly typed in the sense of consuming its argument exactly once, which also implies that it's linear in the linear algebra sense. Before explaining what I mean I'll establish some terminology, because "linear" and "function" are both confusingly overloaded here. I'll use "syntactic function" to mean a lambda term in a program. And I'll use "mathematical function" to mean a mathematical object mapping inputs to outputs. Usually we think of a syntactic function as denoting a mathematical function, but of course it's syntactic functions that we have to work with in a compiler. I'll use "logically linear" to mean linear in the linear logic sense (equivalently, in the linear type sense). It's often described in terms of "consuming" an argument or a logical premise. We say that a syntactic function is logically linear if it obeys the linear typing rules. I'll use "algebraically linear" to refer to mathematical functions on vector spaces that obey Ok, with that out of the way, I think there are two suprising claims we're making about linearity and AD. First, we're claiming that a logically linear type checker can prove that a syntactic function denotes a mathematical function that's algebraically linear. This isn't obvious at all, and I wouldn't have believed it if Gordon Plotkin hadn't patiently explained it to us. The intuition is that we can think of "consuming an input" as "multiplying the input into the function's result". Then it seems plausible that consuming an input exactly once means that you're algebraically linear in that input. For example, here are three functions for which the logical and algebraic notions of linearity clearly coincide.
To make this work formally in a standard logically linear type system, we just need the rule that the type of But what about
Interestingly, we can also make an uncurried version of Hopefully that gives some support to the idea that logical linearity implies algebraic linearity if we set up the primitive typing rules in the right way. Of course, it doesn't go the other way. Just because a syntactic function's denotation is algebraically linear, it doesn't mean that the syntactic function itself is logically linear. For example:
But notice that even though this is algebraically linear, it's not something we'd know how to transpose in an AD system. So the second surprising claim is this: logical linearity isn't required for algebraic linearity but it is required for mechanical transposition of syntactic functions in the AD sense (at least, for the style of transposition that I know how to do). The reason is that we use the "consumed once" property when we do transposition of primitives like Hope that's clearer! We should write this up one of these days. |
@dougalm finally succeeded in writing this down! You Only Linearize Once: Tangents Transpose to Gradients by Radul et al. |
Awesome! I'll check it out. |
Hi dex,
I was reading about how Haskell had just added Linear/Unique Types (https://en.wikipedia.org/wiki/Uniqueness_type) and was curious if that would work with the Dex type system?
In particular, I constantly am messing up random keys in Jax/Dex, and would love if they type system could just prevent me from reusing them without splitting.
The text was updated successfully, but these errors were encountered: