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
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to