2017-02-07 14 views
1

Для быстрого прототипирования в общем режиме было бы удобно иметь возможность легко изменять функцию объекта в произвольной структуре данных. Казалось бы, это связано с вызовом произвольной функции на месте в структуре данных, заменяющей объект в этом месте результатом вызова функции. Common-шепелявость имеет ряд специализированных модификации макросов (например, incf, push, getf и т.д.) для конкретных типов объектов, а также setf для обобщенного места модификации (например, setf-second, setf-aref, setf-gethash, и т.д.). Но вместо того, чтобы изобретать новые специализированные макросы для других типов объектов или мысленно учитывать характеристики каждого макроса (замедляя разработку), было бы неплохо иметь обобщенную возможность настройки, подобную setf, которая была бы проще в использовании, чем setf. Например, вместо (setf (second (getf plist indicator)) (1+ (second (getf plist indicator)))) или (incf (second (getf plist indicator))) можно написать (callf (second (getf plist indicator)) #'1+), используя любую из обычных функций одного аргумента (или лямбда-выражения), предоставляемых обычным пользователем или пользователем. Вот попытка кода:Упрощение сложных выражений setf

(defun call (object function) (funcall function object)) 
(define-modify-macro callf (&rest args) call) 

Будет что-то вроде этой работы для всех общих случаев, и это может реально упростить код на практике?

+0

Является ['DEFINE-MODIFY-MACRO'] (http://clhs.lisp.se/Body/m_defi_2.htm), что вы ищете? – Barmar

ответ

2

callf

Я думаю, что вы ищете, _f от OnLisp 12.4:

(defmacro _f (op place &rest args) 
    "Modify place using `op`, e.g., (incf a) == (_f a 1+)" 
    (multiple-value-bind (vars forms var set access) 
     (get-setf-expansion place) 
    `(let* (,@(mapcar #'list vars forms) 
      (,(car var) (,op ,access ,@args))) 
     ,set))) 

Это использует get-setf-expansion - рабочая лошадь generalized reference обработки.

Отметьте, что _f работает только с single-value местами. IOW, (_f (values a b c) 1+) будет не Приращение всех трех переменных. Не все это трудно исправить, хотя ...

может ли это на самом деле упростить код на практике?

Этот действительно зависит от вашего стиля кодирования и конкретной проблемы, которую вы решаете.

+0

Вот и все. Отличное обсуждение в OnLisp тоже. – davypough