From: Per Bothner <per@bothner.com>
To: kawa@sourceware.org
Subject: match form as a generalization of case
Date: Sun, 22 Jan 2017 04:36:00 -0000 [thread overview]
Message-ID: <4509f53c-2941-4b1b-4935-e7b7bc5090a9@bothner.com> (raw)
In-Reply-To: <CADEOade0r4ijMGMZqrumdpsrBzcyK6QSqnD5pf_hpm71K8jubQ@mail.gmail.com>
I checked into the invoke branch a new 'match' form.
(Actually, it was there before, but was broken.)
I also checked some pattern extension to make match more useful, and
documentation.
If you want to try it out without re-building form git,
you can try this:
http://ftp.gnu.org/gnu/kawa/kawa-2.91_invoke-20170121.zip
That zip file includes the documentation, which you can browse
with the command:
kawa-2.91_invoke/bin/kawa --browse-manual
Here are the highlights. Note also that lambda and let forms
both take PATTERNs now.
-- Syntax: match MATCH-KEY EXPRESSION MATCH-CLAUSE^{+}
The âmatchâ form is a generalization of âcaseâ using PATTERNs,
MATCH-KEY ::= EXPRESSION
MATCH-CLAUSE ::=
â(â PATTERN [GUARD] BODY â)â
The MATCH-KEY is evaluated, Then the MATCH-CLAUSEs are tried in
order. The first MATCH-CLAUSE whose PATTERN matches (and the
GUARD, if any, is true), is selected, and the corresponding BODY
evaluated. It is an error if no MATCH-CLAUSE matches.
(match value
(0 (found-zero))
(x #if (> x 0) (found-positive x))
(x #if (< x 0) (found-negative x))
(x::symbol (found-symbol x))
(_ (found-other)))
One âcaseâ feature is not (yet) directly supported by âmatchâ:
Matching against a list of values. However, this is easy to
simulate using a guard using âmemqâ, âmemvâ, or âmemberâ:
;; compare similar example under case
(match (car '(c d))
(x #!if (memv x '(a e i o u)) âvowel)
(x #!if (memv x '(w y)) âsemivowel)
(x x))
8.3.1 Patterns
--------------
The usual way to bind variables is to match an incoming value against a
âpatternâ. The pattern contains variables that are bound to some value
derived from the value.
(! [x::double y::double] (some-expression))
In the above example, the pattern â[x::double y::double]â is matched
against the incoming value that results from evaluating
â(some-expression)â. That value is required to be a two-element
sequence. Then the sub-pattern âx::doubleâ is matched against element 0
of the sequence, which means it is coerced to a âdoubleâ and then the
coerced value is matched against the sub-pattern âxâ (which trivially
succeeds). Similarly, ây::doubleâ is matched against element 1.
The syntax of patterns is a work-in-progress. (The focus until now has
been in designing and implementing how patterns work in general, rather
than the details of the pattern syntax.)
PATTERN ::= IDENTIFIER
| â_â
| PATTERN-LITERAL
| âââDATUM
| PATTERN â::â TYPE
| â[â LPATTERN^{*} â]â
LPATTERN ::= PATTERN
| â@â PATTERN
| PATTERN â...â
| GUARD
PATTERN-LITERAL ::=
BOOLEAN | number | CHARACTER | STRING
GUARD ::= â#!ifâ EXPRESSION
This is how the specific patterns work:
IDENTIFIER
This is the simplest and most common form of pattern. The
IDENTIFIER is bound to a new variable that is initialized to the
incoming value.
â_â
This pattern just discards the incoming value. It is equivalent to
a unique otherwise-unused IDENTIFIER.
PATTERN-LITERAL
Matches if the value is âequal?â to the PATTERN-LITERAL.
âââDATUM
Matches if the value is âequal?â to the quoted DATUM.
PATTERN â::â TYPE
The incoming value is coerced to a value of the specified TYPE, and
then the coerced value is matched against the sub-PATTERN. Most
commonly the sub-PATTERN is a plain IDENTIFIER, so the latter match
is trivial.
â[â LPATTERN^{*} â]â
The incoming value must be a sequence (a list, vector or similar).
In the case where each sub-pattern is a plain PATTERN, then the
number of sub-patterns must match the size of the sequence, and
each sub-pattern is matched against the corresponding element of
the sequence. More generally, each sub-pattern may match zero or
more consequtive elements of the incoming sequence.
â#!ifâ EXPRESSION
No incoming value is used. Instead the EXPRESSION is evaluated.
If the result is true, matching succeeds (so far); otherwise the
match fails. This form is called a âguardâ
(https://en.wikipedia.org/wiki/Guard_(computer_science)).
--
--Per Bothner
per@bothner.com http://per.bothner.com/
next prev parent reply other threads:[~2017-01-22 4:36 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-17 10:07 behavior of CASE with strings PART 2 Damien MATTEI
2017-01-17 13:24 ` Per Bothner
2017-01-17 15:57 ` Jamison Hope
2017-01-18 6:37 ` Per Bothner
2017-01-19 4:53 ` Per Bothner
2017-01-19 10:04 ` Damien MATTEI
2017-01-19 16:00 ` Per Bothner
2017-01-21 9:47 ` Damien Mattei
2017-01-22 4:36 ` Per Bothner [this message]
2017-01-23 22:12 ` match form as a generalization of case Damien Mattei
2017-01-23 22:27 ` Per Bothner
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4509f53c-2941-4b1b-4935-e7b7bc5090a9@bothner.com \
--to=per@bothner.com \
--cc=kawa@sourceware.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).