GNU bug report logs - #67786
[PATCH] doc: Add documentation for define-record-type*

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: guix-patches; Severity: minor; Reported by: Skyler Ferris <skyvine@HIDDEN>; Keywords: patch; merged with #67787; dated Mon, 11 Dec 2023 20:18:02 UTC; Maintainer for guix-patches is guix-patches@HIDDEN.

Message received at 67786 <at> debbugs.gnu.org:


Received: (at 67786) by debbugs.gnu.org; 13 Jan 2024 18:57:55 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Jan 13 13:57:55 2024
Received: from localhost ([127.0.0.1]:41085 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1rOjCc-00065O-Q8
	for submit <at> debbugs.gnu.org; Sat, 13 Jan 2024 13:57:55 -0500
Received: from mail-40134.protonmail.ch ([185.70.40.134]:50773)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <skyvine@HIDDEN>) id 1rOjCb-000658-Kd
 for 67786 <at> debbugs.gnu.org; Sat, 13 Jan 2024 13:57:54 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com;
 s=protonmail3; t=1705172268; x=1705431468;
 bh=Wlg008Q6829qkwqfnuF4fsjy8diGO7q3LKzZE2a7VOg=;
 h=Date:To:From:Subject:Message-ID:In-Reply-To:References:
 Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID:
 Message-ID:BIMI-Selector;
 b=MPTzi8Ba/C0C78R3og5CyEuy8fUMoRSKlptjwENuskXEsDiaKJJjPLIqe3XPVH4SG
 EdnXy8+ZynvCisz6ouc8a+4Dqlrgi9fk54TlncfPR+8GcAUPLHRr+LAKt2WrCo4Jjz
 k7FX1GYzMfhjCbc9xXreiWImGGmqPR2zHjZ72Hj0Ig5SmxbHCELERQW4Xw3iZ80Z8X
 GGv6/AkJnStB6/WhyAVnw1CoCGOAeDv0IQ2zgrANgFzqbRU3/8WU9FXs+CuoQQu0Z2
 iPHb5Y6Zktgb9qA6vD5/ONS8WGhNGpH+V/lxkFhJAFHbb9p+da4evWi0tRovGHg8CP
 Z2KxHg69fms3w==
Date: Sat, 13 Jan 2024 18:57:30 +0000
To: 67786 <at> debbugs.gnu.org
From: Skyler Ferris <skyvine@HIDDEN>
Subject: Re: doc: Add documentation for define-record-type*
Message-ID: <db1f88f9-6f2e-4353-ae1f-d6080c236097@HIDDEN>
In-Reply-To: <43d0fdc9635394538ffee724beebe885d357bc59.1703713111.git.skyvine@HIDDEN>
References: <43d0fdc9635394538ffee724beebe885d357bc59.1703713111.git.skyvine@HIDDEN>
Feedback-ID: 40635331:user:proton
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 67786
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

Looks like it worked this time! I updated my configuration to send the=20
mail through my provider's servers instead of running exim locally.





Information forwarded to guix-patches@HIDDEN:
bug#67786; Package guix-patches. Full text available.

Message received at 67786 <at> debbugs.gnu.org:


Received: (at 67786) by debbugs.gnu.org; 13 Jan 2024 18:52:55 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Jan 13 13:52:55 2024
Received: from localhost ([127.0.0.1]:41080 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1rOj7m-0005xI-KK
	for submit <at> debbugs.gnu.org; Sat, 13 Jan 2024 13:52:55 -0500
Received: from mail-4316.protonmail.ch ([185.70.43.16]:54633)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <skyvine@HIDDEN>) id 1rOj7j-0005x1-TS
 for 67786 <at> debbugs.gnu.org; Sat, 13 Jan 2024 13:52:53 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com;
 s=protonmail3; t=1705171966; x=1705431166;
 bh=Dm4OsjoBQF0pB43gNCoKEC/2EYDpAKE8Nl+oxqxhPrQ=;
 h=Date:To:From:Cc:Subject:Message-ID:Feedback-ID:From:To:Cc:Date:
 Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector;
 b=W9klPWwsucf6ZxQOBp85m6BzQ/keJEUvz3Xme/W1WKDc1AcTWMxAQlDzST91pDfJe
 vplM2cR+jGfmmUNkknLK29GvjTNnffa3/fwpAt0vFtauS2k3sfyr+e+MDEYRmSCWhH
 tAMbDlahY4g4wUOG3XPD8a6IFwCRO4TJQuA8R/HtV8EteuznHJpFIX4AbZcvgpcmKV
 fV99xeVhcsd7pT/4TbVv2nRnAlOe/rlab+4sCWjZztQdLSr8mWsfdZ734sLEHceH6d
 hYWBGY6lPs6iU/Uph+HXywm9t/BdZT/HmfyU/UJ8aCJcvrxG6vL+InScEbOVbLor1y
 t5wcEYEMdthJQ==
Date: Sat, 13 Jan 2024 18:52:42 +0000
To: 67786 <at> debbugs.gnu.org
From: skyvine@HIDDEN
Subject: Re: doc: Add documentation for define-record-type*
Message-ID: <43d0fdc9635394538ffee724beebe885d357bc59.1703713111.git.skyvine@HIDDEN>
Feedback-ID: 40635331:user:proton
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 67786
Cc: Skyler Ferris <skyvine@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

From: Skyler Ferris <skyvine@HIDDEN>

I wrote this documentation by using the docstring in guix/record.scm as a
starting point and expanding on it/reformatting on it to be appropriate
for inclusion in a manual.

* doc/guix.texi: Add sections describing the typical
usage and API for define-record-type*

Change-Id: I19e7220553d10652c794e6e0172b2c9ee961f54f
---
# This version of the patch updates the commit message to explain that I
# wrote the documentation by using the docstring in guix/records.scm as
# a starting point. This process seemed appropriate to me because it is
# being incorporated into the same project for the same purpose. Most of
# the commit is new content, but some of it is shared with the docstring
# - for example the "thing" struct definition and the explanation of
# struct fields. I think that it is useful for the manual and the
# docstrings to share content when appropriate to avoid accidentally
# communicating contradictory ideas to different audiences, but the
# relationship should still be acknowledged. If there is a more formal
# manner in which I should indicate this please let me know and I will
# be happy to update the commit. This version does not change anything
# other than the commit message.
 doc/contributing.texi |   1 -
 doc/guix.texi         | 274 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 274 insertions(+), 1 deletion(-)

diff --git a/doc/contributing.texi b/doc/contributing.texi
index 7337f4bd58..d920b2589a 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -1313,7 +1313,6 @@ Data Types and Pattern Matching
 notably the fact that it is hard to read, error-prone, and a hindrance
 to proper type error reports.
=20
-@findex define-record-type*
 @findex match-record
 @cindex pattern matching
 Guix code should define appropriate data types (for instance, using
diff --git a/doc/guix.texi b/doc/guix.texi
index e61a893af9..3cb15eeca3 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12606,6 +12606,280 @@ G-Expressions
 @code{(*approximate*)}, but this may change.
 @end deffn
=20
+@node Records in Guix
+@section Records in Guix
+Guix uses @code{define-record-type*} to define structures with a lispy for=
mat.
+Packages, operating systems, etc are all defined with
+@code{define-record-type*} facilities. If one was using this facility to
+define preferences for a text editor, it might look like this:
+
+@lisp
+;; The only valid emulation modes are the symbol 'emacs, the symbol 'vim, =
or
+;; the boolean #f. As a convenience to the user, if they pass in a string
+;; first convert it to a symbol and accept it if it is valid.
+(define (sanitize-emulation-mode value)
+  (let ((symbolized-value (cond ((not value)     #f)
+                                ((string? value) (string->symbol value))
+                                (#t              value))))
+    (unless (or (not symbolized-value)
+                (eq? symbolized-value 'emacs)
+                (eq? symbolized-value 'vim))
+      (throw 'bad-emulation-made
+             (format #f "Unrecognized emulation mode: ~s" value)))
+    symbolized-value))
+
+(define-record-type*
+  <editor-preferences> editor-preferences make-editor-preferences
+  editor-preferences? this-editor-preferences
+  (background-color editor-preferences-background-color
+                    (default "000000"))
+  (text-color       editor-preferences-text-color
+                    (default "FFFFFF"))
+  (emulation-mode   editor-preferences-emulation-mode
+                    (default #f)
+                    (sanitize sanitize-emulation-mode)))
+@end lisp
+
+A user could then define their preferences like this:
+
+@lisp
+(define my-preferences
+  (editor-preferences
+    (background-color "222222")
+    (emulation-mode   'vim)))
+@end lisp
+
+The value contained in @code{my-preferences} contains a custom
+@code{background-color} and @code{emulation-mode}, but keeps the default
+@code{text-color} (@code{"FFFFFF"}). If an invalid @code{emulation-mode} h=
ad
+been specified, for example if the user passed in @code{"vi"} instead of
+@code{"vim"}, @code{sanitize-emulation-mode} would immediately throw an er=
ror.
+
+The program can access values like this:
+
+@lisp
+(editor-preferences-background-color my-preferences)
+@result{} "222222"
+(editor-preferences-text-color my-preferences)
+@result{} "FFFFFF"
+(editor-preferences-emulation-mode my-preferences)
+@result{} 'vim
+@end lisp
+
+There is no way to define setters (all instances are immutable).
+
+@node Record Inheritance
+@subsection Record Inheritance
+It is also possible to inherit from previously defined instances when crea=
ting
+new ones. Continuing with the editor example, someone might want to base t=
heir
+preferences on their friend's preferences but customize a value:
+
+@lisp
+(define friends-preferences
+  (editor-preferences
+    (inherit my-preferences)
+    (emulation-mode 'emacs)))
+@end lisp
+
+This keeps the same @code{background-color} and @code{text-color} that are
+contained in @code{my-preferences} but changes the @code{emulation-mode} t=
o
+be @code{'emacs} instead of @code{'vim}.
+
+Sometimes it does not make sense for a field to be inherited. Suppose that=
 the
+@code{<editor-preferences>} type is updated to contain a username so that =
a
+friendly greeting can be displayed when the program starts up:
+
+@lisp
+;; Usernames must be strings. It would be strange to pass a username as a
+;; symbol, so throw an error in case the user meant to pass in a variable'=
s
+;; value instead of a literal symbol.
+(define (sanitize-username value)
+  (unless (string? value)
+    (throw 'bad-username
+           (format #f "Usernames must be strings! Got: ~s" value)))
+  value)
+
+(define (sanitize-emulation-mode value)
+  (let ((symbolized-value (cond ((not value)     #f)
+                                ((string? value) (string->symbol value))
+                                (#t              value))))
+    (unless (or (not symbolized-value)
+                (eq? symbolized-value 'emacs)
+                (eq? symbolized-value 'vim))
+      (throw 'bad-emulation-made
+             (format #f "Unrecognized emulation mode: ~s" value)))
+    symbolized-value))
+
+(define-record-type*
+  <editor-preferences> editor-preferences make-editor-preferences
+  editor-preferences? this-editor-preferences
+  (username         editor-preferences-username
+                    (innate)
+                    (sanitize sanitize-username))
+  (background-color editor-preferences-background-color
+                    (default "000000"))
+  (text-color       editor-preferences-text-color
+                    (default "FFFFFF"))
+  (emulation-mode   editor-preferences-emulation-mode
+                    (default #f)
+                    (sanitize sanitize-emulation-mode)))
+@end lisp
+
+There are a couple of differences in the new @code{username} field compare=
d to
+the fields we looked at earlier. It is marked as @code{innate}, which mean=
s
+that it will not be inherited. For example, consider what would happen if =
we
+tried to define new instances like this:
+
+@lisp
+(define my-preferences
+  (editor-preferences
+    (username         "my-username")
+    (background-color "222222")
+    (emulation-mode   'vim)))
+
+(define friends-preferences
+  (editor-preferences
+    (inherit my-preferences)
+    (emulation-mode 'emacs)))
+@end lisp
+
+While the @code{friends-preferences} instance still inherits the values fo=
r
+@code{background-color} and @code{text-color}, it will not inherit the val=
ue
+for @code{username}. Furthermore, as the @code{username} field does not de=
fine
+a default value the attempted creation of @code{friends-preferences} will
+actually throw an error. Instead, we could do this:
+
+@lisp
+(define my-preferences
+  (editor-preferences
+    (username         "my-username")
+    (background-color "222222")
+    (emulation-mode   'vim)))
+
+(define friends-preferences
+  (editor-preferences
+    (inherit        my-preferences)
+    (username       "friends-username")
+    (emulation-mode 'emacs)))
+@end lisp
+
+@node @code{define-record-type*} Reference
+@subsection @code{define-record-type*} Reference
+@defmac define-record-type* name syntactic-constructor constructor predica=
te this-identifier fields ...
+
+Define a new record type and associated helpers.
+
+@table @var
+@item name
+A symbol used to name the type, as would normally be provided to a plain
+@code{define-record-type} form. For example, @code{<package>}.
+
+@item syntactic-constructor
+A symbol that will be used to define the user-facing constructor. For exam=
ple,
+the symbol @code{package} is the syntactic constructor for the @code{<pack=
age>}
+structure.
+
+@item constructor
+A symbol that will be used to define the traditional constructor. It is us=
ed in
+the implementation of the syntactic constructor, but will not typically be=
 used
+elsewhere. The traditional @code{make-name} (for example, @code{make-packa=
ge})
+is a fine value to use here.
+
+@item predicate
+A symbol that will be used to test if a value is an instance of this recor=
d.
+For example, @code{package?}.
+
+@item this-identifier
+This symbol can be used when defining fields that need to refer to the str=
uct
+that contains them. For an example of this, see the @code{thunked} field
+property, below.
+
+@item fields
+A set of field specifiers which take the following form:
+
+@lisp
+(field-name field-getter properties ...)
+@end lisp
+
+Each of the properties must have one of the following forms:
+
+@table @code
+@item (default @var{value})
+Defines the default value for the field, if the user does not specify one =
using
+the syntactic constructor.
+
+@item (innate)
+Fields marked as innate will not be inherited from parent objects (see
+Instantiating Records, below, for details of object inheritance).
+
+@item (sanitize @var{proc})
+The value given by the user will be passed into @var{proc} before being st=
ored
+in the object. For example, consider this struct definition:
+
+@lisp
+(define-record-type* <thing> thing make-thing
+  thing?
+  this-thing
+  (name  thing-name
+         (sanitize (lambda (value)
+                     (cond ((string? value) value)
+                           ((symbol? value) (symbol->string value))
+                           (else (throw 'bad! value)))))))
+@end lisp
+
+When creating @code{thing} instances either a string or a symbol can be
+supplied but it will always be stored as a string:
+
+@lisp
+(string? (thing-name (thing (name "some-name"))))
+@result{} #t
+(string? (thing-name (thing (name 'some-name))))
+@result{} #t
+(thing (name 1994))
+@result{} Throw to key `bad!' with args `(1994)'.
+@end lisp
+
+@item (thunked)
+Fields marked as @code{thunked} will actually compute the field's value in=
 the
+current dynamic extent which is useful when referring to fluids in a field=
's
+value. Furthermore, that thunk can access the record it belongs to via the
+@code{this-identifier}. For example:
+
+@lisp
+(define-record-type* <rectangle> rectangle make-rectangle
+  rectangle?
+  this-rectangle
+  (width  rectangle-width)
+  (height rectangle-height)
+  (area rectangle-area (thunked)
+                       (default (* (rectangle-width  this-rectangle)
+                                   (rectangle-height this-rectangle)))))
+
+(define base-rectangle
+  (rectangle
+    (width  2)
+    (height 4)))
+
+(define derived-rectangle
+  (rectangle
+    (inherit base)
+    (width   6)))
+
+(rectangle-area base-rectangle)
+@result{} 8
+
+(rectangle-area derived-rectangle
+@result{} 24
+@end lisp
+
+@item (delayed)
+Fields marked as @code{delayed} are similar to @code{thunked} fields, exce=
pt
+that they are effectively wrapped in a @code{(delay @dots{})} form. Note t=
hat
+delayed fields cannot use @code{this-identifier}.
+@end table
+@end table
+@end defmac
+
 @node Invoking guix repl
 @section Invoking @command{guix repl}
=20
--=20
2.41.0






Information forwarded to guix-patches@HIDDEN:
bug#67786; Package guix-patches. Full text available.

Message received at 67786 <at> debbugs.gnu.org:


Received: (at 67786) by debbugs.gnu.org; 29 Dec 2023 00:17:50 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Dec 28 19:17:50 2023
Received: from localhost ([127.0.0.1]:40499 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1rJ0ZR-0006C3-R1
	for submit <at> debbugs.gnu.org; Thu, 28 Dec 2023 19:17:50 -0500
Received: from mail-4316.protonmail.ch ([185.70.43.16]:62397)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <skyvine@HIDDEN>) id 1rJ0ZO-0006Bo-PS
 for 67786 <at> debbugs.gnu.org; Thu, 28 Dec 2023 19:17:49 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com;
 s=protonmail3; t=1703809060; x=1704068260;
 bh=5L3erPL51L8GhJ2+DKzldi1sPgAeIWZjEyJ6JzxMoUU=;
 h=Date:To:From:Subject:Message-ID:In-Reply-To:References:
 Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID:
 Message-ID:BIMI-Selector;
 b=BGqIl44kp0hRoxT8fiHreRRTEcPIizqoLl2WdBbA8vnBFqw+L3nuYyydyK2okd5Bh
 e73zT2RUoWRapU8liQa9D2X/8+qf0e9AlI6PMKJ06uKRCbLNqWIOonGCLLvow2in89
 5wSirwzZQr+sz8i25DzGtVfa8EFYr/KVprCwAY3cSEt5sdf84mOzzrQ5PcK8lXMJCk
 CvsrrSUF4N6SK2GM7KedRWOenfAQmY7VOXJgjuVBtAiyFIVkQ2OfxWZ1nRrL6cHxhV
 GPMUOwmbBvNwurPnvhfMvGO55PbUUtk2LX+jq3N+wCEpaMShEwp5KAAGXKvgySpQQl
 CIMU8qhkSBZZA==
Date: Fri, 29 Dec 2023 00:17:30 +0000
To: 67786 <at> debbugs.gnu.org
From: Skyler Ferris <skyvine@HIDDEN>
Subject: Re: doc: Add documentation for define-record-type*
Message-ID: <39e76324-0f6a-4c3f-8dbf-c3e004c595f8@HIDDEN>
In-Reply-To: <b843a199-ad7c-43e4-8fe3-4f7bd77989b3@HIDDEN>
References: <b843a199-ad7c-43e4-8fe3-4f7bd77989b3@HIDDEN>
Feedback-ID: 40635331:user:proton
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 67786
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

Oh, I see that there is a help-debbugs mailing list. I'll reach out there.





Information forwarded to guix-patches@HIDDEN:
bug#67786; Package guix-patches. Full text available.

Message received at 67786 <at> debbugs.gnu.org:


Received: (at 67786) by debbugs.gnu.org; 29 Dec 2023 00:12:24 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Dec 28 19:12:24 2023
Received: from localhost ([127.0.0.1]:40494 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1rJ0UC-0003T4-4C
	for submit <at> debbugs.gnu.org; Thu, 28 Dec 2023 19:12:24 -0500
Received: from mail-40131.protonmail.ch ([185.70.40.131]:55103)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <skyvine@HIDDEN>) id 1rJ0U7-0003Sm-IO
 for 67786 <at> debbugs.gnu.org; Thu, 28 Dec 2023 19:12:22 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com;
 s=protonmail3; t=1703808733; x=1704067933;
 bh=6ZAsDqXPflAVhkJa40M2TPpI9KZO3nEi9jlLGo1/RIA=;
 h=Date:To:From:Subject:Message-ID:In-Reply-To:References:
 Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID:
 Message-ID:BIMI-Selector;
 b=NN3LmXXX5BCiJvGCw83X1ZFk9dT2Il7u4w6wHhiwFtmEPDvZIJv13pqp6ebIxvhG9
 J5azjNS19z3mx9ZqC8AVKhV5jdoTWZiOhVltgYlQr5V9a094Bcgl7dS3+qjLXBosLs
 rezLeZU3j+pZTZcLZEcbV4+H8KGSBzUvHDW60Z/arTMSlNPO589qXnyNjd9cq4LlIh
 ke0R6hy0tgSWTjBnaL3ilQGIYc6KE4Tp0ToyXfg+SI+5WZr2yZ1KJ4EoG4sZBOR9Dl
 TYL3Pl7fflNqCqMpl9PEa1ElOTyGTtsg84ga4rYOFMx0KyHCftfGdUz03PFvQxIXap
 y3cyl6tUWs1UQ==
Date: Fri, 29 Dec 2023 00:12:01 +0000
To: 67786 <at> debbugs.gnu.org
From: Skyler Ferris <skyvine@HIDDEN>
Subject: Re: doc: Add documentation for define-record-type*
Message-ID: <afc9e985-f66b-426e-b344-bfc3c9544622@HIDDEN>
In-Reply-To: <b843a199-ad7c-43e4-8fe3-4f7bd77989b3@HIDDEN>
References: <b843a199-ad7c-43e4-8fe3-4f7bd77989b3@HIDDEN>
Feedback-ID: 40635331:user:proton
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 67786
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

Hello again,

I'm not sure if the problem is on my end. I reviewed the logs for the=20
initial message I sent on December 11 and for the one I tried to send=20
yesterday. In both cases, exim indicates that it connected to the=20
appropriate endpoint, wrote a chunked message (BDAT), concluded with a=20
line like "SMTP<< 250 2.0.0 Ok: <number> bytes queued as <id>", then=20
closed the connection. The only difference is that when sending to=20
guix-patches@HIDDEN exim ended up talking to eggs.gnu.org, but when=20
sending to this bug's email address it talked to debbugs.gnu.org. Is=20
there someone I can talk to in order to help diagnose this issue?

Thanks,
Skyler





Information forwarded to guix-patches@HIDDEN:
bug#67786; Package guix-patches. Full text available.

Message received at 67786 <at> debbugs.gnu.org:


Received: (at 67786) by debbugs.gnu.org; 28 Dec 2023 02:04:22 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Dec 27 21:04:22 2023
Received: from localhost ([127.0.0.1]:38176 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1rIfkz-0007sH-Vi
	for submit <at> debbugs.gnu.org; Wed, 27 Dec 2023 21:04:22 -0500
Received: from mail-40131.protonmail.ch ([185.70.40.131]:39493)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <skyvine@HIDDEN>) id 1rIfkx-0007rz-Gx
 for 67786 <at> debbugs.gnu.org; Wed, 27 Dec 2023 21:04:20 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com;
 s=protonmail3; t=1703729053; x=1703988253;
 bh=zXIv2tsz15omCYCjK5NdeyG18/+FZhrMiL6MvmYJbeU=;
 h=Date:To:From:Subject:Message-ID:Feedback-ID:From:To:Cc:Date:
 Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector;
 b=rIDlE/2n0FDMaSz1QZk9K3WSHcKwttFAyTKrur1zRlon+c8XFmADqivwYAEiT2FlQ
 M+mL2ri8YkWtycyWLtxuxssZDKN4vSpRAo0OXpZuGZUkSci9glUZJbNDJL0S017uR5
 Mf2xLcGlY4QEsQyxBZPrXbu4sq0xYhubNb+PnKH8EZwme8QSUKO9OToGHklGe3s/05
 +EyVCqNLWl2iWzOAovOpPaSzJtLK/V0kO0YppnDdeCk0dTrUkqZ9kVEgkuFrna5WuA
 l2qRl2Hs/9JQMadxZhhdxxia00AT+CXg0wBmFC6PXR3/NfHFvXY8QqrO2e5rGnR/2W
 kqOgyEamy5bVw==
Date: Thu, 28 Dec 2023 02:03:56 +0000
To: 67786 <at> debbugs.gnu.org
From: Skyler Ferris <skyvine@HIDDEN>
Subject: Re: doc: Add documentation for define-record-type*
Message-ID: <b843a199-ad7c-43e4-8fe3-4f7bd77989b3@HIDDEN>
Feedback-ID: 40635331:user:proton
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 67786
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

It looks like the non-breaking space issue is still not resolved, and=20
I'm not immediately seeing how to fix it. I'll look at it more later. My=20
`git send-email` usage has been failing to deliver even though it worked=20
for previous patches, so I tried pasting the email into Thuderbird to=20
send it manually, but it seems like Thunderbird is stubborn about about=20
modifying the contents of my email automatically. It will probably work=20
best to fix the problem with `git send-email`.






Information forwarded to guix-patches@HIDDEN:
bug#67786; Package guix-patches. Full text available.

Message received at 67786 <at> debbugs.gnu.org:


Received: (at 67786) by debbugs.gnu.org; 28 Dec 2023 01:23:55 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Dec 27 20:23:55 2023
Received: from localhost ([127.0.0.1]:38132 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1rIf7q-0007Pe-C5
	for submit <at> debbugs.gnu.org; Wed, 27 Dec 2023 20:23:55 -0500
Received: from mail-40133.protonmail.ch ([185.70.40.133]:13889)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <skyvine@HIDDEN>) id 1rIf7n-0007PG-7C
 for 67786 <at> debbugs.gnu.org; Wed, 27 Dec 2023 20:23:52 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com;
 s=protonmail3; t=1703726625; x=1703985825;
 bh=UMEEOINjtXbTms6xqpUqQ7rALvdBrrkjk6VuxipvhcA=;
 h=Date:To:From:Subject:Message-ID:In-Reply-To:References:
 Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID:
 Message-ID:BIMI-Selector;
 b=ruGcYyY1nDJhjQwOxEiUBlhfOsiwOhkXMVJjYH24KvW8T92nI+TylNR1RDwtuZzUq
 KM9mfLKcrcrSecCHIFiEaJVT9QpcTB0OVmnI7WGlt7kCFBD+/7tXVS70WwM7Vg/1SL
 HpyiMt7HYszogMaTEBsSts8DCUiZdIfGoIlaxUG9vdAks1ay0gadkuvHfJ/PQsAWU2
 /1GCqaNbBeI0jP6o5sUxkyLCyn/DoouLYamZvo53GvD8PYIPaGQ8TxIeVvFPXbvWll
 rvI4N6z/W+jEtkGtwOKyTPQ5sO8XnND+x3UaddoLY6p9KxTgQ9vrkRxqF/f31C37+v
 2XEZdzY4flqiA==
Date: Thu, 28 Dec 2023 01:23:21 +0000
To: 67786 <at> debbugs.gnu.org
From: Skyler Ferris <skyvine@HIDDEN>
Subject: Re: doc: Add documentation for define-record-type*
Message-ID: <58aa08f2-37c2-47ab-a16d-99d13e24e911@HIDDEN>
In-Reply-To: <10d46484-1f83-4b5f-9cc7-3d9d68998b33@HIDDEN>
References: <10d46484-1f83-4b5f-9cc7-3d9d68998b33@HIDDEN>
Feedback-ID: 40635331:user:proton
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 67786
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

I wrote this documentation by using the docstring in guix/record.scm as a
starting point and expanding on it/reformatting on it to be appropriate
for inclusion in a manual.

* doc/guix.texi: Add sections describing the typical
usage and API for define-record-type*

Change-Id: I19e7220553d10652c794e6e0172b2c9ee961f54f
---
# It looks like when I sent the last message the spaces in the diff got
# converted to non-breaking spaces, which makes it difficult to read in
# some clients. This version should be easier to read. The notes from
# the previous message are preserved below:
#
# This version of the patch updates the commit message to explain that I
# wrote the documentation by using the docstring in guix/records.scm as
# a starting point. This process seemed appropriate to me because it is
# being incorporated into the same project for the same purpose. Most of
# the commit is new content, but some of it is shared with the docstring
# - for example the "thing" struct definition and the explanation of
# struct fields. I think that it is useful for the manual and the
# docstrings to share content when appropriate to avoid accidentally
# communicating contradictory ideas to different audiences, but the
# relationship should still be acknowledged. If there is a more formal
# manner in which I should indicate this please let me know and I will
# be happy to update the commit. This version does not change anything
# other than the commit message.
 =C2=A0doc/contributing.texi |=C2=A0=C2=A0 1 -
 =C2=A0doc/guix.texi=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 274 =
++++++++++++++++++++++++++++++++++++++++++
 =C2=A02 files changed, 274 insertions(+), 1 deletion(-)

diff --git a/doc/contributing.texi b/doc/contributing.texi
index 7337f4bd58..d920b2589a 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -1313,7 +1313,6 @@ Data Types and Pattern Matching
 =C2=A0notably the fact that it is hard to read, error-prone, and a hindran=
ce
 =C2=A0to proper type error reports.

-@findex define-record-type*
 =C2=A0@findex match-record
 =C2=A0@cindex pattern matching
 =C2=A0Guix code should define appropriate data types (for instance, using
diff --git a/doc/guix.texi b/doc/guix.texi
index e61a893af9..3cb15eeca3 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12606,6 +12606,280 @@ G-Expressions
 =C2=A0@code{(*approximate*)}, but this may change.
 =C2=A0@end deffn

+@node Records in Guix
+@section Records in Guix
+Guix uses @code{define-record-type*} to define structures with a lispy=20
format.
+Packages, operating systems, etc are all defined with
+@code{define-record-type*} facilities. If one was using this facility to
+define preferences for a text editor, it might look like this:
+
+@lisp
+;; The only valid emulation modes are the symbol 'emacs, the symbol=20
'vim, or
+;; the boolean #f. As a convenience to the user, if they pass in a string
+;; first convert it to a symbol and accept it if it is valid.
+(define (sanitize-emulation-mode value)
+=C2=A0 (let ((symbolized-value (cond ((not value)=C2=A0=C2=A0=C2=A0=C2=
=A0 #f)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ((string? value) (string->sym=
bol value))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (#t=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 value))))
+=C2=A0=C2=A0=C2=A0 (unless (or (not symbolized-value)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 (eq? symbolized-value 'emacs)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 (eq? symbolized-value 'vim))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (throw 'bad-emulation-made
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 (format #f "Unrecognized emulation mode: ~s" value)))
+=C2=A0=C2=A0=C2=A0 symbolized-value))
+
+(define-record-type*
+=C2=A0 <editor-preferences> editor-preferences make-editor-preferences
+=C2=A0 editor-preferences? this-editor-preferences
+=C2=A0 (background-color editor-preferences-background-color
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default "000000"))
+=C2=A0 (text-color=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 editor-preferences-=
text-color
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default "FFFFFF"))
+=C2=A0 (emulation-mode=C2=A0=C2=A0 editor-preferences-emulation-mode
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default #f)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (sanitize sanitize-emulation-=
mode)))
+@end lisp
+
+A user could then define their preferences like this:
+
+@lisp
+(define my-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (background-color "222222")
+=C2=A0=C2=A0=C2=A0 (emulation-mode=C2=A0=C2=A0 'vim)))
+@end lisp
+
+The value contained in @code{my-preferences} contains a custom
+@code{background-color} and @code{emulation-mode}, but keeps the default
+@code{text-color} (@code{"FFFFFF"}). If an invalid=20
@code{emulation-mode} had
+been specified, for example if the user passed in @code{"vi"} instead of
+@code{"vim"}, @code{sanitize-emulation-mode} would immediately throw an=20
error.
+
+The program can access values like this:
+
+@lisp
+(editor-preferences-background-color my-preferences)
+@result{} "222222"
+(editor-preferences-text-color my-preferences)
+@result{} "FFFFFF"
+(editor-preferences-emulation-mode my-preferences)
+@result{} 'vim
+@end lisp
+
+There is no way to define setters (all instances are immutable).
+
+@node Record Inheritance
+@subsection Record Inheritance
+It is also possible to inherit from previously defined instances when=20
creating
+new ones. Continuing with the editor example, someone might want to=20
base their
+preferences on their friend's preferences but customize a value:
+
+@lisp
+(define friends-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (inherit my-preferences)
+=C2=A0=C2=A0=C2=A0 (emulation-mode 'emacs)))
+@end lisp
+
+This keeps the same @code{background-color} and @code{text-color} that are
+contained in @code{my-preferences} but changes the @code{emulation-mode} t=
o
+be @code{'emacs} instead of @code{'vim}.
+
+Sometimes it does not make sense for a field to be inherited. Suppose=20
that the
+@code{<editor-preferences>} type is updated to contain a username so that =
a
+friendly greeting can be displayed when the program starts up:
+
+@lisp
+;; Usernames must be strings. It would be strange to pass a username as a
+;; symbol, so throw an error in case the user meant to pass in a variable'=
s
+;; value instead of a literal symbol.
+(define (sanitize-username value)
+=C2=A0 (unless (string? value)
+=C2=A0=C2=A0=C2=A0 (throw 'bad-username
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (format #f "U=
sernames must be strings! Got: ~s" value)))
+=C2=A0 value)
+
+(define (sanitize-emulation-mode value)
+=C2=A0 (let ((symbolized-value (cond ((not value)=C2=A0=C2=A0=C2=A0=C2=
=A0 #f)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ((string? value) (string->sym=
bol value))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (#t=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 value))))
+=C2=A0=C2=A0=C2=A0 (unless (or (not symbolized-value)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 (eq? symbolized-value 'emacs)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 (eq? symbolized-value 'vim))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (throw 'bad-emulation-made
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 (format #f "Unrecognized emulation mode: ~s" value)))
+=C2=A0=C2=A0=C2=A0 symbolized-value))
+
+(define-record-type*
+=C2=A0 <editor-preferences> editor-preferences make-editor-preferences
+=C2=A0 editor-preferences? this-editor-preferences
+=C2=A0 (username=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 editor-pr=
eferences-username
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (innate)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (sanitize sanitize-username))
+=C2=A0 (background-color editor-preferences-background-color
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default "000000"))
+=C2=A0 (text-color=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 editor-preferences-=
text-color
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default "FFFFFF"))
+=C2=A0 (emulation-mode=C2=A0=C2=A0 editor-preferences-emulation-mode
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default #f)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (sanitize sanitize-emulation-=
mode)))
+@end lisp
+
+There are a couple of differences in the new @code{username} field=20
compared to
+the fields we looked at earlier. It is marked as @code{innate}, which mean=
s
+that it will not be inherited. For example, consider what would happen=20
if we
+tried to define new instances like this:
+
+@lisp
+(define my-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (username=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 "my-username")
+=C2=A0=C2=A0=C2=A0 (background-color "222222")
+=C2=A0=C2=A0=C2=A0 (emulation-mode=C2=A0=C2=A0 'vim)))
+
+(define friends-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (inherit my-preferences)
+=C2=A0=C2=A0=C2=A0 (emulation-mode 'emacs)))
+@end lisp
+
+While the @code{friends-preferences} instance still inherits the values fo=
r
+@code{background-color} and @code{text-color}, it will not inherit the=20
value
+for @code{username}. Furthermore, as the @code{username} field does not=20
define
+a default value the attempted creation of @code{friends-preferences} will
+actually throw an error. Instead, we could do this:
+
+@lisp
+(define my-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (username=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 "my-username")
+=C2=A0=C2=A0=C2=A0 (background-color "222222")
+=C2=A0=C2=A0=C2=A0 (emulation-mode=C2=A0=C2=A0 'vim)))
+
+(define friends-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (inherit=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 my-p=
references)
+=C2=A0=C2=A0=C2=A0 (username=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "friends-=
username")
+=C2=A0=C2=A0=C2=A0 (emulation-mode 'emacs)))
+@end lisp
+
+@node @code{define-record-type*} Reference
+@subsection @code{define-record-type*} Reference
+@defmac define-record-type* name syntactic-constructor constructor=20
predicate this-identifier fields ...
+
+Define a new record type and associated helpers.
+
+@table @var
+@item name
+A symbol used to name the type, as would normally be provided to a plain
+@code{define-record-type} form. For example, @code{<package>}.
+
+@item syntactic-constructor
+A symbol that will be used to define the user-facing constructor. For=20
example,
+the symbol @code{package} is the syntactic constructor for the=20
@code{<package>}
+structure.
+
+@item constructor
+A symbol that will be used to define the traditional constructor. It is=20
used in
+the implementation of the syntactic constructor, but will not typically=20
be used
+elsewhere. The traditional @code{make-name} (for example,=20
@code{make-package})
+is a fine value to use here.
+
+@item predicate
+A symbol that will be used to test if a value is an instance of this=20
record.
+For example, @code{package?}.
+
+@item this-identifier
+This symbol can be used when defining fields that need to refer to the=20
struct
+that contains them. For an example of this, see the @code{thunked} field
+property, below.
+
+@item fields
+A set of field specifiers which take the following form:
+
+@lisp
+(field-name field-getter properties ...)
+@end lisp
+
+Each of the properties must have one of the following forms:
+
+@table @code
+@item (default @var{value})
+Defines the default value for the field, if the user does not specify=20
one using
+the syntactic constructor.
+
+@item (innate)
+Fields marked as innate will not be inherited from parent objects (see
+Instantiating Records, below, for details of object inheritance).
+
+@item (sanitize @var{proc})
+The value given by the user will be passed into @var{proc} before being=20
stored
+in the object. For example, consider this struct definition:
+
+@lisp
+(define-record-type* <thing> thing make-thing
+=C2=A0 thing?
+=C2=A0 this-thing
+=C2=A0 (name=C2=A0 thing-name
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (sanitize (lambda (value)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (cond ((string? value) =
value)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 ((symbol? value) (symbol->string value))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 (else (throw 'bad! value)))))))
+@end lisp
+
+When creating @code{thing} instances either a string or a symbol can be
+supplied but it will always be stored as a string:
+
+@lisp
+(string? (thing-name (thing (name "some-name"))))
+@result{} #t
+(string? (thing-name (thing (name 'some-name))))
+@result{} #t
+(thing (name 1994))
+@result{} Throw to key `bad!' with args `(1994)'.
+@end lisp
+
+@item (thunked)
+Fields marked as @code{thunked} will actually compute the field's value=20
in the
+current dynamic extent which is useful when referring to fluids in a=20
field's
+value. Furthermore, that thunk can access the record it belongs to via the
+@code{this-identifier}. For example:
+
+@lisp
+(define-record-type* <rectangle> rectangle make-rectangle
+=C2=A0 rectangle?
+=C2=A0 this-rectangle
+=C2=A0 (width=C2=A0 rectangle-width)
+=C2=A0 (height rectangle-height)
+=C2=A0 (area rectangle-area (thunked)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default (*=
 (rectangle-width this-rectangle)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (rectangle-=
height this-rectangle)))))
+
+(define base-rectangle
+=C2=A0 (rectangle
+=C2=A0=C2=A0=C2=A0 (width=C2=A0 2)
+=C2=A0=C2=A0=C2=A0 (height 4)))
+
+(define derived-rectangle
+=C2=A0 (rectangle
+=C2=A0=C2=A0=C2=A0 (inherit base)
+=C2=A0=C2=A0=C2=A0 (width=C2=A0=C2=A0 6)))
+
+(rectangle-area base-rectangle)
+@result{} 8
+
+(rectangle-area derived-rectangle
+@result{} 24
+@end lisp
+
+@item (delayed)
+Fields marked as @code{delayed} are similar to @code{thunked} fields,=20
except
+that they are effectively wrapped in a @code{(delay @dots{})} form.=20
Note that
+delayed fields cannot use @code{this-identifier}.
+@end table
+@end table
+@end defmac
+
 =C2=A0@node Invoking guix repl
 =C2=A0@section Invoking @command{guix repl}

--=20
2.41.0





Information forwarded to guix-patches@HIDDEN:
bug#67786; Package guix-patches. Full text available.

Message received at 67786 <at> debbugs.gnu.org:


Received: (at 67786) by debbugs.gnu.org; 28 Dec 2023 00:30:06 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Dec 27 19:30:05 2023
Received: from localhost ([127.0.0.1]:38097 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1rIeHk-00046l-9r
	for submit <at> debbugs.gnu.org; Wed, 27 Dec 2023 19:30:05 -0500
Received: from mail-40134.protonmail.ch ([185.70.40.134]:57475)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <skyvine@HIDDEN>) id 1rIeHf-00041i-PD
 for 67786 <at> debbugs.gnu.org; Wed, 27 Dec 2023 19:30:02 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com;
 s=protonmail3; t=1703723393; x=1703982593;
 bh=edeYyfdsS4v0Ic9L8nZdhj7i9ZGMg7t/ZNMhci1azgA=;
 h=Date:To:From:Subject:Message-ID:Feedback-ID:From:To:Cc:Date:
 Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector;
 b=U3dp0Mw0ZhHT4ooRb5i0NTSajEM63uE8YzQBZ8olAD/acsh8lrr22bujh2aqPLine
 3fhW7sh2rzNVNrkxy610GU8zHVqbZHblHRtQQSvVk+16QFUfDXg1/vq7eh7WH4oqrO
 TFP482xa/3ZsLfovXFxSByy6YW7TIbiQ7E5zTgfOe6ipPLp27iZwZgq8ZbytNs+kav
 HkmKVA1CaLAwp6xvPHrphw3Xuvkf7bEi1W9KbKF+2ek4gDa4GrG1DUr8JOoK2DtuPG
 Vd1RXAZii1Vflbhv1tnDJH9r5jxDk/yQoGbv8l7QFlNWS9AB6dLlo3lCRTMSgLmlTo
 YyZrLSIAN2+2A==
Date: Thu, 28 Dec 2023 00:29:43 +0000
To: 67786 <at> debbugs.gnu.org
From: Skyler Ferris <skyvine@HIDDEN>
Subject: Re: doc: Add documentation for define-record-type*
Message-ID: <10d46484-1f83-4b5f-9cc7-3d9d68998b33@HIDDEN>
Feedback-ID: 40635331:user:proton
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 67786
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

I wrote this documentation by using the docstring in guix/record.scm as a
starting point and expanding on it/reformatting on it to be appropriate
for inclusion in a manual.

* doc/guix.texi: Add sections describing the typical
usage and API for define-record-type*

Change-Id: I19e7220553d10652c794e6e0172b2c9ee961f54f
---
# This version of the patch updates the commit message to explain that I
# wrote the documentation by using the docstring in guix/records.scm as
# a starting point. This process seemed appropriate to me because it is
# being incorporated into the same project for the same purpose. Most of
# the commit is new content, but some of it is shared with the docstring
# - for example the "thing" struct definition and the explanation of
# thunked. I think that it is useful for the manual and the
# docstrings to share content when appropriate to avoid accidentally
# communicating contradictory ideas to different audiences, but the
# relationship should still be acknowledged. If there is a more formal
# manner in which I should indicate this please let me know and I will
# be happy to update the commit. This version does not change anything
# other than the commit message.
 =C2=A0doc/contributing.texi |=C2=A0=C2=A0 1 -
 =C2=A0doc/guix.texi=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 274 =
++++++++++++++++++++++++++++++++++++++++++
 =C2=A02 files changed, 274 insertions(+), 1 deletion(-)

diff --git a/doc/contributing.texi b/doc/contributing.texi
index 7337f4bd58..d920b2589a 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -1313,7 +1313,6 @@ Data Types and Pattern Matching
 =C2=A0notably the fact that it is hard to read, error-prone, and a hindran=
ce
 =C2=A0to proper type error reports.

-@findex define-record-type*
 =C2=A0@findex match-record
 =C2=A0@cindex pattern matching
 =C2=A0Guix code should define appropriate data types (for instance, using
diff --git a/doc/guix.texi b/doc/guix.texi
index e61a893af9..3cb15eeca3 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12606,6 +12606,280 @@ G-Expressions
 =C2=A0@code{(*approximate*)}, but this may change.
 =C2=A0@end deffn

+@node Records in Guix
+@section Records in Guix
+Guix uses @code{define-record-type*} to define structures with a lispy=20
format.
+Packages, operating systems, etc are all defined with
+@code{define-record-type*} facilities. If one was using this facility to
+define preferences for a text editor, it might look like this:
+
+@lisp
+;; The only valid emulation modes are the symbol 'emacs, the symbol=20
'vim, or
+;; the boolean #f. As a convenience to the user, if they pass in a string
+;; first convert it to a symbol and accept it if it is valid.
+(define (sanitize-emulation-mode value)
+=C2=A0 (let ((symbolized-value (cond ((not value)=C2=A0=C2=A0=C2=A0=C2=
=A0 #f)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ((string? value) (string->sym=
bol value))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (#t=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 value))))
+=C2=A0=C2=A0=C2=A0 (unless (or (not symbolized-value)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 (eq? symbolized-value 'emacs)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 (eq? symbolized-value 'vim))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (throw 'bad-emulation-made
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 (format #f "Unrecognized emulation mode: ~s" value)))
+=C2=A0=C2=A0=C2=A0 symbolized-value))
+
+(define-record-type*
+=C2=A0 <editor-preferences> editor-preferences make-editor-preferences
+=C2=A0 editor-preferences? this-editor-preferences
+=C2=A0 (background-color editor-preferences-background-color
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default "000000"))
+=C2=A0 (text-color=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 editor-preferences-=
text-color
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default "FFFFFF"))
+=C2=A0 (emulation-mode=C2=A0=C2=A0 editor-preferences-emulation-mode
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default #f)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (sanitize sanitize-emulation-=
mode)))
+@end lisp
+
+A user could then define their preferences like this:
+
+@lisp
+(define my-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (background-color "222222")
+=C2=A0=C2=A0=C2=A0 (emulation-mode=C2=A0=C2=A0 'vim)))
+@end lisp
+
+The value contained in @code{my-preferences} contains a custom
+@code{background-color} and @code{emulation-mode}, but keeps the default
+@code{text-color} (@code{"FFFFFF"}). If an invalid=20
@code{emulation-mode} had
+been specified, for example if the user passed in @code{"vi"} instead of
+@code{"vim"}, @code{sanitize-emulation-mode} would immediately throw an=20
error.
+
+The program can access values like this:
+
+@lisp
+(editor-preferences-background-color my-preferences)
+@result{} "222222"
+(editor-preferences-text-color my-preferences)
+@result{} "FFFFFF"
+(editor-preferences-emulation-mode my-preferences)
+@result{} 'vim
+@end lisp
+
+There is no way to define setters (all instances are immutable).
+
+@node Record Inheritance
+@subsection Record Inheritance
+It is also possible to inherit from previously defined instances when=20
creating
+new ones. Continuing with the editor example, someone might want to=20
base their
+preferences on their friend's preferences but customize a value:
+
+@lisp
+(define friends-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (inherit my-preferences)
+=C2=A0=C2=A0=C2=A0 (emulation-mode 'emacs)))
+@end lisp
+
+This keeps the same @code{background-color} and @code{text-color} that are
+contained in @code{my-preferences} but changes the @code{emulation-mode} t=
o
+be @code{'emacs} instead of @code{'vim}.
+
+Sometimes it does not make sense for a field to be inherited. Suppose=20
that the
+@code{<editor-preferences>} type is updated to contain a username so that =
a
+friendly greeting can be displayed when the program starts up:
+
+@lisp
+;; Usernames must be strings. It would be strange to pass a username as a
+;; symbol, so throw an error in case the user meant to pass in a variable'=
s
+;; value instead of a literal symbol.
+(define (sanitize-username value)
+=C2=A0 (unless (string? value)
+=C2=A0=C2=A0=C2=A0 (throw 'bad-username
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (format #f "U=
sernames must be strings! Got: ~s" value)))
+=C2=A0 value)
+
+(define (sanitize-emulation-mode value)
+=C2=A0 (let ((symbolized-value (cond ((not value)=C2=A0=C2=A0=C2=A0=C2=
=A0 #f)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ((string? value) (string->sym=
bol value))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (#t=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 value))))
+=C2=A0=C2=A0=C2=A0 (unless (or (not symbolized-value)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 (eq? symbolized-value 'emacs)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 (eq? symbolized-value 'vim))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (throw 'bad-emulation-made
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 (format #f "Unrecognized emulation mode: ~s" value)))
+=C2=A0=C2=A0=C2=A0 symbolized-value))
+
+(define-record-type*
+=C2=A0 <editor-preferences> editor-preferences make-editor-preferences
+=C2=A0 editor-preferences? this-editor-preferences
+=C2=A0 (username=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 editor-pr=
eferences-username
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (innate)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (sanitize sanitize-username))
+=C2=A0 (background-color editor-preferences-background-color
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default "000000"))
+=C2=A0 (text-color=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 editor-preferences-=
text-color
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default "FFFFFF"))
+=C2=A0 (emulation-mode=C2=A0=C2=A0 editor-preferences-emulation-mode
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default #f)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (sanitize sanitize-emulation-=
mode)))
+@end lisp
+
+There are a couple of differences in the new @code{username} field=20
compared to
+the fields we looked at earlier. It is marked as @code{innate}, which mean=
s
+that it will not be inherited. For example, consider what would happen=20
if we
+tried to define new instances like this:
+
+@lisp
+(define my-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (username=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 "my-username")
+=C2=A0=C2=A0=C2=A0 (background-color "222222")
+=C2=A0=C2=A0=C2=A0 (emulation-mode=C2=A0=C2=A0 'vim)))
+
+(define friends-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (inherit my-preferences)
+=C2=A0=C2=A0=C2=A0 (emulation-mode 'emacs)))
+@end lisp
+
+While the @code{friends-preferences} instance still inherits the values fo=
r
+@code{background-color} and @code{text-color}, it will not inherit the=20
value
+for @code{username}. Furthermore, as the @code{username} field does not=20
define
+a default value the attempted creation of @code{friends-preferences} will
+actually throw an error. Instead, we could do this:
+
+@lisp
+(define my-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (username=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 "my-username")
+=C2=A0=C2=A0=C2=A0 (background-color "222222")
+=C2=A0=C2=A0=C2=A0 (emulation-mode=C2=A0=C2=A0 'vim)))
+
+(define friends-preferences
+=C2=A0 (editor-preferences
+=C2=A0=C2=A0=C2=A0 (inherit=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 my-p=
references)
+=C2=A0=C2=A0=C2=A0 (username=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "friends-=
username")
+=C2=A0=C2=A0=C2=A0 (emulation-mode 'emacs)))
+@end lisp
+
+@node @code{define-record-type*} Reference
+@subsection @code{define-record-type*} Reference
+@defmac define-record-type* name syntactic-constructor constructor=20
predicate this-identifier fields ...
+
+Define a new record type and associated helpers.
+
+@table @var
+@item name
+A symbol used to name the type, as would normally be provided to a plain
+@code{define-record-type} form. For example, @code{<package>}.
+
+@item syntactic-constructor
+A symbol that will be used to define the user-facing constructor. For=20
example,
+the symbol @code{package} is the syntactic constructor for the=20
@code{<package>}
+structure.
+
+@item constructor
+A symbol that will be used to define the traditional constructor. It is=20
used in
+the implementation of the syntactic constructor, but will not typically=20
be used
+elsewhere. The traditional @code{make-name} (for example,=20
@code{make-package})
+is a fine value to use here.
+
+@item predicate
+A symbol that will be used to test if a value is an instance of this=20
record.
+For example, @code{package?}.
+
+@item this-identifier
+This symbol can be used when defining fields that need to refer to the=20
struct
+that contains them. For an example of this, see the @code{thunked} field
+property, below.
+
+@item fields
+A set of field specifiers which take the following form:
+
+@lisp
+(field-name field-getter properties ...)
+@end lisp
+
+Each of the properties must have one of the following forms:
+
+@table @code
+@item (default @var{value})
+Defines the default value for the field, if the user does not specify=20
one using
+the syntactic constructor.
+
+@item (innate)
+Fields marked as innate will not be inherited from parent objects (see
+Instantiating Records, below, for details of object inheritance).
+
+@item (sanitize @var{proc})
+The value given by the user will be passed into @var{proc} before being=20
stored
+in the object. For example, consider this struct definition:
+
+@lisp
+(define-record-type* <thing> thing make-thing
+=C2=A0 thing?
+=C2=A0 this-thing
+=C2=A0 (name=C2=A0 thing-name
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (sanitize (lambda (value)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (cond ((string? value) =
value)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 ((symbol? value) (symbol->string value))
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 (else (throw 'bad! value)))))))
+@end lisp
+
+When creating @code{thing} instances either a string or a symbol can be
+supplied but it will always be stored as a string:
+
+@lisp
+(string? (thing-name (thing (name "some-name"))))
+@result{} #t
+(string? (thing-name (thing (name 'some-name))))
+@result{} #t
+(thing (name 1994))
+@result{} Throw to key `bad!' with args `(1994)'.
+@end lisp
+
+@item (thunked)
+Fields marked as @code{thunked} will actually compute the field's value=20
in the
+current dynamic extent which is useful when referring to fluids in a=20
field's
+value. Furthermore, that thunk can access the record it belongs to via the
+@code{this-identifier}. For example:
+
+@lisp
+(define-record-type* <rectangle> rectangle make-rectangle
+=C2=A0 rectangle?
+=C2=A0 this-rectangle
+=C2=A0 (width=C2=A0 rectangle-width)
+=C2=A0 (height rectangle-height)
+=C2=A0 (area rectangle-area (thunked)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (default (*=
 (rectangle-width this-rectangle)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (rectangle-=
height this-rectangle)))))
+
+(define base-rectangle
+=C2=A0 (rectangle
+=C2=A0=C2=A0=C2=A0 (width=C2=A0 2)
+=C2=A0=C2=A0=C2=A0 (height 4)))
+
+(define derived-rectangle
+=C2=A0 (rectangle
+=C2=A0=C2=A0=C2=A0 (inherit base)
+=C2=A0=C2=A0=C2=A0 (width=C2=A0=C2=A0 6)))
+
+(rectangle-area base-rectangle)
+@result{} 8
+
+(rectangle-area derived-rectangle
+@result{} 24
+@end lisp
+
+@item (delayed)
+Fields marked as @code{delayed} are similar to @code{thunked} fields,=20
except
+that they are effectively wrapped in a @code{(delay @dots{})} form.=20
Note that
+delayed fields cannot use @code{this-identifier}.
+@end table
+@end table
+@end defmac
+
 =C2=A0@node Invoking guix repl
 =C2=A0@section Invoking @command{guix repl}

--=20
2.41.0






Information forwarded to guix-patches@HIDDEN:
bug#67786; Package guix-patches. Full text available.
Merged 67786 67787. Request was from Mathieu Othacehe <mathieu@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 11 Dec 2023 20:17:11 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Dec 11 15:17:11 2023
Received: from localhost ([127.0.0.1]:54730 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1rCmiE-00017u-OW
	for submit <at> debbugs.gnu.org; Mon, 11 Dec 2023 15:17:11 -0500
Received: from lists.gnu.org ([2001:470:142::17]:51852)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <skyvine@HIDDEN>) id 1rCmiC-00017f-Tj
 for submit <at> debbugs.gnu.org; Mon, 11 Dec 2023 15:17:09 -0500
Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <skyvine@HIDDEN>)
 id 1rCmhr-0000I4-OO
 for guix-patches@HIDDEN; Mon, 11 Dec 2023 15:16:47 -0500
Received: from c-24-143-119-132.customer.broadstripe.net ([24.143.119.132]
 helo=localhost)
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <skyvine@HIDDEN>)
 id 1rCmho-00009y-Tv
 for guix-patches@HIDDEN; Mon, 11 Dec 2023 15:16:47 -0500
Received: from [127.0.0.1] (helo=localhost.localdomain)
 by localhost with esmtp (Exim 4.96.1)
 (envelope-from <skyvine@HIDDEN>) id 1rCmhm-0000Kt-2P;
 Mon, 11 Dec 2023 12:16:42 -0800
From: Skyler Ferris <skyvine@HIDDEN>
To: guix-patches@HIDDEN
Subject: [PATCH] doc: Add documentation for define-record-type*
Date: Mon, 11 Dec 2023 12:16:40 -0800
Message-ID: <9bf2efa9c7aab1661fcf5180d1e536fc6dc0e9b3.1702324538.git.skyvine@HIDDEN>
X-Mailer: git-send-email 2.41.0
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Received-SPF: softfail client-ip=24.143.119.132;
 envelope-from=skyvine@HIDDEN; helo=localhost
X-Spam_score_int: 72
X-Spam_score: 7.2
X-Spam_bar: +++++++
X-Spam_report: (7.2 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001,
 FSL_HELO_NON_FQDN_1=0.001, HELO_LOCALHOST=3.828, KHOP_HELO_FCRDNS=0.26,
 RCVD_IN_PBL=3.335, RDNS_DYNAMIC=0.982, SPF_SOFTFAIL=0.665,
 SPOOFED_FREEMAIL=0.001,
 T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no
X-Spam_action: reject
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: submit
Cc: Skyler Ferris <skyvine@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)

* doc/guix.texi: Add sections describing the typical usage and API
reference for define-record-type*

Change-Id: I19e7220553d10652c794e6e0172b2c9ee961f54f
---
 doc/contributing.texi |   1 -
 doc/guix.texi         | 274 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 274 insertions(+), 1 deletion(-)

diff --git a/doc/contributing.texi b/doc/contributing.texi
index 9e9b89782c..60fcf95b77 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -1311,7 +1311,6 @@ Data Types and Pattern Matching
 notably the fact that it is hard to read, error-prone, and a hindrance
 to proper type error reports.
 
-@findex define-record-type*
 @findex match-record
 @cindex pattern matching
 Guix code should define appropriate data types (for instance, using
diff --git a/doc/guix.texi b/doc/guix.texi
index 1fd2e21608..e9d0fd1466 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12561,6 +12561,280 @@ G-Expressions
 @code{(*approximate*)}, but this may change.
 @end deffn
 
+@node Records in Guix
+@section Records in Guix
+Guix uses @code{define-record-type*} to define structures with a lispy format.
+Packages, operating systems, etc are all defined with
+@code{define-record-type*} facilities. If one was using this facility to
+define preferences for a text editor, it might look like this:
+
+@lisp
+;; The only valid emulation modes are the symbol 'emacs, the symbol 'vim, or
+;; the boolean #f. As a convenience to the user, if they pass in a string
+;; first convert it to a symbol and accept it if it is valid.
+(define (sanitize-emulation-mode value)
+  (let ((symbolized-value (cond ((not value)     #f)
+                                ((string? value) (string->symbol value))
+                                (#t              value))))
+    (unless (or (not symbolized-value)
+                (eq? symbolized-value 'emacs)
+                (eq? symbolized-value 'vim))
+      (throw 'bad-emulation-made
+             (format #f "Unrecognized emulation mode: ~s" value)))
+    symbolized-value))
+
+(define-record-type*
+  <editor-preferences> editor-preferences make-editor-preferences
+  editor-preferences? this-editor-preferences
+  (background-color editor-preferences-background-color
+                    (default "000000"))
+  (text-color       editor-preferences-text-color
+                    (default "FFFFFF"))
+  (emulation-mode   editor-preferences-emulation-mode
+                    (default #f)
+                    (sanitize sanitize-emulation-mode)))
+@end lisp
+
+A user could then define their preferences like this:
+
+@lisp
+(define my-preferences
+  (editor-preferences
+    (background-color "222222")
+    (emulation-mode   'vim)))
+@end lisp
+
+The value contained in @code{my-preferences} contains a custom
+@code{background-color} and @code{emulation-mode}, but keeps the default
+@code{text-color} (@code{"FFFFFF"}). If an invalid @code{emulation-mode} had
+been specified, for example if the user passed in @code{"vi"} instead of
+@code{"vim"}, @code{sanitize-emulation-mode} would immediately throw an error.
+
+The program can access values like this:
+
+@lisp
+(editor-preferences-background-color my-preferences)
+@result{} "222222"
+(editor-preferences-text-color my-preferences)
+@result{} "FFFFFF"
+(editor-preferences-emulation-mode my-preferences)
+@result{} 'vim
+@end lisp
+
+There is no way to define setters (all instances are immutable).
+
+@node Record Inheritance
+@subsection Record Inheritance
+It is also possible to inherit from previously defined instances when creating
+new ones. Continuing with the editor example, someone might want to base their
+preferences on their friend's preferences but customize a value:
+
+@lisp
+(define friends-preferences
+  (editor-preferences
+    (inherit my-preferences)
+    (emulation-mode 'emacs)))
+@end lisp
+
+This keeps the same @code{background-color} and @code{text-color} that are
+contained in @code{my-preferences} but changes the @code{emulation-mode} to
+be @code{'emacs} instead of @code{'vim}.
+
+Sometimes it does not make sense for a field to be inherited. Suppose that the
+@code{<editor-preferences>} type is updated to contain a username so that a
+friendly greeting can be displayed when the program starts up:
+
+@lisp
+;; Usernames must be strings. It would be strange to pass a username as a
+;; symbol, so throw an error in case the user meant to pass in a variable's
+;; value instead of a literal symbol.
+(define (sanitize-username value)
+  (unless (string? value)
+    (throw 'bad-username
+           (format #f "Usernames must be strings! Got: ~s" value)))
+  value)
+
+(define (sanitize-emulation-mode value)
+  (let ((symbolized-value (cond ((not value)     #f)
+                                ((string? value) (string->symbol value))
+                                (#t              value))))
+    (unless (or (not symbolized-value)
+                (eq? symbolized-value 'emacs)
+                (eq? symbolized-value 'vim))
+      (throw 'bad-emulation-made
+             (format #f "Unrecognized emulation mode: ~s" value)))
+    symbolized-value))
+
+(define-record-type*
+  <editor-preferences> editor-preferences make-editor-preferences
+  editor-preferences? this-editor-preferences
+  (username         editor-preferences-username
+                    (innate)
+                    (sanitize sanitize-username))
+  (background-color editor-preferences-background-color
+                    (default "000000"))
+  (text-color       editor-preferences-text-color
+                    (default "FFFFFF"))
+  (emulation-mode   editor-preferences-emulation-mode
+                    (default #f)
+                    (sanitize sanitize-emulation-mode)))
+@end lisp
+
+There are a couple of differences in the new @code{username} field compared to
+the fields we looked at earlier. It is marked as @code{innate}, which means
+that it will not be inherited. For example, consider what would happen if we
+tried to define new instances like this:
+
+@lisp
+(define my-preferences
+  (editor-preferences
+    (username         "my-username")
+    (background-color "222222")
+    (emulation-mode   'vim)))
+
+(define friends-preferences
+  (editor-preferences
+    (inherit my-preferences)
+    (emulation-mode 'emacs)))
+@end lisp
+
+While the @code{friends-preferences} instance still inherits the values for
+@code{background-color} and @code{text-color}, it will not inherit the value
+for @code{username}. Furthermore, as the @code{username} field does not define
+a default value the attempted creation of @code{friends-preferences} will
+actually throw an error. Instead, we could do this:
+
+@lisp
+(define my-preferences
+  (editor-preferences
+    (username         "my-username")
+    (background-color "222222")
+    (emulation-mode   'vim)))
+
+(define friends-preferences
+  (editor-preferences
+    (inherit        my-preferences)
+    (username       "friends-username")
+    (emulation-mode 'emacs)))
+@end lisp
+
+@node @code{define-record-type*} Reference
+@subsection @code{define-record-type*} Reference
+@defmac define-record-type* name syntactic-constructor constructor predicate this-identifier fields ...
+
+Define a new record type and associated helpers.
+
+@table @var
+@item name
+A symbol used to name the type, as would normally be provided to a plain
+@code{define-record-type} form. For example, @code{<package>}.
+
+@item syntactic-constructor
+A symbol that will be used to define the user-facing constructor. For example,
+the symbol @code{package} is the syntactic constructor for the @code{<package>}
+structure.
+
+@item constructor
+A symbol that will be used to define the traditional constructor. It is used in
+the implementation of the syntactic constructor, but will not typically be used
+elsewhere. The traditional @code{make-name} (for example, @code{make-package})
+is a fine value to use here.
+
+@item predicate
+A symbol that will be used to test if a value is an instance of this record.
+For example, @code{package?}.
+
+@item this-identifier
+This symbol can be used when defining fields that need to refer to the struct
+that contains them. For an example of this, see the @code{thunked} field
+property, below.
+
+@item fields
+A set of field specifiers which take the following form:
+
+@lisp
+(field-name field-getter properties ...)
+@end lisp
+
+Each of the properties must have one of the following forms:
+
+@table @code
+@item (default @var{value})
+Defines the default value for the field, if the user does not specify one using
+the syntactic constructor.
+
+@item (innate)
+Fields marked as innate will not be inherited from parent objects (see
+Instantiating Records, below, for details of object inheritance).
+
+@item (sanitize @var{proc})
+The value given by the user will be passed into @var{proc} before being stored
+in the object. For example, consider this struct definition:
+
+@lisp
+(define-record-type* <thing> thing make-thing
+  thing?
+  this-thing
+  (name  thing-name
+         (sanitize (lambda (value)
+                     (cond ((string? value) value)
+                           ((symbol? value) (symbol->string value))
+                           (else (throw 'bad! value)))))))
+@end lisp
+
+When creating @code{thing} instances either a string or a symbol can be
+supplied but it will always be stored as a string:
+
+@lisp
+(string? (thing-name (thing (name "some-name"))))
+@result{} #t
+(string? (thing-name (thing (name 'some-name))))
+@result{} #t
+(thing (name 1994))
+@result{} Throw to key `bad!' with args `(1994)'.
+@end lisp
+
+@item (thunked)
+Fields marked as @code{thunked} will actually compute the field's value in the
+current dynamic extent which is useful when referring to fluids in a field's
+value. Furthermore, that thunk can access the record it belongs to via the
+@code{this-identifier}. For example:
+
+@lisp
+(define-record-type* <rectangle> rectangle make-rectangle
+  rectangle?
+  this-rectangle
+  (width  rectangle-width)
+  (height rectangle-height)
+  (area rectangle-area (thunked)
+                       (default (* (rectangle-width  this-rectangle)
+                                   (rectangle-height this-rectangle)))))
+
+(define base-rectangle
+  (rectangle
+    (width  2)
+    (height 4)))
+
+(define derived-rectangle
+  (rectangle
+    (inherit base)
+    (width   6)))
+
+(rectangle-area base-rectangle)
+@result{} 8
+
+(rectangle-area derived-rectangle
+@result{} 24
+@end lisp
+
+@item (delayed)
+Fields marked as @code{delayed} are similar to @code{thunked} fields, except
+that they are effectively wrapped in a @code{(delay @dots{})} form. Note that
+delayed fields cannot use @code{this-identifier}.
+@end table
+@end table
+@end defmac
+
 @node Invoking guix repl
 @section Invoking @command{guix repl}
 

base-commit: 2b782f67266b42bb40015bd23ce2443be2f9b01f
-- 
2.41.0





Acknowledgement sent to Skyler Ferris <skyvine@HIDDEN>:
New bug report received and forwarded. Copy sent to guix-patches@HIDDEN. Full text available.
Report forwarded to guix-patches@HIDDEN:
bug#67786; Package guix-patches. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Sat, 20 Jan 2024 12:30:02 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.