Skip to content
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

Add letrec terms #469

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft

Add letrec terms #469

wants to merge 3 commits into from

Conversation

Kmeakin
Copy link
Contributor

@Kmeakin Kmeakin commented Jan 19, 2023

Adds new letrec term. Type-checking is surprisingly easy:

  • Insert a fresh type variable for each definition
  • Check each definition's pattern against its type variable
  • Check each definition's RHS against its type variable

The hard part is evaluation. I think this would require lazy evaluation. At the moment any letrec definitions just evaluate to #error, so you can check that letrec type-checks, but can't run it

Todos

  • Evaluating letrec definitions
  • Generating fresh names when distilling letrec definitions
  • Currently, you must annotate each recursive definition if it is used recursively, otherwise you will get an error about trying to apply an argument to a metavariable. I think postponing would fix this?
  • Recursive top-level def items. Will leave for a later PR
  • Check that letrec definitions are safe to evaluate. I believe we can use the algorithm from A Practical Mode System for Recursive Definitions. Will leave for a later PR
  • Syntax bikeshedding
    • Should letrec be spelled letrec (as in Scheme) or let rec (as in ML)?
    • I'd like each definition to be separated by ;, but I cannot figure out how to do so without LALRPOP complaining about ambiguity, so for now the separator is ,

@Kmeakin Kmeakin marked this pull request as ready for review January 19, 2023 09:02
@Kmeakin Kmeakin mentioned this pull request Jan 20, 2023
@Kmeakin Kmeakin force-pushed the letrec branch 2 times, most recently from eaf448a to 775d5e7 Compare January 23, 2023 13:57
@brendanzab
Copy link
Member

brendanzab commented Jan 23, 2023

Oh wow, neat. Do you have any ideas about how this might interact with termination checking? IIUC some type theories have a type for “well founded recursion”, but this might not be the best for an actual implementation?

Syntax wise, I think I like let rec actually - unsure about a nice way to handle multiple mutually recursive bindings though. I do also wonder also if it would be better (in Fathom) to limit recursive bindings to the top level.

I wonder if we can find binary formats that might exercise this feature? Might be useful to test it on some real world stuff.

I’m unsure about merging this right now, but I really appreciate the exploration! I’ve found recursive bindings to a bit intimidating, so this stuff is very helpful! Takes a bit to understand and synthesise some of the research, and turn it into an implementation.

@Kmeakin Kmeakin marked this pull request as draft January 26, 2023 18:04
@Kmeakin
Copy link
Contributor Author

Kmeakin commented Jan 27, 2023

Oh wow, neat. Do you have any ideas about how this might interact with termination checking? IIUC some type theories have a type for “well founded recursion”, but this might not be the best for an actual implementation?

Sometime down the line we could add recursion checking, but I don't think its a priority since our type theory is already inconsistent (we have Type : Type)

@Kmeakin
Copy link
Contributor Author

Kmeakin commented Jan 27, 2023

I do also wonder also if it would be better (in Fathom) to limit recursive bindings to the top level.

I decided to do local recursive binding first, because it allows me to test out the typechecking rules without needing to implement lazy evaluation: just return #error when evaluation defs in letrec. Adding recursive def items should be simple: just adjust the type checking rules and make def items lazy

@brendanzab
Copy link
Member

brendanzab commented Jan 30, 2023

I don't think its a priority since our type theory is already inconsistent (we have Type : Type)

Yeah I had been planning to remove this at some point – just hadn’t got around to it yet! See #316 😓

@Kmeakin Kmeakin force-pushed the letrec branch 3 times, most recently from 6713eaf to 9b1dac7 Compare January 31, 2023 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants