-
Notifications
You must be signed in to change notification settings - Fork 983
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
make-parameter with non-unit converter function #409
Comments
Parameterize has to call the parameter in order to restore its previous value, which will invoke the converter function. Since your converter function modifies the value it's storing, every time you restore the previous value it will be increased by 10. |
In the design of R7RS, when the body of Will Chez Scheme follow this semantic? |
Actually, R7RS states (in Section 4.26):
Since the conversion procedure in this case is not idempotent, Chez Scheme's semantics seem compatible with R7RS. |
I don't share the opinion that the current behavior of chez is correct as per R7RS:
|
I read through the make-parameter and parameterize section of r7rs and saw this:
So, the initial expectation is correct, with respect to r7rs. |
Let's leave the conversation about R7RS for a moment, which is somewhat moot since Chez Scheme is an R6RS implemntion not an R7RS implementation, and talk about the interface that function generated by The procedure produced by This still admits many useful filter procedures and we use them fairly extensively. We are just restricted to the procedures that return the same value for value they return. This can be as simple as a procedure that converts its arguments into boolean values: (lambda (x) (and x #t)) Or more complicated, such as one that expects a boolean or output-port and returns an input-port or false, (lambda (x)
(cond
[(eq? x #t) (console-output-port)]
[(eq? x #f) #f]
[(and (output-port? x) (textual-port? x)) x]
[else (error #f "expected boolean or textual output port" x)])) This hints at our primary use of this, which is to restrict the values the parameter can take on: (lambda (x)
(unless (procedure? x) (error #f "expected procedure" x))
x) At any rate, not useless at all, though not designed with your use case in mind. The advantage to this implementation is that it is very simple and gets the advantage that mutable cell that holds the value of the parameter is isolated to a single single source point in the program, with some protection around what values it might hold. An implementation like that in SRFI-39 provides the behavior you want, with the complication that the procedure produced by It is possible, in fact, to get the behavior you want by using SRFI-39 in your program, instead of Chez Scheme's implementation of Back to the R7RS. My apologies on my misreading of this, in my quick scan I had missed the sentence:
That is what I get for scanning this quickly while I'm waiting on a test to finish at work. |
Yep, missed that on my quick read through, should have been more thorough, my apologies. |
thanks for the detailed explanation, very helpful! In fact I don't have an issue with the chez implementation but just stumbled over this because I am writing a toy scheme, and use chez as a reference in some cases. I kinda understand how chez implements this, but there is one part that to me seems more like an implementation choice than a necessity: you are saying that the conversion is executed on the parameter function each time, but that parameter function is returned by make-parameter, which just gets an init value. so can it not use the init value each time rather than the parameter? That would result in the conversion/filter not getting called in a nested way... |
No, the procedure returned by (let ([v (guard init)])
(case-lambda
[() v]
[(u) (set! v (guard u))])) Where In order to support setting |
Parameters originated in Chez Scheme as a replacement for plain variables when customizing the behavior of a procedure or subsystem through some method other than passing extra arguments. For example, the One reason why parameters are superior to variables is that the new value can be checked when the parameter is set. For example, Another is that a parameter can act upon the new value whenever it is set. For example, A parameter can even do non-trivial things when referenced. For example, The r7rs parameter mechanism is less expressive than Chez Scheme's in at least three ways:
So Chez Scheme won't be adopting the r7rs semantics, outside of a possible future r7rs compatibility library. In any case, the behavior described in the original post is correct. Other behaviors are also correct depending on the evaluation order of the arguments to |
great discussion and feedback, thanks a lot! |
I am using make-parameter with a custom converter function like so:
which gives me:
I don't think this is correct, I think it should be:
also note that if I remove the innermost parameterize, I get:
So the parameterize seems to affect the outer binding, that can't be right! Perhaps the converter function gets called at the wrong point? or perhaps in the wrong context so that it sees it's own previous value as an input?
The text was updated successfully, but these errors were encountered: