koka-lang / koka

Koka language compiler and interpreter
http://koka-lang.org
Other
3.26k stars 161 forks source link

Internal compiler error ("label is not a constant") where single-letter effect is in angle brackets #353

Closed JanBeh closed 9 months ago

JanBeh commented 1 year ago

The following program causes a compiler error on Koka 2.4.2:

fun x() : <e> ()
  ()

Output:

*** internal compiler error: Type.Type.labelNameEx: label is not a constant
JanBeh commented 1 year ago

Possibly related:

evertedsphere commented 1 year ago

The cause of this is:

tid
  = do (id,rng) <- qvarid <|> typeidCtx
       return (if isTypeVar id then TpVar id rng else TpCon id rng)
  <|>
    do (id,rng) <- wildcard <?> ""
       return (TpVar id rng)

where isTypeVar generalises incorrectly in the presence of type variables that are a single lowercase letter:

isTypeVar :: Name -> Bool
isTypeVar name
  = case nameId name of
      (c:cs) -> (isLower c && all isDigit cs)
      _      -> False

I'm not sure what the intention is here (I'm new to Koka and this issue is my first time looking around). If this is intended to handle metavariables or similar (given that digits at the end are allowed), perhaps the numeric suffix could be required to be nonempty. If this is intended to allow for automatic universal quantification (à la Haskell) over effects, it seems unintuitive for it to be restricted to single-character type variables.

(Also, how do I write a forall explicitly in the type for a normal function when binding a type variable at the top level? The book doesn't seem to have any examples of the precise syntax required, and all the foralls in the library are either externs or bound in the type of an argument.)

cc @b-studios

TimWhiting commented 1 year ago

I have run into the pain point of only being able to use single-character type variables, and from my experience, this is intended to allow for automatic universal quantification.

For a normal function a forall looks like this I think:

fun first<a>(x: list<a>, y: a): a
  x.head.default(y)

Note that having a forall in the parameters seems to require an annotation for the return value as well if it depends on an argument that contains forall type.

TimWhiting commented 9 months ago

This is fixed on dev and will be in the next release