From mboxrd@z Thu Jan 1 00:00:00 1970 From: ludo@gnu.org (Ludovic =?utf-8?Q?Court=C3=A8s?=) Subject: G expressions Date: Thu, 24 Apr 2014 00:23:02 +0200 Message-ID: <871twneldl.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha1; protocol="application/pgp-signature" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:42415) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wd5ZZ-0001VB-IK for guix-devel@gnu.org; Wed, 23 Apr 2014 18:23:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wd5ZQ-0004N6-Fb for guix-devel@gnu.org; Wed, 23 Apr 2014 18:23:21 -0400 Received: from hera.aquilenet.fr ([2a01:474::1]:40743) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wd5ZQ-0004Mq-0g for guix-devel@gnu.org; Wed, 23 Apr 2014 18:23:12 -0400 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 997A81A34 for ; Thu, 24 Apr 2014 00:23:10 +0200 (CEST) Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5rXs6nx0D66o for ; Thu, 24 Apr 2014 00:23:10 +0200 (CEST) Received: from pluto (reverse-83.fdn.fr [80.67.176.83]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 2B5FB7F8 for ; Thu, 24 Apr 2014 00:23:10 +0200 (CEST) List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org To: guix-devel@gnu.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello! 1. The Problem =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D There=E2=80=99s a recurrent problem that we need to communicate the file na= me of store items to Scheme code that is going to live in another process: expressions to build a derivation, Scheme files that are to be loaded by other processes, etc. This had been partly addressed by having =E2=80=98build-expression->derivat= ion=E2=80=99 install two global variables in the build code: =E2=80=98%build-inputs=E2= =80=99 and =E2=80=98%outputs=E2=80=99. However, for generated Scheme files (as in (gnu system) and related modules), there=E2=80=99s no such mechanism. Thus, either we use something like: (mlet %store-monad ((ls (package-file coreutils "bin/ls"))) (text-file "foo" (object->string `(system* ,ls)))) but then the problem is that the resulting text file doesn=E2=80=99t hold a reference to Coreutils, which is wrong. Or, we do something like: (text-file* "foo" "(system* \"" coreutils "/bin/ls\")") The resulting file does have a reference to Coreutils, but the approach obviously sucks. Besides, =E2=80=98%build-inputs=E2=80=99 is not particularly elegant either= , and it=E2=80=99s error-prone (if you refer to an input by the wrong name, you only notice when building, with an obscure wrong-type-arg error.) That=E2=80=99s been = OK as it=E2=80=99s only used occasionally in package recipes. 2. G Expressions =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =E2=80=9CG-expressions=E2=80=9D, or gexps, are meant to address these two i= ssues mentioned above: 1. Replacing a reference to a package or derivation by its output file name; 2. Keeping track of the derivations it refers to. In addition, the substitution in (1) must be done lazily, so that you get the output file name for the =E2=80=98%current-system=E2=80=99 value wh= en the gexp is used. The =E2=80=98gexp=E2=80=99 form is essentially like =E2=80=98quasiquote=E2= =80=99, with =E2=80=98ungexp=E2=80=99 as the counterpart of =E2=80=98unquote=E2=80=99: (gexp (system* (string-append (ungexp coreutils) "/bin/ls"))) That gexp can then be passed to =E2=80=98gexp->file=E2=80=99, which returns= a derivation that builds a file containing: (system* (string-append "/gnu/store/=E2=80=A6" "/bin/ls")) And it can also be used to describe derivation builds: (gexp->derivation "foo" (gexp (begin (mkdir (ungexp output)) (chdir (ungexp output)) (symlink (ungexp coreutils) "cu")))) Note that we don=E2=80=99t need #:inputs here, because the gexp embeds that info. So eventually, we could even get rid of the label in the =E2=80=98in= puts=E2=80=99 field of packages (not a priority, though.) We could use some sugar to make it more concise (suggestions welcome): (gexp->derivation "foo" #~(begin (mkdir #$output) (chdir #$output) (symlink #$coreutils "cu"))) 3. Conclusion =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D I think gexps can be helpful to serialize Scheme code that refers to packages/derivations. Preliminary work is in =E2=80=98wip-gexp=E2=80=99. What do you think? 4. Related Work :-) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D HOP has a quotation mechanism to introduce client-side code in server code and vice-versa: (