1

For rapid prototyping purposes in common-lisp it would be convenient to be able to easily function-modify an object in an arbitrary data structure. This would seem to involve calling an arbitrary function on a place in the data structure, replacing the object at that place with the result of the function call. Common-lisp has a number of specialized modification macros (eg, incf, push, getf, etc) for particular types of objects, and setf for generalized place modification (eg, setf-second, setf-aref, setf-gethash, etc). But rather than inventing new specialized macros for other object types, or having to mentally consider the characteristics of each macro (slowing down development), it might be nice to have a generalized setf-like modification capability that was simpler to use than setf. For example, instead of (setf (second (getf plist indicator)) (1+ (second (getf plist indicator)))) or (incf (second (getf plist indicator))), one might write (callf (second (getf plist indicator)) #'1+), using any of the normal one argument functions (or lambda-expression) provided by common-lisp or the user. Here is an attempt at code:

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

Will something like this work for all general cases, and can it actually simplify code in practice?

1
  • Is DEFINE-MODIFY-MACRO what you're looking for? Commented Feb 7, 2017 at 21:43

1 Answer 1

2

callf

I think what you are looking for is _f from 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))) 

This uses get-setf-expansion - the workhorse of generalized reference handling.

Note that _f only works with single-value places. IOW, (_f (values a b c) 1+) will not increment all 3 variables. It is not all that hard to fix that though...

can it actually simplify code in practice?

This really depends on your coding style and the specific problem you are solving.

Sign up to request clarification or add additional context in comments.

1 Comment

That's it. Great discussion in OnLisp too.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.