[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

G-Expressions and Scope Preservation

From: Chris Marusich
Subject: G-Expressions and Scope Preservation
Date: Mon, 20 Jan 2020 13:27:50 -0800
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)

Hi Ludo,

In your paper "Code Staging in GNU Guix" [1], you use the following
example to illustrate how G-Expressions are hygienic ("they preserve
lexical scope across stages"):

(let ((gen-body (lambda (x)
                  #~(let ((x 40))
                      (+ x #$x)))))
  #~(let ((x 2))
      #$(gen-body #~x)))

You explain that it expands to something like this:

(let ((x-1bd8-0 2))
  (let ((x-4f05-0 40))
    (+ x-4f05-0 x-1bd8-0)))

However, when I write this gexp to disk, it doesn't look like that:

scheme@(guile-user)> ,use (guix)
scheme@(guile-user)> (define ex
                       (let ((gen-body (lambda (x)
                                         #~(let ((x 40))
                                             (+ x #$x)))))
                         #~(let ((x 2))
                             #$(gen-body #~x))))
scheme@(guile-user)> ex
$2 = #<gexp (let ((x 2)) #<gexp-input #<gexp (let ((x 40)) (+ x #<gexp-input 
#<gexp x 7f29a4ed92a0>:out>)) 7f29a4ed9240>:out>) 7f29a4ed91e0>
scheme@(guile-user)> ,run-in-store (lower-object (scheme-file "example" ex))
$3 = #<derivation /gnu/store/l8h0d3jx9wj9b1mn84bvmss4ng3dhmi5-example.drv => 
/gnu/store/mhlvarq8hc9c40by7sfq7yqvxvjdq7rp-example 7f299a13abe0>
scheme@(guile-user)> ,run-in-store (built-derivations (list $3))
building path(s) `/gnu/store/mhlvarq8hc9c40by7sfq7yqvxvjdq7rp-example'
$4 = #t

The file /gnu/store/mhlvarq8hc9c40by7sfq7yqvxvjdq7rp-example contains
the following expression:

(let ((x 2)) (let ((x 40)) (+ x x)))

This looks different than what I expected.  I expected something more
like what you had written in the paper.  Am I missing something?

I thought this would be an easy way to see the scope preservation in
action, but I get the feeling I've misunderstood something.  I tried
some other ways to use the gexp, and the results were similar:

scheme@(guile-user)> (define write-result
                       #~(with-output-to-file #$output
                           (lambda ()
                             (write #$ex))))
scheme@(guile-user)> (define write-ex-literally
                       #~(with-output-to-file #$output
                           (lambda ()
                             (write '#$ex))))
scheme@(guile-user)> ,run-in-store (gexp->derivation "write-result" 
$7 = #<derivation /gnu/store/p2wbvzh1c07bj2hjz9h3ngyf35ncdgh0-write-result.drv 
=> /gnu/store/jaf44b767y5n2m0zd6q9qswhzv2hsy96-write-result 7fda1342e960>
scheme@(guile-user)> ,run-in-store (gexp->derivation "write-ex-literally" 
$8 = #<derivation 
/gnu/store/kpb7k7n36q64dv4zyjpp0s84ynmvp6z6-write-ex-literally.drv => 
/gnu/store/rhhm38j6yxfs0q7jrvdrv02r7zb9ai8j-write-ex-literally 7fda1342e780>

The file /gnu/store/jaf44b767y5n2m0zd6q9qswhzv2hsy96-write-result
contained "80", and the file
/gnu/store/rhhm38j6yxfs0q7jrvdrv02r7zb9ai8j-write-ex-literally contained
the following S-Expression:

(let ((x 2)) (let ((x 40)) (+ x x)))

Can you help me to understand why I'm seeing this result instead of a
result that looks more like the one you presented in your paper?

Thank you,



Attachment: signature.asc
Description: PGP signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]