From: swedebugia <swedebugia@riseup.net>
To: Ricardo Wurmus <rekado@elephly.net>
Cc: "guix-devel@gnu.org" <guix-devel@gnu.org>
Subject: Re: Learning the match-syntax...
Date: Tue, 8 Jan 2019 09:25:34 +0100 [thread overview]
Message-ID: <9bf31a36-3774-5dc2-8fe7-acc34e3d6a7f@riseup.net> (raw)
In-Reply-To: <87bm4s862z.fsf@elephly.net>
On 2019-01-07 23:18, Ricardo Wurmus wrote:
>
> 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.
This was exactly what I needed to understand! <3
I went ahead and coded all morning and now I ported one of the
medium-level procedures in guile-wikidata to use match:
(define* (get-label qid
#:key (language 'en))
"Return STRING with label in the target language. Supports only one
language. Defaults to \"en\"."
(and-let* ((l "labels")
(result (wdquery-alist (getentities-uri qid l #:languages language))))
(match result
((_ (entities (q id type (labels (result (value . val) lang) _
...) _ ...)))
val))))
scheme@(wikidata apis) [39]> (load "../guile-wikidata/wikidata/apis.scm")
scheme@(wikidata apis) [39]> (get-label "Q1111")
$25 = "electric charge"
scheme@(wikidata apis) [39]> (get-label "Q1111" #:language 'sv)
$26 = "elektrisk laddning"
--
Cheers Swedebugia
next prev parent reply other threads:[~2019-01-08 8:18 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
2019-01-08 8:25 ` swedebugia [this message]
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=9bf31a36-3774-5dc2-8fe7-acc34e3d6a7f@riseup.net \
--to=swedebugia@riseup.net \
--cc=guix-devel@gnu.org \
--cc=rekado@elephly.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.