Minimal extension for ,. syntax
We have just added specializations of the wrap-in-quote... generics to Clasp's eclector-client. Clasp does have destructive splicing (as rare as that is) but ,. gets turned into ,@ by Eclector,
This PR is an idea for a minimal extension to enable destructive splicing without changing the signature of wrap-in-unquote-splicing and making the default for wrap-in-unquote-nsplicing be the appropriate specialization of wrap-in-unquote-splicing.
Obviously, error messages, tests, etc. could be updated.
FYI @Bike
I'm not opposed to adding this for now.
However, in the long run, I would like to turn several groups of related functions into more extensible protocols. For example something like (make-{structure-instance,…} client …) → (make-literal client :structure-instance …), (make-literal client 'float :type 'double-float :sign …), (make-literal client 'hash-table …) and (wrap-in-{function,quote,unquote,unquote-splicing} client …) → (wrap-in client :unquote … :splicing t :destructive t)`.
I understand either way.
I do like the make-* pattern a lot more. Also, using keys as arguments like (wrap-in client :unquote … :splicing t :destructive t) prevents specialization on those values. I would suggest something like (make-form client :unquote-nsplicing form)
I do like the
make-*pattern a lot more.
Can you please clarify? Do yo prefer separate functions make-structure-instance, … over a single function make-literal or do you prefer the change make-structure-instance, … → make-literal over the change wrap-in-quote, … → wrap-in
Also, using keys as arguments like
(wrap-in client :unquote … :splicing t :destructive t)prevents specialization on those values. I would suggest something like(make-form client :unquote-nsplicing form)
I haven't thought about the design at this level of detail.
In any case, one additional possibility would be something like
(defclass any-wrapping () ())
(defclass any-unquote (any-wrapping) ())
(defclass any-unquote-splicing (any-unquote) ())
(defclass unquote-nsplicing (any-unquote-splicing) ())
(defvar *unquote-nsplicing* (make-instance 'unquote-nsplicing))
with calls of the form (wrap-in client *unquote-nsplicing* form). This would allow the client to specialize to both all unquote variants (or even all wrapping variants) or specific ones.
I meant that I find the "wrap-in-*" naming to be a bit strange. I prefer "make-*" since it doesn't create implications as to how the thing is created. For example, SBCL creates a structure for unquote, whereas ECL, CLASP, CLISP and Mezzano all create something like (unquote bla).
I don't personally have a preference about multiple functions. I do really like your idea about using a class hierarchy for things like unquote. That's pretty clever.