After comparing function argument lists in Python and Scheme, here’s a Scheme construct that Python definitely doesn’t have. (Although I’m not saying that it would be impossible to implement something similar…)
The construct I’m talking about is a special form called fluid-let. It’s not part of the Scheme standard, but many implementations provide it anyway (including Chicken).
Consider the following code:
(define x 4) (define (report) (printf "I ate ~a hamburgers.~n" x)) (report)
This prints “I ate 4 hamburgers.” So far, so good.
Now, if we wrap the call to report in a let…
(let ((x 15)) (report))
…it *still* prints “I ate 4 hamburgers.” This is expected, because the x defined in the let does not affect the x referenced by report, which is a global.
However, with fluid-let we can change this, and shadow the global x anyway. Witness:
(fluid-let ((x 15)) (report))
This prints “I ate 15 hamburgers.” This greatly mystified me at first, but it’s actually not so difficult to understand what is going on. fluid-let stores the old value of x, then sets it to the new value (15), then executes the code in its body, and finally restores x to its original value.
In fact, fluid-let can be written as a macro. Quite instructive, although not necessarily easy to understand…
Note: Apparently fluid-let only works with globals. The following does *not* work (at least not in Chicken):
(define (make-report x) (lambda () (printf "I ate ~a hamburgers.~n" x))) (define report (make-report 4)) (report) ;; 4 hamburgers ;; error: (fluid-let ((x 15)) (report))
…because there is no global x to shadow.