ChezScheme
ChezScheme copied to clipboard
Add `single-valued` flag to primitives to help reduce `call-with-values` expressions
In particular this is useful to reduce begin0
expressions that have a single valued result, to avoid the creation of an intermediate lambda
or list
to save the value.
The single-valued
flag is autodetected from the signature, so it would be useful to add the signatures to the system
procedures.
This needs new bootfiles, so the checks in travis-ci fails. Look at this test instead.
I'm optimistic and I think this PR is correct, but I have a lot of related questions anyway:
I made a memoized version of single-valued?
instead of a direct one because it detect many more opportunities during the compilation of the compiler, specially in cpnanopass.ss
There is no memoized version of true-valued?
. I don't expect that it would be very useful, so I didn't modify it.
The functions simple?
and simple/profile?
use the same flag for memoization. Is that correct?
I added a special case to single-valued?
to detect call-with-values
, apply
and $apply
and go inside the procedure, because they always call the procedure and the result is the result of the call to the procedure. I think it's ok to avoid the arity check here. There are a few (5) similar functions, like call-with-port
, but I didn't add them because they are probably not used too much.
I made a similar change to boolean-valued?
because it also doesn't need too much checks. (It's possible to make a similar extension to pure?
and the other memoized functions, but they must ensure that there are no errors, so I didn't modify them.)
I was thinking about adding the single-valued
flag to the true
and boolean-valued
flags (like pure
, that implies discard
). I finally didn't change that.
Update:Ijust added an special case for dynamic-wind
.
I rebased the commit. The second commit has some improvements based in code by @mflatt , but I made some changes. (I think they should be squashed before merging.)
I made the flags boolean
and true
imply single-valued
. I think it make more sense, specially because boolean
is autodetected from the signature, and true
can also be autodetected in the future.
I'd like to make abort-op
imply boolean
, true
and single-valued
too. It can be helpful to detect the boolean
result in code like
(if (something) (list? x) (error))
I didn't make mifoldable
imply single-valued
. I'm not sure what is better here. The code for the reduction of mifoldable
expressions with multiple results is wrong (it generates an exception that is catched and discarded, so the net effect is nothing). It can be fixed modifying the reduction for mifoldable or adding a cp02 version for exact-integer-sqrt that is the only case.
I didn't make pure
imply single-valued
neither. I'm not sure what is better here. I tried to follow the code but I was confused, so I'm not sure if the pure
functions with multiple return values are reduced or not. Anyway, there are only a few (5?) primitives that would be affected.
Tiny update: Change the signature of exact-integer-sqrt
to use uint
instead of integer
. (This should be squashed before merging.)
Included in v9.9.9 merge 47daa9b34016de84fd111801d9d589d15a523abe.