G.R.O.S.S., which stands for Get Rid Of Slimy GirlS, is a club which consists of only two members: Calvin and Hobbes. The club was founded in the garage of their house. To clear space for its activities, Calvin and (purportedly) Hobbes push Calvin's parents' car, causing it to roll into a ditch (but not suffer damage); the incident necessitates changing the club's location to Calvin's treehouse. They hold meetings to attempt to annoy Susie Derkins. Notable actions include planting a fake secret tape near her in attempt to draw her in to a trap, trapping her in a closet at their house, and creating elaborate water balloon traps. Calvin gave himself and Hobbes important positions in the club, Calvin being "Dictator-for-Life" and Hobbes being "President-and-First-Tiger". They go into Calvin's treehouse for their club meetings and often get into fights during them. The password to get into the treehouse is intentionally long and difficult, which has on at least one occasion ruined Calvin's plans. (Because Hobbes can climb the tree without the rope, he got to think up the password, which heaps praise upon tigers.) An example of this can be seen in the comic strip where Calvin, rushing to get into the treehouse to throw things at a passing Susie Derkins, insults Hobbes, who is in the treehouse and thus has to let down the rope. Hobbes forces Calvin to say the password for insulting him. By the time Susie arrives, in time to hear Calvin saying some of the password, causing him to stumble, Calvin is on "Verse Seven: Tigers are perfect!/The E-pit-o-me/of good looks and grace/and quiet..uh..um..dignity". The opportunity to pelt Susie with something having passed, Calvin threatens to turn Hobbes into a rug. G.R.O.S.S. is one of the most common adventures that Calvin has. The club anthem begins: "Ohhhh Gross, best club in the cosmos..."
One type of environment in Common Lisp is the dynamic environment. Bindings established in this environment have dynamic extent, which means that a binding is established at the start of the execution of some construct, such as a let block, and disappears when that construct finishes executing: its lifetime is tied to the dynamic activation and deactivation of a block. However, a dynamic binding is not just visible within that block; it is also visible to all functions invoked from that block. This type of visibility is known as indefinite scope. Bindings which exhibit dynamic extent (lifetime tied to the activation and deactivation of a block) and indefinite scope (visible to all functions which are called from that block) are said to have dynamic scope.
Common Lisp has support for dynamically scoped variables, which are also called special variables. Certain other kinds of bindings are necessarily dynamically scoped also, such as restarts and catch tags. Function bindings cannot be dynamically scoped using flet (which only provides lexically scoped function bindings), but function objects (a first-level object in Common Lisp) can be assigned to dynamically scoped variables, bound using let in dynamic scope, then called using funcall or APPLY.
Dynamic scope is extremely useful because it adds referential clarity and discipline to global variables. Global variables are frowned upon in computer science as potential sources of error, because they can give rise to ad-hoc, covert channels of communication among modules that lead to unwanted, surprising interactions.
In Common Lisp, a special variable which has only a top-level binding behaves just like a global variable in other programming languages. A new value can be stored into it, and that value simply replaces what is in the top-level binding. Careless replacement of the value of a global variable is at the heart of bugs caused by use of global variables. However, another way to work with a special variable is to give it a new, local binding within an expression. This is sometimes referred to as "rebinding" the variable. Binding a dynamically scoped variable temporarily creates a new memory location for that variable, and associates the name with that location. While that binding is in effect, all references to that variable refer to the new binding; the previous binding is hidden. When execution of the binding expression terminates, the temporary memory location is gone, and the old binding is revealed, with the original value intact. Of course, multiple dynamic bindings for the same variable can be nested.
In Common Lisp implementations which support multithreading, dynamic scopes are specific to each thread of execution. Thus special variables serve as an abstraction for thread local storage. If one thread rebinds a special variable, this rebinding has no effect on that variable in other threads. The value stored in a binding can only be retrieved by the thread which created that binding. If each thread binds some special variable *x*, then *x* behaves like thread-local storage. Among threads which do not rebind *x*, it behaves like an ordinary global: all of these threads refer to the same top-level binding of *x*.
Dynamic variables can be used to extend the execution context with additional context information which is implicitly passed from function to function without having to appear as an extra function parameter. This is especially useful when the control transfer has to pass through layers of unrelated code, which simply cannot be extended with extra parameters to pass the additional data. A situation like this usually calls for a global variable. That global variable must be saved and restored, so that the scheme doesn't break under recursion: dynamic variable rebinding takes care of this. And that variable must be made thread-local (or else a big mutex must be used) so the scheme doesn't break under threads: dynamic scope implementations can take care of this also.
In the Common Lisp library, there are many standard special variables. For instance, all standard I/O streams are stored in the top-level bindings of well-known special variables. The standard output stream is stored in *standard-output*.
Suppose a function foo writes to standard output:
To capture its output in a character string, *standard-output* can be bound to a string stream and called:
-> "Hello, world" ; gathered output returned as a string