IRC channel logs

2022-07-19.log

back to list of logs

***karlosz_ is now known as karlosz
<lloda>there's a repl shortcut ,re (module)
<ekaitz>hi! does guile have a profiler?
<dsmith-work>Morning Greetings, Guilers
<ekaitz>oh! I just found the ,profile command
<lloda>ekaitz: https://www.gnu.org/software/guile/manual/html_node/Statprof.html
<ekaitz>lloda: yeah! I just found that through the ,profile command, thanks a lot!
<lloda>:thumbsup:
<tohoyn>ekaitz: I suggest you to read https://lists.gnu.org/archive/html/guile-user/2021-02/msg00096.html too
<tohoyn>IMHO the cumulative time measurement in the current Guile is broken
***X-Scale` is now known as X-Scale
<tribals>Hello! I have a question about pattern matching and srfi-9 records
<tribals>(= field pat) a ``field'' of an object
<tribals>What is this "field" is?
<tribals>Here the $ pattern is used to match a SRFI-9 record of type person containing two or more slots. The value of the first slot is bound to name. The = pattern is used to apply force on the second slot, and then checking that the result matches the given pattern.
<tribals>Why so cumbersome example?
<tribals>Yes, it's funny - recursive friends, lol.
<tribals>But what the hell, on the haven and in the earth, this `(= field pat)` is?
<tribals> https://www.gnu.org/software/guile/manual/html_node/Pattern-Matching.html
<tribals>Example: https://paste.debian.net/1247713/
<tribals>According to docs, I'm supposed to guess what "field" is?
<tribals>No explanation, no examples
<lilyp>"field" here means a procedure to extract a value from pat
<tribals>Hello, lilyp! Thanks for answering me! ^_^
<tribals>Did you saw my example, though?
<tribals>In there, I'm trying to use `(country-name ...)` "to extract a value from pat". What is this "pat" supposed to be, indeed?
<tribals> https://www.gnu.org/software/guile/manual/html_node/Pattern-Matching.html#:~:text=Here%20is%20a%20more%20complex%20example%3A
<tribals>Could I be given a simple example instead, please?
<lilyp>(match australia ((= country-name "Australia") "Yay, kangaroos!") ((= country-name "Austria") "No kangaroos for you"))
<tribals>Okay. How to bind it? I want the body to be `(string-append "Yay, kangaroos in " name "!")`
<lilyp>(match australia ((= country-name (and "Australia" name)) (string-append "Yay, kangaroos in " name "!")) ((= country-name "Austria") "No kangaroos for you"))
<lilyp>$2 = "Yay, kangaroos in Australia!"
<tribals>How to write a pattern that matches "country with name Australia, but only <country>!" Assuming I've `(define-record-type <country-music-land> (make-country-music-land name) country-music-land? (name country-name))` ?
<lilyp>(and (? country?) (= country-name "Australia")) ?
<tribals>`(and "New-Zealand" name)` - that's strange...
<tribals>why not `(match c (($ <country> a-pattern-i'm-not-aware-of-to-match-a-field) 'Yay!))` ?
<lilyp>$ matches records by ABI
<tribals>I mean, that `($ <record-type ...)` already mathches records, not?
<lilyp>so ($ <country> "Australia") matches australia if name is the first field
<lilyp>alternatively if you don't know the ABI, you could still (and ($ <country>) (= country-name "Australia"))
<tribals>Lord, what's that thing ABI? why I'm ever need to know that?
<lilyp>"ABI" or "application binary interface" is here meant as a shorthand for the order in which record fields have been declared
<lilyp>if you know C, you might be familiar with structs and how they are packed
<tribals> https://ibb.co/54fN98M
<tribals>I *know* what ABI is. I don't know why pattern matching of record types depend on it
<lilyp>well, you could read the description for $ or you could just trust me to know that it does :)
<tribals>That is the point.
<tribals>I'm sure I dont' need to ask random habitue of an IRC channel in order to figure it out.
<tribals>Thank you anyway
<lilyp>"Here the ‘$’ pattern is used to match a SRFI-9 record of type PERSON
<lilyp>containing two or more slots. The value of the first slot is bound to
<lilyp>NAME."
<lilyp>So yeah, slot order matching *is* documented by example
<tribals>There is no example. I'm not tend to count Alice-and-Bob as example.
<lilyp>Here is a more complex example:
<tribals>SRFI-9 record of type PERSON
<tribals><lilyp> containing two or more slots
<tribals> https://ibb.co/7W2ZJPV
<tribals>Where is the slots in SRFI-9 records?
<lilyp>each field is a slot
<civodul>i think i wrote the Alice-and-Bob example and i like it :-)
<civodul>it illustrates $ and =
<tribals>civodul: I disagree. It illustrates nothing.
<civodul>surely we can do better and add more examples, but is this one particularly bad?
<civodul>well okay
<civodul>tribals: could you elaborate though?
<civodul>i trust it didn't work for you, but how could it be improved?
<tribals> (match alice
<tribals> (($ person name (= force (($ person "Bob"))))
<tribals>($ person name (= force (($ person "Bob")))
<civodul>yes i can read it
<tribals>It uses two patterns at once, so it is not clear what get's bound to what?
<civodul>there's a paragraph below explaining taht
<civodul>but yes, it's a more complex example, as the manual says
<civodul>maybe we need more simpler examples?
<lilyp>I mean you do see the records yourself
<lilyp>the record is literally (make-person "Alice" (delay (list bob)))
<tribals>At first glance, it is not even clear that force is a procedure (should be procedure? again, docs has nothing to say). Only if reader is aware that it is builtin, he can spot it.
<tribals>(= field pat) a ``field'' of an object
<lilyp>force is a documented procedure
<civodul>yeah i'm not sure i follow
<civodul>does the fact that the example uses a promise make it harder to grasp?
<lilyp>I think the confusion is with fields vs. slots in SRFI records
<civodul>('force' is for promises)
<civodul>ah
<lilyp>slots are a low-level implementation detail, whereas fields are what they are called on the high level
<lilyp>thus "field" of object invites confusion
<civodul>this part uses the word "slot", but today i'd rather use "field" because we're talking about plain records, not GOOPS objects
<tribals>Okay, now I know it has to be a procedure. Here is my example, again: https://paste.debian.net/1247725/
<tribals>Why does it not work?
<tribals>It is a very similar to your.
<lilyp>because the first field (slot) of a country is not a country
<civodul>so you're applying 'country-name' on a string
<civodul>you can either write: ($ <country> "Australia")
<civodul>or: (= country-name "Australia")
<civodul>the latter would throw an exception if the thing being matched is not a <country> though, so the former is preferable
<tribals>first depends on fields order, which depends on ABI (now I know that); second match anything with `(country-name`), not just countries
<tribals>>the latter would throw an exception if the thing being matched is not a <country> thoug
<tribals>why so?
<lilyp>country-name checks that its argument is a country and throws an exception if not, just so you know
<tribals>That's nice
<tribals>($ person name (= force (($ person "Bob"))))
<tribals> | | | \ /
<tribals> | | | `--+----------------------'
<tribals> | | | `- "field" pattern 1
<tribals> | | `- another "field" pattern, or binding?
<tribals> | `- which record-type to match?
<tribals> `- "match records" mode
<tribals> So, I read 1 as "call force on field, then match its value with whatever pattern is supplied"
<tribals>($ <country> (= country-name "Australia"))
<tribals> \ /
<tribals> `------------- 2 --------'
<tribals>So, I read 2 as "call country-name on record, then match with literal value"
<tribals>This is because I read "(= field pat)" (and corresponding "a ``field'' of an object") as is. A field of an object is, eg. `(country-name ...)`
<tribals>Is `(country-name ...)` a field?
<lilyp>civodul: I think renaming ``field'' to ``accessor'' is the right choice here
<tribals>I mean, patter matching is hard topic at its own. Why to mix another hard topic (force/delay)?
<tribals>Then I need to "decipher" example instead of just reading it.
<tribals>In this is only one example of "feild" matching.
<tribals>In docs*
<lilyp>force and delay are not that hard tho?
<tribals>Is *is* hard when there is two, instead of one.
<lilyp>I mean it is literally said to be a complex example and then explained exactly what it does ._.
<tribals>The whole Scheme is about simplifying things down to simplest possible form.
<tribals>I mean, why it needs "to be a complex example". Why simple example doesn't qualifies here?
<lilyp>complex example shows more features with less space
<lilyp>the Guile manual is already considered TL;DR by many, so that's something to consider
<tribals>That's what makes me sad. Then becomes a "cypher".
<tribals>then docs*
<tribals>> complex example shows more features with less space
<tribals>Are you lack a space?
<tribals>Clean explanation doesn't hurt.
<tribals>Clean means simple. Simple as Scheme.
<lilyp>Well, IMHO most of the patterns are self-explanatory and those that aren't can be found in code bases in a manner that makes you learn by reading.
<lilyp>both $ and = find application in Guix, for example
<lilyp>Plus you literally have an interpreter for experiments, so you could weasel your way out by trial and error.
<lilyp>That does require some skill w.r.t. interpreting error messages though.
<tribals>They would be self-explanatory, but only if there is "self" - example.
<tribals>Let's see with examples:
<tribals>cd projects/guix; rg -t lisp -A 10 -B 5 '\(\(\$ .* \(=' -p | less
<tribals>Wow! There isn't many!
<tribals>tests/derivations.scm
<tribals>772- "(λ (α) (+ α 1))"))))))))))
<tribals>773-
<tribals>774-(test-assert "build-expression->derivation and derivation-prerequisites"
<tribals>775- (let ((drv (build-expression->derivation %store "fail" #f)))
<tribals>776- (any (match-lambda
<tribals>777: (($ <derivation-input> (= derivation-file-name path))
<tribals>778- (string=? path (derivation-file-name (%guile-for-build)))))
<tribals>How this differs from mine?
<tribals>($ <derivation-input> (= derivation-file-name path)
<lilyp>Check derivation-input
<lilyp>Also = has uses outside of $ so your grep fails you.
<lilyp>See the gnome updater for a simpler one
<lilyp>and again, if you see $ in the wild without =, you probably wouldn't be confused either
<tribals>That's the point. After reading docs, I has been sure it must be used in place of field pattern. Isn't that true?
<lilyp>particularly not in the guix code base where the coding style suggests using the slot name and not somehting random
<lilyp>It is so not true
<lilyp>(match "42" ((= string->number 42) #t))
<lilyp>(= procedure pat) matches object if (procedure object) matches pat
<lilyp>where (procedure object) is a literal function call
<lilyp>the ``field'' comes from the fact that this is how fields are written in scheme – as simple procedure calls
<lilyp>there is nothing that distinguishes (car list) syntactically from (person-age alice)
<tribals>`((procedure object) "Australia")` => `((country-name country) "Australia"))`
<lilyp>your confusion stems from the belief that ``field'' here implies something special when it in fact does not
***Guest3516 is now known as chrislck
<lilyp>yeah, so going back to my earlier example (match australia ((= country-name "Australia") #t))
<tribals>But instead `(country-name "Australia")` which is obviously wrong
<lilyp>(match (country-name australia) ((= country-name "Australia") "WTF are you doing here???"))
<lilyp>does it cause the same error as your example? why yes it does
<tribals>My confusion originates from belief that `(= ...)` extracts a field from record, but, only if it is passed a record, and not "slot" of that record
<lilyp>you are already deconstructing your record with $ though
<lilyp>($ <country> this-is-not-a-country this-is-not-a-country-either country-does-not-have-three-fields ...)
<tribals>and only way to match a record non-positionally is use `(= ...)`
<lilyp>yes, and you can use the (and ) pattern to apply guards
<lilyp>(and (? country?) (= country-name "Australia"))
<lilyp>is semantically equivalent though less efficient to ($ <country> "Australia") with your ABI
<tribals>And naming bindings in a `($ ...)` pattern doesn't magically make them extract record fields from corresponding "slots". Indeed, they can be named any way: `(match a-country-at-this-time (($ country fluf pluf) (list fluf pluf)))`
<lilyp>exactly
<tribals>Now, would not it be useful for future readers to net be confused same way?
<tribals>*not
<lilyp>I already wrote this ages ago, by calling it (= accessor pat) and saying that it matches if (accessor exp) matches pat
<tribals>I mean, this example makes me believe field names *does* matter: `($ <country> name code)` It's obvious to think than "names comes from, well, name". But this is a lie. It even *depends* on ABI. Docs say nothing about it.
<dsmith-work>Tom Lord Obituary: https://berkeleydailyplanet.com/issue/2022-06-26/article/49837
<tribals>lilyp: Hope this ever will be written in docs.
<tribals>Thank you all who participated in this little discussion ^_^ It is too late. I'm leaving... zZZ
<dsmith-work>(Tom Lord did the initial Guile as a port of SCM as a library)