On 22 Sep 2013, at 20:45, Steve Haflich <[email protected]> wrote:
> No, it is generally possible to write portable setf expanders that work with
> multiple-value places provided the platform conforms to the ANS requirements.
> I have some extreme examples on another machine I may share to the list later.
>
> I think to be portable transparent assure would need to collect and return
> multiple values, with the hope that the compiler would eliminate that stuff
> if the place were a single-value form like a variable or known function.
OK, it seems you mean something like this:
(defmacro assure (type form &environment env)
(multiple-value-bind
(vars vals store-vars writer reader)
(get-setf-expansion ,form env)
(declare (ignore store-vars writer))
`(let* ,(mapcar 'list vars vals)
(check-type ,reader ,type)
,reader)))
However, this is not good enough. Something as simple as (assure integer (+ x
y)) already doesn't work. The requirement that form is a generalized reference
is an artifact that comes from check-type, but that shouldn't leak through.
I came up with another version. I believe this should work:
(defmacro assure (type form)
(let ((values (copy-symbol 'values)))
`(let ((,values (multiple-value-list ,form)))
(declare (dynamic-extent values))
(etypecase (values-list ,values)
(,type (values-list ,values))))))
…except that this also doesn't work in some Common Lisp implementations for
multiple values, but I think it should and those implementations need to be
fixed.
Pascal
--
Pascal Costanza
The views expressed in this email are my own, and not those of my employer.