egraphs-good / egglog

egraphs + datalog!
https://egraphs-good.github.io/egglog/
MIT License
459 stars 54 forks source link

Mutually recursive datatypes #397

Closed yihozhang closed 1 month ago

yihozhang commented 4 months ago

Currently, datatypes cannot be mutually recursive. For example, the following is not allowed

(datatype Foo
  (foo Bar))

(datatype Bar
  (bar Foo))

OCaml supports mutually recursive type with the type ... and ... keyword. We can probably do something similar:

(datatype Foo
  (foo Bar)
and      Bar
  (bar Foo))

Or

(datatype Foo
  (foo Bar)
 andalso  Bar
  (bar Foo))

Or

(datatype*
  Foo
    (foo Bar)
  Bar
    (bar Foo))

Or (Jul 25 updates: we are more in favor of this syntax)

(datatype*
  (Foo
    (foo Bar))
  (Bar
    (bar Foo)))

Or maybe there is a better syntax for this?


Another pattern we commonly have (but is not supported) is

(datatype Expr
    (Call String VecExpr))
(sort VecExpr (Vec Expr))

Our recursive datatypes should also have a good support for this.

saulshanabrook commented 4 months ago

FWIW in the Python bindings mutually recursive data types are supported through late binding type annotations. All classes/datatypes are translated to plain sort definitions & functions.

oflatt commented 4 months ago

One advantage of this proposal is that it would still allow mutually recursive data types even if we made datatype closed, instead of open as it is now

saulshanabrook commented 4 months ago

Thought: Could make all types "lazy", that would support recursive data.... With the current syntax, then we just defer processing until it's defined.

saulshanabrook commented 1 month ago

This was fixed in #432