Carlos
4/8/2015 9:53:00 AM
On 08/04/2015 11:23, Pascal J. Bourguignon wrote:
> Carlos <angus@quovadis.com.ar> writes:
>
>> On 08/04/2015 9:50, jarausch@skynet.be wrote:
>>> Hi,
>>>
>>> as an example I'd like to write a macro for accessing functions stored
>>> in a struct. Then I'd like to use this macro within a macrolet.
>>> This doesn't work (probably) because macrolet doesn't evaluate its
>>> first argument.
>>>
>>> Can this be done in Common Lisp?
>>>
>>> I could write a macro which generates the whole macrolet invocation but that's
>>> not the solution I'm looking for since I'd like to use several such macros in an
>>> unspecified way within a macrolet.
>>>
>>> Here is an example which does not work (yet)
>>>
>>> (defstruct Node
>>> (key-fct nil :type (function(Node) string))
>>> (Name "" :type string)
>>> )
>>>
>>> (defun Node-Key(Nd)
>>> (declare (Node Nd))
>>> (format nil ">>>~a<<<" (ND-Name Nd)))
>>>
>>>
>>> (defparameter MyNode (make-Node :Name "ItsMe" :key-fct #'Node-Key))
>>>
>>>
>>> (defmacro struct-access (method method-fct)
>>> `(,method(This) (let ((obj (gensym)))
>>> `(let ((,obj ,This)) (funcall (,',method-fct ,obj) ,obj)))))
>>>
>>>
>>> (macrolet (((struct-access get-key ND-key-fct)))
>>> (get-key MyNode))
>>>
>>> ;; E R R O R
>>> ;; The list ((STRUCT-ACCESS GET-KEY ND-KEY-FCT)) is too short
>>> ;; to be a legal local macro definition.
>>>
>>>
>>> Many thanks for a hint,
>>> Helmut
>>>
>>
>> All to avoid writing FUNCALL, no? ;)
>>
>> You can use classes, instead of structs (create a small class with
>> just key-fct, and define the method get-key on it. Then, make it the
>> parent of the others).
>>
>> Or you can define your own whole construct. For example,
>>
>> (defmacro with-struct-accesses (pairs &body body)
>> `(flet ,(mapcar (lambda (pair)
>> `(,(car pair) (this)
>> (funcall (,(cadr pair) this) this)))
>> pairs)
>> ,@body))
>>
>> usage:
>>
>> (with-struct-accesses ((get-key nd-key-fct)
>> (get-other-key other-key-fct))
>> (get-key node))
>
> Or just use with-accessors
>
> (with-accessors ((key nd-key-fct)
> (other-key other-key-fct)) node
> (setf key other-key))
>
>
> (with-accessors ((src-key nd-key-fct)) src-node
> (with-accessors ((dst-key nd-key-fct)) dst-node
> (setf dst-key src-key)))
It's not enough; he wants to FUNCALL the value returned by the accessor.
--