Closed colin-mcd closed 2 years ago
(which is unintuitive). Is this wrong, or is it intended?
Well… it feels intuitive to me? In a call-by-value language (such as ML or Scheme but not Haskell), using fail
(throwing an exception) as an argument makes the entire application fail, even if the applied function does not use its argument. So (\ c:Bool. true) fail
should also fail. (Because the type of c
is Bool
and there is no arrow in this type Bool
, even the linear language allows this expression (\ c:Bool. true) fail
. And it's intuitive to me for this expression to fail, whether in the affine language or in the linear language.)
The way I'm thinking the affine-to-linear translation should work is
e
has unit type then discard e in
translates to let unit=e in
e
has pair type then discard e in
translates to let (x,y)=e in discard x in discard y in
e
has sum type then discard e in…
translates to case e of inl x -> discard x in… | inr y -> discard y in…
(actually it might be better to avoid duplicating …
by using an intermediate result of unit type)e
has function type then discard e in…
translates to case e of inl f -> fail | inr u -> let unit=u in…
e0 e1
translates to case e0 of inl f -> f e1 | inr u -> fail
as you know, and more interestingly, \ x1. e2
translates to if amb then inl (\ x1. e2) else discard all my free variables, or at least all my free variables whose types contain arrows, in inr unit
One possible solution (if it is indeed not desired), I think, would be to do the same trick we do with functions on all local variables.
As someone used to call-by-value, I'd ask those who desire this trick to change their c:Bool
to a thunk c:Unit->Bool
.
Alright, makes sense then! I'll close this issue, since this is indeed the desired behavior.
How should we make the affine term
\ b. (\ c. if b then true else c) fail
linear? If we follow the rules from the document and realize too that each individual case needs to use the same set of vars as each other case, then it becomesif amb then inl (\ b. case (if amb then inl (\ c. if b then (if c then true else true) else c) else (if b then inr unit else inr unit)) of inl f -> f fail | inr u -> fail) else inr unit
Note that
if b then true else c
becomesif b then (if c then true else true) else c
, which becausec
will befail
, would cause this term to fail even whenb
istrue
(which is unintuitive). Is this wrong, or is it intended?One possible solution (if it is indeed not desired), I think, would be to do the same trick we do with functions on all local variables. That way, c would get type
Bool + Unit
(fromif amb then inl fail else inr unit
), and thethen
case would fail on theinl fail
branch and proceed as normal on theinr unit
branch. EDIT: my proposed solution won't work for terms like\ b. if b then b else true
because in theelse
case it will assumeb
isinr unit
(failing if it isinl
), but because we useb
elsewhere (we are case splitting on it), it must already beinl
.