On Apr 21, Ed Cavazos wrote:
>> So I read about parameters and they are "thread specific". I can of
> course see how this is a virtue in many cases, and a benfit over
> variables. However, in the above case, after spawning off a thread I
> lose contact with those parameters from my REPL. Right now I'm
> thinking that I should launch a GUI from within the thread which
> will be my tether to the parameters. Or perhaps a way to launch a
> REPL that introspects into the environment of a spawned thread.
I don't think there's anything wrong with such global variables,
especially if you mark them with **'s -- after all, they do exactly
what you want them to do, which is share modifiable information
between threads... (You might want to add a semaphore protection if
there's a way to get to a bogus configuration.)
If you still insist on a parameter, then one option would be to have a
parameter-like function that will access a global but will be shared
since it will not be a parameter, for example, one that has a
parameter-like-function inside it. I had a similar problem with my
webserver -- I wanted to have "special" parameters that when they are
created, they are shared among all sub-threads. This is the code that
I use:
----------------------------------------------------------------------
(define (make-connection-parameter . default)
;; This returns a parameter-like function that uses a parameter to store an
;; actual value-function and use that. The effect is that once we set the
;; value, all created threads will share that value. Note that since
;; check-parameter-procedure accept any function of 0/1 args, this will also
;; behave with parameterize.
(define param (make-parameter #f))
(define (connection-parameter . args)
(let ((p (param)))
(cond
((and p (null? args)) (p))
(p (p (car args)))
((null? args)
(if (null? default)
(error 'connection-parameter "accessing uninitialized parameter")
(car default)))
;; don't create a parameter that will be used in the global thread
((eq? (current-thread) *toplevel-thread*) (set! default args))
(else (param
(let ((v (1st args)))
(define (p . args)
(if (null? args) v (set! v (car args))))
(if (promise? v)
;; this is so only initial promises are possible and nothing
;; else gets the penalty of `promise?'
(lambda args (set! v (force v)) (param p) (apply p args))
p)))))))
connection-parameter)
----------------------------------------------------------------------
But it is very tricky to get the details right, and I'm not sure how
stable the whole thing is. I think that for you a global is enough.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!