A few days ago, I changed the Mint compiler to allow non-void code objects to be spliced in where statement form is required:
1 2 | Code<Integer> x = <| 1 |>; Code<Void> c = <| { `x } |>; |
This essentially generates the code below, which allows the 1
to be discarded:
1 |
Eddy pointed out that there is still a problem: Since I do a static type check on the type argument of Code<T>
, the proper form cannot be determined if there is a wildcard Code<?>
. We can check at run-time whether a code object is in statement form or whether it is an expression whose result needs to be discarded, but we cannot simply write an if-statement, because one of the alternatives would always be syntactically incorrect:
1 2 3 4 5 | <| { if (c.isStat) { `c; // already in statement form } else { Object temp = `c; // expression, discard result } } |>; |
If c.isStat
is true, then the else-branch is syntactically incorrect; if c.isStat
is false, then there is a syntax error in the then-branch. Eddy pointed out that we can handle the Code<?>
case, though, because the two branches are in future-stage code. That is, we can turn
1 | <| { `(c); } |> |
into
1 2 3 4 5 |
Unfortunately, this gets more complicated if there is more than one Code<?>
being escaped in. We would have cases, where
is the number of
Code<?>
objects being stitched in:
1 | <| { `(c); `(d); } |> |
would have to be turned into
1 2 3 4 5 6 7 8 9 |
I think for now I will change the compiler so that escaping a Code<?>
in as a statement generates a compiler error. It seems like this is an unimportant corner case, and I don’t want to spend my time on something that is rarely beneficial. Again, this only happens for Code<?>
, and only when escaping into bracket with a code block where statement form is required by Java rules.