effekt-lang / effekt

A language with lexical effect handlers and lightweight effect polymorphism
https://effekt-lang.org
MIT License
332 stars 24 forks source link

Unhelpful error message when boxing blocks #356

Open jiribenes opened 10 months ago

jiribenes commented 10 months ago

The motivation is wrapping a block into a box in order to facilitate a nicer API. (using orElse { ... } { ... } instead of orElse(box { ... }, box { ... }). I don't quite know whether this is just a bad error message or if it's an actual bug in Typer:

Here's the offending code:

interface OrElse {
  def orElse[T](m1: => T / {} at {}, m2: => T / {} at {}): T 
}

def orElse[T] { m1: => T / {} }{ m2: => T / {} }: T / {OrElse} = {
  do orElse(box { m1 }, box { m2 })
}

which returns the following unhelpful message:

Screenshot 2024-01-12 at 17 52 30

If I just ANF it, I get the same message. When I remove the braces, I get a different error:

interface OrElse {
  def orElse[T](m1: => T / {} at {}, m2: => T / {} at {}): T 
}
def orElse[T] { m1: => T / {} }{ m2: => T / {} }: T / {OrElse} = {
  val f1 = box m1;
  val f2 = box m2;
  do orElse(f1, f2)
}

returns:

Screenshot 2024-01-12 at 17 51 07
b-studios commented 10 months ago

I think there are a few different issues here. The first error message is indeed confusing.

However, the second message is expected: you are passing f1 which has capture m1 to the operation which requires an empty capture set.

On a high level: I deeply understand the motivation of avoiding box in the API but I think it's not possible this way.

Maybe we can make it more lightweight by changing syntax somehow

jiribenes commented 10 months ago

On a high level: I deeply understand the motivation of avoiding box in the API but I think it's not possible this way.

I thought so, but I still wanted to report the confusing error message — dealing with boxing and captures is difficult already.

jiribenes commented 5 months ago

Update: the error is slightly different now (unfortunately still unhelpful though...)

Screenshot 2024-06-04 at 14 00 05
jiribenes commented 1 month ago

Update: Current error on 0.3.0:

Screenshot 2024-09-25 at 23 24 03
jiribenes commented 15 hours ago

This issue popped up again, on 0.9.0, the following code:

record Container(eqz: Int => Bool at {})
def empty { eqz: Int => Bool }: Container =
  Container(box { eqz })

reports "Expected identifier" on the very last character (the closing paren) which is extremely unhelpful :(