mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-12 06:41:13 +02:00
add fluid->parameter
* module/ice-9/boot-9.scm (make-parameter): Add a docstring. (fluid->parameter): New interface. Use it when turning port fluids into parameters. * doc/ref/api-scheduling.texi (Parameters): Deffn instead of defun for make-parameter documentation. Add docs for fluid->parameter.
This commit is contained in:
parent
5a35d42aa5
commit
a6bd32406d
2 changed files with 63 additions and 12 deletions
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009, 2010, 2012
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009, 2010, 2012, 2013
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -869,7 +869,7 @@ through several layers of calls before reaching the point they should
|
||||||
affect. And introducing a new setting to existing code is often easier
|
affect. And introducing a new setting to existing code is often easier
|
||||||
with a parameter object than adding arguments.
|
with a parameter object than adding arguments.
|
||||||
|
|
||||||
@defun make-parameter init [converter]
|
@deffn {Scheme Procedure} make-parameter init [converter]
|
||||||
Return a new parameter object, with initial value @var{init}.
|
Return a new parameter object, with initial value @var{init}.
|
||||||
|
|
||||||
If a @var{converter} is given, then a call @code{(@var{converter}
|
If a @var{converter} is given, then a call @code{(@var{converter}
|
||||||
|
@ -888,7 +888,7 @@ canonical form. For example,
|
||||||
(my-param 0.75)
|
(my-param 0.75)
|
||||||
(my-param) @result{} 3/4
|
(my-param) @result{} 3/4
|
||||||
@end example
|
@end example
|
||||||
@end defun
|
@end deffn
|
||||||
|
|
||||||
@deffn {library syntax} parameterize ((param value) @dots{}) body1 body2 @dots{}
|
@deffn {library syntax} parameterize ((param value) @dots{}) body1 body2 @dots{}
|
||||||
Establish a new dynamic scope with the given @var{param}s bound to new
|
Establish a new dynamic scope with the given @var{param}s bound to new
|
||||||
|
@ -926,6 +926,21 @@ locations. That includes the separate locations when outside any
|
||||||
separate initial location in each dynamic state, all initialized to the
|
separate initial location in each dynamic state, all initialized to the
|
||||||
given @var{init} value.
|
given @var{init} value.
|
||||||
|
|
||||||
|
New code should probably just use parameters instead of fluids, because
|
||||||
|
the interface is better. But for migrating old code or otherwise
|
||||||
|
providing interoperability, Guile provides the @code{fluid->parameter}
|
||||||
|
procedure:
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} fluid->parameter fluid [conv]
|
||||||
|
Make a parameter that wraps a fluid.
|
||||||
|
|
||||||
|
The value of the parameter will be the same as the value of the fluid.
|
||||||
|
If the parameter is rebound in some dynamic extent, perhaps via
|
||||||
|
@code{parameterize}, the new value will be run through the optional
|
||||||
|
@var{conv} procedure, as with any parameter. Note that unlike
|
||||||
|
@code{make-parameter}, @var{conv} is not applied to the initial value.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
As alluded to above, because each thread usually has a separate dynamic
|
As alluded to above, because each thread usually has a separate dynamic
|
||||||
state, each thread has its own locations behind parameter objects, and
|
state, each thread has its own locations behind parameter objects, and
|
||||||
changes in one thread are not visible to any other. When a new dynamic
|
changes in one thread are not visible to any other. When a new dynamic
|
||||||
|
|
|
@ -2929,6 +2929,34 @@ but it fails to load."
|
||||||
(set-struct-vtable-name! <parameter> '<parameter>)
|
(set-struct-vtable-name! <parameter> '<parameter>)
|
||||||
|
|
||||||
(define* (make-parameter init #:optional (conv (lambda (x) x)))
|
(define* (make-parameter init #:optional (conv (lambda (x) x)))
|
||||||
|
"Make a new parameter.
|
||||||
|
|
||||||
|
A parameter is a dynamically bound value, accessed through a procedure.
|
||||||
|
To access the current value, apply the procedure with no arguments:
|
||||||
|
|
||||||
|
(define p (make-parameter 10))
|
||||||
|
(p) => 10
|
||||||
|
|
||||||
|
To provide a new value for the parameter in a dynamic extent, use
|
||||||
|
`parameterize':
|
||||||
|
|
||||||
|
(parameterize ((p 20))
|
||||||
|
(p)) => 20
|
||||||
|
(p) => 10
|
||||||
|
|
||||||
|
The value outside of the dynamic extent of the body is unaffected. To
|
||||||
|
update the current value, apply it to one argument:
|
||||||
|
|
||||||
|
(p 20) => 10
|
||||||
|
(p) => 20
|
||||||
|
|
||||||
|
As you can see, the call that updates a parameter returns its previous
|
||||||
|
value.
|
||||||
|
|
||||||
|
All values for the parameter are first run through the CONV procedure,
|
||||||
|
including INIT, the initial value. The default CONV procedure is the
|
||||||
|
identity procedure. CONV is commonly used to ensure some set of
|
||||||
|
invariants on the values that a parameter may have."
|
||||||
(let ((fluid (make-fluid (conv init))))
|
(let ((fluid (make-fluid (conv init))))
|
||||||
(make-struct <parameter> 0
|
(make-struct <parameter> 0
|
||||||
(case-lambda
|
(case-lambda
|
||||||
|
@ -2938,6 +2966,22 @@ but it fails to load."
|
||||||
prev)))
|
prev)))
|
||||||
fluid conv)))
|
fluid conv)))
|
||||||
|
|
||||||
|
(define* (fluid->parameter fluid #:optional (conv (lambda (x) x)))
|
||||||
|
"Make a parameter that wraps a fluid.
|
||||||
|
|
||||||
|
The value of the parameter will be the same as the value of the fluid.
|
||||||
|
If the parameter is rebound in some dynamic extent, perhaps via
|
||||||
|
`parameterize', the new value will be run through the optional CONV
|
||||||
|
procedure, as with any parameter. Note that unlike `make-parameter',
|
||||||
|
CONV is not applied to the initial value."
|
||||||
|
(make-struct <parameter> 0
|
||||||
|
(case-lambda
|
||||||
|
(() (fluid-ref fluid))
|
||||||
|
((x) (let ((prev (fluid-ref fluid)))
|
||||||
|
(fluid-set! fluid (conv x))
|
||||||
|
prev)))
|
||||||
|
fluid conv))
|
||||||
|
|
||||||
(define (parameter? x)
|
(define (parameter? x)
|
||||||
(and (struct? x) (eq? (struct-vtable x) <parameter>)))
|
(and (struct? x) (eq? (struct-vtable x) <parameter>)))
|
||||||
|
|
||||||
|
@ -2972,15 +3016,7 @@ but it fails to load."
|
||||||
;;; Current ports as parameters.
|
;;; Current ports as parameters.
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
(let ((fluid->parameter
|
(let ()
|
||||||
(lambda (fluid conv)
|
|
||||||
(make-struct <parameter> 0
|
|
||||||
(case-lambda
|
|
||||||
(() (fluid-ref fluid))
|
|
||||||
((x) (let ((prev (fluid-ref fluid)))
|
|
||||||
(fluid-set! fluid (conv x))
|
|
||||||
prev)))
|
|
||||||
fluid conv))))
|
|
||||||
(define-syntax-rule (port-parameterize! binding fluid predicate msg)
|
(define-syntax-rule (port-parameterize! binding fluid predicate msg)
|
||||||
(begin
|
(begin
|
||||||
(set! binding (fluid->parameter (module-ref (current-module) 'fluid)
|
(set! binding (fluid->parameter (module-ref (current-module) 'fluid)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue