Previous: , Up: Variables   [Contents][Index]


5.8.6 Fluid Variables

Special variables have a number of drawbacks, especially when used in conjunction with the module system (see Modules and Special Variables). As a consequence of these drawbacks, rep provides a second method of implementing dynamically scoped variables, known as fluid variables, or just fluids.

A fluid is a first class Lisp object that may be passed around like any other Lisp object. Its sole function is to provide a location from which dynamic bindings may be created. Fluids are anonymous objects, they are usually named by being stored in lexically scoped variables.

Function: make-fluid #!optional value

Create and return a new fluid, it will have an initial binding of value (or false if value is undefined).

Function: fluid fluid

Return the value of the most recently created binding of the fluid variable object fluid.

Function: fluid-set fluid value

Set the value of the most recently created binding of the fluid variable object fluid to value.

Function: with-fluids fluids values thunk

Call the zero parameter function thunk (and return the value that it returns) with new bindings created for each of the fluid variables specified in the list fluids.

For each member of fluids the corresponding member of the values list provides the initial value of the new binding.

If the lists fluids and values are not of the same length, an error is signalled.

Macro: let-fluids bindings body …

A convenient wrapper around with-fluids, similar to the let syntax.

The list bindings associates the names of lexical variables containing fluid objects, with the values to bind to those fluid objects. Once the bindings have been installed, the body … forms are evaluated, and the bindings removed. The value of the last of the body … forms is returned.

Here is an example code fragment using fluid variables and let-fluids:

(define a (make-fluid))
(define b (make-fluid))

(let-fluids ((a 1)
             (b 2))
  (+ (fluid a) (fluid b))) ⇒ 3

;; Compare with let.
(define c 'outer)
(define (foo) c)

(define (bar)
   (let ((c 'inner)) (foo)))

(bar)
   ⇒ outer
;; The let binding is newly established inside of bar,
;; and foo doesn't see it.

Previous: , Up: Variables   [Contents][Index]