[racket] Saving and restoring many parameters

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Wed Oct 19 07:03:19 EDT 2011

(I'm sorry if you got this message already; I thought I sent it
already but I don't see it.)

What about the current-output/error-port? what about the
current-namespace? current-custodian?

There are lots of parameters that affect core functions in subtle ways
and if you do something like this in plot, it seems like it could lead
to serious confusion someday. Also, it can introduce leaks.

Of course, I don't have a specific example of how it could go wrong,
so you're welcome to treat that as a reason to ignore me. :)

Robby

On Tue, Oct 18, 2011 at 4:43 PM, Neil Toronto <neil.toronto at gmail.com> wrote:
> I hear you. If I used any parameters except the plot ones, I'd have a
> problem, and write macros as you suggest. (Or save and restore the
> exceptions instead.) For now, I'm trying Matthew's suggestion, and using
> this:
>
>    (define (parameterize-procedure t)
>      (define parameterization (current-parameterization))
>      (make-keyword-procedure
>       (lambda (kws kw-args . rest)
>         (call-with-parameterization
>          parameterization
>          (lambda () (keyword-apply t kws kw-args rest))))))
>
> In plot-pict, it looks like
>
>    (dc (parameterize-procedure
>         (lambda (the-dc x y)
>           (plot/dc ... the-dc x y ...)) ...))
>
> It seems to work just fine. *crosses fingers* There may be some parameters
> that slideshow uses that I'm not aware of, though...
>
> But I think I *want* to save every parameter value. If a user plots a
> function that uses a parameter, I want the function to use the value as it
> was on the call to 'plot-pict', not its value later.
>
> Neil T
>
> On 10/18/2011 01:48 PM, Robby Findler wrote:
>>
>> There are parameterizations, but they pick up all parameters and that
>> may make other things go wrong (or you have to be more careful how you
>> look up your parameter values but I think you might object to that on
>> similar grounds to the below).
>>
>> I would probably use the solution you have below, but with some macro
>> help. Specifically, in the place where you define all those paramters,
>> use a macro to define them, and then have other macros that
>> collaborate with the defining macros to capture and restore the
>> parameter values.
>>
>> Robby
>>
>> On Tue, Oct 18, 2011 at 2:40 PM, Neil Toronto<neil.toronto at gmail.com>
>>  wrote:
>>>
>>> Executive summary: Is there a good way to save a large set of parameter
>>> values, or *all* the parameter values, and then restore them when needed?
>>>
>>> In the new PLoT, much of a plot's appearance is controlled by parameters.
>>> I
>>> use parameters because there are so many appearance-controlling values
>>> that
>>> passing them into the plot area as arguments would get silly very
>>> quickly. I
>>> dislike functions with 20 arguments, and I *really* dislike duplicating
>>> all
>>> those arguments in every function in a call chain. Parameters are a
>>> perfect
>>> remedy.
>>>
>>> There's one problem, though: to produce a slideshow pict of a plot, I
>>> need
>>> to do this:
>>>
>>>    (dc (lambda (the-dc x y)
>>>          (plot/dc ... the-dc x y ...)) ...)
>>>
>>> where 'plot/dc' draws a plot on a device context. Because the call to
>>> 'plot/dc' is in a thunk, it gets the *current* parameter values, which is
>>> very wrong. That makes it impossible to, for example, change the
>>> background
>>> color of only one plot in a slideshow by doing
>>>
>>>    (parameterize ([plot-background  "red"])
>>>      (plot-pict ...))
>>>
>>> The problem is that the pict returned by 'dc' calls the drawing thunk
>>> *after* the dynamic scope in which 'plot-background' is "red".
>>>
>>> To fix the problem, I'm doing this:
>>>
>>>    (define foreground (plot-foreground))
>>>    (define background (plot-background))
>>>    (define foreground-alpha (plot-foreground-alpha))
>>>    (define background-alpha (plot-background-alpha))
>>>    (define font-size (plot-font-size))
>>>    ...
>>>    (define animating? (plot-animating?))
>>>
>>>    (dc (lambda (the-dc x y)
>>>          (parameterize ([plot-foreground        foreground]
>>>                         [plot-background        background]
>>>                         [plot-foreground-alpha  foreground-alpha]
>>>                         [plot-background-alpha  background-alpha]
>>>                         [plot-font-size         font-size]
>>>                         ...
>>>                         [plot-animating?        animating?])
>>>            (plot/dc ... the-dc x y ...))) ...)
>>>
>>> Besides looking evil, it's barely maintainable. Every time I add an
>>> appearance-controlling parameter, I have to remember to add it to the
>>> above
>>> incantation. (Actually, there are two.)
>>>
>>> I've had a similar problem with the click-and-drag-to-rotate 3D plots.
>>> Because I was already using threads for that, I just made sure the render
>>> thread is always (transitively) a child of the thread in which the call
>>> to
>>> 'plot3d' was made. It therefore inherits the original parameter values.
>>>
>>> So I can use threads to save parameter values. I could make a render
>>> thread
>>> to solve my 'plot-pict' problem. But is there a better way?
>>>
>>> Neil T
>>> _________________________________________________
>>>  For list-related administrative tasks:
>>>  http://lists.racket-lang.org/listinfo/users
>>>
>
>



Posted on the users mailing list.