Ludovic Courtès <[email protected]> writes:

> Hi Tomas,
>
> Tomas Volf <[email protected]> skribis:
>
>> first, let me thank you for your time and willingness to engage in this
>> discussion.  For large part, let us agree to disagree, but one final
>> question below, if you would have time to enlighten me.  (Well, and
>> technically also one more comment.)
>
> Thank you.  I also appreciate your critical view on this and other
> matters!
>
>> Here I do not understand.  I have read the paper while back (and enjoyed
>> it), but I still do not get it.  Thunks (as implemented by (thunked))
>> are not necessary for the delayed computation no?  Any lambda would
>> suffice no?  So wrapping it in a lambda of a single argument (the record
>> instance) instead of zero (thunk) would achieve the same result, but
>> allow removing all the magic.
>>
>> True, it would be more verbose when getting the value
>>
>>     ((package-inputs pkg) pkg)
>>
>> versus current
>>
>>     (package-inputs pkg)
>>
>> but it would achieve the same effect right?
>
> Yes, you are right; this is what the ‘thunked’ property does.
>
> I chose to have a thin layer atop records to abstract this away.  That
> way, one doesn’t have to explicitly write (lambda () …) and one doesn’t
> have to “call” fields that happen to be thunked.  That makes the
> interface simpler and leaves more freedom for the record type developer
> who can easily move between thunked, delayed, or default.
>
> Incidentally, the introduction of ‘this-package’ was made possible
> thanks to this abstraction.  Without it, we’d have to change every
> occurrence of:
>
>   (package
>     ;; …
>     (inputs (lambda () …)))
>
> to:
>
>   (package
>     ;; …
>     (inputs (lambda (this-package) …)))
>
> And then change:
>
>   ((package-inputs p))
>
> to:
>
>   ((package-inputs p) p)
>
> The syntactic abstraction is very helpful here.

There could be helpers provided, but yes, I see your point.

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 ...)))

?  That is *very* likely to be unique name with no collision with user
code, and is not much more verbose.  It is bit longer, but more
descriptive as well and easier to grasp.

With this naming pattern, I would argue the names would be unique enough
that the mechanism could even be extended to all fields, not just
thunked, removing major source of confusion, with hopefully minimal risk
(especially if combined with Maxim's suggestion to give a warning when
shadowing is detected).

I would hope this would satisfy all involved parties (well, at least I
would be happy with this ^_^).  What do you think?

(Bike shedding material: this-package-inputs vs this-package/inputs)

Tomas

PS: Maybe later it would even be possible to extend this to allow cross
references (and maybe usage when not inheriting, to make it cohesive):

    (package
      (inherit foo)
      (description
        (string-append this-package-name " at " this-package-version)))

-- 
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.

Attachment: signature.asc
Description: PGP signature

Reply via email to