hydromatic / morel

Standard ML interpreter, with relational extensions, implemented in Java
Apache License 2.0
294 stars 15 forks source link

Closure equality #176

Open julianhyde opened 2 years ago

julianhyde commented 2 years ago

A closure (lambda plus environment) should equal another closure that is the same code applied to the same environment.

For example, consider this query:

- from i in [1, 2, 3, 2]
=   yield {i, iPlus = fn h => h + i}
=   group iPlus compute count;
val it =
  [{count=1,iPlus=fn},{count=1,iPlus=fn},{count=1,iPlus=fn},{count=1,iPlus=fn}]
  : {count:int, iPlus:int -> int} list

It returns 4 rows, because the two instances of (fn => h + i) {i: 2} do not compare equal, but it should return 3 rows, like this:

val it =
  [{count=1,iPlus=fn},{count=2,iPlus=fn},{count=1,iPlus=fn}]
  : {count:int, iPlus:int -> int} list

Note that in Standard ML, a closure or lambda is not an equality type:

Standard ML of New Jersey v110.79 [built: Sat Oct 26 12:27:04 2019]
- val x = fn i => i;
val x = fn : 'a -> 'a
- x = x;
stdIn:2.1-2.6 Error: operator and operand don't agree [equality type required]
  operator domain: ''Z * ''Z
  operand:         ('Y -> 'Y) * ('X -> 'X)
  in expression:
    x = x
- [] = [];
stdIn:1.5 Warning: calling polyEqual
val it = true : bool

I don't know whether Morel's group should require equality types.