Access to the caller's globals, not your own

ojacobson at heroku.com ojacobson at heroku.com
Mon Nov 14 15:04:35 EST 2016


On Monday, November 14, 2016 at 12:21:00 AM UTC-5, Steven D'Aprano wrote:

> Don't tell me to make SPAMIFY a parameter of the function. I know that. That's 
> what I would normally do, but *occasionally* it is still useful to have a 
> global configuration setting, and those are the cases I'm talking about.

This is the motivation behind Racket's parameters system <http://docs.racket-lang.org/reference/parameters.html>. A _parameter_ has the following properties:

* It can be read or written whenever it is in scope. By convention, parameters are global variables, but they can also be created in more limited lexical scopes.

* A parameter can be set. Once set, all subsequent reads in any scope will produce the last set value.

So far, so good: these are exactly like module-scoped globals in Python. Where it gets interesting is the parameterize function <http://docs.racket-lang.org/reference/parameters.html#%28form._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._parameterize%29%29>: it introduces a dynamically-scoped set of new bindings for all included parameters, then evaluates a body (a procedure) with those bindings, then removes the bindings and restores the parameters to their values prior to parameterize. Any changes to those parameters within the body is also reverted: it's applied to the new binding introduced by parameterize, rather than to the "parent" binding.

Parameterizing a call means that changes to the "global variables" implemented as parameters have predictable scope and can be reliably restored to their prior values, meaning they're a fairly safe way to implement "config" globals.

Parameters are implemented using thread-local variables that point to stacks of bindings, where parameterize introduces a new stack frame for each listed parameter.

It's a neat system.

-o



More information about the Python-list mailing list