GNU bug report logs - #68413
Ungexp doesn't work on deep lists

Previous Next

Package: guix;

Reported by: Justin Veilleux <terramorpha <at> cock.li>

Date: Sat, 13 Jan 2024 01:53:01 UTC

Severity: normal

To reply to this bug, email your comments to 68413 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guix <at> gnu.org:
bug#68413; Package guix. (Sat, 13 Jan 2024 01:53:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Justin Veilleux <terramorpha <at> cock.li>:
New bug report received and forwarded. Copy sent to bug-guix <at> gnu.org. (Sat, 13 Jan 2024 01:53:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Justin Veilleux <terramorpha <at> cock.li>
To: bug-guix <at> gnu.org
Subject: Ungexp doesn't work on deep lists
Date: Fri, 12 Jan 2024 20:52:21 -0500
Hi, I've been using G-expressions for some time and have always been
hindered by `ungexp` not working on deeper lists. For instance, when I
want to embed in a G-expression a list of packages, it works

>(define packages (list coreutils gnu-make ...))
>
> #~(for-each
>    (lambda (f)
>      ... do-something)
>    '#$packages)

But as soon as I use an object in which the file-like objects are
deeper, it fails

> (define packages
>         (list
>          (cons "coreutils" coreutils)
>          (cons "make" gnu-make)
>          ...))
>
> #~(for-each
>    (lambda (f)
>      ... do-something)
>    '#$packages)

If I send a patch to "fix" this, will it be usefull or is there a reason
for this behavior?

Thanks.




Information forwarded to bug-guix <at> gnu.org:
bug#68413; Package guix. (Sat, 13 Jan 2024 11:39:01 GMT) Full text and rfc822 format available.

Message #8 received at 68413 <at> debbugs.gnu.org (full text, mbox):

From: Josselin Poiret <dev <at> jpoiret.xyz>
To: Justin Veilleux <terramorpha <at> cock.li>, 68413 <at> debbugs.gnu.org
Subject: Re: bug#68413: Ungexp doesn't work on deep lists
Date: Sat, 13 Jan 2024 12:38:38 +0100
[Message part 1 (text/plain, inline)]
Hi Justin,

Justin Veilleux <terramorpha <at> cock.li> writes:

>> (define packages
>>         (list
>>          (cons "coreutils" coreutils)
>>          (cons "make" gnu-make)
>>          ...))
>>
>> #~(for-each
>>    (lambda (f)
>>      ... do-something)
>>    '#$packages)
>
> If I send a patch to "fix" this, will it be usefull or is there a reason
> for this behavior?

I think IMO that it's a bug, but it's also quite tricky to properly
traverse deep structures like this.  The bug comes from the fact that in
gexp->sexp, we traverse lists by matching the reference with (refs ...),
but that doesn't match if the reference is a pair instead.  Then, it
tries to match with ($ <gexp-input> (? self-quoting? x)), which does
match since self-quoting? apparently returns #t on a pair, whether or
not its constituents are also self-quoting.

Best,
-- 
Josselin Poiret
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-guix <at> gnu.org:
bug#68413; Package guix. (Mon, 15 Jan 2024 09:47:02 GMT) Full text and rfc822 format available.

Message #11 received at 68413 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Josselin Poiret <dev <at> jpoiret.xyz>
Cc: Justin Veilleux <terramorpha <at> cock.li>, 68413 <at> debbugs.gnu.org
Subject: Re: bug#68413: Ungexp doesn't work on deep lists
Date: Mon, 15 Jan 2024 10:46:42 +0100
Hi,

Josselin Poiret <dev <at> jpoiret.xyz> skribis:

> Justin Veilleux <terramorpha <at> cock.li> writes:
>
>>> (define packages
>>>         (list
>>>          (cons "coreutils" coreutils)
>>>          (cons "make" gnu-make)
>>>          ...))
>>>
>>> #~(for-each
>>>    (lambda (f)
>>>      ... do-something)
>>>    '#$packages)
>>
>> If I send a patch to "fix" this, will it be usefull or is there a reason
>> for this behavior?
>
> I think IMO that it's a bug, but it's also quite tricky to properly
> traverse deep structures like this.  The bug comes from the fact that in
> gexp->sexp, we traverse lists by matching the reference with (refs ...),
> but that doesn't match if the reference is a pair instead.  Then, it
> tries to match with ($ <gexp-input> (? self-quoting? x)), which does
> match since self-quoting? apparently returns #t on a pair, whether or
> not its constituents are also self-quoting.

Actually, what bug are we talking about?  It seems to work for me with
this example:

--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> (define packages `(("coreutils" ,coreutils) ("make" ,gnu-make)))
scheme@(guile-user)> ,build (scheme-file "foo" #~(begin '#$packages))
building /gnu/store/lq9gvbilv0y2nph00zxk6bn3lvcgdxqq-foo.drv...
$7 = "/gnu/store/9ryh6v80jvjv3kwx0q782h26h9gbaclj-foo"
scheme@(guile-user)> (call-with-input-file $7 get-string-all)
$8 = "(begin (quote ((\"coreutils\" \"/gnu/store/mppp9hwxizx9g9pikwcvvshb2ffxyq7p-coreutils-9.1\") (\"make\" \"/gnu/store/9fadhs5qmwl5x7f669a0v39b3ryrmmf1-make-4.3\"))))"
--8<---------------cut here---------------end--------------->8---

One of the design decisions for gexps was to ensure that substituting a
file-like object by its file name would be O(1) in most cases.

Substitution in lists as in the example above is supported, but
primarily for backward compatibility.  It should be avoided when
possible because it’s inefficient: ‘gexp->sexp’ needs to traverse the
whole list/tree in search of potential candidates.

Thanks,
Ludo’.




Information forwarded to bug-guix <at> gnu.org:
bug#68413; Package guix. (Mon, 15 Jan 2024 16:29:01 GMT) Full text and rfc822 format available.

Message #14 received at 68413 <at> debbugs.gnu.org (full text, mbox):

From: Josselin Poiret <dev <at> jpoiret.xyz>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: Justin Veilleux <terramorpha <at> cock.li>, 68413 <at> debbugs.gnu.org
Subject: Re: bug#68413: Ungexp doesn't work on deep lists
Date: Mon, 15 Jan 2024 17:28:47 +0100
[Message part 1 (text/plain, inline)]
Hi Ludo,

Ludovic Courtès <ludo <at> gnu.org> writes:

> Actually, what bug are we talking about?  It seems to work for me with
> this example:
>
> --8<---------------cut here---------------start------------->8---
> scheme@(guile-user)> (define packages `(("coreutils" ,coreutils) ("make" ,gnu-make)))
> scheme@(guile-user)> ,build (scheme-file "foo" #~(begin '#$packages))
> building /gnu/store/lq9gvbilv0y2nph00zxk6bn3lvcgdxqq-foo.drv...
> $7 = "/gnu/store/9ryh6v80jvjv3kwx0q782h26h9gbaclj-foo"
> scheme@(guile-user)> (call-with-input-file $7 get-string-all)
> $8 = "(begin (quote ((\"coreutils\" \"/gnu/store/mppp9hwxizx9g9pikwcvvshb2ffxyq7p-coreutils-9.1\") (\"make\" \"/gnu/store/9fadhs5qmwl5x7f669a0v39b3ryrmmf1-make-4.3\"))))"
> --8<---------------cut here---------------end--------------->8---
>
> One of the design decisions for gexps was to ensure that substituting a
> file-like object by its file name would be O(1) in most cases.
>
> Substitution in lists as in the example above is supported, but
> primarily for backward compatibility.  It should be avoided when
> possible because it’s inefficient: ‘gexp->sexp’ needs to traverse the
> whole list/tree in search of potential candidates.

Notice that OP's example uses `(("thing" . ,package)), ie. lists of
pairs and not lists of lists, as in your case!

Best,
-- 
Josselin Poiret
[signature.asc (application/pgp-signature, inline)]

This bug report was last modified 1 year and 150 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.