Move parameters documentation to core
* doc/ref/api-scheduling.texi (Fluids and Dynamic States): Update for default values. (Parameters): Move here from srfi-39, and adapt.
This commit is contained in:
parent
cd3370bac1
commit
99db1bc2e2
2 changed files with 129 additions and 155 deletions
|
|
@ -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
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009, 2010, 2012
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
* Blocking:: How to block properly in guile mode.
|
||||
* Critical Sections:: Avoiding concurrency and reentries.
|
||||
* Fluids and Dynamic States:: Thread-local variables, etc.
|
||||
* Parameters:: Dynamic scoping in Scheme.
|
||||
* Futures:: Fine-grain parallelism.
|
||||
* Parallel Forms:: Parallel execution of forms.
|
||||
@end menu
|
||||
|
|
@ -680,9 +681,11 @@ used for testing whether an object is actually a fluid. The values
|
|||
stored in a fluid can be accessed with @code{fluid-ref} and
|
||||
@code{fluid-set!}.
|
||||
|
||||
@deffn {Scheme Procedure} make-fluid
|
||||
@deffn {Scheme Procedure} make-fluid [dflt]
|
||||
@deffnx {C Function} scm_make_fluid ()
|
||||
Return a newly created fluid.
|
||||
@deffnx {C Function} scm_make_fluid_with_default (dflt)
|
||||
Return a newly created fluid, whose initial value is @var{dflt}, or
|
||||
@code{#f} if @var{dflt} is not given.
|
||||
Fluids are objects that can hold one
|
||||
value per dynamic state. That is, modifications to this value are
|
||||
only visible to code that executes with the same dynamic state as
|
||||
|
|
@ -694,7 +697,7 @@ with its own dynamic state, you can use fluids for thread local storage.
|
|||
@deffn {Scheme Procedure} make-unbound-fluid
|
||||
@deffnx {C Function} scm_make_unbound_fluid ()
|
||||
Return a new fluid that is initially unbound (instead of being
|
||||
implicitly bound to @code{#f}.
|
||||
implicitly bound to some definite value).
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fluid? obj
|
||||
|
|
@ -707,8 +710,8 @@ Return @code{#t} iff @var{obj} is a fluid; otherwise, return
|
|||
@deffnx {C Function} scm_fluid_ref (fluid)
|
||||
Return the value associated with @var{fluid} in the current
|
||||
dynamic root. If @var{fluid} has not been set, then return
|
||||
@code{#f}. Calling @code{fluid-ref} on an unbound fluid produces a
|
||||
runtime error.
|
||||
its default value. Calling @code{fluid-ref} on an unbound fluid produces
|
||||
a runtime error.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fluid-set! fluid value
|
||||
|
|
@ -820,6 +823,119 @@ Like @code{scm_with_dynamic_state}, but call @var{func} with
|
|||
@var{data}.
|
||||
@end deftypefn
|
||||
|
||||
@node Parameters
|
||||
@subsection Parameters
|
||||
|
||||
@cindex SRFI-39
|
||||
@cindex parameter object
|
||||
@tindex Parameter
|
||||
|
||||
A parameter object is a procedure. Calling it with no arguments returns
|
||||
its value. Calling it with one argument sets the value.
|
||||
|
||||
@example
|
||||
(define my-param (make-parameter 123))
|
||||
(my-param) @result{} 123
|
||||
(my-param 456)
|
||||
(my-param) @result{} 456
|
||||
@end example
|
||||
|
||||
The @code{parameterize} special form establishes new locations for
|
||||
parameters, those new locations having effect within the dynamic scope
|
||||
of the @code{parameterize} body. Leaving restores the previous
|
||||
locations. Re-entering (through a saved continuation) will again use
|
||||
the new locations.
|
||||
|
||||
@example
|
||||
(parameterize ((my-param 789))
|
||||
(my-param)) @result{} 789
|
||||
(my-param) @result{} 456
|
||||
@end example
|
||||
|
||||
Parameters are like dynamically bound variables in other Lisp dialects.
|
||||
They allow an application to establish parameter settings (as the name
|
||||
suggests) just for the execution of a particular bit of code, restoring
|
||||
when done. Examples of such parameters might be case-sensitivity for a
|
||||
search, or a prompt for user input.
|
||||
|
||||
Global variables are not as good as parameter objects for this sort of
|
||||
thing. Changes to them are visible to all threads, but in Guile
|
||||
parameter object locations are per-thread, thereby truly limiting the
|
||||
effect of @code{parameterize} to just its dynamic execution.
|
||||
|
||||
Passing arguments to functions is thread-safe, but that soon becomes
|
||||
tedious when there's more than a few or when they need to pass down
|
||||
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]
|
||||
Return a new parameter object, with initial value @var{init}.
|
||||
|
||||
If a @var{converter} is given, then a call @code{(@var{converter}
|
||||
val)} is made for each value set, its return is the value stored.
|
||||
Such a call is made for the @var{init} initial value too.
|
||||
|
||||
A @var{converter} allows values to be validated, or put into a
|
||||
canonical form. For example,
|
||||
|
||||
@example
|
||||
(define my-param (make-parameter 123
|
||||
(lambda (val)
|
||||
(if (not (number? val))
|
||||
(error "must be a number"))
|
||||
(inexact->exact val))))
|
||||
(my-param 0.75)
|
||||
(my-param) @result{} 3/4
|
||||
@end example
|
||||
@end defun
|
||||
|
||||
@deffn {Scheme Syntax} parameterize ((param value) @dots{}) body @dots{}
|
||||
Establish a new dynamic scope with the given @var{param}s bound to new
|
||||
locations and set to the given @var{value}s. @var{body} is evaluated
|
||||
in that environment, the result is the return from the last form in
|
||||
@var{body}.
|
||||
|
||||
Each @var{param} is an expression which is evaluated to get the
|
||||
parameter object. Often this will just be the name of a variable
|
||||
holding the object, but it can be anything that evaluates to a
|
||||
parameter.
|
||||
|
||||
The @var{param} expressions and @var{value} expressions are all
|
||||
evaluated before establishing the new dynamic bindings, and they're
|
||||
evaluated in an unspecified order.
|
||||
|
||||
For example,
|
||||
|
||||
@example
|
||||
(define prompt (make-parameter "Type something: "))
|
||||
(define (get-input)
|
||||
(display (prompt))
|
||||
...)
|
||||
|
||||
(parameterize ((prompt "Type a number: "))
|
||||
(get-input)
|
||||
...)
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
Parameter objects are implemented using fluids (@pxref{Fluids and
|
||||
Dynamic States}), so each dynamic state has its own parameter
|
||||
locations. That includes the separate locations when outside any
|
||||
@code{parameterize} form. When a parameter is created it gets a
|
||||
separate initial location in each dynamic state, all initialized to the
|
||||
given @var{init} value.
|
||||
|
||||
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
|
||||
state or thread is created, the values of parameters in the originating
|
||||
context are copied, into new locations.
|
||||
|
||||
@cindex SRFI-39
|
||||
Guile's parameters conform to SRFI-39 (@pxref{SRFI-39}).
|
||||
|
||||
|
||||
@node Futures
|
||||
@subsection Futures
|
||||
@cindex futures
|
||||
|
|
|
|||
|
|
@ -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, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
|
@ -3846,134 +3846,14 @@ from a closed port.
|
|||
@node SRFI-39
|
||||
@subsection SRFI-39 - Parameters
|
||||
@cindex SRFI-39
|
||||
@cindex parameter object
|
||||
@tindex Parameter
|
||||
|
||||
This SRFI provides parameter objects, which implement dynamically
|
||||
bound locations for values. The functions below are available from
|
||||
This SRFI adds support for dynamically-scoped parameters. SRFI 39 is
|
||||
implemented in the Guile core; there's no module needed to get SRFI-39
|
||||
itself. Parameters are documented in @ref{Parameters}.
|
||||
|
||||
@example
|
||||
(use-modules (srfi srfi-39))
|
||||
@end example
|
||||
|
||||
A parameter object is a procedure. Called with no arguments it
|
||||
returns its value, called with one argument it sets the value.
|
||||
|
||||
@example
|
||||
(define my-param (make-parameter 123))
|
||||
(my-param) @result{} 123
|
||||
(my-param 456)
|
||||
(my-param) @result{} 456
|
||||
@end example
|
||||
|
||||
The @code{parameterize} special form establishes new locations for
|
||||
parameters, those new locations having effect within the dynamic scope
|
||||
of the @code{parameterize} body. Leaving restores the previous
|
||||
locations, or re-entering through a saved continuation will again use
|
||||
the new locations.
|
||||
|
||||
@example
|
||||
(parameterize ((my-param 789))
|
||||
(my-param) @result{} 789
|
||||
)
|
||||
(my-param) @result{} 456
|
||||
@end example
|
||||
|
||||
Parameters are like dynamically bound variables in other Lisp dialects.
|
||||
They allow an application to establish parameter settings (as the name
|
||||
suggests) just for the execution of a particular bit of code,
|
||||
restoring when done. Examples of such parameters might be
|
||||
case-sensitivity for a search, or a prompt for user input.
|
||||
|
||||
Global variables are not as good as parameter objects for this sort of
|
||||
thing. Changes to them are visible to all threads, but in Guile
|
||||
parameter object locations are per-thread, thereby truly limiting the
|
||||
effect of @code{parameterize} to just its dynamic execution.
|
||||
|
||||
Passing arguments to functions is thread-safe, but that soon becomes
|
||||
tedious when there's more than a few or when they need to pass down
|
||||
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.
|
||||
|
||||
|
||||
@sp 1
|
||||
@defun make-parameter init [converter]
|
||||
Return a new parameter object, with initial value @var{init}.
|
||||
|
||||
A parameter object is a procedure. When called @code{(param)} it
|
||||
returns its value, or a call @code{(param val)} sets its value. For
|
||||
example,
|
||||
|
||||
@example
|
||||
(define my-param (make-parameter 123))
|
||||
(my-param) @result{} 123
|
||||
|
||||
(my-param 456)
|
||||
(my-param) @result{} 456
|
||||
@end example
|
||||
|
||||
If a @var{converter} is given, then a call @code{(@var{converter}
|
||||
val)} is made for each value set, its return is the value stored.
|
||||
Such a call is made for the @var{init} initial value too.
|
||||
|
||||
A @var{converter} allows values to be validated, or put into a
|
||||
canonical form. For example,
|
||||
|
||||
@example
|
||||
(define my-param (make-parameter 123
|
||||
(lambda (val)
|
||||
(if (not (number? val))
|
||||
(error "must be a number"))
|
||||
(inexact->exact val))))
|
||||
(my-param 0.75)
|
||||
(my-param) @result{} 3/4
|
||||
@end example
|
||||
@end defun
|
||||
|
||||
@deffn {library syntax} parameterize ((param value) @dots{}) body @dots{}
|
||||
Establish a new dynamic scope with the given @var{param}s bound to new
|
||||
locations and set to the given @var{value}s. @var{body} is evaluated
|
||||
in that environment, the result is the return from the last form in
|
||||
@var{body}.
|
||||
|
||||
Each @var{param} is an expression which is evaluated to get the
|
||||
parameter object. Often this will just be the name of a variable
|
||||
holding the object, but it can be anything that evaluates to a
|
||||
parameter.
|
||||
|
||||
The @var{param} expressions and @var{value} expressions are all
|
||||
evaluated before establishing the new dynamic bindings, and they're
|
||||
evaluated in an unspecified order.
|
||||
|
||||
For example,
|
||||
|
||||
@example
|
||||
(define prompt (make-parameter "Type something: "))
|
||||
(define (get-input)
|
||||
(display (prompt))
|
||||
...)
|
||||
|
||||
(parameterize ((prompt "Type a number: "))
|
||||
(get-input)
|
||||
...)
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Parameter object} current-input-port [new-port]
|
||||
@deffnx {Parameter object} current-output-port [new-port]
|
||||
@deffnx {Parameter object} current-error-port [new-port]
|
||||
This SRFI extends the core @code{current-input-port} and
|
||||
@code{current-output-port}, making them parameter objects. The
|
||||
Guile-specific @code{current-error-port} is extended too, for
|
||||
consistency. (@pxref{Default Ports}.)
|
||||
|
||||
This is an upwardly compatible extension, a plain call like
|
||||
@code{(current-input-port)} still returns the current input port, and
|
||||
@code{set-current-input-port} can still be used. But the port can now
|
||||
also be set with @code{(current-input-port my-port)} and bound
|
||||
dynamically with @code{parameterize}.
|
||||
@end deffn
|
||||
This module does export one extra function: @code{with-parameters*}.
|
||||
This is a Guile-specific addition to the SRFI, similar to the core
|
||||
@code{with-fluids*} (@pxref{Fluids and Dynamic States}).
|
||||
|
||||
@defun with-parameters* param-list value-list thunk
|
||||
Establish a new dynamic scope, as per @code{parameterize} above,
|
||||
|
|
@ -3981,30 +3861,8 @@ taking parameters from @var{param-list} and corresponding values from
|
|||
@var{values-list}. A call @code{(@var{thunk})} is made in the new
|
||||
scope and the result from that @var{thunk} is the return from
|
||||
@code{with-parameters*}.
|
||||
|
||||
This function is a Guile-specific addition to the SRFI, it's similar
|
||||
to the core @code{with-fluids*} (@pxref{Fluids and Dynamic States}).
|
||||
@end defun
|
||||
|
||||
|
||||
@sp 1
|
||||
Parameter objects are implemented using fluids (@pxref{Fluids and
|
||||
Dynamic States}), so each dynamic state has it's own parameter
|
||||
locations. That includes the separate locations when outside any
|
||||
@code{parameterize} form. When a parameter is created it gets a
|
||||
separate initial location in each dynamic state, all initialized to
|
||||
the given @var{init} value.
|
||||
|
||||
As alluded to above, because each thread usually has a separate
|
||||
dynamic state, each thread has it's own locations behind parameter
|
||||
objects, and changes in one thread are not visible to any other. When
|
||||
a new dynamic state or thread is created, the values of parameters in
|
||||
the originating context are copied, into new locations.
|
||||
|
||||
SRFI-39 doesn't specify the interaction between parameter objects and
|
||||
threads, so the threading behaviour described here should be regarded
|
||||
as Guile-specific.
|
||||
|
||||
@node SRFI-42
|
||||
@subsection SRFI-42 - Eager Comprehensions
|
||||
@cindex SRFI-42
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue