For Development HEAD DRAFTSearch (procedure/syntax/module):

Next: , Previous: , Up: Core library   [Contents][Index]

6.16 Parameters

A parameter is Scheme’s way to implement dynamically scoped states. It is codified in srfi-39 and incorporated into R7RS.

It is a special procedure created by make-parameter. It accepts zero or one argument. When called without an argument, it returns the current value. If an argument is passed, it alters its current value with the given value, and returns the previous value.

Using parameterize macro, which is similar to let syntactially, rebinds the parameters’ value during execution of its body, dynamically rather than lexically.

(define var (make-parameter 0))

(define (show-var) (print (var)))

(show-var)  ; prints 0

(parameterize ((var 1))
  (show-var))    ; prints 1

(define f)

(parameterize ((var 2))
  (set! f (lambda () (show-var))))

(f) ; prints 0, since its out of the dynamic extent of var=2

If a control trasfers from or to parameterize’s body by continuations, the parameter refers to the value corresponding the dynamic envrionment it is accessed.

A parameter’s value can be mutated by calling the parameter with the new value:

(define var (make-parameter 0))

(var) ; ⇒ 0

(var 1)

(var) ; ⇒ 1

;; Gauche extension: you can use set! too
(set! (var) 2)

(var) ; ⇒ 2

Note: As of 0.9.13, Gauche’s parameter is thread-local: Changes of its value aren’t visible from other threads. This is going to change. If you’re using a parameter simply for thread specific storage, consider replacing it with a thread local (see Thread local storage). If you want a parameter that’s thread-local, use make-thread-parameter instead of make-parameter.

Function: make-parameter value :optional filter
Function: make-thread-parameter value :optional filter
Function: make-shared-parameter value :optional filter

[R7RS base][SRFI-226] Creates a parameter whose initial value is value. If an optional argument filter is given, it must be a procedure that takes one argument and returns one value; whenever the parameter’s value is about to change, the procedure is called with the given value, and the value the procedure returns will be the parameter’s value. The filter procedure can raise an error or reject to change the parameter’s value.

A parameter can be a thread parameter or a shared parameter. When you mutate a thread parameter, the change is only visible in the same thread; the value in other threads isn’t affected. On the other hand, the storage of a shared parameter is shared by all threads, and mutation is visible from all threads. However, once you parameterize it, mutation is only visible from the thread that shares the same parameterization.

R7RS only defines make-parameter and does not specify the behavior with threads. Up until 0.9.12, Gauche made the default parameter thread-local. However, SRFI-226 specifies the default parameter shared, and specify make-thread-parameter to be used to create a thread parameter.

For the backward compatibility, make-parameter still returns a thread parameter for the time being, unless you explicitly use srfi-226. Eventually we switch make-parameter to return a shared parameter, so you want to replace it with make-thread-parameter if that’s what you want. During transition, you can use make-shared-parameter (Gauche specific procedure) to explicitly create a shared parameter.

NB: In 0.9.9 and before, this procedure returns a parameter object, and we used object-apply method to make it behave like a procedure. However, R7RS explicitly defines the return values to be a procedure; notably, portable code expects (procedure? (make-parameter 'z)) returns #t.

As of 0.9.10, we switched make-parameter to return a procedure. It won’t change the external behavior, except when you test the parameter p with (is-a? p <parameter>); you have to use parameter? instead.

Macro: parameterize ((param value) …) body …

[R7RS base] Evaluates body …, with change parameter param’s value to the given value within the dynamic scope of body …. Returns the value(s) of the result of the last body.

Some examples:

(define a (make-parameter 1))
(a) ⇒ 1
(a 2) ⇒ 1
(a) ⇒ 2
(parameterize ((a 3))
  (a)) ⇒ 3
(a) ⇒ 2
Function: parameter? obj

Returns #t iff obj is an object created by make-parameter.

Note: Some built-in procedures such as current-input-port behaves like parameters. They aren’t created by make-parameter, though, and returns #f for parameter?.

Next: , Previous: , Up: Core library   [Contents][Index]

For Development HEAD DRAFTSearch (procedure/syntax/module):