-
Notifications
You must be signed in to change notification settings - Fork 26
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
Move away from using Moniker for variable binding #181
Comments
Updated the description with a link to this example: https://github.com/jozefg/nbe-for-mltt/ |
I haven't tried to understand them very much, but some recent work in Haskell on nominal stuff, in case it might come in helpful: |
Thanks for linking those @glaebhoerl, much appreciated! 👍 |
I have a Rust port of Nbe using semantic type checking up at brendanzab/rust-nbe-for-mltt. I think this is the approach I am going to go with, but it will be a bit tricky to make! |
@AndrasKovacs has put together a nice approach in smalltt. I don't really understand it yet though (the implementation is a little tricky to understand), so I might persist with the nbe-for-mltt approach for now, which seems more approachable. I think we'll be able to adapt smalltt easier by that stage though, if we wanted to. |
While i haven't tried it yet, another thing worth looking into Similar to the graph approach is using hypergraphs, Ueda has a number of papers on name binding and lambda terms as hypergraphs Name Binding is Easy with Hypergraphs Not aware of any rust libraries for dealing with hypergraphs being available yet though. |
Oooh thanks! I've heard of hypergraphs before! Both from @sashaboyd and @robrix https://twitter.com/rob_rix/status/1224461727678509057. One of the issues I'm running into with the way I'm doing NbE in #197 is that it's hard to check the equivalence of dependent record types using this representation: pub enum Value {
⋮
/// Record type extension.
RecordTypeExtend(String, Arc<Value>, Closure),
/// Empty record types.
RecordTypeEmpty,
⋮ |
Our autobinding library, Moniker is currently not pulling its weight in terms of making it easy to understand the internals of Pikelet and will make supporting a high performance compiler heading into the future. In the words of @kleimkuhler:
Also from conversations on Gitter, @boomshroom and others have struggled with grasping Moniker, so it's not an isolated issue! @jonsterling has also noted on Twitter that he is not really a fan of using ABTs (Abstract binding trees) in implementations:
It's not only this - moniker is also standing in the way of using visitors in the compiler, and will cause us performance problems down the line as Pikelet codebases get larger. It also could make salsa/adapton style incrementalism harder.
Requirements for name binding
The problems we will have to tackle when moving to a new variable binding scheme is:
λx.e [e/x]
should not result inλx.x
)λx.x
should be equivalent toλy.y
)Possible solutions
We have a number of options open to us:
Nominal binding
Use nominal binding, like in David Christiansen's NBE tutorial - could be compatible with visitor-based futsion which might amortize some of the performance penalties. @pythonesque has expressed some concern over going down this route though, especially when it comes to recursive bindings.
Graph libraries
Use petgraph, like in Program Synthesis is Possible in Rust. Not sure how well this would support alpha equivalence though. This feels similar to the Scope Graph stuff from A Theory of Name Resolution. I'm not sure if this has ever been applied to dependently typed languages though, and it is off-the beaten track in terms of the main-line of research.
Locally Nameless
Continue to use a locally nameless approach as with moniker, but bring it into Pikelet. This might result in lots of traversals though, Lean has workarounds though. Also not compatible with visitors.
Explicit substitutions with a fully representation
Apparently locally nameless has not been proven stable under substitution(?) for delayed substitutions, so we'd have to go with a fully nameless representation here, like in autosubst. This is well understood, but might be harder to get to work with visitors. The advantage would be that it would be quite close to what we would be doing in a theorem prover if we ever wanted to do a soundness proof of Pikelet.
Use "semantic type checking"
This is what @jonsterling has advocated to me on Twitter:
I will have to think about this more in order to get my head around it!
Here is an example type checker that uses the technique: https://github.com/jozefg/nbe-for-mltt/
Improve Moniker's performance and documentation
I feel like it still would be handy to have a nice way of doing binding, but perhaps this would require more experimentation using other techniques first. I'm not sure though.
The text was updated successfully, but these errors were encountered: