From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id sxDqNu5+EmKocAAAgWs5BA (envelope-from ) for ; Sun, 20 Feb 2022 18:48:30 +0100 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id SM6SLu5+EmIqtAAAG6o9tA (envelope-from ) for ; Sun, 20 Feb 2022 18:48:30 +0100 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 5355D2CBA8 for ; Sun, 20 Feb 2022 18:48:30 +0100 (CET) Received: from localhost ([::1]:35384 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nLqJx-0000cG-9E for larch@yhetil.org; Sun, 20 Feb 2022 12:48:29 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34208) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nLqJU-0000c6-FR for guix-devel@gnu.org; Sun, 20 Feb 2022 12:48:03 -0500 Received: from [2a02:1800:120:4::f00:15] (port=34782 helo=andre.telenet-ops.be) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nLqJS-0008R0-5y for guix-devel@gnu.org; Sun, 20 Feb 2022 12:48:00 -0500 Received: from [172.20.10.5] ([188.189.201.217]) by andre.telenet-ops.be with bizsmtp id xVnt2600V4hw5t001VnurT; Sun, 20 Feb 2022 18:47:55 +0100 Message-ID: Subject: Semantics of circular imports From: Maxime Devos To: Philip McGrath , Ekaitz Zarraga , Ricardo Wurmus , guix-devel@gnu.org Date: Sun, 20 Feb 2022 18:47:49 +0100 In-Reply-To: <6012789.Rgyoke53jH@bastet> References: <2067ba1e606855eace261fd0b0ae9721b369bbd5.camel@telenet.be> <753ba5897ed397b5e95175cd139137975245945b.camel@telenet.be> <6012789.Rgyoke53jH@bastet> Content-Type: multipart/signed; micalg="pgp-sha512"; protocol="application/pgp-signature"; boundary="=-HRX+WOD7NA3SB97dt11r" User-Agent: Evolution 3.38.3-1 MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telenet.be; s=r22; t=1645379275; bh=Czvx4PRhSvD+9LEKbSHK5P8BLHYnbXe5STDB1y8QdQM=; h=Subject:From:To:Cc:Date:In-Reply-To:References; b=JMM6O2k+LpRlcYNQt5HuPL6CFrDAQHulBaTDJXB28rH5mfNpnLjE4OGicNMDsCg+y 6t5hzc5Z2d99mM4mPPcYeqBUEIdeLj3WBJjSUssyA7gxMiIkZaNzwaMqugohaSiuRp YvcCwn7IJr8C0EXiBvF2uCXSp1EZ/rx/BqVSjmrjatjaSvjsCBKmSJRuvC0NFmiHkr Ba/XcuZftNdRxroqZcwn4Xlz9/rjovMn1964zWTflLA/nq7eOZJ53rgSfE10CzQiBp kOVVC8DW0Q9oxpJkGDkNa/0o7rCi2MKSSqwgScbHwLjxy2ExVUmu+kQSdus/TDaL5W 5AwwV9XleSl6A== X-Host-Lookup-Failed: Reverse DNS lookup failed for 2a02:1800:120:4::f00:15 (failed) Received-SPF: pass client-ip=2a02:1800:120:4::f00:15; envelope-from=maximedevos@telenet.be; helo=andre.telenet-ops.be X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: guix-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Liliana Marie Prikler Errors-To: guix-devel-bounces+larch=yhetil.org@gnu.org Sender: "Guix-devel" X-Migadu-Flow: FLOW_IN X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1645379310; h=from:from:sender:sender: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:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=Czvx4PRhSvD+9LEKbSHK5P8BLHYnbXe5STDB1y8QdQM=; b=oENboHsyabS1TZ+s+t7iOFCx668ghqZ1rqa6Vl+xFVrNhNU5mr+xygm05usn5zG9S634hV m6aAoXMpp30q5YupHhzxSkBhViwSpPXAQn42MC1GEGeh3/aqDnnpezfYss4d/VaElduTXa alFPyXJ4sywFiobfoTOyDC6Ir22u1wQVR+uu2nvlavq2fkE5S8MVRqNb3eEgmqcWfKnaqc 96nh6vTVM/N5j805bqG7wH5DyCcijgO0dd9SRaj2/d9Z0dmx+iYZ72of2DGSRhimN/4yYm qZ4FQdn+3UY5fVK5uIABAbVT4xH082PO8/PBp2YFgl8hhZGYSFV0c1pChOgaVg== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1645379310; a=rsa-sha256; cv=none; b=Vr7fNKE2pTzmP0GiLQVYkVpGRomAjwphymOab5Yq4eHbxnfTFWmrsTFXSkcPkDDZOcN+c2 XWdzNHbTGj/yjrlDE5IHZtPeZ89SbE4TckhBNqXIgMJwuLTdvYiWdsQ2vKeUfM68/UgLLK U5CtnYNKyt6wd89O4SIRWzEPwQzehqpmjV5PPSxl32X2k41TdOHPnMVRq0EQ/CTpRDGt4S dQBtKRwlXj6W/TlE0Ib077jghtC525F9ChwOi78NhMmc1cHFPKcvNhiA8D7WfH9fEj0lVR fV+oIOPADp4Qv2P7kVdkAMm5YJd+/s8kAjrAuB6LvjXyXXImL7AxNa/K1pXucw== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=telenet.be header.s=r22 header.b=JMM6O2k+; dmarc=fail reason="SPF not aligned (relaxed)" header.from=telenet.be (policy=none); spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -2.73 Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=telenet.be header.s=r22 header.b=JMM6O2k+; dmarc=fail reason="SPF not aligned (relaxed)" header.from=telenet.be (policy=none); spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 5355D2CBA8 X-Spam-Score: -2.73 X-Migadu-Scanner: scn1.migadu.com X-TUID: DfzzfjKBlgUu --=-HRX+WOD7NA3SB97dt11r Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Philip McGrath schreef op zo 20-02-2022 om 11:47 [-0500]: > I was just (or maybe am still?) dealing with some issues caused by cyclic > imports of package modules while updating Racket to 8.4: see in particula= r > , as well as #66, #112, and #113 in= the > same thread. > [...] > I find the semantics of Guile's cyclic module imports very confusing, > and I don't know of any documentation for what is and isn't supported > other than advice from Ludo=E2=80=99 in =E2=80=94is there any? (The following explanation ignores syntax transformers, #:select and #:autoload.) Basically, a module consists of a hash table and a thunk initialising the hash table. A few situations to demonstrate: ;; Non-cyclic (define-module (foo) #:export (foo)) (define foo 0) (define-module (bar) #:export (bar) #:use-module (foo)) (define bar (+ 1 foo)) The thunk of 'foo' would be (lambda () (set-module-value! '(foo) 'foo 0)) and the thunk of 'bar' would be (lambda () ;; This calls the thunk of 'foo' if it hasn't yet been called ;; before. (initialise-module '(foo)) (set-module-value! '(bar) 'bar (+ 1 (module-value '(foo) 'foo 0)))) ;; Cyclic, non-problematic (define-module (foo) #:export (foo) #:use-module (bar)) (define foo 0) (define (calculate-foobar) (+ 1 (calculate-bar)) (define-module (bar) #:export (calculate-bar) #:use-module (foo)) (define (calculate-bar) (+ 1 foo)) The initialisation thunk of 'foo' would be (lambda () (initialise-module '(bar)) ; L1 (set-module-value! '(foo) 0) ; L2 (set-module-value! '(foo) 'calculate-foobar ; L3 (lambda () (+ 1 ((module-value '(bar) 'calculate-bar)))))) ; L4 and the thunk of 'bar' is: (lambda () (initialise-module '(foo)) ; L6 (set-module-value! '(bar) 'calculate-bar ; L7 (lambda () (+ 1 (module-value '(foo) 'foo))))) ; L8 Now let's see what happens if the module (bar) is loaded: ; Initialising '(bar)' (initialise-module '(foo)) ; L6 ;; (foo) has not yet begun initialisation, so run the thunk: -> (initialise-module '(bar)) ; L1 ;; (bar) is being initialised, so don't do anything here -> (set-module-value! '(foo) 0) ; L2 -> (set-module-value! '(foo) 'calculate-foobar ; L3 (lambda () (+1 ((module-value '(bar) 'calculate-bar)))) ; L4 The hash table of '(bar)' does not yet contain 'calculate-bar', but that's not a problem because the procedure 'calculate-foobar' is not yet run. (set-module-value! '(bar) '(calculate-bar) ; L7 (lambda () (+ 1 (module-value '(foo) 'foo)))) ; L8 ;; The hash table of '(foo)' contains 'foo', so no problem! ;; Alternatively, even if '(foo)' did not contain 'foo', ;; the procedure '(calculate-bar)' is not yet run, so no problem! ;; Done! Now for a problematic import cycle: (define-module (foo) #:export (foo) #:use-module (bar)) (define foo (+ 1 bar)) (define-module (bar) #:export (bar) #:use-module (foo)) (define bar (+ 1 foo)) Now let's reason what happens when we try importing 'bar'. The init thunk of '(foo)' is: (lambda () (initialise-module '(bar)) ; L1 (set-module-value! '(foo) 'foo (+ 1 (module-value '(bar) 'bar)))) ; L2 and the thunk of '(bar)': (lambda () (initialise-module '(foo)) ; L3 (set-module-value! '(bar) 'bar (+ 1 (module-value '(foo) 'foo)))) ; L4 Now let's see what happens if 'bar' is loaded: ; Initialising (bar) (initialise-module! '(foo)) ; L3 ;; (foo) has not yet begun initialisation, so run the thunk: -> (initialise-module '(bar)) ; L1 ;; (bar) is already initialising, so don't do anything -> (set-module-value! '(foo) 'foo (+ 1 bar))) Oops, the variable foo of the module (foo) has not yet been defined, so an 'unbound-variable' exception is raised! I hope that illustrates a little when and when not cyclic imports work! Greetings, Maxime. --=-HRX+WOD7NA3SB97dt11r Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYhJ+xRccbWF4aW1lZGV2 b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7u6lAQD+BVaO58jDBl74naP7I48hdgnd ji1kl1pItSg2iXct1QEAgXHhF6orE8eUKdyO1E+F1PWWeTyY6SMXyNY050hpfAs= =qzJK -----END PGP SIGNATURE----- --=-HRX+WOD7NA3SB97dt11r--