all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
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

  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.