effekt-lang / effekt-lang/effekt

Mutual recursive objects - when to allow them?

Open
#600 3 comments 1 reaction 0 assignees View on GitHub
question requires-design
Dominant language
Scala
Stars
469
Forks
41
Avg merge
1d 16h
Merged PRs (30d)
23

Description

Assume we defined:
```
interface Ping { def ping(): Unit }
interface Pong { def pong(): Unit }
```
Then, the following top-level definition is accepted by Effekt (albeit not working for LLVM):
```
def pinger = new Ping { def ping() = ponger.pong() }
def ponger = new Pong { def pong() = pinger.ping() }
```
(let's ignore non-termination here, we could add a counter).

Locally in a function, this does not compile (`ponger` is not defined):
```
def foo() = {
def pinger = new Ping { def ping() = ponger.pong() }
def ponger = new Pong { def pong() = pinger.ping() }
()
}
```

Also, the following (which uses boxing implicitly) doesn't work (locally or globally):
```
def mkPing {ponger: Pong} = new Ping { def ping() = ponger.pong() }
def mkPong {pinger: Ping} = new Pong { def pong() = pinger.ping() }

def pingr = unbox mkPing { pongr }
def pongr = unbox mkPong { pingr }
```

IIUC, this means that mutually recursive interface definitions are only possible on the toplevel, and not in LLVM.
Is this the behavior we want? Which of those should work? (Are there interesting other variants?)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.