Open jaredly opened 1 year ago
Here's a third option.
Right now various constructors that wrap unboxed types are designated as 'newtypes' in the scheme code emitter. This causes there to be no data
wrapper around them. The point being that they're already first-class scheme objects, so they don't need to be wrapped to behave appropriately like they do in Haskell. Also, matching on the data part of a 'newtype' is a no-op. We just turn match x with N y -> ...
into essentially let x = id y in ...
.
Char
could be slightly different, where the constructor applies the Nat -> Char
transformation, and unpacking applies the Char -> Nat
transformation. Then these implementations work, because they are composites of an identity (un)pack and a coercing (un)pack. And also any other builtins that (un)pack a Char
expecting it to contain the same unboxed stuff as a Nat
will also work, although I don't know if there are any other examples.
Unison considers conversion between
char
andnat
to be a simple casthttps://github.com/unisonweb/unison/blob/bba24cd2425ef15ca6c43d656c4eea2a78a26e32/parser-typechecker/src/Unison/Runtime/Builtin.hs#L1998-L1999
Because of this, the generated chez code for
Char.toNat
andChar.fromNat
isidentity
.But in the chez & racket runtimes, they are considered distinct, so performing
fx+
on chars results in a runtime error. (in racket, preformingunsafe-fx+
on chars results in a special#garbage
value, which is also a problem).Solutions I can see: 1) special-case these builtins in
SchemeDefn.toIndentedText
as I do in this draft PR 2) modify builtin.hs to indicate that, while they are treated the same by the unison / haskell runtime, they need to be explicitly converted under scheme