-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reevaluate use of Store
/references for recursive variables
#1948
Comments
OK, it is necessary, and I remember/understand why now after trying the experiment of removing them. I will write up an explanation here, and leave this open until I have added more comments in the source code (I will wait until after merging #1928). Evaluating a non-recursive To evaluate a recursive However, we do actually need to put something in the environment! Consider a (bogus) definition like One potential solution is to put some special "blackhole" value for the variable into the context. If this value is ever encountered, that means the value of the variable was needed to compute its own value, and we can throw an "infinite loop detected" error. So the idea is this: when evaluating This sounds great, but it's actually subtly wrong! The problem is that the value of something like a lambda is a closure that captures its current environment. This is absolutely critical to make lambdas work correctly. But it also means that, in this example, the value of The simplest solution is to have All that is well and good, but I still think there may be an opportunity to simplify the code --- I am not sure whether we need the complication of incorporating delay/force. i.e. maybe we can get away with memory cells in the store having only two possible states: |
This old discussion is relevant: #150 |
After reading the discussion linked above, I can see why we might want the "memoized delay" for building lazy data structures, but I think it was a mistake to use this mechanism for evaluating recursive bindings. Currently, to evaluate a recursive I think we should be able to keep the memoized delay mechanism in place but stop using it for recursive bindings. I will give it a shot. |
Actually, I now think we should just
Once we add #1660, programmers can implement their own laziness, i.e. memoizing delay (if they want to e.g. make lazy infinite streams or whatever), as follows. Assume we have primitives
where
I am not sure whether we can get away with leaving off the |
I forget why I did it this way, and I am not sure that it is really necessary. It certainly introduces extra complication (e.g. the need to wrap free variables in
force
during elaboration). We should either get rid of it, or add some clear comments explaining why it is necessary.The text was updated successfully, but these errors were encountered: