Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: > Deep binding has undesirable overhead of its own, as I'm sure you are > aware, i.e., reference cost proportional to the number of current dynamic > bindings. Yes, but at least I, as a user, can control whether to pay the price or now if they're available. With parameters, I can't. (I could do create the cells lazily doing some kind of copy-on-write, but as soon as the write happens, presumably I the price is paid then. At least when we were working on process cells for scsh, we couldn't figure out a truly satisfactory solution.) -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
I don't know how interested you are in continuing this benchmarking, but mzscheme has a model like chez's, but only allocates space for the parameters when they are changed. Different tradeoffs, I expect, but it would be at least one other data point. Robby On 2/23/07, R. Kent Dybvig <[EMAIL PROTECTED]> wrote: > > In implementation, yes. But my thread system is based on pthreads, and > > you'd have to have quite a few parameters to notice the difference in > > thread-creation or memory overhead. Applications don't typically use > > very many thread parameters in any case. > > It's still a problem that you pay for something even if you don't use > it: As the number of loaded libraries that use parameters grows, so do > all of your threads. This is probably not a problem in a system with > (comparatively) heavyweight threads such as pthreads Right, which was my point. While I doubt this would be a problem even with a lightweight thread system (it hasn't been with SWL), one could use instead a sparse representation that creates per-thread locations lazily, which should be possible at least for the ones that have their original values at the point where the thread is forked. > , but it is a > problem in systems where threads take up only a few words in the > absence of parameters. > (For reference, the Scheme 48 Scheme code contains 33 fluids---if > those were parameters, they would take up 33 slots in *each* thread, > which is significant given the lightweight nature of Scheme 48's > threads.) Maybe. Being skeptical, however, I installed Scheme48 on my Mac laptop and did a couple of quick tests. Test 1: attempt to determine the space overhead for maintaining a length-33 parameter vector. For both tests, I ran the following boilerplate code: ,open threads ,open spatial (define make-list (lambda (n x) (if (= n 0) '() (cons x (make-list (- n 1) x) (define spin1 (lambda () (let f () (f (define spin2 (lambda () (let f ((v (make-vector 33))) (f v ,collect For both runs, collect reported 772039 words free after collection. For run 1, I created 10 threads running spin1, which doesn't allocate a vector: (map spawn (make-list 10 spin1)) ,collect Collect reported 766974 words free after collection, a net difference of 5065 words. For run 2, I created 10 threads running spin2, which allocates a vector of length 33 (per thread): (map spawn (make-list 10 spin2)) ,collect In this case, collect reported 766604 words free after collection, a net difference of 5435 words, which is an increase in the net of 7.3% over run2. I ran a different test to see how the thread creation-time cost might be affected. Again I used two runs, this time with the following boilerplate code: ,open threads ,open spatial (define make-list (lambda (n x) (if (= n 0) '() (cons x (make-list (- n 1) x) (define quick1 (lambda () 0)) (define quick2 (lambda () (make-vector 33))) For the first run I created 1000 threads running quick1, which doesn't allocate a vector. ,time (begin (map spawn (make-list 1 quick1)) 0) For the second run I created 1000 threads running quick2, which allocates a vector of length 33 (per thread). ,time (begin (map spawn (make-list 1 quick2)) 0) The times reported over 10 tries of the first run ranged from .47 to .52 seconds, and for 10 tries of the second, .47 to .53 seconds. The average times were .482 and .483 seconds respectively, or essentially the same given the time variances. So, while 7.3% might or might not be considered significant space overhead, there's essentially no difference in time. Of course, with more thread parameters, both space and time overhead would go up. It's impossible to extrapolate from the timing numbers, but extrapolating from the space numbers, we'd pass 100% overhead, i.e., double the space taken up by each running thread, at about 451 thread parameters. > (Pure deep binding doesn't have this problem.) Deep binding has undesirable overhead of its own, as I'm sure you are aware, i.e., reference cost proportional to the number of current dynamic bindings. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
I am posting this as an individual member of the Scheme community. I am not speaking for the R6RS editors, and this message should not be confused with the editors' eventual formal response. Kent Dybvig quoting Mike Sperber: > > (Pure deep binding doesn't have this problem.) > > Deep binding has undesirable overhead of its own, as I'm sure you are > aware, i.e., reference cost proportional to the number of current dynamic > bindings. And deep binding can, of course, be cached on a per-thread basis, which does not, of course, change the worst-case behavior, which I could go on about, but... I think you guys have reached the point where you are arguing over minutia. In particular, the performance issues appear miniscule compared to many other costs that are being introduced by the draft R6RS (e.g. the as-yet-unknown-but-quite-possibly-significant cost of letrec* semantics for internal and library definitions), and the semantic issues appear miniscule considering the fact that Scheme doesn't even have a portable memory model for multi-threaded execution. Will ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> > In implementation, yes. But my thread system is based on pthreads, and > > you'd have to have quite a few parameters to notice the difference in > > thread-creation or memory overhead. Applications don't typically use > > very many thread parameters in any case. > > It's still a problem that you pay for something even if you don't use > it: As the number of loaded libraries that use parameters grows, so do > all of your threads. This is probably not a problem in a system with > (comparatively) heavyweight threads such as pthreads Right, which was my point. While I doubt this would be a problem even with a lightweight thread system (it hasn't been with SWL), one could use instead a sparse representation that creates per-thread locations lazily, which should be possible at least for the ones that have their original values at the point where the thread is forked. > , but it is a > problem in systems where threads take up only a few words in the > absence of parameters. > (For reference, the Scheme 48 Scheme code contains 33 fluids---if > those were parameters, they would take up 33 slots in *each* thread, > which is significant given the lightweight nature of Scheme 48's > threads.) Maybe. Being skeptical, however, I installed Scheme48 on my Mac laptop and did a couple of quick tests. Test 1: attempt to determine the space overhead for maintaining a length-33 parameter vector. For both tests, I ran the following boilerplate code: ,open threads ,open spatial (define make-list (lambda (n x) (if (= n 0) '() (cons x (make-list (- n 1) x) (define spin1 (lambda () (let f () (f (define spin2 (lambda () (let f ((v (make-vector 33))) (f v ,collect For both runs, collect reported 772039 words free after collection. For run 1, I created 10 threads running spin1, which doesn't allocate a vector: (map spawn (make-list 10 spin1)) ,collect Collect reported 766974 words free after collection, a net difference of 5065 words. For run 2, I created 10 threads running spin2, which allocates a vector of length 33 (per thread): (map spawn (make-list 10 spin2)) ,collect In this case, collect reported 766604 words free after collection, a net difference of 5435 words, which is an increase in the net of 7.3% over run2. I ran a different test to see how the thread creation-time cost might be affected. Again I used two runs, this time with the following boilerplate code: ,open threads ,open spatial (define make-list (lambda (n x) (if (= n 0) '() (cons x (make-list (- n 1) x) (define quick1 (lambda () 0)) (define quick2 (lambda () (make-vector 33))) For the first run I created 1000 threads running quick1, which doesn't allocate a vector. ,time (begin (map spawn (make-list 1 quick1)) 0) For the second run I created 1000 threads running quick2, which allocates a vector of length 33 (per thread). ,time (begin (map spawn (make-list 1 quick2)) 0) The times reported over 10 tries of the first run ranged from .47 to .52 seconds, and for 10 tries of the second, .47 to .53 seconds. The average times were .482 and .483 seconds respectively, or essentially the same given the time variances. So, while 7.3% might or might not be considered significant space overhead, there's essentially no difference in time. Of course, with more thread parameters, both space and time overhead would go up. It's impossible to extrapolate from the timing numbers, but extrapolating from the space numbers, we'd pass 100% overhead, i.e., double the space taken up by each running thread, at about 451 thread parameters. > (Pure deep binding doesn't have this problem.) Deep binding has undesirable overhead of its own, as I'm sure you are aware, i.e., reference cost proportional to the number of current dynamic bindings. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> Then the relevant section of our paper is directly applicable. > > Not at all. The mere existence of thread-local storage does not cause any > problems. The problems arise with the hypothetical dynamic-binding and > capture mechanisms described in the section. There's no reason to believe > that they also arise with parameterize. The section I was referring to (5.3) talks about thread-local storage, and its negative effects. The problems aren't tied to any specific dynamic-binding mechanism---as soon as you have thread-local cells, (and you do) the problems arise. The paragraph that talks about capture mechanisms (it doesn't talk about any hypothetical "dynamic-binding mechanism, as far as I can see) identifies *additional* problems, depending on the specific choices you make. You may think that the choices you are the right ones, but they aren't obvious, and come with a specific set of trade-offs. I personally find remembering the particular choices made in a given system, and their consequences for modular programs difficult, which is why I dislike parameters. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> I've got an operational question: The description seems to indicate >> that the sheer presence of a parameter leads to the allocation of >> storage in each thread, whether the thread accesses the parameter or >> not. Does this mean that, the more live parameters there are in the >> system, the more expensive threads become? > > In implementation, yes. But my thread system is based on pthreads, and > you'd have to have quite a few parameters to notice the difference in > thread-creation or memory overhead. Applications don't typically use > very many thread parameters in any case. It's still a problem that you pay for something even if you don't use it: As the number of loaded libraries that use parameters grows, so do all of your threads. This is probably not a problem in a system with (comparatively) heavyweight threads such as pthreads, but it is a problem in systems where threads take up only a few words in the absence of parameters. (Pure deep binding doesn't have this problem.) (For reference, the Scheme 48 Scheme code contains 33 fluids---if those were parameters, they would take up 33 slots in *each* thread, which is significant given the lightweight nature of Scheme 48's threads.) Consequently, adopting parameters now restricts the choices available to implementors and users later. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> Then the relevant section of our paper is directly applicable. Not at all. The mere existence of thread-local storage does not cause any problems. The problems arise with the hypothetical dynamic-binding and capture mechanisms described in the section. There's no reason to believe that they also arise with parameterize. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
R. Kent Dybvig scripsit: > In implementation, yes. But my thread system is based on pthreads, and > you'd have to have quite a few parameters to notice the difference in > thread-creation or memory overhead. Applications don't typically use > very many thread parameters in any case. The same points apply to Chicken, which stashes parameters constructed by make-parameter (the only kind that are per-thread) in a per-thread vector. -- What asininity could I have uttered John Cowan <[EMAIL PROTECTED]> that they applaud me thus? http://www.ccil.org/~cowan --Phocion, Greek orator ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> I've got an operational question: The description seems to indicate > that the sheer presence of a parameter leads to the allocation of > storage in each thread, whether the thread accesses the parameter or > not. Does this mean that, the more live parameters there are in the > system, the more expensive threads become? In implementation, yes. But my thread system is based on pthreads, and you'd have to have quite a few parameters to notice the difference in thread-creation or memory overhead. Applications don't typically use very many thread parameters in any case. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> As dynamic binding can be implemented in > terms of `dynamic-wind' anyway, I don't see how this is relevant. It's only relevant in that your claim was bogus. > What I'm interested in, however, it whether my implementation is > faithful to your semantics. Is it? Well, it's my code, so yes I guess it is. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >>From Section 13.4: > > When a thread parameter is created, a separate location is set aside in > each current and future thread to hold the value of the parameter's > internal state variable. (This location may be eliminated by the > storage manager when the parameter becomes inaccessible.) Changes to the > thread parameter in one thread are not seen by any other thread. I've got an operational question: The description seems to indicate that the sheer presence of a parameter leads to the allocation of storage in each thread, whether the thread accesses the parameter or not. Does this mean that, the more live parameters there are in the system, the more expensive threads become? -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Michael Sperber scripsit:
> So, in effect, parameters give you thread-local cells, right?
Well, provided threads are implemented on top of continuations
("green threads") and not primitively underneath them.
--
I could dance with you till the cowsJohn Cowan
come home. On second thought, I'd http://www.ccil.org/~cowan
rather dance with the cows when you [EMAIL PROTECTED]
came home. --Rufus T. Firefly
___
r6rs-discuss mailing list
[email protected]
http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: > You haven't implemented parameters in terms of your dynamic binding, > that's how. You've merely presented my own implementation of > parameterize in terms of dynamic-wind back to me and put in code the > exact implementation of make-thread-parameter that I described. In > short, you've done nothing to prove your claim that you could > implement parameters with your dynamic-binding mechanism plus > thread-local storage. Do you now admit that this claim is false? Ermh, I admit I haven't *used* dynamic binding, and only thread-local storage. When I wrote the original message, I didn't fully understand your semantics, and wasn't sure whether dynamic binding was required. (Specifically, I wasn't sure whether a parameter is a thread-local cell with binding thrown in or a dynamically-bound variable bound to a thread-local location.) As dynamic binding can be implemented in terms of `dynamic-wind' anyway, I don't see how this is relevant. What I'm interested in, however, it whether my implementation is faithful to your semantics. Is it? -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> So, in effect, parameters give you thread-local cells, right? >> >> (define (make-thread-cell v) (make-parameter v)) >> (define (thread-cell-ref c) (c)) >> (define (thread-cell-set! c v) (c v)) > > Yes, if although in Chez Scheme you have to replace make-parameter with > make-thread-parameter. Thread parameters *are* thread-local cells. Then the relevant section of our paper is directly applicable. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> >> I was assuming I'd use your definition unchanged. > > But, to repeat, here's your definition: > > (define-syntax parameterize > (lambda (x) > (syntax-case x () > [(_ ((x v) ...) e1 e2 ...) > (with-syntax ([(p ...) (generate-temporaries #'(x ...))] >[(y ...) (generate-temporaries #'(x ...))]) >#'(let ([p x] ... [y v] ...) >(let ([swap (lambda () (let ([t (p)]) (p y) (set! y t)) ...)]) > (dynamic-wind #t swap (lambda () e1 e2 ...) swap]))) > > How does it fall down? You haven't implemented parameters in terms of your dynamic binding, that's how. You've merely presented my own implementation of parameterize in terms of dynamic-wind back to me and put in code the exact implementation of make-thread-parameter that I described. In short, you've done nothing to prove your claim that you could implement parameters with your dynamic-binding mechanism plus thread-local storage. Do you now admit that this claim is false? Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> So, in effect, parameters give you thread-local cells, right? > > (define (make-thread-cell v) (make-parameter v)) > (define (thread-cell-ref c) (c)) > (define (thread-cell-set! c v) (c v)) Yes, if although in Chez Scheme you have to replace make-parameter with make-thread-parameter. Thread parameters *are* thread-local cells. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: > This allows different threads to assign different default values to its > parameters, with only those that are parameterized by a continuation > overriding those defaults. For example, I might want each thread to > redirect its diagnostic output to a different port by setting the > current-output-port parameter while letting a continuation determine the > values of other parameters via parameterize. So, in effect, parameters give you thread-local cells, right? (define (make-thread-cell v) (make-parameter v)) (define (thread-cell-ref c) (c)) (define (thread-cell-set! c v) (c v)) -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> > Okay, but where's the definition of parameterize in terms of your >> > dynamic binding construct? It didn't make it into your note. >> >> I was assuming I'd use your definition unchanged. > > [...] > I'm looking for proof of this claim, i.e., a definition of the parameter > mechanism in terms of your dynamic-binding mechanism and thread-local > storage. So far you've only offered up a definition of make-parameter > that is independent of your dynamic-binding mechanism and no definition of > parameterize. I wrote: >> I was assuming I'd use your definition unchanged. But, to repeat, here's your definition: (define-syntax parameterize (lambda (x) (syntax-case x () [(_ ((x v) ...) e1 e2 ...) (with-syntax ([(p ...) (generate-temporaries #'(x ...))] [(y ...) (generate-temporaries #'(x ...))]) #'(let ([p x] ... [y v] ...) (let ([swap (lambda () (let ([t (p)]) (p y) (set! y t)) ...)]) (dynamic-wind #t swap (lambda () e1 e2 ...) swap]))) How does it fall down? -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Feb 21, 2007, at 10:31 AM, Michael Sperber wrote: "R. Kent Dybvig" <[EMAIL PROTECTED]> writes: So you directly contradicted yourself from one note to the next. I missed that, obviously. Could you clarify? I can clarify. Here are two sentences posted by you along with the dates and times: On Feb 20, 2007, at 12:26 PM, Michael Sperber wrote: This suggests to me that parameters, as intended by you, are an even more general mechanism than dynamic binding and thread-local assignment. On Feb 20, 2007, at 3:02 PM, Michael Sperber wrote: Nice try! However, parameters are neither simple nor general. So, in two and a half hours, parameters changed from begin too general to being not general enough. I believe this is what Kent means by you directly contradicting yourself from one note to the next. Aziz,,,___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> Just as a quick clarification: if, in the scenario below, thread T2 > uses parameterize to change P1 and P2 before invoking K1 (instead of > mutation), then the values seen by the whatever's left to be done in > the continuation K1 would be 0 and 1, not 2 and 2, right? If you mean that code executed in K1 would see P1=1 and P2=0, then you are correct. Parameterize affects only the code in its continuation, and the continuation in T2 that parameterizes P1 and P2 is aborted when K1 is invoked, so the code executed in K1 sees the original value of P2 and the T1-parameterized value of P1. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> > Okay, but where's the definition of parameterize in terms of your > > dynamic binding construct? It didn't make it into your note. > > I was assuming I'd use your definition unchanged. In: http://lists.r6rs.org/pipermail/r6rs-discuss/2007-February/001561.html you wrote: In contrast, dynamic binding as a separate mechanism is simple and modular. Combined with thread-local storage (less simple and not modular, but still simpler than parameters), you can build parameters. I'm looking for proof of this claim, i.e., a definition of the parameter mechanism in terms of your dynamic-binding mechanism and thread-local storage. So far you've only offered up a definition of make-parameter that is independent of your dynamic-binding mechanism and no definition of parameterize. In fact, I don't think your dynamic binding mechanism is capable of implementing parameterize, in combination with thread-local storage or otherwise, so if we want parameterize, we have to use something like my definition. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Just as a quick clarification: if, in the scenario below, thread T2 uses parameterize to change P1 and P2 before invoking K1 (instead of mutation), then the values seen by the whatever's left to be done in the continuation K1 would be 0 and 1, not 2 and 2, right? In code, the first program is what Kent describes below in mzscheme notation and the second is the change I'm asking about (and we see what he predicts for the first case): ;; program 1, like Kent's below (define p1 (make-parameter 0)) (define p2 (make-parameter 0)) (define k #f) (define t (thread (λ () (parameterize ([p1 1]) (write ((call/cc (λ (_k) (set! k _k) void (newline) (thread-wait t) ;; wait for t to complete (thread (λ () (p1 2) (p2 2) (k (λ () (list (p1) (p2)) ;; program 2, the one I'm asking about: (define p1 (make-parameter 0)) (define p2 (make-parameter 0)) (define k #f) (define t (thread (λ () (parameterize ([p1 1]) (write ((call/cc (λ (_k) (set! k _k) void (newline) (thread-wait t) (thread (λ () (parameterize ([p1 2] [p2 2]) (k (λ () (list (p1) (p2))) Robby On 2/21/07, R. Kent Dybvig <[EMAIL PROTECTED]> wrote: > So the swapping compensates for the effect of side effects, and gets a > notion similar to "call/cc captures the contents of the storage > associated with the parameters." Except it seems to break down in the > presence of threads, as Kent explained here: > > http://lists.r6rs.org/pipermail/r6rs-discuss/2007-February/001536.html There's no claim of any break down in that note, just a clarification: call/cc effectively captures only the values of the parameters that are parameterized in the continuation, rather than the values of all parameters. Here's an example illustrating the difference. Let's assume that: parameter P1 is defined to be 0 parameter P2 is defined to be 0 thread T1 parameterizes P1 to 1 then grabs a continuation K1 thread T2 assigns P1 to 2 and P2 to 2, then invokes K1 If call/cc were to capture the current contents of *all* parameter locations: code run in K1 by T2 would see P1 = 1 and P2 = 0 Since, however, call/cc actually captures only the current contents of the parameters parameterized in the continuation, only the value of P1 is captured, and code run in K1 by T2 actually sees P1 = 1 and P2 = 2 This allows different threads to assign different default values to its parameters, with only those that are parameterized by a continuation overriding those defaults. For example, I might want each thread to redirect its diagnostic output to a different port by setting the current-output-port parameter while letting a continuation determine the values of other parameters via parameterize. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> So the swapping compensates for the effect of side effects, and gets a > notion similar to "call/cc captures the contents of the storage > associated with the parameters." Except it seems to break down in the > presence of threads, as Kent explained here: > > http://lists.r6rs.org/pipermail/r6rs-discuss/2007-February/001536.html There's no claim of any break down in that note, just a clarification: call/cc effectively captures only the values of the parameters that are parameterized in the continuation, rather than the values of all parameters. Here's an example illustrating the difference. Let's assume that: parameter P1 is defined to be 0 parameter P2 is defined to be 0 thread T1 parameterizes P1 to 1 then grabs a continuation K1 thread T2 assigns P1 to 2 and P2 to 2, then invokes K1 If call/cc were to capture the current contents of *all* parameter locations: code run in K1 by T2 would see P1 = 1 and P2 = 0 Since, however, call/cc actually captures only the current contents of the parameters parameterized in the continuation, only the value of P1 is captured, and code run in K1 by T2 actually sees P1 = 1 and P2 = 2 This allows different threads to assign different default values to its parameters, with only those that are parameterized by a continuation overriding those defaults. For example, I might want each thread to redirect its diagnostic output to a different port by setting the current-output-port parameter while letting a continuation determine the values of other parameters via parameterize. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: > So you directly contradicted yourself from one note to the next. I missed that, obviously. Could you clarify? > I've read that section several times without getting much out of it, but > nothing I see there applies to the parameter mechanism. Don't Chez's parameters provide the kind of thread-local storage the paper talks about? (I'm really not sure at this point.) > To replace parameters with your restricted construct, one need only > define your value-binding construct in terms of parameters and use > it in place of parameters. That's not enough for your particular API, as you can't take away mutation from an existing, provided parameter. > Okay, but where's the definition of parameterize in terms of your > dynamic binding construct? It didn't make it into your note. I was assuming I'd use your definition unchanged. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> What's the four-argument version of `dynamic-wind'? Oops, sorry. The #t argument tells dynamic-wind to execute the in and out thunk invocations uninteruptably along with their addition to or removal from the winders list, which makes the code more robust if interrupts (like keyboard or timer interrupts) can occur. I should have left it out of the version I posted. > > Anyway, didn't you just complain that parameters are too general? > > Yes. So? So you directly contradicted yourself from one note to the next. > >> Moreover, the particular design you chose is problematic because it > >> destroys modularity. > > > > You've offered no evidence to this effect here or in your Scheme workshop > > paper, which does not anticipate the design. > > The paper doesn't anticipate anything. The authors did, however. If > I understand the semantics of Chez's parameters with respect correctly > (I probably still don't), then the scenario section 5.3 of the paper > applies. If it doesn't, I hope you'll enlighten me. I've read that section several times without getting much out of it, but nothing I see there applies to the parameter mechanism. > Mutation is insidious in that, operating > behind the scenes, it breaks through abstractions. Take the (r6rs > mutable-pairs) library: Abstracting over it is not enough to get the > benefits of its absence. Abstracting would be sufficient, but mutable pairs are so pervasive that doing so is impractical. For the programmer to replace mutable pairs with their own immutable pairs, the programmer would have to recode all of the library primitives that accept list or pair arguments, lambda, the reader, and the printer. To replace parameters with your restricted construct, one need only define your value-binding construct in terms of parameters and use it in place of parameters. Mutable pairs also affect efficiency in a pervasive manner; to eliminate this one would have to rewrite parts of the compiler and storage manager. There's no such pervasive efficiency problem here, and if there were, one would have to eliminate the constructs parameters are defined in terms of, e.g., set! and dynamic-wind, as well as parameters to get any benefit beyond that derived by definining your value-binding construct in terms of parameterize. > I'm still unsure of the semantics of Chez's `parameterize' > wrt. threads, so I'll probably get it wrong at first try. Here's it, > in terms of your code: Forget about threads then and just define a version that works in the degenerate case of a single-threaded system. > (define make-parameter > (case-lambda >[(init guard) > (let ([v (make-thread-cell (guard init))]) > (case-lambda >[() v] >[(u) (thread-cell-set! v (guard u))]))] >[(init) (make-parameter init values)])) Okay, but where's the definition of parameterize in terms of your dynamic binding construct? It didn't make it into your note. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Abdulaziz Ghuloum scripsit: > Swapping is needed, rather than restoring the old value, so that when > you get out of the dynamic context, and then back in, the value of the > parameter is restored to what it was when you got out, not to what it > was when you first got in. Maybe a simple example is a better > explanation. Thanks, that was very helpful. (Chicken's built-in "parameterize" behaves identically to your definition, except that it doesn't like escape procedures called without an argument. Changing (out-k) to (out-k 0) makes all well.) BTW, the point of posting the Chicken source was not to show how Chicken does it, particularly, but rather to show that most of the code is specific to thread support. This is in the end the main reason to standardize parameters: so that implementers who provide threads (almost everybody) can make parameters and threads interoperate (whether by cloning or by refreshing). A portable implementation of parameters will inevitably be thread-blind. -- John Cowan[EMAIL PROTECTED]http://ccil.org/~cowan If a traveler were informed that such a man [as Lord John Russell] was leader of the House of Commons, he may well begin to comprehend how the Egyptians worshiped an insect. --Benjamin Disraeli ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Abdulaziz Ghuloum <[EMAIL PROTECTED]> writes: > On Feb 21, 2007, at 5:30 AM, Michael Sperber wrote: > >> So the swapping compensates for the effect of side effects, and gets a >> notion similar to "call/cc captures the contents of the storage >> associated with the parameters." Except it seems to break down in the >> presence of threads, as Kent explained here: >> >> http://lists.r6rs.org/pipermail/r6rs-discuss/2007-February/001536.html > > I don't see how Kent "explained" that the model breaks down. You're right he didn't really explain, but he did contradict the statement I made above. As to what that means precisely, I'm hoping Kent will clear up in the course of the discussion. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Feb 20, 2007, at 11:05 PM, John Cowan wrote: Apparently, Chicken requires parameter procedures to return only one value. So does Chez. In the following, using the procedure "values" as a guard is a shorthand for (lambda (x) x) since returning multiple values to a single-value context raises an error in Chez. (define make-parameter (case-lambda [(init guard) (let ([v (guard init)]) (case-lambda [() v] [(u) (set! v (guard u))]))] [(init) (make-parameter init values)])) Aziz,,,___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Feb 21, 2007, at 6:00 AM, Abdulaziz Ghuloum wrote: I don't see how Kent "explained" that the model breaks down. All I can get is Kent making a distinction between ... and ... Of course I'm not speaking for Kent. He can correct me if I'm wrong. Aziz,,,___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Feb 21, 2007, at 5:30 AM, Michael Sperber wrote: Abdulaziz Ghuloum <[EMAIL PROTECTED]> writes: [Lots of explanation] Basically, in your model, you lose side effects when you exit the dynamic context, while in Kent's model, side effects to parameters are remembered and restored properly. So the swapping compensates for the effect of side effects, and gets a notion similar to "call/cc captures the contents of the storage associated with the parameters." Except it seems to break down in the presence of threads, as Kent explained here: http://lists.r6rs.org/pipermail/r6rs-discuss/2007-February/001536.html I don't see how Kent "explained" that the model breaks down. All I can get is Kent making a distinction between 1. manipulating a value stored in a parameter (using parameterize or by direct procedure application) and 2. mutating the location where a parameter object (a procedure) is stored (using set!). Since a parameter in Chez is a first-class object, parameterize captures the value of the object, not the location where the parameter is stored. This is in contrast with fluid-let, which captures the location of the dynamic variable and mutates it using set!. Aziz,,, ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Abdulaziz Ghuloum <[EMAIL PROTECTED]> writes: > [Lots of explanation] > Basically, in your model, you lose side effects when you exit the > dynamic context, while in Kent's model, side effects to parameters > are remembered and restored properly. So the swapping compensates for the effect of side effects, and gets a notion similar to "call/cc captures the contents of the storage associated with the parameters." Except it seems to break down in the presence of threads, as Kent explained here: http://lists.r6rs.org/pipermail/r6rs-discuss/2007-February/001536.html Now, everything I know about the issue indicates that fracture points like this are inherent in the use of thread-local storage, and no amount of compensation can get back the simple semantics back. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Here's just another simple interactive session in which three nested REPLs can each modify its own prompt-string, and how one can switch from any one to of them to the other without any interference. Aziz,,, Petite Chez Scheme Version 7.2 Copyright (c) 1985-2006 Cadence Research Systems > (begin (call/cc (lambda (k) (set! main-k k))) (printf "Welcome to main-k\n")) Welcome to main-k > (parameterize ([waiter-prompt-string "#"]) (new-cafe)) ## (begin (call/cc (lambda (k) (set! hash-k k))) (printf "Welcome to hash-k\n")) Welcome to hash-k ## (parameterize ([waiter-prompt-string "$"]) (new-cafe)) $$$ (begin (call/cc (lambda (k) (set! dollar-k k))) (printf "Welcome to dollar-k\n")) Welcome to dollar-k $$$ 12 12 $$$ (main-k) Welcome to main-k > 17 17 > (hash-k) Welcome to hash-k ## (dollar-k) Welcome to dollar-k $$$ (waiter-prompt-string "!") !!! #t #t !!! ^D ## (dollar-k) Welcome to dollar-k !!! (hash-k) Welcome to hash-k ## (waiter-prompt-string "%") %% 'here? here? %% ^D > (hash-k) Welcome to hash-k %% (dollar-k) Welcome to dollar-k !!! ^D %% ^D > ^D ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Feb 21, 2007, at 3:21 AM, Michael Sperber wrote: Can you explain in simple terms why `swap' is needed rather than the restore-the-old-value semantics in the alternative version I posted? Swapping is needed, rather than restoring the old value, so that when you get out of the dynamic context, and then back in, the value of the parameter is restored to what it was when you got out, not to what it was when you first got in. Maybe a simple example is a better explanation. Using this definition of parameterize: (define-syntax parameterize (syntax-rules () [(_ ((x v)) e1 e2 ...) (let ([p x] [y v]) (let ([swap (lambda () (let ([t (p)]) (p y) (set! y t)))]) (dynamic-wind swap (lambda () e1 e2 ...) swap)))])) (define P (make-parameter #f)) (write (P)) ; writes #f (parameterize ([P #t]) ;;; we're inside, so the value is #t (write (P))) ; => writes #t ;;; we're out (write (P)) ; writes #f (parameterize ([P #t]) ;;; we're in and the value is #t (P 17) ;;; we're still in, and the value is 17 (write (P))) ; writes 17 ;;; we're out, and the value is restored to #f (in both implementations) (write (P)) ; writes #f (define out-k #f) (parameterize ([P #t]) ;;; the value is #t here (P 17) ;;; the value is 17 here (call/cc (lambda (k) (set! out-k k))) ;;; the continuation was captured when P was 17 (write (P))) ; writes 17 ;;; we're out and the value is #f (write (P)) ; writes #f (out-k) ; writes 17 since P was 17 when the continuation was captured ; the swap on the way out remembers that and the swap on the ; way back in reinstates it. (write (P)) ; writes #f Now using your definition of parameterize: (define-syntax parameterize (syntax-rules () [(_ ((x v)) e1 e2 ...) (let ([p x] [new v]) (let ([prev (p)]) (dynamic-wind (lambda () (p new)) (lambda () e1 e2 ...) (lambda () (p prev)])) Everything will run the same except that the call to (out-k) will write #t instead of 17 since that's what your code does on entry (and re- entry) to the dynamic context: set the parameter to the same "new" value. Basically, in your model, you lose side effects when you exit the dynamic context, while in Kent's model, side effects to parameters are remembered and restored properly. Aziz,,,___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Abdulaziz Ghuloum <[EMAIL PROTECTED]> writes: > All the code does is "swap before going in" and "swap when you come > out". > I honestly fail to see the complexity. That's because you're smarter than me. (And I mean this exactly the way I've written it, no irony intended.) Can you explain in simple terms why `swap' is needed rather than the restore-the-old-value semantics in the alternative version I posted? And, while we're at it, explain the interaction between continuations and the *values* of the parameters (or their cells), rather than resorting to an imperative model that talks about the actions performed to get the values. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Feb 21, 2007, at 2:20 AM, Michael Sperber wrote: The problem is that seemingly simple code can have complex behavior. In this case, the complexity derives from `swap'. This is the implementation of fluid-let as in TSPL3: (define-syntax fluid-let (syntax-rules () ((_ ((x v)) e1 e2 ...) (let ((y v)) (let ((swap (lambda () (let ((t x)) (set! x y) (set! y t) (dynamic-wind swap (lambda () e1 e2 ...) swap)) And here is the implementation of parameterize (simplified to one binding): (define-syntax parameterize (syntax-rules () [(_ ((x v)) e1 e2 ...) (let ([p x] [y v]) (let ([swap (lambda () (let ([t (p)]) (p y) (set! y t)))]) (dynamic-wind swap (lambda () e1 e2 ...) swap)))])) All the code does is "swap before going in" and "swap when you come out". I honestly fail to see the complexity. Aziz,,,___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Feb 21, 2007, at 1:42 AM, John Cowan wrote: Felix Klock scripsit: Am I right in thinking that in all of the sample implementations of parameterize that have been presented so far, the body of the parameterize expression is not in tail position with respect to the entire expression? I do not know what Scheme implementations besides PLT Scheme support this, but it is one of the potential properties of parameterize that I think we should be discussing. Is this done using the Bacon/Baker technique? http://www.accesscom.com/~darius/writings/dynatail.html http://home.pipeline.com/~hbaker1/BuriedStale.html The way PLT Scheme does it is via "continuation marks." Other people on this list can do a better job than I explaining the details, but the quick version of the idea is that the continuation structure is extended to carry particular values (or more generally, key/value pairs) and updates to these values are done in a fashion that preserves tail recursion. From my preliminary skimming of the links you gave, it seems like continuation marks might be considered a useful generalization of the ideas presented there: 1. Continuation marks allow different modules to install continuation marks in a safe-for-space fashion without the two modules being aware of each other. (Even when they each call each other tail recursively.) 2. Continuation marks provide a controlled interface to the sort of stack inspection described by Bacon. There's no need to hack on the interpreter: they're already there, and you get to install your own marks in your code. You can find examples illustrating these advantages in John Clements' work (as well as motivating examples for providing continuation marks in the first place.) On the other hand, Clements' thesis does not cite Bacon or Baker. I infer that either John was not aware of their work, or there is some key distinction differentiating PLT's continuation marks from the Bacon/Baker approach. Anyway, I am not suggesting that we add continuation marks to R6RS. I mainly wanted to point out that: 1. There are other approaches to implementing parameterize besides using dynamic-wind 2. These other approaches may have positive characteristics (such as improved asymptotic space efficiency) 3. If R6RS standardizes on an interface for parameters, it should not rule out this sort of implementation for parameterize. (I do not know if any of the proposed parameter interfaces would do so.) -Felix ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> However, parameters are neither simple nor general. > > Here is an implementation of make-parameter and parameterize in about 20 > lines of r5.92rs code. Adding thread parameters requires an additional > few lines of nonstandard code. I suppose whether you'd call the code or > the mechanism it implements "simple" is a matter of taste, but it is > simple to me. > [...] > (define-syntax parameterize > (lambda (x) > (syntax-case x () > [(_ ((x v) ...) e1 e2 ...) > (with-syntax ([(p ...) (generate-temporaries #'(x ...))] >[(y ...) (generate-temporaries #'(x ...))]) >#'(let ([p x] ... [y v] ...) >(let ([swap (lambda () (let ([t (p)]) (p y) (set! y t)) ...)]) > (dynamic-wind #t swap (lambda () e1 e2 ...) swap]))) What's the four-argument version of `dynamic-wind'? > The generality derives from the fact that a parameter is a procedure and, > when the parameter is referenced or set, directly or through parameterize, > it can do anything one can imagine a procedure doing. The problem is that seemingly simple code can have complex behavior. In this case, the complexity derives from `swap'. As I mentioned earlier, one desirable characteristics of dynamically-bound variables is that a continuation captures their values. In your design, the continuation neither captures the values nor the locations, but instead captures *actions* (involving `swap') leading to the current values. If swapping were replaced by the even simpler restoration of the previous value like so (sorry, once again my `syntax-case' kung-fu does not hack it, so it's `syntax-rules' and one parameter only): (define-syntax paramize (syntax-rules () ((paramize ((?name ?val)) ?body ...) (let ((p ?name)) (let ((previous (p)) (val ?val)) (dynamic-wind (lambda () (p val)) (lambda () ?body ...) (lambda () (p previous ... you get different semantics. So the implications are subtle, at least sufficiently subtle for me to have trouble gauging their effect on programs. > Anyway, didn't you just complain that parameters are too general? Yes. So? >> Moreover, the particular design you chose is problematic because it >> destroys modularity. > > You've offered no evidence to this effect here or in your Scheme workshop > paper, which does not anticipate the design. The paper doesn't anticipate anything. The authors did, however. If I understand the semantics of Chez's parameters with respect correctly (I probably still don't), then the scenario section 5.3 of the paper applies. If it doesn't, I hope you'll enlighten me. > From what I can make out of the rather vague concept in your paper, > I don't think the design does destroy modularity. > > While reasoning about programs that both parameterize and directly modify > parameters might be difficult, especially when escape procedures and > threads are involved, this is no more so than for other effects. Right. Which is why an effect-less version of dynamic binding has simple semantics. > If the effects are the problem, you can build an abstraction layer that > prohibits direct mutation and thus preserves whatever modularity you think > has been destroyed. Including the general mechanism and allowing people > to create restricted abstractions seems more in the spirit of Scheme than > including one or more of the restricted abstractions. While I this is a weird interpretation of the "spirit of Scheme" by me, the problem goes deeper: Mutation is insidious in that, operating behind the scenes, it breaks through abstractions. Take the (r6rs mutable-pairs) library: Abstracting over it is not enough to get the benefits of its absence. >> In contrast, dynamic binding as a separate >> mechanism is simple and modular. Combined with thread-local storage >> (less simple and not modular, but still simpler than parameters), you >> can build parameters. > > I don't see how you could build the full generality of parameters and > parameterize---please enlighten me. It would be enough to demonstrate it > for the single-threaded world using mutable variables or objects in place > of thread-local storage, i.e., any storage that's local to the single > thread of a single-threaded system. If you actually can implement > parameterize and mutable parameters using your dynamic value binding and > some form of state, I wonder in what sense your dyanmic value binding > actually preserves the modularity you want. I'm still unsure of the semantics of Chez's `parameterize' wrt. threads, so I'll probably get it wrong at first try. Here's it, in terms of your code: (define make-parameter (case-lambda [(init guard) (let ([v (make-thread-cell (guard init))]) (case-lambda [() v] [(u) (thread-cell-set! v (guard u))]))] [(init) (make-parameter init values)])) --
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
John Cowan <[EMAIL PROTECTED]> writes: > Michael Sperber scripsit: > >> Nice try! However, parameters are neither simple nor general. >> Moreover, the particular design you chose is problematic because it >> destroys modularity. In contrast, dynamic binding as a separate >> mechanism is simple and modular. Combined with thread-local storage >> (less simple and not modular, but still simpler than parameters), you >> can build parameters. > > Nice try. But thread-local storage requires threads, which are out of > scope for R6RS. Exactly. :-) However, we have regular storage, so all the semantics you need in the absense of threads can be explained in terms of that. > Can you give an example of the kind of dynamic binding you mean? You just leave mutation out of the API, and all mention in the spec that dynamic variables are bound to some kind of storage location. Instead, dynamic binding binds dynamic variables to the values specified in the binding form. Then it's trivial to hook up continuations and dynamic variables: A continuation just captures the dynamic environment, i.e. the values of the dynamic variables. (This doesn't even have to involve any copying, if deep binding is used as an implementation strategy.) -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Felix Klock scripsit: > Am I right in thinking that in all of the sample implementations of > parameterize that have been presented so far, the body of the > parameterize expression is not in tail position with respect to the > entire expression? > > I do not know what Scheme implementations besides PLT Scheme support > this, but it is one of the potential properties of parameterize that > I think we should be discussing. Is this done using the Bacon/Baker technique? http://www.accesscom.com/~darius/writings/dynatail.html http://home.pipeline.com/~hbaker1/BuriedStale.html -- Mos Eisley spaceport. You will never John Cowan see a more wretched hive of scum and[EMAIL PROTECTED] villainy -- unless you watch thehttp://www.ccil.org/~cowan Jerry Springer Show. --georgettesworld.com ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Am I right in thinking that in all of the sample implementations of parameterize that have been presented so far, the body of the parameterize expression is not in tail position with respect to the entire expression? I do not know what Scheme implementations besides PLT Scheme support this, but it is one of the potential properties of parameterize that I think we should be discussing. -Felix ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Abdulaziz Ghuloum scripsit: > I don't think this demonstrates any implementation complexity of > parameters. > If you intended this to demonstrate something else besides how > complex it is > implemented in chicken, then please explain. It illustrates the thread-local implementation that Chicken provides. Your implementation (and the version Kent posted) don't do anything for thread-locality. -- They tried to pierce your heart John Cowan with a Morgul-knife that remains in the http://www.ccil.org/~cowan wound. If they had succeeded, you would become a wraith under the domination of the Dark Lord. --Gandalf ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Feb 20, 2007, at 11:05 PM, John Cowan wrote: It requires considerable behind-the-scenes machinery, as you can see, I don't think this demonstrates any implementation complexity of parameters. If you intended this to demonstrate something else besides how complex it is implemented in chicken, then please explain. For what it's worth, the implementation of make-parameter and parameterize in my compiler (ikarus) is almost identical to what Kent posted two messages up. The following is taken directly from the source of the implementation: (define make-parameter (case-lambda [(x) (case-lambda [() x] [(v) (set! x v)])] [(x guard) (unless (procedure? guard) (error 'make-parameter "~s is not a procedure" guard)) (set! x (guard x)) (case-lambda [() x] [(v) (set! x (guard v))])])) (define-syntax parameterize (lambda (x) (syntax-case x () [(_ () b b* ...) #'(let () b b* ...)] [(_ ([olhs* orhs*] ...) b b* ...) (with-syntax ([(lhs* ...) (generate-temporaries #'(olhs* ...))] [(rhs* ...) (generate-temporaries #'(orhs* ...))]) #'(let ([lhs* olhs*] ... [rhs* orhs*] ...) (let ([swap (lambda () (let ([t (lhs*)]) (lhs* rhs*) (set! rhs* t)) ...)]) (dynamic-wind swap (lambda () b b* ...) swap]))) With the exception of a call to error, everything in this code is portable as far as R5.92RS is concerned. Aziz,,, ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
R. Kent Dybvig scripsit: > Here is an implementation of make-parameter and parameterize in about 20 > lines of r5.92rs code. Adding thread parameters requires an additional > few lines of nonstandard code. Here's Chicken's code for make-parameter (I have globally changed "%" to "%" and "%%" to "%%" in symbols). Apparently, Chicken requires parameter procedures to return only one value. (define make-parameter (let ([count 0]) (lambda (init . guard) (let* ([guard (if (pair? guard) (car guard) (lambda (x) x))] [val (guard init)] [i count]) (set! count (fx+ count 1)) (when (fx>= i (%size %default-parameter-vector)) (set! %default-parameter-vector (%grow-vector %default-parameter-vector (fx+ i 1) (%%undefined (%setslot %default-parameter-vector i val) (lambda arg (let ([n (%size %current-parameter-vector)]) (cond [(pair? arg) (when (fx>= i n) (set! %current-parameter-vector (%grow-vector %current-parameter-vector (fx+ i 1) %snafu))) (%setslot %current-parameter-vector i (guard (%slot arg 0))) (%%undefined)] [(fx>= i n) (%slot %default-parameter-vector i)] [else (let ([val (%slot %current-parameter-vector i)]) (if (eq? val %snafu) (%slot %default-parameter-vector i) val))]))) It requires considerable behind-the-scenes machinery, as you can see, including a pair of growable vectors named %default-parameter-vector and %current-parameter-vector (which latter is apparently thread-local). And here's parameterize as a low-level macro: (%register-macro 'parameterize (let ([car car] [cadr cadr] [map map] ) (lambda (bindings . body) (%check-syntax 'parameterize bindings '#((_ _) 0)) (let* ([swap (gensym)] [params (%map car bindings)] [vals (%map cadr bindings)] [aliases (%map (lambda (z) (gensym)) params)] [aliases2 (%map (lambda (z) (gensym)) params)] ) `(let ,(%append (map %list aliases params) (map %list aliases2 vals)) (let ((,swap (lambda () ,@(map (lambda (a a2) `(let ((t (,a))) (,a ,a2) (%%set! ,a2 t))) aliases aliases2 (%dynamic-wind ,swap (lambda () ,@body) ,swap))) -- Schlingt dreifach einen Kreis vom dies!John Cowan <[EMAIL PROTECTED]> Schliesst euer Aug vor heiliger Schau, http://www.ccil.org/~cowan Denn er genoss vom Honig-Tau, Und trank die Milch vom Paradies.-- Coleridge (tr. Politzer) ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> However, parameters are neither simple nor general. Here is an implementation of make-parameter and parameterize in about 20 lines of r5.92rs code. Adding thread parameters requires an additional few lines of nonstandard code. I suppose whether you'd call the code or the mechanism it implements "simple" is a matter of taste, but it is simple to me. (define make-parameter (case-lambda [(init guard) (let ([v (guard init)]) (case-lambda [() v] [(u) (set! v (guard u))]))] [(init) (make-parameter init values)])) (define-syntax parameterize (lambda (x) (syntax-case x () [(_ ((x v) ...) e1 e2 ...) (with-syntax ([(p ...) (generate-temporaries #'(x ...))] [(y ...) (generate-temporaries #'(x ...))]) #'(let ([p x] ... [y v] ...) (let ([swap (lambda () (let ([t (p)]) (p y) (set! y t)) ...)]) (dynamic-wind #t swap (lambda () e1 e2 ...) swap]))) The generality derives from the fact that a parameter is a procedure and, when the parameter is referenced or set, directly or through parameterize, it can do anything one can imagine a procedure doing. Anyway, didn't you just complain that parameters are too general? > Moreover, the particular design you chose is problematic because it > destroys modularity. You've offered no evidence to this effect here or in your Scheme workshop paper, which does not anticipate the design. From what I can make out of the rather vague concept in your paper, I don't think the design does destroy modularity. While reasoning about programs that both parameterize and directly modify parameters might be difficult, especially when escape procedures and threads are involved, this is no more so than for other effects. If the effects are the problem, you can build an abstraction layer that prohibits direct mutation and thus preserves whatever modularity you think has been destroyed. Including the general mechanism and allowing people to create restricted abstractions seems more in the spirit of Scheme than including one or more of the restricted abstractions. > In contrast, dynamic binding as a separate > mechanism is simple and modular. Combined with thread-local storage > (less simple and not modular, but still simpler than parameters), you > can build parameters. I don't see how you could build the full generality of parameters and parameterize---please enlighten me. It would be enough to demonstrate it for the single-threaded world using mutable variables or objects in place of thread-local storage, i.e., any storage that's local to the single thread of a single-threaded system. If you actually can implement parameterize and mutable parameters using your dynamic value binding and some form of state, I wonder in what sense your dyanmic value binding actually preserves the modularity you want. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Michael Sperber scripsit: > Nice try! However, parameters are neither simple nor general. > Moreover, the particular design you chose is problematic because it > destroys modularity. In contrast, dynamic binding as a separate > mechanism is simple and modular. Combined with thread-local storage > (less simple and not modular, but still simpler than parameters), you > can build parameters. Nice try. But thread-local storage requires threads, which are out of scope for R6RS. Can you give an example of the kind of dynamic binding you mean? -- When I'm stuck in something boring John Cowan where reading would be impossible or(who loves Asimov too) rude, I often set up math problems for [EMAIL PROTECTED] myself and solve them as a way to pass http://www.ccil.org/~cowan the time. --John Jenkins ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> This suggests to me that parameters, as intended by you, are an even >> more general mechanism than dynamic binding and thread-local >> assignment. As Scheme generally tries to avoid piling feature upon >> feature, it's a better strategy to offer the building blocks and let >> people build the parameter mechanism they want from them. > > Nice try! Simple but general mechanisms like parameters, however, are > precisely the kind of building blocks that allow us to avoid piling > feature upon feature. Restricting them reduces their generality and hence > their ability to serve as a basis for other features. Nice try! However, parameters are neither simple nor general. Moreover, the particular design you chose is problematic because it destroys modularity. In contrast, dynamic binding as a separate mechanism is simple and modular. Combined with thread-local storage (less simple and not modular, but still simpler than parameters), you can build parameters. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> This suggests to me that parameters, as intended by you, are an even > more general mechanism than dynamic binding and thread-local > assignment. As Scheme generally tries to avoid piling feature upon > feature, it's a better strategy to offer the building blocks and let > people build the parameter mechanism they want from them. Nice try! Simple but general mechanisms like parameters, however, are precisely the kind of building blocks that allow us to avoid piling feature upon feature. Restricting them reduces their generality and hence their ability to serve as a basis for other features. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Michael Sperber scripsit: > As Scheme generally tries to avoid piling feature upon > feature, it's a better strategy to offer the building blocks and let > people build the parameter mechanism they want from them. That, no doubt, is why R5.92RS has three different record packages and all kinds of numbers. At least they *are* piled one on another instead of being fundamentally incompatible. How parameters are to be implemented depends on fundamental factors of a Scheme implementation that are outside the R*RS purview, notably whether there are primitive threads and how they work. As such, I still think it's important to standardize the interface to this widely provided feature. -- John Cowan [EMAIL PROTECTED] I am a member of a civilization. --David Brin ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: > This destroys one of the nice, simple properties of parameters, which is > that they are simply procedures and can be created by any means, not just > via make-parameter. This means that the encapsulated location can be just > about anything---a memory-mapped device address, a file, a screen image, > an environment variable, etc. This suggests to me that parameters, as intended by you, are an even more general mechanism than dynamic binding and thread-local assignment. As Scheme generally tries to avoid piling feature upon feature, it's a better strategy to offer the building blocks and let people build the parameter mechanism they want from them. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Robby Findler scripsit: > FWIW, that's not true for mzscheme. Parameters there answer #t to > parameter? and one cannot use parameterize with an arbitrary > procedure. Is that not the case for chez? On Chicken, you can use parameterize with an arbitrary procedure, but only procedures made with make-parameter are thread-local. I used the white-hat/black-hat test to determine that. -- We do, doodley do, doodley do, doodley do,John Cowan <[EMAIL PROTECTED]> What we must, muddily must, muddily must, muddily must; Muddily do, muddily do, muddily do, muddily do,http://www.ccil.org/~cowan Until we bust, bodily bust, bodily bust, bodily bust. --Bokonon ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On 2/19/07, R. Kent Dybvig <[EMAIL PROTECTED]> wrote: ... one of the nice, simple properties of parameters, which is that they are simply procedures and can be created by any means, not just via make-parameter. This means that the encapsulated location can be just about anything---a memory-mapped device address, a file, a screen image, an environment variable, etc. FWIW, that's not true for mzscheme. Parameters there answer #t to parameter? and one cannot use parameterize with an arbitrary procedure. Is that not the case for chez? Robby ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> No, it wouldn't, because if I link to somebody else's code that uses > mutation behind the scenes, modularity is lost. In other words, Mike really does want to deny Kent the right to do what he wants. (Of course, Kent also wants to deny Mike the right to deny Kent the right to do what he wants.) > Here's a countersuggestion: We adopt a simple API than SRFI 39 with an > opaque representation for parameters, without mutation. It could be > just like SRFI 39, with the exception that dereference gets its own > operation: > > (parameter-ref param) > retrieves the value of param. This destroys one of the nice, simple properties of parameters, which is that they are simply procedures and can be created by any means, not just via make-parameter. This means that the encapsulated location can be just about anything---a memory-mapped device address, a file, a screen image, an environment variable, etc. > Mutation can then be specified via (probably several different) SRFIs, > and/or you can implement a Chez-specific extension which gives you > what you want. But not in portable code. A better solution is for you to avoid using my code, because if I need to modify a parameter, I'll find a way to do it, and it will be even harder for you to understand than if you let me have a direct mechanism. That's the way it goes with most restrictions. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> So, maybe it's just me, but you see I'm having trouble understanding >> the subtleties of the Chez model for parameters. > > I think it would have been easier for you had you accepted my original > statement that Chez Scheme's model has the semantics you seem to want as > long as mutation isn't involved. You could have answered most if not all > of your subsequent questions by referring back to that statement. But it's precisely the semantics of mutation that bothers me, which is also what my questions were about. > I don't believe that this would give me what I want if we adopt your > value-only dynamic binding, but I have a different suggestion that should > give both of us what we want: We adopt SRFI 39 now and generalize to > threads later by having make-parameter do what Chez Scheme's > make-thread-parameter currently does. No, it wouldn't, because if I link to somebody else's code that uses mutation behind the scenes, modularity is lost. I also really like the API. Here's a countersuggestion: We adopt a simple API than SRFI 39 with an opaque representation for parameters, without mutation. It could be just like SRFI 39, with the exception that dereference gets its own operation: (parameter-ref param) retrieves the value of param. Mutation can then be specified via (probably several different) SRFIs, and/or you can implement a Chez-specific extension which gives you what you want. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> So, maybe it's just me, but you see I'm having trouble understanding > the subtleties of the Chez model for parameters. I think it would have been easier for you had you accepted my original statement that Chez Scheme's model has the semantics you seem to want as long as mutation isn't involved. You could have answered most if not all of your subsequent questions by referring back to that statement. There's actually nothing subtle about the model. Parameterize works just as advertised---the same in a threaded setting as in a nonthreaded setting---and thread parameters modify or read the current thread's storage location. I'm sure one can write subtle programs using the model, but that's true with any of our building blocks. > On the other hand, dynamic binding without mutation thrown in has very > simple semantics and arguably covers most of what's important about SRFI > 39. I don't think it does. It's not uncommon for me to change parameters directly. > Thread-local storage is also useful and has reasonably simple > semantics, but, in my experience, needed much less frequently. (In > Scheme 48, the necessity arises to infrequently that we just stick the > handful of thread-local values into the thread data structure itself.) That's where they are stored in Chez Scheme as well, in an extensible part of the data structure so that applications can create their own thread-local storage. Surely your set is also extensible, unless you've somehow managed to anticipate all possible application needs for thread-local storage. > If both are implemented, it should at least be up to the user how to > combine them. I don't believe that this would give me what I want if we adopt your value-only dynamic binding, but I have a different suggestion that should give both of us what we want: We adopt SRFI 39 now and generalize to threads later by having make-parameter do what Chez Scheme's make-thread-parameter currently does. With this proposal, Mike can choose by convention (possibly enforced by an abstraction layer) never to change directly the parameters he parameterizes, giving him the separate thread-local storage and dynamic binding semantics he wants, even after we add threads. Meanwhile, Kent can ignore Mike's convention and get the more general semantics he wants. Mike and Kent both get what they want, except in the sense that Mike is denied the right to prevent Kent from doing what he wants. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> So would a simple way to describe the semantics be that `call/cc' >> captures the *contents* of the locations of the thread parameters? > > Not quite. You could say that call/cc captures the contents of the > locations of the thread parameters that are parameterized in the > continuation. For parameters that are never modified via set! this > amounts to the same thing. So, maybe it's just me, but you see I'm having trouble understanding the subtleties of the Chez model for parameters. Moreover, other people have come to different conclusions about how those subtleties play out. On the other hand, dynamic binding without mutation thrown in has very simple semantics and arguably covers most of what's important about SRFI 39. Thread-local storage is also useful and has reasonably simple semantics, but, in my experience, needed much less frequently. (In Scheme 48, the necessity arises to infrequently that we just stick the handful of thread-local values into the thread data structure itself.) If both are implemented, it should at least be up to the user how to combine them. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> So would a simple way to describe the semantics be that `call/cc' > captures the *contents* of the locations of the thread parameters? Not quite. You could say that call/cc captures the contents of the locations of the thread parameters that are parameterized in the continuation. For parameters that are never modified via set! this amounts to the same thing. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> OK, thanks for clarifying. Does this mean that, if you capture an >> escape procedure inside a dynamic binding, and you invoke that escape >> procedure in a different thread, the thread where the escape procedure >> is invoked will see a different value when it dereferences the >> parameter than the capturing thread? > > No. Whether the continuation is invoked by the same or a different > thread, the value will be the same as the one in place when the > continuation was created. [...] So would a simple way to describe the semantics be that `call/cc' captures the *contents* of the locations of the thread parameters? -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> OK, thanks for clarifying. Does this mean that, if you capture an > escape procedure inside a dynamic binding, and you invoke that escape > procedure in a different thread, the thread where the escape procedure > is invoked will see a different value when it dereferences the > parameter than the capturing thread? No. Whether the continuation is invoked by the same or a different thread, the value will be the same as the one in place when the continuation was created. Here's an example: (let ([child-k #f] [p (make-thread-parameter 0)]) (fork-thread (lambda () (set! child-k (parameterize ([p 1]) ((call/cc (lambda (k) (lambda () k (write (p)) (let f () (unless child-k (f))) (call/cc (lambda (k) (child-k (lambda () (write (p)) (k) (write (p))) This writes 010. All three writes are performed by the main thread, which never parameterizes p. The first and third writes are performed outside of any parameterization of p and thus print the initial value, 0. The second write prints 1, however, because that's the value of p at the point where the continuation child-k is created, and the thunk passed to child-k is invoked in that continuation. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> I'm probably being dense, but I'm still not quite sure I understand >> what you're saying. I'm assuming you're saying what I said above, >> namely that, upon invoking a continuation, the dynamic bindings are >> restored to the same locations as in the thread where the continuation >> was captured, and thus now shared between the two thread. > > No, the values are restored to locations of the thread that invokes the > continuation. OK, thanks for clarifying. Does this mean that, if you capture an escape procedure inside a dynamic binding, and you invoke that escape procedure in a different thread, the thread where the escape procedure is invoked will see a different value when it dereferences the parameter than the capturing thread? -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> I'm probably being dense, but I'm still not quite sure I understand > what you're saying. I'm assuming you're saying what I said above, > namely that, upon invoking a continuation, the dynamic bindings are > restored to the same locations as in the thread where the continuation > was captured, and thus now shared between the two thread. No, the values are restored to locations of the thread that invokes the continuation. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> > When the continuation is invoked, any dynamic bindings of the new >> > continuation are restored (to the invoking thread's locations), >> >> To the locations or their values? If it's the locations, are they >> then shared between the thread where the continuation was captured and >> the thread where it's invoked? > > Sorry for the imprecision. The values of the continuation are restored to > the locations of the thread. I'm probably being dense, but I'm still not quite sure I understand what you're saying. I'm assuming you're saying what I said above, namely that, upon invoking a continuation, the dynamic bindings are restored to the same locations as in the thread where the continuation was captured, and thus now shared between the two thread. If that's true, the formerly thread-local nature of the parameters seems to be fractured. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> > When the continuation is invoked, any dynamic bindings of the new > > continuation are restored (to the invoking thread's locations), > > To the locations or their values? If it's the locations, are they > then shared between the thread where the continuation was captured and > the thread where it's invoked? Sorry for the imprecision. The values of the continuation are restored to the locations of the thread. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
bear <[EMAIL PROTECTED]> writes: > dynamic-wind introduces a segment of code which must be executed whenever > entering or leaving a continuation. Threads mean that a particular > continuation may be entered and/or left simultaneously by different > threads. If you cannot guarantee that the continuation was created > by the same thread that's entering/leaving it, you cannot make an > effective semaphore on the winding code without using a (mutable) > variable that must be in shared memory. Hence, necessary hideousness; > you cannot have both threads and continuations in the absence of > mutation. Again, the full story on that is in the Scheme workshop paper cited earlier. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: > When the continuation is invoked, any dynamic bindings of the new > continuation are restored (to the invoking thread's locations), To the locations or their values? If it's the locations, are they then shared between the thread where the continuation was captured and the thread where it's invoked? -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> Hopefully you agree that all of the output should consist of some > combination of "initial-x", "initial-y", "new-x", and "new-y" > (rather than some thread printing "hello world"). (You might > reasonably not agree even to that, of course!) Or perhaps output like "initiinitiaal-xl\nnew--y\nx...". > The stronger claim that I was making and that I think you are countering > is that all threads should observe the changes in the same order. > In other words, if any thread prints "initial-x" and "new-y" then > no thread will print "new-x" and "initial-y" (and vice versa). > > You are suggesting it should be the other way around and that threads > might disagree about in what order the two set!-s took effect. That's certainly a possibility. In particular, I haven't seen documentation to the effect that Posix threads, upon which Chez Scheme's thread system is based, guarantees to the user and thus requires of the implementation that memory writes migrate to all threads in the same order. But I was actually reacting to the first part of your original statement: > If one has non-deterministic interrupts, and continuations, then one has > threads.As with C's sequencing points, there are (only) specific > points in the execution of a serial segment of Scheme code where a thread > switch is permitted but that is a very fine-grained limitation. I doubt an efficient multiprocessor implementation of Scheme can be had if the language dictates the points at which a switch in this model can occur to be anything like C's sequencing points, regardless of any other issues. > 1. Are primitive operations atomic? I would say no. Atomic primitive operations aren't particularly useful: when multiple threads are manipulating a shared resource, more than one operation is often involved, and the threads must synchronize at a higher level anyway. Given this, it would be unfortunate if synchronization overhead were also incurred at the lower level. It would be even more unfortunate if the synchronization occurred when resources aren't actually being shared. > 2. Are primitive operations serializable? If I understand what you mean, I would say no to this as well. > (I withdraw any earlier suggestion that I have any strong opinion > about the right answer to either question except to wonder aloud > if a single language might have mechanisms that support each of: > > 1/2:no/noyes/no yes/yes > > in which case, the yes/yes answer for R6RS might be the > conservative choice (with an eye towards adding other options > later)?) If R6RS were to include a thread mechanism, it seems to me that no/no would be the conservative choice, since it would allow the widest range of implementation choices and wouldn't give programmers guarantees that might later be revoked. The draft R6RS doesn't mention anything about threads, however, and I doubt that the final version will either. R6RS already guarantees yes/yes, again if I understand your terminology, for the nonthreaded programs it covers. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
R. Kent Dybvig wrote: Threads are fine, regardless of implementation, if the effect is "as if" we were witnessing an interrupt driven, serial execution of continuations. That may be desirable for lightweight threads operating on a single processor, but the overhead of arranging this for a multiprocessor thread system would likely be prohibitive. Hmm. Really? To make sure I understand and to share with the list a reference to a classic paper, suppose that a program contains: (define x 'initial-x) (define y 'initial-y) and one thread performs: (set! x 'new-x) while another thread performs: (set! y 'new-y) finally, other threads all do: (write x) (newline) (write y) Hopefully you agree that all of the output should consist of some combination of "initial-x", "initial-y", "new-x", and "new-y" (rather than some thread printing "hello world"). (You might reasonably not agree even to that, of course!) The stronger claim that I was making and that I think you are countering is that all threads should observe the changes in the same order. In other words, if any thread prints "initial-x" and "new-y" then no thread will print "new-x" and "initial-y" (and vice versa). You are suggesting it should be the other way around and that threads might disagree about in what order the two set!-s took effect. If that's what you mean, it would reflect the hardware design trend towards weaker shared memory consistency guarantees in multiprocessor systems.That in turn reflects the physical properties of signal propagation at relativistic scales as described in the classic paper: http://research.microsoft.com/users/lamport/pubs/pubs.html#mutual "The Mutual Exclusion Problem -- Part I: A Theory of Interprocess Communication, Part II: Statement and Solutions" Perhaps the basic design choices for threads can (among many other ways) be described as: 1. Are primitive operations atomic? 2. Are primitive operations serializable? (I withdraw any earlier suggestion that I have any strong opinion about the right answer to either question except to wonder aloud if a single language might have mechanisms that support each of: 1/2:no/noyes/no yes/yes in which case, the yes/yes answer for R6RS might be the conservative choice (with an eye towards adding other options later)?) I think the big thing that is missing, to make things *not hideous*, is (I hope I'm using the terminology correctly), delimited continuations. In Guile Scheme (even absent true threads), I found it useful to have a construct like: (call-with-one-shot-continuation (lambda (k) )) These are simply "one-shot" continuations. Delimited continuations (also called partial continuations or subcontinuations) are something different. I wrote poorly. I was thinking of Guile's feature for creating "dynamic roots" which I think probably are, essentially, delimited continuations but I'll look further into before abusing the terminology further. -t ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> If one has non-deterministic interrupts, and continuations, then one has > threads.As with C's sequencing points, there are (only) specific > points in the execution of a serial segment of Scheme code where a thread > switch is permitted but that is a very fine-grained limitation. > > Threads are fine, regardless of implementation, if the effect is "as if" > we were witnessing an interrupt driven, serial execution of continuations. That may be desirable for lightweight threads operating on a single processor, but the overhead of arranging this for a multiprocessor thread system would likely be prohibitive. > I think the big thing that is missing, to make things *not hideous*, > is (I hope I'm using the terminology correctly), delimited continuations. > In Guile Scheme (even absent true threads), I found it useful to > have a construct like: > > (call-with-one-shot-continuation (lambda (k) )) These are simply "one-shot" continuations. Delimited continuations (also called partial continuations or subcontinuations) are something different. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> dynamic-wind introduces a segment of code which must be executed whenever > entering or leaving a continuation. Threads mean that a particular > continuation may be entered and/or left simultaneously by different > threads. If you cannot guarantee that the continuation was created > by the same thread that's entering/leaving it, you cannot make an > effective semaphore on the winding code without using a (mutable) > variable that must be in shared memory. Hence, necessary hideousness; > you cannot have both threads and continuations in the absence of > mutation. No exclusion is necessary if the state used by dynamic wind is per-thread, as is the case in Chez Scheme. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> No, I'm suggesting that one should dynamically bind *values*, not > locations, and do the locations mechanism orthogonally to that. > Again, the details are all in the paper. While the mechanism your paper describes may be useful, dynamic binding of per-thread locations has also proven to be useful in practice, and the interaction with threads and continuations has not proven to be problematic (or worse). In any case, if you provide per-thread locations, I predict that programmers will want to dynamically bind them. > ... and how exactly is it defined? Does the contents of the location > migrate with the continuation? I'm assuming no, from your > description. However, it's often desirable (if mutation isn't > involved) for the value of a dynamic binding to migrate. So, I'm sure > the semantics is well defined, but it's often not the one I want. I'd > rather mix and match, which for me typically means not doing mutation > anyway. When the continuation is invoked, any dynamic bindings of the new continuation are restored (to the invoking thread's locations), just as when any continuation is invoked. I believe this is indistinguishable from the semantics you want if no explicit mutation is involved. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On 2/12/07, bear <[EMAIL PROTECTED]> wrote: . dynamic-wind introduces a segment of code which must be executed whenever entering or leaving a continuation. Threads mean that a particular continuation may be entered and/or left simultaneously by different threads. If you cannot guarantee that the continuation was created by the same thread that's entering/leaving it, you cannot make an effective semaphore on the winding code without using a (mutable) variable that must be in shared memory. Hence, necessary hideousness; you cannot have both threads and continuations in the absence of mutation. The return value of the entry and exit thunks is discarded and are only for effect. If there is no mutation, then there is no effect of running the entry and exit thunks. -- ~jrm ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Mon, 12 Feb 2007, Michael Sperber wrote: > >bear <[EMAIL PROTECTED]> writes: > >> On Sat, 10 Feb 2007, Michael Sperber wrote: >> >>> Anyway, the behavior of Chez's thread parameters isn't covered by what >>> I meant as "hideous". However, even Chez's thread parameters (which >>> behave the same as PLT Scheme's parameters, I believe) are problematic >>> when threads and continuations interact. Things are simpler when >>> dynamic binding and (possibly thread-local) mutation are separate >>> mechanisms. >> >> I think that the interaction of threads and continuations is *Necessarily* >> hideous, especially in the presence of mutation. > >No. In the absence of mutation, it's unproblematic. dynamic-wind introduces a segment of code which must be executed whenever entering or leaving a continuation. Threads mean that a particular continuation may be entered and/or left simultaneously by different threads. If you cannot guarantee that the continuation was created by the same thread that's entering/leaving it, you cannot make an effective semaphore on the winding code without using a (mutable) variable that must be in shared memory. Hence, necessary hideousness; you cannot have both threads and continuations in the absence of mutation. Bear ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
bear <[EMAIL PROTECTED]> writes: > On Sat, 10 Feb 2007, Michael Sperber wrote: > >> Anyway, the behavior of Chez's thread parameters isn't covered by what >> I meant as "hideous". However, even Chez's thread parameters (which >> behave the same as PLT Scheme's parameters, I believe) are problematic >> when threads and continuations interact. Things are simpler when >> dynamic binding and (possibly thread-local) mutation are separate >> mechanisms. > > I think that the interaction of threads and continuations is *Necessarily* > hideous, especially in the presence of mutation. No. In the absence of mutation, it's unproblematic. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> That's a strange way to interpret "separate," since both mechanisms >> are joined with parameters. Why aren't dynamic binding and >> thread-local storage separate? > > Hmm. I guess any mechanism that allows per-thread locations to be > dynamically bound would be considered a combined mechanism by your > definition. Are you suggesting that one should not dynamically bind > per-thread locations? No, I'm suggesting that one should dynamically bind *values*, not locations, and do the locations mechanism orthogonally to that. Again, the details are all in the paper. >> Our Scheme workshop spells out exactly >> what the semantic problems are. (Specifically, they occur when a >> escape procedure created in one thread is invoked in another.) > > Again, I don't believe that there is a problem. Parameterize, like > fluid-let, just assigns a new value on entry and restores the old on exit, > and the semantics wrt thread-local paramters, even if the assignment is > performed by a continuation created in another thread, is totally well > defined. ... and how exactly is it defined? Does the contents of the location migrate with the continuation? I'm assuming no, from your description. However, it's often desirable (if mutation isn't involved) for the value of a dynamic binding to migrate. So, I'm sure the semantics is well defined, but it's often not the one I want. I'd rather mix and match, which for me typically means not doing mutation anyway. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
bear wrote: I think that the interaction of threads and continuations is *Necessarily* hideous, especially in the presence of mutation. It may be a mistake for the same language to even have both. At the very least one ought to be well-defined in terms of the other. Hmm. I'm not so sure about the "*necessarily* hideous" part but strongly agree about defining threads in terms of continuations. If one has non-deterministic interrupts, and continuations, then one has threads.As with C's sequencing points, there are (only) specific points in the execution of a serial segment of Scheme code where a thread switch is permitted but that is a very fine-grained limitation. Threads are fine, regardless of implementation, if the effect is "as if" we were witnessing an interrupt driven, serial execution of continuations. I think the big thing that is missing, to make things *not hideous*, is (I hope I'm using the terminology correctly), delimited continuations. In Guile Scheme (even absent true threads), I found it useful to have a construct like: (call-with-one-shot-continuation (lambda (k) )) Many variations are possible. The idea is that K is a continuation for the whole form and is the same continuation with which is implicitly executed. The catch is that the second (and all subsequent) times that that continuation is executed, instead, an error is raised.I have no strong opinion about how that error is handled... I think it would be fine if it were required to abort the entire program execution. One can implement call-with-one-shot-continuation in R5RS Scheme but it deserves promotion to the language as a core concept because it cries out for special implementation.(Similarly, call-with-upwards-only -continuation and call-with-upwards-one-shot-.) Given a construct such as that, one could then define something like PARALLEL-MAP.At first glance, the "fortress" programming language appears to have gone this route, making PARALLEL-MAP the default because of its significant utility in a lot of scientific programming. -t ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Sun, 11 Feb 2007, John Cowan wrote: > OT: I've noticed a tendency in Scheme libraries to eschew global value > definitions for functions that return a constant value. Has anyone > else noticed this (I can't point to evidence offhand), and does anyone > know why? It makes the call site use a function call instead of a variable reference. That means that when you're making changes later, you can change the *way* something is defined (using a function) instead of just the definition (using a value). For example, you may initially implement a program that updates the display every 0.2 seconds, and then later decide that you want to update the display less often (or not at all) when being run as a shell script and more often when being run at a user interaction window. If you defined the update-frequency as a variable, then you can change its value across the program by changing a constant in the source. But if you defined it as a function, then you can change the *WAY* it's computed (ie, check to see if the program is running in batch mode) by changing a function in the source. Bear ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Sat, 10 Feb 2007, Michael Sperber wrote: > Anyway, the behavior of Chez's thread parameters isn't covered by what > I meant as "hideous". However, even Chez's thread parameters (which > behave the same as PLT Scheme's parameters, I believe) are problematic > when threads and continuations interact. Things are simpler when > dynamic binding and (possibly thread-local) mutation are separate > mechanisms. I think that the interaction of threads and continuations is *Necessarily* hideous, especially in the presence of mutation. It may be a mistake for the same language to even have both. At the very least one ought to be well-defined in terms of the other. Bear ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> That's a strange way to interpret "separate," since both mechanisms > are joined with parameters. Why aren't dynamic binding and > thread-local storage separate? Hmm. I guess any mechanism that allows per-thread locations to be dynamically bound would be considered a combined mechanism by your definition. Are you suggesting that one should not dynamically bind per-thread locations? I can't myself imagine wanting to dynamically bind locations that aren't per thread. > Our Scheme workshop spells out exactly > what the semantic problems are. (Specifically, they occur when a > escape procedure created in one thread is invoked in another.) Again, I don't believe that there is a problem. Parameterize, like fluid-let, just assigns a new value on entry and restores the old on exit, and the semantics wrt thread-local paramters, even if the assignment is performed by a continuation created in another thread, is totally well defined. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> Why not just use ordinary Scheme top-level variables, then, and use > SET! to change them on the occasions when it might be required? > Why use separate machinery for them? One motivation is that such top-level variables essentially become reserved words. One cannot redefine them at top level without affecting the code that references them. For example, if the reader and printer consult the variable case-sensitive and some application defines it for its own purposes, the behavior of the reader and printer changes as the value of the application's variable changes. On the other hand, if the reader and printer consult the parameter case-sensitive and some application redefines it for its own purposes, the reader and printer are unaffected. In general, an application can redefine the name of any parameter for its own purposes, and it can give a parameter a different name if it needs to use the parameter. This motivation is not as strong if applications use libraries and avoid the top level. Another motivation is that parameter values can be checked at the point of assignment rather than at the point of reference. For example, the parameter print-level in Chez Scheme must be #f or a nonnegative integer, and a violation of this restriction is signaled when the parameter is set (called with the new print-level). As a result, the user gets feedback when the error occurs, and the printer need not check the value whenever it accesses the parameter. > OT: I've noticed a tendency in Scheme libraries to eschew global value > definitions for functions that return a constant value. Has anyone > else noticed this (I can't point to evidence offhand), and does anyone > know why? I can't speak to this in general, but when I do so it's for reasons similar to the first given above and also to prevent users from changing the supposed constant. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: > Now we're down to problematic, but I don't believe even that is true. It > certainly hasn't been problematic with either Chez Scheme's native threads > or SWL's continuation-based threads. Furthermore, the mechanisms *are* > separate---make-parameter and make-thread-parameter create parameters and > parameterize performs dynamic binding. So I don't even see the basis for > your claim. That's a strange way to interpret "separate," since both mechanisms are joined with parameters. Why aren't dynamic binding and thread-local storage separate? Our Scheme workshop spells out exactly what the semantic problems are. (Specifically, they occur when a escape procedure created in one thread is invoked in another.) -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
John Cowan <[EMAIL PROTECTED]> writes: > Michael Sperber scripsit: > >> OK, thanks. Now, this is different from SRFI 39, where a parameter is >> bound to a single storage cell. Presumably, the spec could be twisted >> to allow thread creation to create new storage cells, but I believe >> this was specifically not the intent of SRFI 39. > > Diffidently I suggest that perhaps you remember the history too well > and the final spec not well enough. As written SRFI 39 makes no > references (and deliberately so) to threads. It defines the behavior > for single-threaded Schemes only, and is consistent with any of these > multi-threaded behaviors: > > 1)share dynamic state among all threads > 2)clone dynamic state when a new thread is made > 3)give each new thread a fresh dynamic state The problem is that bad interaction with threads is inevitable, no matter which specific decision you make. The degree of badness varies, but not the presence of it in principle. Having said that, the spec of SRFI 39 says that the procedure returned by `make-parameter' >> When it is called with no argument, the content of the cell bound to >> this parameter object in the current dynamic environment is >> returned. Now, I don't see how this could be interpreted in different ways in the presence of threads, at least if a parameter is created in thread B after a thread A has been created, and then thread A references the parameter---note how the spec says "global dynamic environment". (If it's the other way around, as I said, thread creation might clone the cell.) However, as I said, I don't think it matters much: The consequences are bad either way: Conflating dynamic binding with mutable state is a bad idea, especially as cleanly separating them is possible and easy. It's also "piling feature upon feature", which Scheme isn't about. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
R. Kent Dybvig scripsit: > Global parameters are typically but not always set once and forgotten; an > application might change the collection parameters, for example, to suit > different modes of operation. It generally doesn't make sense to localize > them, however, or they would be defined as thread parameters. Why not just use ordinary Scheme top-level variables, then, and use SET! to change them on the occasions when it might be required? Why use separate machinery for them? OT: I've noticed a tendency in Scheme libraries to eschew global value definitions for functions that return a constant value. Has anyone else noticed this (I can't point to evidence offhand), and does anyone know why? > In contrast, a much wider range of parameters are thread parameters: [examples snipped] That's the sort of thing I'd expect to use parameters for, when localizing is important. -- When I'm stuck in something boring John Cowan where reading would be impossible or(who loves Asimov too) rude, I often set up math problems for [EMAIL PROTECTED] myself and solve them as a way to pass http://www.ccil.org/~cowan the time. --John Jenkins ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> I'd like to know what Chez global parameters tend to be used for, > and whether they are normally set-and-forget things like CL > defparameter or whether it is common to localize them. They tend to be used sparingly for things that are inherently global. For example, the built-in global parameters control what happens when the system first starts up (e.g., scheme-script, which is called when the system is started as a script, or command-line, which contains a list of command-line arguments), garbage collection (e.g., collect-trip-bytes, which determines after how much allocation a collection is requested), and the console ports used by the interactive debugger when an error occurs. Global parameters are typically but not always set once and forgotten; an application might change the collection parameters, for example, to suit different modes of operation. It generally doesn't make sense to localize them, however, or they would be defined as thread parameters. In contrast, a much wider range of parameters are thread parameters: ones that control reading or printing (e.g., case-sensitive and print-radix), handlers for various conditions (e.g., keyboard interrupts, errors, warnings, resets), the current input/output ports, the trace output port, compiler behavior (e.g., optimization, profiling), REPL behavior (e.g., waiter-prompt-string, interaction-environment), pretty-printer behavior (e.g., pretty-line-length, pretty-standard-indent), and more. There are around a dozen built-in global parameters and around four dozen built-in thread parameters. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
R. Kent Dybvig scripsit: > Actually, Chez Scheme's threads and parameters get along perfectly well. > We have both global and thread parameters, and most parameters end up > being thread parameters. So I respectfully disagree that the interaction > is hideous---or even bad. I'd like to know what Chez global parameters tend to be used for, and whether they are normally set-and-forget things like CL defparameter or whether it is common to localize them. -- I don't know half of you half as well John Cowan as I should like, and I like less than half [EMAIL PROTECTED] of you half as well as you deserve. http://www.ccil.org/~cowan --Bilbo ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> OK, thanks. Now, this is different from SRFI 39, where a parameter is > bound to a single storage cell. Presumably, the spec could be twisted > to allow thread creation to create new storage cells, but I believe > this was specifically not the intent of SRFI 39. Okay, we've gone from hideous to twisted. But no twisting is necessary, since make-parameter in Chez Scheme still creates one location. make-thread-parameter is the version that creates per-thread locations. Even having make-parameter itself use per-thread locations is an upward-compatible extension when one adds threads. > Anyway, the behavior of Chez's thread parameters isn't covered by what > I meant as "hideous". However, even Chez's thread parameters (which > behave the same as PLT Scheme's parameters, I believe) are problematic > when threads and continuations interact. Things are simpler when > dynamic binding and (possibly thread-local) mutation are separate > mechanisms. Now we're down to problematic, but I don't believe even that is true. It certainly hasn't been problematic with either Chez Scheme's native threads or SWL's continuation-based threads. Furthermore, the mechanisms *are* separate---make-parameter and make-thread-parameter create parameters and parameterize performs dynamic binding. So I don't even see the basis for your claim. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Michael Sperber scripsit: > OK, thanks. Now, this is different from SRFI 39, where a parameter is > bound to a single storage cell. Presumably, the spec could be twisted > to allow thread creation to create new storage cells, but I believe > this was specifically not the intent of SRFI 39. Diffidently I suggest that perhaps you remember the history too well and the final spec not well enough. As written SRFI 39 makes no references (and deliberately so) to threads. It defines the behavior for single-threaded Schemes only, and is consistent with any of these multi-threaded behaviors: 1) share dynamic state among all threads 2) clone dynamic state when a new thread is made 3) give each new thread a fresh dynamic state I wrote the following bit of code to probe the behavior of various Schemes: (require-extension (srfi 18)) (require-extension (srfi 39)) (define hat (make-parameter 'new)) (define (black-hat) (hat 'black)) (define (white-hat) (hat 'white)) (define (print-hat guy) (display guy) (display " guy, ") (display (hat)) (display " hat") (newline)) (define (bad-guy) (print-hat 'bad) (black-hat) (print-hat 'bad)) (print-hat 'good) (white-hat) (print-hat 'good) (thread-join! (thread-start! (make-thread bad-guy))) (print-hat 'good) (Note that since the thread is joined immediately after it is started, the concurrency is entirely deterministic; I'm assuming that no Scheme is smart enough to figure this out.) I ran it on Chicken, a type 2 (cloning) system, and got the following (Felix is on record that both type 1 and type 3 systems are deeply flawed, but that's just him): good guy, new hat good guy, white hat bad guy, white hat bad guy, black hat good guy, white hat Presumably a type 1 (sharing) system would report the good guy as wearing a black hat in the fifth line of output, and a type 3 (refreshing) system would report the bad guy as wearing a new hat in the third line. -- John Cowan http://ccil.org/~cowan[EMAIL PROTECTED] In might the Feanorians / that swore the unforgotten oath brought war into Arvernien / with burning and with broken troth. and Elwing from her fastness dim / then cast her in the waters wide, but like a mew was swiftly borne, / uplifted o'er the roaring tide. --the Earendillinwe ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >>From Section 13.4: > > When a thread parameter is created, a separate location is set aside in > each current and future thread to hold the value of the parameter's > internal state variable. OK, thanks. Now, this is different from SRFI 39, where a parameter is bound to a single storage cell. Presumably, the spec could be twisted to allow thread creation to create new storage cells, but I believe this was specifically not the intent of SRFI 39. Anyway, the behavior of Chez's thread parameters isn't covered by what I meant as "hideous". However, even Chez's thread parameters (which behave the same as PLT Scheme's parameters, I believe) are problematic when threads and continuations interact. Things are simpler when dynamic binding and (possibly thread-local) mutation are separate mechanisms. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> Could you explain what the difference between global and thread > parameters is in Chez Scheme? I can't find an explanation in the > online user's manual. >From Section 13.4: When a thread parameter is created, a separate location is set aside in each current and future thread to hold the value of the parameter's internal state variable. (This location may be eliminated by the storage manager when the parameter becomes inaccessible.) Changes to the thread parameter in one thread are not seen by any other thread. When a new thread is created (see fork-thread), the current value (not location) of each thread parameter is inherited from the forking thread by the new thread. So when a thread parameterizes a thread parameter, it's parameterizing it's own. It usually makes no sense for one of multiple threads to parameterize a global parameter. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
"R. Kent Dybvig" <[EMAIL PROTECTED]> writes: >> Sure. All I'm arguing for is not making the wrong decision. The >> interaction that SRFI 39 entails happens to be particularly hideous, >> and unnecessary at that. > > Actually, Chez Scheme's threads and parameters get along perfectly well. > We have both global and thread parameters, and most parameters end up > being thread parameters. So I respectfully disagree that the interaction > is hideous---or even bad. Could you explain what the difference between global and thread parameters is in Chez Scheme? I can't find an explanation in the online user's manual. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
> Sure. All I'm arguing for is not making the wrong decision. The > interaction that SRFI 39 entails happens to be particularly hideous, > and unnecessary at that. Actually, Chez Scheme's threads and parameters get along perfectly well. We have both global and thread parameters, and most parameters end up being thread parameters. So I respectfully disagree that the interaction is hideous---or even bad. Kent ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
John Cowan <[EMAIL PROTECTED]> writes: > Michael Sperber scripsit: > >> That's a pretty incomplete characterization of the discussion: Since >> the semantics includes mutation, an eventual (bad) interaction with >> threads is inevitable. > > Mutation and threads *never* interact well, but Scheme is full of > mutation: if it didn't have mutation, it would be Erlang or something. > Consequently, whoever is going to implement threads in Scheme must > make many decisions about the behavior of threads, and the decision > about parameters is just another of them. Sure. All I'm arguing for is not making the wrong decision. The interaction that SRFI 39 entails happens to be particularly hideous, and unnecessary at that. > # I agree that the API of parameters is not abstract, and that this > # could be improved with separate procedures (or syntax) for creation, > # mutation, reading and binding of dynamic variables. I did not propose > # this because of the convergence by many implementations to the > # "parameters" API and I wanted to place minimal burden on > # implementors/users of this API. So most everybody isn't happy with the API in SRFI 39. SRFIs are perfectly suited for codifying widely implemented interfaces. It's not a good idea to set something we know is defective into the standard. >> > The reason for making parameters part of the standard, beside their >> > general utility, is that they are intertwingled with the current-*-port >> > facilities, which are explicitly specified as parameters by SRFI-39. >> > As a result, it is hard to load a portable implementation of parameters >> > into a Scheme that doesn't have it; current-*-port cannot be rebound >> > by parameterize correctly. >> >> That seems to be a defect of SRFI 39, and hardly sufficient reason to >> force it into the standard. Actually, thinking about it, with the R5.92RS interface the current ports, implementing all of SRFI 39 on top of it is no longer a problem. (Given that there's now `call-with-ports'.) So I think there's even less reason to put SRFI 39 into the standard. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
Michael Sperber scripsit: > That's a pretty incomplete characterization of the discussion: Since > the semantics includes mutation, an eventual (bad) interaction with > threads is inevitable. Mutation and threads *never* interact well, but Scheme is full of mutation: if it didn't have mutation, it would be Erlang or something. Consequently, whoever is going to implement threads in Scheme must make many decisions about the behavior of threads, and the decision about parameters is just another of them. > Moreover, the interface for parameters is bizarre. Some elaboration > on that argument can be found at: > > http://srfi.schemers.org/srfi-39/mail-archive/msg00017.html Quite so. I think however that Marc Feeley's reply is very much to the point: # I agree that the API of parameters is not abstract, and that this # could be improved with separate procedures (or syntax) for creation, # mutation, reading and binding of dynamic variables. I did not propose # this because of the convergence by many implementations to the # "parameters" API and I wanted to place minimal burden on # implementors/users of this API. The agreement has only become better since. There is a great deal to be said for standardizing what has proved itself in practice, rather than standardizing novelties that may or may not turn out to be the Right Thing. > > The reason for making parameters part of the standard, beside their > > general utility, is that they are intertwingled with the current-*-port > > facilities, which are explicitly specified as parameters by SRFI-39. > > As a result, it is hard to load a portable implementation of parameters > > into a Scheme that doesn't have it; current-*-port cannot be rebound > > by parameterize correctly. > > That seems to be a defect of SRFI 39, and hardly sufficient reason to > force it into the standard. Why a defect? Why should the R5RS dynamic environment and the SRFI-39 dynamic environment be separate and distinct? That makes no sense to me at all. A side effect of making parameters part of the library is that (current-*-port port) would be added. -- Long-short-short, long-short-short / Dactyls in dimeter, John Cowan Verse form with choriambs / (Masculine rhyme): [EMAIL PROTECTED] One sentence (two stanzas) / Hexasyllabically Challenges poets who / Don't have the time. --robison who's at texas dot net ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
John Cowan <[EMAIL PROTECTED]> writes: > I have searched the various status reports and seen nothing about > dynamic binding, dynamic variables, or parameters. I suggest > that SRFI-39 be incorporated into R6RS as the (r6rs parameters) > library. > [...] > Judging by the SRFI-39 mail archives, the only thing controversial > about the final form of the SRFI is the behavior when interacting > with threads. As threads are not part of R6RS, the issue does not > arise. That's a pretty incomplete characterization of the discussion: Since the semantics includes mutation, an eventual (bad) interaction with threads is inevitable. For gory details, check out: Martin Gasbichler, Eric Knauel, Michael Sperber Richard A. Kelsey: How to Add Threads to a Sequential Language Without Getting Tangled Up, In The 2003 Scheme Workshop, Boston, Ma., October 2003. This paper is available from: http://www-pu.informatik.uni-tuebingen.de/users/sperber/papers/ Moreover, the interface for parameters is bizarre. Some elaboration on that argument can be found at: http://srfi.schemers.org/srfi-39/mail-archive/msg00017.html In any case, SRFI 39 (standing by itself) can be implemented portably on top of R5.92RS. It may indeed be a good idea to have a standard policy and/or interface for dynamically bound parameters, but there doesn't seem to be universal agreement on what that should look like. > The reason for making parameters part of the standard, beside their > general utility, is that they are intertwingled with the current-*-port > facilities, which are explicitly specified as parameters by SRFI-39. > As a result, it is hard to load a portable implementation of parameters > into a Scheme that doesn't have it; current-*-port cannot be rebound > by parameterize correctly. That seems to be a defect of SRFI 39, and hardly sufficient reason to force it into the standard. -- Cheers =8-} Mike Friede, Völkerverständigung und überhaupt blabla ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
Re: [r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library
On Sun, 4 Feb 2007, John Cowan wrote: I have searched the various status reports and seen nothing about dynamic binding, dynamic variables, or parameters. I suggest that SRFI-39 be incorporated into R6RS as the (r6rs parameters) library. Yes, I agree. Please standardize parameters. Andre ___ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
