From: Tomas Volf <wolf@wolfsden.cz>
To: guile-devel@gnu.org
Cc: Tomas Volf <wolf@wolfsden.cz>
Subject: [PATCH] doc: Extend documentation for (ice-9 match)
Date: Wed, 6 Sep 2023 16:06:38 +0200 [thread overview]
Message-ID: <20230906142222.11673-1-wolf@wolfsden.cz> (raw)
Extend the documentation for (ice-9 match) module with explanation of
some of the patterns and also provide more examples for them. That
should make it more useful for people trying to use the module for the
first time just based on the documentation.
* doc/ref/match.texi (Pattern Matching): Explain some patterns and
provide more examples
---
When I tried to use (ice-9 match) for the first time, I was not able to,
except the most basic usage. The documentation was not very helful, so
I went to the IRC. I got help, but I was also asked to try to
contribute to the docs with examples that would have helped me in the
first place.
I think even more additions would be useful, but I still do not
understand the pattern matching fully, so they are not a part of this
patch. Examples would be: How and when I should use quasi-patterns?
What does `ooo' stand for? Does `box' refer to SRFI-111 or something
else?
I was following the HACKING file, so I added myself into the THANKS
file, I am not sure if I was supposed to for this relatively trivial
change.
THANKS | 1 +
doc/ref/match.texi | 75 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 76 insertions(+)
diff --git a/THANKS b/THANKS
index aa4877e95..bb07cda83 100644
--- a/THANKS
+++ b/THANKS
@@ -38,6 +38,7 @@ Contributors since the last release:
BT Templeton
David Thompson
Bake Timmons
+ Tomas Volf
Mark H Weaver
Göran Weinholt
Ralf Wildenhues
diff --git a/doc/ref/match.texi b/doc/ref/match.texi
index f5ea43118..b5a0147fa 100644
--- a/doc/ref/match.texi
+++ b/doc/ref/match.texi
@@ -181,6 +181,81 @@ The names @code{quote}, @code{quasiquote}, @code{unquote},
@code{or}, @code{not}, @code{set!}, @code{get!}, @code{...}, and
@code{___} cannot be used as pattern variables.
+@code{string}, @code{number}, and others refer to literal strings,
+numbers, and others. Therefore pattern @code{string} binds the value to
+identifier @code{string}, pattern @code{"string"} matches if the value
+is @code{"string"}. Example demonstrating this (by using very bad
+naming):
+
+@example
+(let ()
+ (match "foo"
+ (number number)))
+@result{} "foo"
+@end example
+
+The field operator (@code{(= field pat)}) has no relation to the fields
+of SRFI-9 records. The @code{field} should be an expression evaluating
+to a procedure taking a single argument, and @code{pat} is matched
+against the return value. Simple example:
+
+@example
+(let ()
+ (match '(1 2)
+ ((= cadr x)
+ x)))
+@result{} 2
+@end example
+
+The record operator(@code{($ record-name pat_1 ... pat_n)}) can be used
+for matching SRFI-9 and SRFI-99 records. Patterns are matched against
+the slots in order, not all have to be present, and there is no way to
+skip a slot. Example demonstrating the usage:
+
+@example
+(define-record-type <foo>
+ (make-foo bar baz zab)
+ foo?
+ (bar foo-bar)
+ (baz foo-baz)
+ (zab foo-zab))
+
+(let ((obj (make-foo 1 '2 "three")))
+ (match obj
+ ;; Make sure obj is a <foo> instance, with bar slot being a number
+ ;; and zab slot being a string. We do not care about baz slot,
+ ;; therefore we use _ to match anything.
+ (($ <foo> (? number?) _ (? string?))
+ "ok")))
+@result{} "ok"
+@end example
+
+If you need to ensure that a value is of a specific record type and at
+the same time bind it to a variable, the record operator will not be
+enough by itself, since you can only capture the fields. You would need
+to combine it with other patterns, for example @code{(? foo? obj)}.
+
+When you need to apply multiple patterns, or a check and a pattern, you
+can use (@code{(? predicate pat_1 ... pat_n)}) for that. The patterns
+are evaluated is if in the @code{(and ...)}. If, for example, you want
+to check something is a symbol and at the same time bind the value to a
+variable, it could look like this:
+
+@example
+(let ()
+ (match '(delete . some-id)
+ (('delete . (? symbol? id))
+ ;; We now could, for example, use the id to delete from some alist.
+ id)))
+@result{} some-id
+@end example
+
+@c FIXME: Remove this remark once everything is clearly described and
+@c consulting the comment is no longer necessary.
+If you are unclear about how something works, you can try consulting the
+large comment at the top of the @code{module/ice-9/match.upstream.scm}
+file in your guile distribution.
+
Here is a more complex example:
@example
--
2.41.0
next reply other threads:[~2023-09-06 14:06 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-06 14:06 Tomas Volf [this message]
2023-09-19 22:57 ` [PATCH] doc: Extend documentation for (ice-9 match) Maxime Devos
2023-10-15 17:40 ` Tomas Volf
2023-10-17 20:41 ` Maxime Devos
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230906142222.11673-1-wolf@wolfsden.cz \
--to=wolf@wolfsden.cz \
--cc=guile-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).