guix-patches
[Top][All Lists]
Advanced

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

[bug#51838] [PATCH v5 06/45] guix: node-build-system: Refactor patch-dep


From: Philip McGrath
Subject: [bug#51838] [PATCH v5 06/45] guix: node-build-system: Refactor patch-dependencies phase.
Date: Mon, 20 Dec 2021 13:03:13 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.3.1

Hi,

On 12/18/21 12:52, Liliana Marie Prikler wrote:
Hi,

Am Samstag, dem 18.12.2021 um 12:03 -0500 schrieb Philip McGrath:
[...]

The Guix codebase is generally not the place to play around with
destructive semantics.  If you can avoid assoc-set!, I think you
ought to, especially if it helps making a two-step process into a
single-step one.  Anything I'm missing here?

I agree that assoc-set! is best avoided. (I am a Racketeer: we don't
mutate pairs.) However, this code was already using assoc-set!: the
change in this patch is merely to use it correctly.

AFAIK neither `info "(guile)Association Lists"` nor SRFI-1 (`info
"(guile)SRFI-1 Association Lists"`) provide a non-destructive assoc-
set operation. Note in particular that acons and alist-cons do not
work, since they don't remove existing entries for the same key: they
would result in duplicate keys being written to the JSON object. (In
theory this has undefined semantics; in practice, I believe Node.js
would use the wrong entry.)

Of course, I know how to write a little library of purely functional
association list operations---but that seems vastly out of scope for
this patch series (which has already grown quite large). Furthermore,
if we were going to make such changes, I think it might be better to
change the representation of JSON objects to use a real immutable
dictionary type, probably VHash (though it looks like those would
still need missing functions, at which point a wrapper type that
validated keys and maintained a consistent hash-proc might be even
better). Alternatively we could use guile-json, which at least avoids
the need for improper alists to disambiguate objects from arrays, but
we would have to address the issues in Guix commit
a4bb18921099b2ec8c1699e08a73ca0fa78d0486.

All of that reinforces my sense that we should not try to change this
here.
I think you misread me here.  One thing that's bugging me is that you
(just like whoever wrote this before) strip the @ only to reintroduce
it.  I think it'd be better if (resolve-dependencies) simply took a
list and the let-block deconstructed the json.

As for the package-meta -> package-meta conversion, imo that could
perfectly be done with match or SXML transformation.  WDYT?


I definitely am not understanding what you have in mind here. When you write "strip the @", I'm not sure what you're referring to, because there are multiple "@" tags here, one beginning each JSON object. (Maybe this is obvious, but it hadn't been obvious to me.) So, the (guix build json) representation of a "package.json" file might look like this:

```
`(@ ("name" . "apple")
    ("version" . "1.0")
    ("dependencies". (@ ("banana" . "*")
                        ("pear" . "*")))
    ("devDependencies" . (@ ("peach" . "*")
                            ("orange" . "*")))
    ("peerDependencies" . (@ ("node-gyp" . "7.x")))
    ("peerDependenciesMeta" . (@ ("node-gyp" . (@ ("optional" . #t)))))
    ("optionalDependencies" . (@ ("node-gyp" . "7.x"))))
```

An unfortunate consequence of this representation is that JSON objects are not usable directly as association lists: some procedures expecting association lists seem to silently ignore the non-pair at the head of the list, but I don't think that's guaranteed, and other procedures just don't work. In particular, `append` applied to two JSON objects does not produce a JSON object, even ignoring the problem of duplicate keys.

Given that the current code adds "peerDependencies" as additional "dependencies", the choice (as I see it) is between the current approach, in which `resolve-dependencies` returns genuine association lists and the `let*` block turns them JSON objects, or changing `resolve-dependencies` to return JSON objects and implementing `json-object-append`, which doesn't seem obviously better, unless it were part of broader changes. (As an aside, I am not convinced that the current handling of "peerDependencies" is right, but I think reevaluating that behavior is out of scope for this patch series, and particularly for this patch, in which, as Tim said in <https://issues.guix.gnu.org/51838#234>, my goal was merely to make the use of `assoc-set!` safe.)

I definitely think the broader situation should be improved!

But I think those improvements are out of scope for this patch series. It seems like much more discussion would be needed on what the improvements should be, and potentially coordination with other users of (guix build json). Personally, I'd want to represent JSON objects with a real immutable dictionary type that gave us more guarantees about correctness by construction. If we continue with tagged association lists, we should write a little library of purely functional operations on JSON objects. But that all seems very far afield.

-Philip





reply via email to

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