all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Ricardo Wurmus <rekado@elephly.net>
To: swedebugia <swedebugia@riseup.net>
Cc: "guix-devel@gnu.org" <guix-devel@gnu.org>
Subject: Re: Learning the match-syntax...
Date: Mon, 07 Jan 2019 23:18:28 +0100	[thread overview]
Message-ID: <87bm4s862z.fsf@elephly.net> (raw)
In-Reply-To: <9ee2cc12-7394-6256-7268-adc43c1a56c9@riseup.net>


Hej swedebugia,

> e.g.
> (match '(1 2 "y" "x")
>   (1
>    'one)
>   (number
>    'number))
>
> Will match any number for the first clause and any string for the
> second. It ONLY checks if it is a number.

This is not correct.  The first clause does not match because the number
1 is not equal to the list '(1 2 "y" "x").  So we fall through to the
next pattern.  That pattern is just the variable name “number”, which
will match absolutely anything.  “number” will be bound to '(1 2 "y"
"x") and the return value of the clause is the symbol 'number.

> To actually match something e.g. the "x" literally we need to nest the
> match like this:
>
> (match '(1 2 y x)
>   (string
>    (match string
> 	("x"
>           'x!)))
>   (number
>    'number))

No.  Here the first pattern matches absolutely anything.  The name
“string” could be anything at all.  It’s just the name of a variable
that should be bound.  So here you first bind '(1 2 y x) to the variable
“string”, and then you try match the value of that very same variable to
the string "x", which fails.  Hence we fall through to the next clause,
where the pattern is just the variable “number”, which will bind to
absolutely anything.  So that’s what happens and the symbol 'number is
returned.

> Positional arguments work like this:
>
> (match '(1 2 y x)
>   ;match the third item
>   (_ _ string
>    ;check if it is the literal "x"
>    (match string
> 	("x"
>           'x!)))
>   (number
>    'number))
>
> Correct?

No.  If you run this in the REPL you’ll see an error.  You have
misunderstood how match works.  Here’s another example:

(match '(1 2 x y)
  ((one two three four)
   (format #f
           "the first value is ~a, the second is ~a, the third is ~a and the fourth is ~a\n"
           one two three four))
  ((this will never match)
   #f))

Here we have two clauses: the first clause has the pattern

   (one two three four)

i.e. a list of four variables.  This matches the value exactly.  Each
variable is bound to one of the values of the list.

The second clause has also four variables and would match just as well,
but it will not be considered as the first pattern has already matched.

Does this make things clearer?


To match by *type* (as you tried above) you need to use predicates.
Here’s an example:

(match '(1 2 x y)
  (((? string? one) two three four)
   'will-not-match)
  ((this (? number? will) totally match)
   will))

The first pattern would only match if the first value were a string
(which would be bound to the variable “one”).  But it is not, so the
next pattern is tried.  There we want to match against four variables of
which the second needs to be a number.  This matches, so “will” is bound
to the number 2, which is what we return.

--
Ricardo

  reply	other threads:[~2019-01-07 22:34 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-18 20:45 `guix lint' warn of GitHub autogenerated source tarballs Arun Isaac
2018-12-19  8:43 ` Pierre Neidhardt
2018-12-19 14:07 ` Ludovic Courtès
2018-12-19 14:33   ` Efraim Flashner
2018-12-19 17:43     ` Arun Isaac
2018-12-19 19:29       ` Efraim Flashner
2018-12-21 20:50         ` Ludovic Courtès
2018-12-21 21:00           ` swedebugia
2018-12-25 14:32           ` Efraim Flashner
2019-01-05 17:39             ` Ludovic Courtès
2019-01-05 21:25               ` Learning the match-syntax swedebugia
2019-01-05 22:35                 ` Ricardo Wurmus
2019-01-06 21:36                 ` Chris Marusich
2019-01-07 17:34                   ` swedebugia
2019-01-07 22:18                     ` Ricardo Wurmus [this message]
2019-01-08  8:25                       ` swedebugia
2019-01-08 20:32                         ` Ricardo Wurmus

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=87bm4s862z.fsf@elephly.net \
    --to=rekado@elephly.net \
    --cc=guix-devel@gnu.org \
    --cc=swedebugia@riseup.net \
    /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.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.