1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-10 22:10:21 +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:
Andy Wingo 2013-01-21 11:16:29 +01:00
parent 5a35d42aa5
commit a6bd32406d
2 changed files with 63 additions and 12 deletions

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 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
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}.
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) @result{} 3/4
@end example
@end defun
@end deffn
@deffn {library syntax} parameterize ((param value) @dots{}) body1 body2 @dots{}
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
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
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

View file

@ -2929,6 +2929,34 @@ but it fails to load."
(set-struct-vtable-name! <parameter> '<parameter>)
(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))))
(make-struct <parameter> 0
(case-lambda
@ -2938,6 +2966,22 @@ but it fails to load."
prev)))
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)
(and (struct? x) (eq? (struct-vtable x) <parameter>)))
@ -2972,15 +3016,7 @@ but it fails to load."
;;; Current ports as parameters.
;;;
(let ((fluid->parameter
(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))))
(let ()
(define-syntax-rule (port-parameterize! binding fluid predicate msg)
(begin
(set! binding (fluid->parameter (module-ref (current-module) 'fluid)