Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jiribenes opened this issue Oct 4, 2024 · 0 comments
Open
Labels
feature New feature or request quality-of-life

Comments

@jiribenes
Copy link
Contributor

jiribenes commented Oct 4, 2024

This is a minified version of a boxing[?]-related issue arising in #561:

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
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:

if (idx > 0 and (heap.cmp)(arr.unsafeGet(parent(idx)), arr.unsafeGet(idx)) is Greater()) {

ANF-ing the s.eq(k, 0) like this:

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"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request quality-of-life
Projects
None yet
Development

No branches or pull requests

1 participant