I saw your pull request adding the warning, thank you very much, that should ease the things a lot. I have added the #7424 into my RSS reader and am looking forward to it getting merged.
Ludovic Courtès <[email protected]> writes: > Tomas Volf <[email protected]> skribis: > >> Incidentally, I completely forgot that this-packages is a thing (I never >> managed to use it correctly, I usually end up in infinite loops). But >> that gives me an idea. What about: >> >> (let ((services (modify-services ...))) >> (operating-system >> (inherit %base-os) >> (services this-operating-system-services))) >> >> (package >> (inherit foo) >> (inputs (modify-inputs this-package-inputs ...))) >> >> ? > > And where would the identifier ‘this-package-inputs’ come from? > > There’s an important property of macros referred to as “hygiene” (a > proper name would be “referential transparency”). One aspect of it is > that any binding that is introduced must appear in the source. For > example, ‘this-package’ appears as an argument to ‘define-record-type*’. > Hence my question. Well, I assumed it could be done using datum->syntax, by putting together this-package (or whatever user configured) with name of the current field. But if that would be problem for some reason, you could always just do (define-record-type* <package> package make-package package? this-package ... (inputs package-inputs (default '()) (thunked this-package-inputs) ; <-- HERE (sanitize sanitize-inputs)) ...) > > (There’s a way to break this hygiene rule (‘define-configuration’ does > that), but it’s fraught with peril.) > > Besides, one might be tempted to think that: > > this-package-inputs = (package-inputs this-package) > > … which would not be the case. Wait, it is not? Ugh, my head starts to hurt a little. :) (package (inherit %base) (inputs (package-inputs %base))) (package (inherit %base) (inputs (package-inputs this-package))) (package (inherit %base) (inputs inputs)) What is a difference between these three? Up till now I have assumed all three produce identical resulting package. (Sorry to keep up with the constant questions, if there is recommended reading instead, I will gladly do that instead, but records are not documented at all last time I checked. And reading records.scm gave me a headache instead of knowledge. :/ The code is far outside my skill level.) > > Ludo’. > > PS: Instead of introducing a new binding, my initial implementation used > a global syntax parameter, ‘inherited-value’, which would only be > valid within the body of an inherited thunked field. Good thing: no > shadowing. Bad thing: every user of a record type would have to > import (guix records) to access ‘inherited-value’—a showstopper. > To a degree, I assume that could have been done as: (define-record-type* <package> package make-package package? this-package inherited-value ; <-- HERE and then let-bind it in every thunked field? If it is possible for this-package, it should work for inherited-value as well I assume. This would still have the benefit that it would be exactly one extra binding to worry regarding shadowing. -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
