11.3.2 Parameters

► |  | The Racket Reference

1 | Language Model
2 | Notation for Documentation
3 | Syntactic Forms
4 | Datatypes
5 | Structures
6 | Classes and Objects
7 | Units
8 | Contracts
9 | Pattern Matching
10 | Control Flow
11 | Concurrency and Parallelism
12 | Macros
13 | Input and Output
14 | Reflection and Security
15 | Operating System
16 | Memory Management
17 | Unsafe Operations
18 | Running Racket
| Bibliography
| Index

► | 11 | Concurrency and Parallelism

11.1 | Threads
11.2 | Synchronization
11.3 | Thread-Local Storage
11.4 | Futures
11.5 | Places
11.6 | Engines
11.7 | Machine Memory Order

▼ | 11.3 | Thread-Local Storage

11.3.1 | Thread Cells
11.3.2 | Parameters

On this page:

make-parameter
parameterize
parameterize*
make-derived-parameter
parameter?
parameter-procedure=?
current-parameterization
call-with-parameterization
parameterization?

top contents ← prev up next →

#### 11.3.2 Parameters🔗ℹ

> > > Dynamic Binding: parameterize in The Racket Guide introduces parameters.

See Parameters for basic information on the parameter model. Parameters correspond to preserved thread fluids in Scsh [Gasbichler02].

To parameterize code in a thread- and continuation-friendly manner, use parameterize. The parameterize form introduces a fresh thread cell for the dynamic extent of its body expressions.

When a new thread is created, the parameterization for the new thread’s initial continuation is the parameterization of the creator thread. Since each parameter’s thread cell is preserved, the new thread “inherits” the parameter values of its creating thread. When a continuation is moved from one thread to another, settings introduced with parameterize effectively move with the continuation.

In contrast, direct assignment to a parameter (by calling the parameter procedure with a value) changes the value in a thread cell, and therefore changes the setting only for the current thread. Consequently, as far as the memory manager is concerned, the value originally associated with a parameter through parameterize remains reachable as long the continuation is reachable, even if the parameter is mutated.

> procedure (make-parameter v [guard name realm]) → parameter?
> v : any/c
> guard : (or/c (any/c . -> . any) #f) = #f
> name : symbol? = 'parameter-procedure
> realm : symbol? = 'racket

Returns a new parameter procedure. The value of the parameter is initialized to v in all threads.

If guard is not #f, it is used as the parameter’s guard procedure. A guard procedure takes one argument. Whenever the parameter procedure is applied to an argument, the argument is passed on to the guard procedure. The result returned by the guard procedure is used as the new parameter value. A guard procedure can raise an exception to reject a change to the parameter’s value. The guard is not applied to the initial v.

The name argument is used as the parameter procedure’s name as reported by object-name, and realm is used as the reported as reported by procedure-realm.

Changed in version 7.4.0.6 of package base: Added the name argument.
Changed in version 8.4.0.2: Added the realm argument.

> > syntax
> > (parameterize ([parameter-expr value-expr] ...)
> > body ...+)
> | parameter-expr |  | : |  | parameter?

> > > Dynamic Binding: parameterize in The Racket Guide introduces parameterize.

The result of a parameterize expression is the result of the last body. The parameter-exprs determine the parameters to set, and the value-exprs determine the corresponding values to install while evaluating the bodys. The parameter-exprs and value-exprs are evaluated left-to-right (interleaved), and then the parameters are bound in the continuation to preserved thread cells that contain the values of the value-exprs; the result of each parameter-expr is checked with parameter? just before it is bound. The last body is in tail position with respect to the entire parameterize form.

Outside the dynamic extent of a parameterize expression, parameters remain bound to other thread cells. Effectively, therefore, old parameters settings are restored as control exits the parameterize expression.

If a continuation is captured during the evaluation of parameterize, invoking the continuation effectively re-introduces the parameterization, since a parameterization is associated to a continuation via a continuation mark (see Continuation Marks) using a private key.

Examples:

> > (parameterize ([exit-handler (lambda (x) 'no-exit)])
> (exit))
> > (define p1 (make-parameter 1))
> > (define p2 (make-parameter 2))
> > (parameterize ([p1 3]
> [p2 (p1)])
> (cons (p1) (p2)))
> '(3 . 1)
> > (let ([k (let/cc out
> (parameterize ([p1 2])
> (p1 3)
> (cons (let/cc k
> (out k))
> (p1))))])
> (if (procedure? k)
> (k (p1))
> k))
> '(1 . 3)
> > (define ch (make-channel))
> > (parameterize ([p1 0])
> (thread (lambda ()
> (channel-put ch (cons (p1) (p2))))))
> #<thread>
> > (channel-get ch)
> '(0 . 2)
> > (define k-ch (make-channel))
> > (define (send-k)
> (parameterize ([p1 0])
> (thread (lambda ()
> (let/ec esc
> (channel-put ch
> ((let/cc k
> (channel-put k-ch k)
> (esc)))))))))
> > (send-k)
> #<thread>
> > (thread (lambda () ((channel-get k-ch)
> (let ([v (p1)])
> (lambda () v)))))
> #<thread>
> > (channel-get ch)
> 1
> > (send-k)
> #<thread>
> > (thread (lambda () ((channel-get k-ch) p1)))
> #<thread>
> > (channel-get ch)
> 0

> > syntax
> > (parameterize* ((parameter-expr value-expr) ...)
> > body ...+)

Analogous to let* compared to let, parameterize* is the same as a nested series of single-parameter parameterize forms.

> > procedure
> > (make-derived-parameter |  | parameter |  |  |  |
> > |  | guard |  |  |  |
> > |  | wrap |  |  |  |
> > | [ | name |  |  |  |
> > |  | realm]) |  | → |  | parameter?
> parameter : parameter?
> guard : (any/c . -> . any)
> wrap : (any/c . -> . any)
> name : symbol? = (object-name parameter)
> realm : symbol? = (procedure-realm parameter)

Returns a parameter procedure that sets or retrieves the same value as parameter, but with:

- guard applied when setting the parameter (before any guard associated with parameter), and

- wrap applied when obtaining the parameter’s value.

The name argument is used as the parameter procedure’s name as reported by object-name, and realm is used as the reported as reported by procedure-realm. Supply values for guard and wrap if the goal is merely to replace the name or realm of parameter.

See also chaperone-procedure, which can also be used to guard parameter procedures.

Changed in version 8.15.0.4 of package base: Added the name and realm arguments.

> procedure (parameter? v) → boolean?
> v : any/c

Returns #t if v is a parameter procedure, #f otherwise.

> procedure (parameter-procedure=? a b) → boolean?
> a : parameter?
> b : parameter?

Returns #t if the parameter procedures a and b always modify the same parameter with the same guards (although possibly with different chaperones), #f otherwise.

> procedure (current-parameterization) → parameterization?

Returns the current continuation’s parameterization.

> > procedure
> > (call-with-parameterization |  | parameterization |  |  |  |
> > |  | thunk) |  | → |  | any
> parameterization : parameterization?
> thunk : (-> any)

Calls thunk (via a tail call) with parameterization as the current parameterization.

> procedure (parameterization? v) → boolean?
> v : any/c

Returns #t if v is a parameterization returned by current-parameterization, #f otherwise.
top contents ← prev up next →