all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Ludovic Courtès" <ludo@gnu.org>
To: Ricardo Wurmus <rekado@elephly.net>
Cc: 34948@debbugs.gnu.org
Subject: [bug#34948] [PATCH 1/3] records: Allow thunked fields to refer to 'this-record'.
Date: Sat, 23 Mar 2019 16:18:11 +0100	[thread overview]
Message-ID: <87imw9zkjw.fsf@gnu.org> (raw)
In-Reply-To: <87y35660fw.fsf@elephly.net> (Ricardo Wurmus's message of "Fri, 22 Mar 2019 22:53:07 +0100")

Hi!

Ricardo Wurmus <rekado@elephly.net> skribis:

> Ludovic Courtès <ludo@gnu.org> writes:
>
>> * guix/records.scm (this-record): New syntax parameter.
>> (make-syntactic-constructor)[wrap-field-value]: When F is thunked,
>> return a one-argument lambda instead of a thunk, and parameterize
>> THIS-RECORD.
>
> So the value of the thunked field is no longer strictly a thunk?

Indeed, it’s now a one-argument procedure.  It doesn’t matter much
though because users never see this procedure.

> I’m having difficulties understanding how this works.  Why does the
> “thunked field” now require an argument (“x”)?

This argument is the record itself, then bound to ‘this-record’ in the
lexical scope of the field.

> We use the syntax parameter “this-record” to introduce a new binding
> with this name in the context of the “value” of the field.  The
> parameter value is … hard to make out.  How does the syntax-case macro
> in the following syntax-parameterize expression evaluate to the record
> itself?  Would #,x not be sufficient to refer to the argument of the
> field accessor?
>
>>           (define (wrap-field-value f value)
>>             (cond ((thunked-field? f)
>> -                  #`(lambda () #,value))
>> +                  #`(lambda (x)
>> +                      (syntax-parameterize ((this-record
>> +                                             (lambda (s)
>> +                                               (syntax-case s ()
>> +                                                 (id
>> +                                                  (identifier? #'id)
>> +                                                  #'x)))))

Here ‘x’ is the identifier of a variable that exists at run time.  So we
cannot write #,x because we’d be referring to a variable ‘x’ that exists
at macro-expansion time, and there’s no such variable here.

The ‘syntax-case’ here is just so that ‘this-record’ matches only when
used as an identifier, like this:

  (foo this-record)

… and does not match when used like this:

  (this-record)

or like that:

  (this-record x y z)

We could just as well make it (identifier-syntax #'x) though that’s
slightly less precise.

A macro expansion is worth a thousand words :-), so:

--8<---------------cut here---------------start------------->8---
scheme@(guix records)> (define-record-type* <foo> foo make-foo foo?
			 (bar foo-bar (default 42))
			 (baz foo-baz (thunked)))
scheme@(guix records)> ,optimize (foo-baz x)
$11 = (let ((x x))
  ((if (eq? (struct-vtable x) <foo>)
     (struct-ref x 1)
     (throw 'wrong-type-arg
            '%foo-baz-real
            "Wrong type argument: ~S"
            (list x)
            (list x)))
   x))
scheme@(guix records)> ,optimize (foo (baz (+ 77 (foo-bar this-record))))
$12 = (begin
  (if (eq? #{% <foo> abi-cookie}# 2292347072401235576)
    (if #f #f)
    (throw 'record-abi-mismatch-error
           'abi-check
           "~a: record ABI mismatch; recompilation needed"
           (list <foo>)
           '()))
  (let ((s (allocate-struct <foo> 2)))
    (struct-set! s 0 42)
    (struct-set!
      s
      1
      (lambda (x)
        (+ 77
           (if (eq? (struct-vtable x) <foo>)
             (struct-ref x 0)
             (throw 'wrong-type-arg
                    'foo-bar
                    "Wrong type argument: ~S"
                    (list x)
                    (list x))))))
    s))
--8<---------------cut here---------------end--------------->8---

I hope this clarifies things!

Ludo’.

  reply	other threads:[~2019-03-23 15:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-22 17:21 [bug#34948] [PATCH 0/3] Turn 'essential-services' into an <operating-system> field Ludovic Courtès
2019-03-22 17:27 ` [bug#34948] [PATCH 1/3] records: Allow thunked fields to refer to 'this-record' Ludovic Courtès
2019-03-22 17:27   ` [bug#34948] [PATCH 2/3] accounts: Add default value for the 'home-directory' field of <user-account> Ludovic Courtès
2019-03-22 17:27   ` [bug#34948] [PATCH 3/3] system: Add 'essential-services' field to <operating-system> Ludovic Courtès
2019-03-25 20:42     ` Arun Isaac
2019-03-25 23:02       ` bug#34948: " Ludovic Courtès
2019-03-26  6:58         ` [bug#34948] " Arun Isaac
2019-03-22 21:53   ` [bug#34948] [PATCH 1/3] records: Allow thunked fields to refer to 'this-record' Ricardo Wurmus
2019-03-23 15:18     ` Ludovic Courtès [this message]
2019-03-23 16:05     ` Ludovic Courtès
2019-03-30 10:37       ` Ludovic Courtès
2019-03-30 14:20       ` Ludovic Courtès

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=87imw9zkjw.fsf@gnu.org \
    --to=ludo@gnu.org \
    --cc=34948@debbugs.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.