effekt-lang / effekt-lang/effekt
Cannot automatically unbox a boxed function if it's a record field
- 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