effekt-lang / effekt-lang/effekt

Cannot automatically unbox a boxed function if it's a record field

Open
#635 0 comments 0 reactions 0 assignees View on GitHub
feature quality-of-life
Dominant language
Scala
Stars
469
Forks
41
Avg merge
1d 16h
Merged PRs (30d)
23

Description

This is a minified version of a boxing[?]-related issue arising in #561:
```scala
record IntSet(eq: (Int, Int) => Bool at {})

def get(s: IntSet, k: Int) = {
s.eq(k, 0) match {
//~^~~~~~~~~
// ^ Wrong number of value arguments, given 3, but eq expects 1.

case true => <>
case false => <>
}
}
```

The actual failing example

```scala
record Map[K, V](m: MapInternal[K, V], cmp: (K, K) => Ordering at {})

type MapInternal[K, V] {
Bin(size: Int, k: K, v: V, left: MapInternal[K, V], right: MapInternal[K, V]);
Tip()
}

def get[K, V](map: Map[K, V], k: K): Option[V] = {
map.m match {
case Tip() => None()
case Bin(size, k2, v, l, r) =>
map.cmp(k, k2) match {
// ~~~^~~~~~~~~~~
case Less() => l.get(k)
case Greater() => r.get(k)
case Equal() => Some(v)
}
}
}
```

---

Interestingly enough, something similar seems to work perfectly fine in the heap example in #585:

https://github.com/effekt-lang/effekt/blob/72702b30a79eb7dee7f3478ef65be68076dd2d3b/libraries/common/heap.effekt#L26

ANF-ing the `s.eq(k, 0)` like this:
```scala
val zero? = s.eq(k, 0)
zero? match { ... }
```
doesn't work either, not even if I annotate the new binding with `: Bool`.

---

Of course, one can:
1. explicitly unbox: `(unbox s.eq)(k, 0)`, but that's not exactly pretty
2. unpack the `s`: `val Set(eq) = s; eq(k, 0) match { ... }`, but I don't like it either... :/
3. wrap in parens: `(s.eq)(k, 0)`, thanks to @marzipankaiser for the mention :)

However, I'd really like to write it directly: is there a way to see through this layer of indirection?
Or could we at least have a nicer error message here saying "try unpacking by hand"?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the minimal IntSet reproducer in the issue and compare its record-field call with the working heap.effekt example linked from #585. Trace how a boxed function is called through a record field, including the ANF variant, and consider the expected direct-call behavior or diagnostic; done when the direct form works or reports a clear remedy.

Written by the indexing model from the issue text.

Assessment

Tech stack
scala
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.