From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms9.migadu.com with LMTPS id cC+mN+ldfGS7CAAASxT56A (envelope-from ) for ; Sun, 04 Jun 2023 11:48:25 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id eO2UN+ldfGSfcwEAauVa8A (envelope-from ) for ; Sun, 04 Jun 2023 11:48:25 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 8E08A3B88 for ; Sun, 4 Jun 2023 11:48:25 +0200 (CEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q5kLF-0005D7-B8; Sun, 04 Jun 2023 05:48:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q5kLD-0005Ao-LW for guix-patches@gnu.org; Sun, 04 Jun 2023 05:48:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1q5kLD-0005Va-DX for guix-patches@gnu.org; Sun, 04 Jun 2023 05:48:03 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1q5kLD-0006rR-AF for guix-patches@gnu.org; Sun, 04 Jun 2023 05:48:03 -0400 Subject: bug#63135: [PATCH v2 0/5] MATCH-RECORD improvements Resent-From: Josselin Poiret Original-Sender: "Debbugs-submit" Resent-To: guix-patches@gnu.org Resent-Date: Sun, 04 Jun 2023 09:48:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: cc-closed 63135 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: "(" , 63135-done@debbugs.gnu.org Cc: "\(" Mail-Followup-To: 63135@debbugs.gnu.org, dev@jpoiret.xyz, paren@disroot.org Received: via spool by 63135-done@debbugs.gnu.org id=D63135.168587204226258 (code D ref 63135); Sun, 04 Jun 2023 09:48:03 +0000 Received: (at 63135-done) by debbugs.gnu.org; 4 Jun 2023 09:47:22 +0000 Received: from localhost ([127.0.0.1]:45070 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1q5kKY-0006pS-5f for submit@debbugs.gnu.org; Sun, 04 Jun 2023 05:47:22 -0400 Received: from jpoiret.xyz ([206.189.101.64]:56226) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1q5kKW-0006pJ-Df for 63135-done@debbugs.gnu.org; Sun, 04 Jun 2023 05:47:21 -0400 Received: from authenticated-user (jpoiret.xyz [206.189.101.64]) by jpoiret.xyz (Postfix) with ESMTPA id 2886A1852FF; Sun, 4 Jun 2023 09:47:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jpoiret.xyz; s=dkim; t=1685872039; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Dy1O84DV5qwKFYAKsGY1tpnccYnHmSpHt8NGW4n41bg=; b=X6dY/b69S+qP+xKX2Z+qVL9H0pwSBBn3kKCTfLLFr1PNK8deAqHAc1aysM3/A/JQJnt4gu Y+83eM9BPBjOTAU4fd0k9A7EFbwSVbZ4Y1gffAwWys+qiFeCD0s/mHsMn/vIaLG9p382S1 N3R57fQs04lvldbMWZZ3EVmAGr2U6iMlh4w18JXeX8Bpt1tntLndwp4NbwwXJ5kAds/HuO GCwevNDJFjjtM5HtuXH6FF+NLk3JlhOaqKEn+w4ALI2wH5/dlzuU0LH0HtizVWoUnam3fq x042ikYv0L1h7M0MJ7ZrLJNteWCLmPnXg1lPfiZNjpapprU5welMxXpKwQsCsw== In-Reply-To: <20230428191905.13860-1-paren@disroot.org> References: <20230428191905.13860-1-paren@disroot.org> Date: Sun, 04 Jun 2023 11:47:17 +0200 Message-ID: <878rczeeze.fsf@jpoiret.xyz> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spamd-Bar: / X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Josselin Poiret X-ACL-Warn: , Josselin Poiret via Guix-patches From: Josselin Poiret via Guix-patches via Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: guix-patches-bounces+larch=yhetil.org@gnu.org X-Migadu-Country: US X-Migadu-Flow: FLOW_IN ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1685872105; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:resent-to:resent-from:resent-sender: resent-message-id:in-reply-to:in-reply-to:references:references: list-id:list-help:list-unsubscribe:list-subscribe:list-post: dkim-signature; bh=Dy1O84DV5qwKFYAKsGY1tpnccYnHmSpHt8NGW4n41bg=; b=hQbCIaBMGioNC28ucV5dbjtA7yhsoTdFjqi0+LsRCbhnaqKDyzxr4Eg+DWoUiLwbep84v3 rR4yw0t13gEdbqhXtuAX95wA6z6sCmmJ3y3Ks0ssOQ4nmdhK762N5lebmno8uq0BNQM+Sp PuyK+15naF96tYQgn82ancOTw+YMr5s/ACmrU6a4LZ8/V+UvEc/0sMMV2tjWUivO8VycPr FCSYDJMFtL795cZ0KjT+CSgeYuU9tN+lqT8igEbSAxvwnjqB5olRMApWBA9QTLl7PnHmei ssXfq5IHaPLZ3oCfPiMiIZR8MgNVGU+wsdqMKRnRAeucqHWn6dISLX2pSjHW+g== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=jpoiret.xyz header.s=dkim header.b="X6dY/b69"; dmarc=pass (policy=none) header.from=gnu.org; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" ARC-Seal: i=1; s=key1; d=yhetil.org; t=1685872105; a=rsa-sha256; cv=none; b=eFwjmY20Tf0pyVlHlEMHSrlRw3zjrdoDs8t3D6RJipuNzcf1PX3OW/rVNAwh4ook3V/1II lQSQs6tuEaF4uK7l1lyxWciPw1j5hh2cKLMYnpX9a+/P/Dc+j5LznFxEk51o4nCnte8UyL 3uxzHO+j30B9DN6KcYMGg5owKhiCOiOPr8RTYc8ego0fBgrSfefEpLnqU37vyRYh1PL4nE RvYLeWXlJQmNlwXLubNsxjF9/8466pbqNMHPun+gBa25jaqv8KN26a93AZIkJJ12cSpcrX T+Bdmm8rbcWu5P3tDv6JecHUGvWOx0Y9nHiXqgE1r+9im/uYZ+C34IvuKs7JRg== X-Migadu-Scanner: scn1.migadu.com X-Migadu-Spam-Score: -5.28 Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=jpoiret.xyz header.s=dkim header.b="X6dY/b69"; dmarc=pass (policy=none) header.from=gnu.org; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 8E08A3B88 X-Spam-Score: -5.28 X-TUID: Hs2sE6QfHptS --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Hi, "(" writes: > This v2 fixes the dir-locals.el file so that it indents MATCH-RECORD > properly and adds a MATCH-RECORD-LAMBDA macro. > > ( (5): > records: match-record: Raise a syntax error if TYPE is nonexistent. > records: match-record: Display more helpful field-not-found error. > records: match-record: Support thunked and delayed fields. > dir-locals: Fix MATCH-RECORD indentation. > records: Add MATCH-RECORD-LAMBDA. > > .dir-locals.el | 3 +- > guix/records.scm | 110 +++++++++++++++++++++++++++++++--------------- > tests/records.scm | 41 +++++++++++++++++ > 3 files changed, 117 insertions(+), 37 deletions(-) Thanks! For some reason your From identity line messed up my patch mangling tools, so I committed with (unmatched-paren instead of just ( as author. Might be the emacs code I'm using that's hitting some corner cases. Pushed as 178ffed3b7fe1784fff67b963c5c4bb667fbad2a with the modifications below (that's a git-range-diff). Basically, I dropped "Display more helpful field-not-found error." since it was causing issues when the body contained an ellipsis, and chose not to display the total form that the error appeared in, but instead attach proper source properties to the field syntax object in a new commit. I also added a test case for match-lambda with an ellipsis in the body, and added match-record-lambda to (guix read-print). 1: b2b374fafa =3D 1: 1a4aace3af records: match-record: Raise a syntax err= or if TYPE is nonexistent. 2: 1b3949cae7 < -: ---------- records: match-record: Display more helpful= field-not-found error. 3: 8def5ef633 ! 2: b88e38d4b5 records: match-record: Support thunked and = delayed fields. @@ guix/records.scm: (define (recutils->alist port) (lambda (s) - "Look up FIELD in the given list and return an expression that re= presents -its offset in the record. Raise a syntax violation when the field is= not --found, displaying it as originating in form S*." +-found." - (syntax-case s () -- ((_ s* field offset ()) +- ((_ field offset ()) +- (syntax-violation 'lookup-field "unknown record type field" + "Look up FIELD in the given list and return both an expression th= at represents +its offset in the record and a procedure that wraps it to return its = \"true\" value +(for instance, FORCE is returned in the case of a delayed field). RE= CORD is passed -+to thunked values. Raise a syntax violation when the field is not fo= und, displaying -+it as originating in form S*." ++to thunked values. Raise a syntax violation when the field is not fo= und." + (syntax-case s (normal delayed thunked) -+ ((_ s* record field offset ()) - (syntax-violation 'match-record - "unknown record type field" - #'s* #'field)) -- ((_ s* field offset (head tail ...)) -+ ((_ s* record field offset ((head normal) tail ...)) ++ ((_ record field offset ()) ++ (syntax-violation 'match-record ++ "unknown record type field" + s #'field)) +- ((_ field offset (head tail ...)) ++ ((_ record field offset ((head normal) tail ...)) + (free-identifier=3D? #'field #'head) + #'(values offset identity)) -+ ((_ s* record field offset ((head delayed) tail ...)) ++ ((_ record field offset ((head delayed) tail ...)) (free-identifier=3D? #'field #'head) - #'offset) -- ((_ s* field offset (_ tail ...)) -- #'(lookup-field s* field (+ 1 offset) (tail ...)))))) +- ((_ field offset (_ tail ...)) +- #'(lookup-field field (+ 1 offset) (tail ...)))))) + #'(values offset force)) -+ ((_ s* record field offset ((head thunked) tail ...)) ++ ((_ record field offset ((head thunked) tail ...)) + (free-identifier=3D? #'field #'head) + #'(values offset (cut <> record))) -+ ((_ s* record field offset (_ tail ...)) -+ #'(lookup-field+wrapper s* record field ++ ((_ record field offset (_ tail ...)) ++ #'(lookup-field+wrapper record field + (+ 1 offset) (tail ...)))))) =20=20=20=20=20=20 (define-syntax match-record-inner (lambda (s) (syntax-case s () - ((_ s* record type ((field variable) rest ...) body ...) + ((_ record type ((field variable) rest ...) body ...) - #'(let-syntax ((field-offset (syntax-rules () - ((_ f) -- (lookup-field s* field 0 f))))) +- (lookup-field field 0 f))))) - (let* ((offset (type (map-fields type match-record) field-= offset)) - (variable (struct-ref record offset))) + #'(let-syntax ((field-offset+wrapper + (syntax-rules () + ((_ f) -+ (lookup-field+wrapper s* record field 0 f))= ))) ++ (lookup-field+wrapper record field 0 f))))) + (let* ((offset wrap (type (map-fields type match-record) + field-offset+wrapper)) + (variable (wrap (struct-ref record offset)))) - (match-record-inner s* record type (rest ...) body ...))= )) - ((_ s* record type (field rest ...) body ...) + (match-record-inner record type (rest ...) body ...)))) + ((_ record type (field rest ...) body ...) ;; Redirect to the canonical form above. @@ guix/records.scm: (define-syntax match-record - (lambda (s) + (syntax-rules () "Bind each FIELD of a RECORD of the given TYPE to it's FIELD name. The order in which fields appear does not matter. A syntax error is = raised if -an unknown field is queried. @@ guix/records.scm: (define-syntax match-record -The current implementation does not support thunked and delayed field= s." - ;; TODO support thunked and delayed fields +an unknown field is queried." - (syntax-case s () - ((_ record type (fields ...) body ...) - #`(if (eq? (struct-vtable record) type) + ((_ record type (fields ...) body ...) + (if (eq? (struct-vtable record) type) + (match-record-inner record type (fields ...) body ...) =20=20=20=20=20 ## tests/records.scm ## @@ tests/records.scm: (define (location-alist loc) 4: 25d001ca8d =3D 3: e6dc1d3996 dir-locals: Fix MATCH-RECORD indentation. 5: 384d6c9562 ! 4: 4cd5293621 records: Add MATCH-RECORD-LAMBDA. @@ .dir-locals.el ;; TODO: Contribute these to Emacs' scheme-mode. (eval . (put 'let-keywords 'scheme-indent-function 3)) =20=20=20=20=20 + ## guix/read-print.scm ## +@@ guix/read-print.scm: (define %special-forms + ('letrec* 2) + ('match 2) + ('match-record 3) ++ ('match-record-lambda 2) + ('when 2) + ('unless 2) + ('package 1) + ## guix/records.scm ## @@ guix/records.scm: (define-module (guix records) alist->record @@ guix/records.scm: (define-module (guix records) ;;; Commentary: ;;; @@ guix/records.scm: (define-syntax match-record - (match-record-inner #,s record type (fields ...) body ..= .) - (throw 'wrong-type-arg record)))))) + (match-record-inner record type (fields ...) body ...) + (throw 'wrong-type-arg record))))) =20=20=20=20=20=20 +(define-syntax match-record-lambda -+ (lambda (s) ++ (syntax-rules () + "Return a procedure accepting a single record of the given TYPE f= or which each +FIELD will be bound to its FIELD name within the returned procedure. = A syntax error +is raised if an unknown field is queried." -+ (syntax-case s () -+ ((_ type (field ...) body ...) -+ #`(lambda (record) -+ (if (eq? (struct-vtable record) type) -+ (match-record-inner #,s record type (field ...) body .= ..) -+ (throw 'wrong-type-arg record))))))) ++ ((_ type (field ...) body ...) ++ (lambda (record) ++ (if (eq? (struct-vtable record) type) ++ (match-record-inner record type (field ...) body ...) ++ (throw 'wrong-type-arg record)))))) + ;;; records.scm ends here =20=20=20=20=20 =2D: ---------- > 5: f045c7ac80 records: match-record: Do not show intern= al form. =2D: ---------- > 6: 178ffed3b7 tests: records: Add test for ellipsis in = body. =2D-=20 Josselin Poiret --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQHEBAEBCgAuFiEEOSSM2EHGPMM23K8vUF5AuRYXGooFAmR8XaUQHGRldkBqcG9p cmV0Lnh5egAKCRBQXkC5FhcaiiqdDACzw0Zo+U4MSZDB/+npEQekhFdhwHHiJT1Q 8dhvp2OTCNcBlnyx8vg2KEqz+OmCAmD3En+r8yH3EJdILyMomKsHVtNmmxwgQW7H g1GTd0lbeoy9tXqOwwutxUkWfh7l2gXBwNQlJ2taHneNZKSmoxabFMRMa4Py9S9V 93a6K/zCAyYXcTK1OgEgWKgkoIgOMqqr6sghpxVRcewwHF2o6Y+YSgUbdkQM1rQE MV7rsrvNdJUdwY68pcUuXy07lagXfkKODMoO1Laj8WBJThAxLxEZd2xej6BSXjWg lIghPWnYgndBzV+26zKk8EPM7OISrg4yIi3Lc9CZGZ8TtrPThSciEnr+iT6zgWFY oEXBnyRK9LFnTjVdMYBDrmqSW9xxzlobaFWAMFN9+ZPl1UT1Inrb0gbGtPC4zpHN 0JSj/K/B8KkkEYg0ERODcEr5zW9PfNCymcgpZ7eDj8RFREBm4AxpKyyd7hjV3cU6 QNzbR11VLA/xQ6kl4oH1GJ7R8kVbL68= =uaXt -----END PGP SIGNATURE----- --=-=-=--