* [bug#60225] [PATCH] records: match-record supports specifying a different variable name.
@ 2022-12-20 17:40 Attila Lendvai
2022-12-21 22:15 ` Ludovic Courtès
2022-12-22 2:14 ` [bug#60225] [PATCH v2 1/2] " Attila Lendvai
0 siblings, 2 replies; 6+ messages in thread
From: Attila Lendvai @ 2022-12-20 17:40 UTC (permalink / raw)
To: 60225; +Cc: Attila Lendvai
An example:
(match-record obj <my-type>
(field1 (field2 custom-var-name) field3)
...)
---
guix/records.scm | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/guix/records.scm b/guix/records.scm
index 13463647c8..0b2487a156 100644
--- a/guix/records.scm
+++ b/guix/records.scm
@@ -592,13 +592,16 @@ (define-syntax lookup-field
(define-syntax match-record-inner
(lambda (s)
(syntax-case s ()
- ((_ record type (field rest ...) body ...)
- #`(let-syntax ((field-offset (syntax-rules ()
+ ((_ record type ((field-name variable-name) rest ...) body ...)
+ #'(let-syntax ((field-offset (syntax-rules ()
((_ f)
- (lookup-field field 0 f)))))
+ (lookup-field field-name 0 f)))))
(let* ((offset (type map-fields field-offset))
- (field (struct-ref record offset)))
+ (variable-name (struct-ref record offset)))
(match-record-inner record type (rest ...) body ...))))
+ ((_ record type (field rest ...) body ...)
+ ;; Redirect to the canonical form above.
+ #'(match-record-inner record type ((field field) rest ...) body ...))
((_ record type () body ...)
#'(begin body ...)))))
--
2.35.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [bug#60225] [PATCH] records: match-record supports specifying a different variable name.
2022-12-20 17:40 [bug#60225] [PATCH] records: match-record supports specifying a different variable name Attila Lendvai
@ 2022-12-21 22:15 ` Ludovic Courtès
2022-12-22 2:14 ` [bug#60225] [PATCH v2 1/2] " Attila Lendvai
1 sibling, 0 replies; 6+ messages in thread
From: Ludovic Courtès @ 2022-12-21 22:15 UTC (permalink / raw)
To: Attila Lendvai; +Cc: 60225
Hi,
Attila Lendvai <attila@lendvai.name> skribis:
> An example:
>
> (match-record obj <my-type>
> (field1 (field2 custom-var-name) field3)
> ...)
Nice! It looks like a useful extension to me.
> - ((_ record type (field rest ...) body ...)
> - #`(let-syntax ((field-offset (syntax-rules ()
> + ((_ record type ((field-name variable-name) rest ...) body ...)
> + #'(let-syntax ((field-offset (syntax-rules ()
I’d just drop ‘-name’, it’s all names anyway. :-)
Could you also add a test in ‘tests/records.scm’ next to the others?
TIA,
Ludo’.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [bug#60225] [PATCH v2 1/2] records: match-record supports specifying a different variable name.
2022-12-20 17:40 [bug#60225] [PATCH] records: match-record supports specifying a different variable name Attila Lendvai
2022-12-21 22:15 ` Ludovic Courtès
@ 2022-12-22 2:14 ` Attila Lendvai
2022-12-22 2:14 ` [bug#60225] [PATCH v2 2/2] tests: records: Add a failing test for match-record Attila Lendvai
2022-12-27 22:49 ` bug#60225: " Ludovic Courtès
1 sibling, 2 replies; 6+ messages in thread
From: Attila Lendvai @ 2022-12-22 2:14 UTC (permalink / raw)
To: 60225; +Cc: Attila Lendvai
An example:
(match-record obj <my-type>
(field1 (field2 custom-var-name) field3)
...)
* guix/records.scm (match-record-inner): Add support for the new syntax.
* tests/records.scm ("match-record, simple"): Add a simple test case for the
new syntax.
---
guix/records.scm | 9 ++++++---
tests/records.scm | 4 ++--
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/guix/records.scm b/guix/records.scm
index 13463647c8..1f097c7108 100644
--- a/guix/records.scm
+++ b/guix/records.scm
@@ -592,13 +592,16 @@ (define-syntax lookup-field
(define-syntax match-record-inner
(lambda (s)
(syntax-case s ()
- ((_ record type (field rest ...) body ...)
- #`(let-syntax ((field-offset (syntax-rules ()
+ ((_ record type ((field variable) rest ...) body ...)
+ #'(let-syntax ((field-offset (syntax-rules ()
((_ f)
(lookup-field field 0 f)))))
(let* ((offset (type map-fields field-offset))
- (field (struct-ref record offset)))
+ (variable (struct-ref record offset)))
(match-record-inner record type (rest ...) body ...))))
+ ((_ record type (field rest ...) body ...)
+ ;; Redirect to the canonical form above.
+ #'(match-record-inner record type ((field field) rest ...) body ...))
((_ record type () body ...)
#'(begin body ...)))))
diff --git a/tests/records.scm b/tests/records.scm
index 8504c8d5a5..b1203dfeb7 100644
--- a/tests/records.scm
+++ b/tests/records.scm
@@ -540,8 +540,8 @@ (define-record-type* <foo> foo make-foo
(first second)
(list first second))
(match-record (foo (first 'a) (second 'b)) <foo>
- (second first)
- (list first second)))))
+ (second (first first/new-var))
+ (list first/new-var second)))))
(test-equal "match-record, unknown field"
'syntax-error
--
2.35.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [bug#60225] [PATCH v2 2/2] tests: records: Add a failing test for match-record.
2022-12-22 2:14 ` [bug#60225] [PATCH v2 1/2] " Attila Lendvai
@ 2022-12-22 2:14 ` Attila Lendvai
2022-12-27 22:53 ` [bug#60225] [PATCH] records: match-record supports specifying a different variable name Ludovic Courtès
2022-12-27 22:49 ` bug#60225: " Ludovic Courtès
1 sibling, 1 reply; 6+ messages in thread
From: Attila Lendvai @ 2022-12-22 2:14 UTC (permalink / raw)
To: 60225; +Cc: Attila Lendvai
* tests/records.scm ("match-record, syntactic interference"): New failing test.
---
i'm not sure what's going on here, but it looks like a bug to me.
i've experienced this in real code, and the error message was
not very helpful.
tests/records.scm | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/tests/records.scm b/tests/records.scm
index b1203dfeb7..8a48e2fd07 100644
--- a/tests/records.scm
+++ b/tests/records.scm
@@ -561,4 +561,27 @@ (define-record-type* <foo> foo make-foo
(make-fresh-user-module)))
(lambda (key . args) key)))
+(test-expect-fail 1)
+(test-equal "match-record, syntactic interference"
+ '(1 2)
+ (begin
+ (define* (make-form #:optional (bindings '()))
+ `(begin
+ (use-modules (guix records))
+
+ (let ((first 42)) ; here it does not interfere
+ (define-record-type* <foo> foo make-foo
+ foo?
+ (first foo-first (default 1))
+ (second foo-second))
+
+ (let (,@bindings) ; but here it does interfere
+ (match-record (foo (second 2)) <foo>
+ (first second)
+ (list first second))))))
+ ;; This works fine.
+ (eval (make-form) (make-fresh-user-module))
+ ;; But this fails, although I think it shouldn't.
+ (eval (make-form '((second 43))) (make-fresh-user-module))))
+
(test-end)
--
2.35.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [bug#60225] [PATCH] records: match-record supports specifying a different variable name.
2022-12-22 2:14 ` [bug#60225] [PATCH v2 2/2] tests: records: Add a failing test for match-record Attila Lendvai
@ 2022-12-27 22:53 ` Ludovic Courtès
0 siblings, 0 replies; 6+ messages in thread
From: Ludovic Courtès @ 2022-12-27 22:53 UTC (permalink / raw)
To: Attila Lendvai; +Cc: 60225
Attila Lendvai <attila@lendvai.name> skribis:
> * tests/records.scm ("match-record, syntactic interference"): New failing test.
> ---
>
> i'm not sure what's going on here, but it looks like a bug to me.
[...]
> + (let (,@bindings) ; but here it does interfere
> + (match-record (foo (second 2)) <foo>
> + (first second)
> + (list first second))))))
This has to do with how macro “literals” are matched (info "(guile)
Syntax Rules"):
A literal matches an input expression if the input expression is an
identifier with the same name as the literal, and both are unbound(1).
Although literals can be unbound, usually they are bound to allow
them to be imported, exported, and renamed. *Note Modules::, for more
information on imports and exports. In Guile there are a few standard
auxiliary syntax definitions, as specified by R6RS and R7RS:
In the example above, the ‘let’ binding for ‘second’ was shadowing the
other ‘second’.
(I think this was recently discussed on guix-devel or something.)
Ludo’.
^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#60225: [PATCH] records: match-record supports specifying a different variable name.
2022-12-22 2:14 ` [bug#60225] [PATCH v2 1/2] " Attila Lendvai
2022-12-22 2:14 ` [bug#60225] [PATCH v2 2/2] tests: records: Add a failing test for match-record Attila Lendvai
@ 2022-12-27 22:49 ` Ludovic Courtès
1 sibling, 0 replies; 6+ messages in thread
From: Ludovic Courtès @ 2022-12-27 22:49 UTC (permalink / raw)
To: Attila Lendvai; +Cc: 60225-done
Hi,
Attila Lendvai <attila@lendvai.name> skribis:
> An example:
>
> (match-record obj <my-type>
> (field1 (field2 custom-var-name) field3)
> ...)
>
> * guix/records.scm (match-record-inner): Add support for the new syntax.
> * tests/records.scm ("match-record, simple"): Add a simple test case for the
> new syntax.
Applied, thanks!
Ludo’.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-12-27 22:54 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-20 17:40 [bug#60225] [PATCH] records: match-record supports specifying a different variable name Attila Lendvai
2022-12-21 22:15 ` Ludovic Courtès
2022-12-22 2:14 ` [bug#60225] [PATCH v2 1/2] " Attila Lendvai
2022-12-22 2:14 ` [bug#60225] [PATCH v2 2/2] tests: records: Add a failing test for match-record Attila Lendvai
2022-12-27 22:53 ` [bug#60225] [PATCH] records: match-record supports specifying a different variable name Ludovic Courtès
2022-12-27 22:49 ` bug#60225: " Ludovic Courtès
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.