all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: ludo@gnu.org (Ludovic Courtès)
To: guix-devel@gnu.org
Subject: G expressions
Date: Thu, 24 Apr 2014 00:23:02 +0200	[thread overview]
Message-ID: <871twneldl.fsf@gnu.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 3509 bytes --]

Hello!

1. The Problem
===============

There’s a recurrent problem that we need to communicate the file name 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 ‘build-expression->derivation’
install two global variables in the build code: ‘%build-inputs’ and
‘%outputs’.

However, for generated Scheme files (as in (gnu system) and related
modules), there’s 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’t 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, ‘%build-inputs’ is not particularly elegant either, and it’s
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’s been OK as
it’s only used occasionally in package recipes.


2. G Expressions
=================

“G-expressions”, or gexps, are meant to address these two issues
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 ‘%current-system’ value when the gexp
is used.

The ‘gexp’ form is essentially like ‘quasiquote’, with ‘ungexp’ as the
counterpart of ‘unquote’:

  (gexp (system* (string-append (ungexp coreutils) "/bin/ls")))

That gexp can then be passed to ‘gexp->file’, which returns a derivation
that builds a file containing:

  (system* (string-append "/gnu/store/…" "/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’t need #:inputs here, because the gexp embeds that
info.  So eventually, we could even get rid of the label in the ‘inputs’
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
==============

I think gexps can be helpful to serialize Scheme code that refers to
packages/derivations.  Preliminary work is in ‘wip-gexp’.
What do you think?


4. Related Work :-)
====================

HOP has a quotation mechanism to introduce client-side code in server
code and vice-versa:

  (<BUTTON>
    :onclick ~(with-hop ($foo)))

Nix uses string interpolation to keep achieve what we do:

  script = ''${coreutils}/bin/ls'';

Here ${coreutils} is replaced by the output file name, and the resulting
string internally has additional info about the reference to that
derivation.

Ludo’.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

             reply	other threads:[~2014-04-23 22:23 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-23 22:23 Ludovic Courtès [this message]
2014-04-28  7:43 ` G expressions Ludovic Courtès
2014-04-28 14:03   ` Amirouche Boubekki
2014-04-28 15:58     ` Ludovic Courtès
2014-04-28 21:45   ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=871twneldl.fsf@gnu.org \
    --to=ludo@gnu.org \
    --cc=guix-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.