GNU bug report logs -
#34948
[PATCH 0/3] Turn 'essential-services' into an <operating-system> field
Previous Next
Reported by: Ludovic Courtès <ludo <at> gnu.org>
Date: Fri, 22 Mar 2019 17:22:02 UTC
Severity: normal
Tags: patch
Done: Ludovic Courtès <ludo <at> gnu.org>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
Hi!
Ricardo Wurmus <rekado <at> elephly.net> skribis:
> Ludovic Courtès <ludo <at> 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’.
This bug report was last modified 6 years and 53 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.