guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] GNU Guile branch, stable-2.0, updated. v2.0.6-80-ga144a7


From: Ludovic Courtès
Subject: [Guile-commits] GNU Guile branch, stable-2.0, updated. v2.0.6-80-ga144a7a
Date: Sat, 10 Nov 2012 21:27:34 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=a144a7a8467734c349399e3173df8e1c6c41a2a5

The branch, stable-2.0 has been updated
       via  a144a7a8467734c349399e3173df8e1c6c41a2a5 (commit)
       via  ec7e4f77ecbdc5ba28da8078e3a457d411f675bd (commit)
      from  3d01c19a78929b89df2c3d1368cb435268259856 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit a144a7a8467734c349399e3173df8e1c6c41a2a5
Author: Ludovic Courtès <address@hidden>
Date:   Sat Nov 10 17:27:14 2012 +0100

    doc: Document SRFI-9 functional setters.
    
    * doc/ref/api-compound.texi (Functional ``Setters''): New section.

commit ec7e4f77ecbdc5ba28da8078e3a457d411f675bd
Author: Ludovic Courtès <address@hidden>
Date:   Sat Nov 10 16:02:35 2012 +0100

    doc: Move SRFI-9 records under "Compound Data Types".
    
    Suggested by Mark Weaver.
    
    * doc/ref/srfi-modules.texi (SRFI-9): Keep the node, but move contents
      to...
    * doc/ref/api-compound.texi (SRFI-9 Records): ...here.
      (Record Overview): New section.

-----------------------------------------------------------------------

Summary of changes:
 doc/ref/api-compound.texi |  253 ++++++++++++++++++++++++++++++++++++++++++++-
 doc/ref/srfi-modules.texi |  104 +------------------
 2 files changed, 254 insertions(+), 103 deletions(-)

diff --git a/doc/ref/api-compound.texi b/doc/ref/api-compound.texi
index d020774..6aaed06 100644
--- a/doc/ref/api-compound.texi
+++ b/doc/ref/api-compound.texi
@@ -25,8 +25,10 @@ values can be looked up within them.
 * Generalized Vectors::         Treating all vector-like things uniformly.
 * Arrays::                      Matrices, etc.
 * VLists::                      Vector-like lists.
-* Records::                     
-* Structures::                  
+* Record Overview::             Walking through the maze of record APIs.
+* SRFI-9 Records::              The standard, recommended record API.
+* Records::                     Guile's historical record API.
+* Structures::                  Low-level record representation.
 * Dictionary Types::            About dictionary types in general.
 * Association Lists::           List-based dictionaries.
 * VHashes::                     VList-based dictionaries.   
@@ -2249,7 +2251,254 @@ Return a new vlist whose contents correspond to 
@var{lst}.
 Return a new list whose contents match those of @var{vlist}.
 @end deffn
 
address@hidden Record Overview
address@hidden Record Overview
 
address@hidden record
address@hidden structure
+
address@hidden, also called @dfn{structures}, are Scheme's primary
+mechanism to define new disjoint types.  A @dfn{record type} defines a
+list of @dfn{fields} that instances of the type consist of.  This is like
+C's @code{struct}.
+
+Historically, Guile has offered several different ways to define record
+types and to create records, offering different features, and making
+different trade-offs.  Over the years, each ``standard'' has also come
+with its own new record interface, leading to a maze of record APIs.
+
+At the highest level is SRFI-9, a high-level record interface
+implemented by most Scheme implementations (@pxref{SRFI-9}).  It defines
+a simple and efficient syntactic abstraction of record types and their
+associated type predicate, fields, and field accessors.  SRFI-9 is
+suitable for most uses, and this is the recommended way to create record
+types in Guile.  Similar high-level record APIs include SRFI-35
+(@pxref{SRFI-35}) and R6RS records (@pxref{rnrs records syntactic}).
+
+Then comes Guile's historical ``records'' API (@pxref{Records}).  Record
+types defined this way are first-class objects.  Introspection
+facilities are available, allowing users to query the list of fields or
+the value of a specific field at run-time, without prior knowledge of
+the type.
+
+Finally, the common denominator of these interfaces is Guile's
address@hidden API (@pxref{Structures}).  Guile's structures are the
+low-level building block for all other record APIs.  Application writers
+will normally not need to use it.
+
+Records created with these APIs may all be pattern-matched using Guile's
+standard pattern matcher (@pxref{Pattern Matching}).
+
+
address@hidden SRFI-9 Records
address@hidden SRFI-9 Records
+
address@hidden SRFI-9
address@hidden record
+
+SRFI-9 standardizes a syntax for defining new record types and creating
+predicate, constructor, and field getter and setter functions.  In Guile
+this is the recommended option to create new record types (@pxref{Record
+Overview}).  It can be used with:
+
address@hidden
+(use-modules (srfi srfi-9))
address@hidden example
+
address@hidden {library syntax} define-record-type type @* (constructor 
fieldname @dots{}) @* predicate @* (fieldname accessor [modifier]) @dots{}
address@hidden 1
+Create a new record type, and make various @code{define}s for using
+it.  This syntax can only occur at the top-level, not nested within
+some other form.
+
address@hidden is bound to the record type, which is as per the return
+from the core @code{make-record-type}.  @var{type} also provides the
+name for the record, as per @code{record-type-name}.
+
address@hidden is bound to a function to be called as
address@hidden(@var{constructor} fieldval @dots{})} to create a new record of
+this type.  The arguments are initial values for the fields, one
+argument for each field, in the order they appear in the
address@hidden form.
+
+The @var{fieldname}s provide the names for the record fields, as per
+the core @code{record-type-fields} etc, and are referred to in the
+subsequent accessor/modifier forms.
+
address@hidden is bound to a function to be called as
address@hidden(@var{predicate} obj)}.  It returns @code{#t} or @code{#f}
+according to whether @var{obj} is a record of this type.
+
+Each @var{accessor} is bound to a function to be called
address@hidden(@var{accessor} record)} to retrieve the respective field from a
address@hidden  Similarly each @var{modifier} is bound to a function to
+be called @code{(@var{modifier} record val)} to set the respective
+field in a @var{record}.
address@hidden deffn
+
address@hidden
+An example will illustrate typical usage,
+
address@hidden
+(define-record-type employee-type
+  (make-employee name age salary)
+  employee?
+  (name    get-employee-name)
+  (age     get-employee-age    set-employee-age)
+  (salary  get-employee-salary set-employee-salary))
address@hidden example
+
+This creates a new employee data type, with name, age and salary
+fields.  Accessor functions are created for each field, but no
+modifier function for the name (the intention in this example being
+that it's established only when an employee object is created).  These
+can all then be used as for example,
+
address@hidden
+employee-type @result{} #<record-type employee-type>
+
+(define fred (make-employee "Fred" 45 20000.00))
+
+(employee? fred)        @result{} #t
+(get-employee-age fred) @result{} 45
+(set-employee-salary fred 25000.00)  ;; pay rise
address@hidden example
+
+The functions created by @code{define-record-type} are ordinary
+top-level @code{define}s.  They can be redefined or @code{set!} as
+desired, exported from a module, etc.
+
address@hidden Non-toplevel Record Definitions
+
+The SRFI-9 specification explicitly disallows record definitions in a
+non-toplevel context, such as inside @code{lambda} body or inside a
address@hidden block.  However, Guile's implementation does not enforce that
+restriction.
+
address@hidden Custom Printers
+
+You may use @code{set-record-type-printer!} to customize the default printing
+behavior of records.  This is a Guile extension and is not part of SRFI-9.  It
+is located in the @nicode{(srfi srfi-9 gnu)} module.
+
address@hidden {Scheme Syntax} set-record-type-printer! name thunk
+Where @var{type} corresponds to the first argument of 
@code{define-record-type},
+and @var{thunk} is a procedure accepting two arguments, the record to print, 
and
+an output port.
address@hidden deffn
+
address@hidden
+This example prints the employee's name in brackets, for instance 
@code{[Fred]}.
+
address@hidden
+(set-record-type-printer! employee-type
+  (lambda (record port)
+    (write-char #\[ port)
+    (display (get-employee-name record) port)
+    (write-char #\] port)))
address@hidden example
+
address@hidden Functional ``Setters''
+
address@hidden functional setters
+
+When writing code in a functional style, it is desirable to never alter
+the contents of records.  For such code, a simple way to return new
+record instances based on existing ones is highly desirable.
+
+The @code{(srfi srfi-9 gnu)} module extends SRFI-9 with facilities to
+return new record instances based on existing ones, only with one or
+more field values address@hidden setters}.  First, the
address@hidden works like
address@hidden, except that fields are immutable and setters
+are defined as functional setters.
+
address@hidden {Scheme Syntax} define-immutable-record-type type @* 
(constructor fieldname @dots{}) @* predicate @* (fieldname accessor [modifier]) 
@dots{}
+Define @var{type} as a new record type, like @code{define-record-type}.
+However, the record type is made @emph{immutable} (records may not be
+mutated, even with @code{struct-set!}), and any @var{modifier} is
+defined to be a functional setter---a procedure that returns a new
+record instance with the specified field changed, and leaves the
+original unchanged (see example below.)
address@hidden deffn
+
address@hidden
+In addition, the generic @code{set-field} and @code{set-fields} macros
+may be applied to any SRFI-9 record.
+
address@hidden {Scheme Syntax} set-field (field sub-fields ...) record value
+Return a new record of @var{record}'s type whose fields are equal to
+the corresponding fields of @var{record} except for the one specified by
address@hidden
+
address@hidden must be the name of the getter corresponding to the field of
address@hidden being ``set''.  Subsequent @var{sub-fields} must be record
+getters designating sub-fields within that field value to be set (see
+example below.)
address@hidden deffn
+
address@hidden {Scheme Syntax} set-fields record ((field sub-fields ...) value) 
...
+Like @code{set-field}, but can be used to set more than one field at a
+time.  This expands to code that is more efficient than a series of
+single @code{set-field} calls.
address@hidden deffn
+
+To illustrate the use of functional setters, let's assume these two
+record type definitions:
+
address@hidden
+(define-record-type <address>
+  (address street city country)
+  address?
+  (street  address-street)
+  (city    address-city)
+  (country address-country))
+
+(define-immutable-record-type <person>
+  (person age email address)
+  person?
+  (age     person-age set-person-age)
+  (email   person-email set-person-email)
+  (address person-address set-person-address))
address@hidden example
+
address@hidden
+First, note that the @code{<person>} record type definition introduces
+named functional setters.  These may be used like this:
+
address@hidden
+(define fsf-address
+  (address "Franklin Street" "Boston" "USA"))
+
+(define rms
+  (person 30 "rms@@gnu.org" fsf-address))
+
+(and (equal? (set-person-age rms 60)
+             (person 60 "rms@@gnu.org" fsf-address))
+     (= (person-age rms) 30))
address@hidden #t
address@hidden example
+
address@hidden
+Here, the original @code{<person>} record, to which @var{rms} is bound,
+is left unchanged.
+
+Now, suppose we want to change both the street and age of @var{rms}.
+This can be achieved using @code{set-fields}:
+
address@hidden
+(set-fields rms
+  ((person-age) 60)
+  ((person-address address-street) "Temple Place"))
address@hidden #<<person> age: 60 email: "rms@@gnu.org"
+  address: #<<address> street: "Temple Place" city: "Boston" country: "USA">>
address@hidden example
+
address@hidden
+Notice how the above changed two fields of @var{rms}, including the
address@hidden field of its @code{address} field, in a concise way.  Also
+note that @code{set-fields} works equally well for types defined with
+just @code{define-record-type}.
 
 @node Records
 @subsection Records
diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi
index 0e2fa9d..70a49c8 100644
--- a/doc/ref/srfi-modules.texi
+++ b/doc/ref/srfi-modules.texi
@@ -1862,110 +1862,12 @@ procedures easier.  It is documented in @xref{Multiple 
Values}.
 
 @node SRFI-9
 @subsection SRFI-9 - define-record-type
address@hidden SRFI-9
address@hidden record
 
 This SRFI is a syntax for defining new record types and creating
-predicate, constructor, and field getter and setter functions.  In
-Guile this is simply an alternate interface to the core record
-functionality (@pxref{Records}).  It can be used with,
+predicate, constructor, and field getter and setter functions.  It is
+documented in the ``Compound Data Types'' section of the manual
+(@pxref{SRFI-9 Records}).
 
address@hidden
-(use-modules (srfi srfi-9))
address@hidden example
-
address@hidden {library syntax} define-record-type type @* (constructor 
fieldname @dots{}) @* predicate @* (fieldname accessor [modifier]) @dots{}
address@hidden 1
-Create a new record type, and make various @code{define}s for using
-it.  This syntax can only occur at the top-level, not nested within
-some other form.
-
address@hidden is bound to the record type, which is as per the return
-from the core @code{make-record-type}.  @var{type} also provides the
-name for the record, as per @code{record-type-name}.
-
address@hidden is bound to a function to be called as
address@hidden(@var{constructor} fieldval @dots{})} to create a new record of
-this type.  The arguments are initial values for the fields, one
-argument for each field, in the order they appear in the
address@hidden form.
-
-The @var{fieldname}s provide the names for the record fields, as per
-the core @code{record-type-fields} etc, and are referred to in the
-subsequent accessor/modifier forms.
-
address@hidden is bound to a function to be called as
address@hidden(@var{predicate} obj)}.  It returns @code{#t} or @code{#f}
-according to whether @var{obj} is a record of this type.
-
-Each @var{accessor} is bound to a function to be called
address@hidden(@var{accessor} record)} to retrieve the respective field from a
address@hidden  Similarly each @var{modifier} is bound to a function to
-be called @code{(@var{modifier} record val)} to set the respective
-field in a @var{record}.
address@hidden deffn
-
address@hidden
-An example will illustrate typical usage,
-
address@hidden
-(define-record-type employee-type
-  (make-employee name age salary)
-  employee?
-  (name    get-employee-name)
-  (age     get-employee-age    set-employee-age)
-  (salary  get-employee-salary set-employee-salary))
address@hidden example
-
-This creates a new employee data type, with name, age and salary
-fields.  Accessor functions are created for each field, but no
-modifier function for the name (the intention in this example being
-that it's established only when an employee object is created).  These
-can all then be used as for example,
-
address@hidden
-employee-type @result{} #<record-type employee-type>
-
-(define fred (make-employee "Fred" 45 20000.00))
-
-(employee? fred)        @result{} #t
-(get-employee-age fred) @result{} 45
-(set-employee-salary fred 25000.00)  ;; pay rise
address@hidden example
-
-The functions created by @code{define-record-type} are ordinary
-top-level @code{define}s.  They can be redefined or @code{set!} as
-desired, exported from a module, etc.
-
address@hidden Non-toplevel Record Definitions
-
-The SRFI-9 specification explicitly disallows record definitions in a
-non-toplevel context, such as inside @code{lambda} body or inside a
address@hidden block.  However, Guile's implementation does not enforce that
-restriction.
-
address@hidden Custom Printers
-
-You may use @code{set-record-type-printer!} to customize the default printing
-behavior of records.  This is a Guile extension and is not part of SRFI-9.  It
-is located in the @nicode{(srfi srfi-9 gnu)} module.
-
address@hidden {Scheme Syntax} set-record-type-printer! name thunk
-Where @var{type} corresponds to the first argument of 
@code{define-record-type},
-and @var{thunk} is a procedure accepting two arguments, the record to print, 
and
-an output port.
address@hidden deffn
-
address@hidden
-This example prints the employee's name in brackets, for instance 
@code{[Fred]}.
-
address@hidden
-(set-record-type-printer! employee-type
-  (lambda (record port)
-    (write-char #\[ port)
-    (display (get-employee-name record) port)
-    (write-char #\] port)))
address@hidden example
 
 @node SRFI-10
 @subsection SRFI-10 - Hash-Comma Reader Extension


hooks/post-receive
-- 
GNU Guile



reply via email to

[Prev in Thread] Current Thread [Next in Thread]