1

I found this snippet of code from oremacs

(defmacro csetq (variable value)
  `(funcall (or (get ',variable 'custom-set) 'set-default) ',variable ,value))

I would like to expand this macro so that is can take multiple pairs of arguments similar to setq (e.g. (csetq foo 'bar fod 'baz str "a") etc). I made an initial attempt, but it always returns nil and leaves me with a lot of nested progn forms when expanded.

(defmacro csetq (variable value &rest rest)
  (when variable
      `(progn (funcall (or (get ',variable 'custom-set) 'set-default) ',variable ,value)
              (csetq ,(car rest) ,(cadr rest) ,(cddr rest)))))

Is there a way to fix this macro so that it returns the last value set (similar to setqand does not nest?

Prgrm.celeritas
  • 849
  • 6
  • 15
  • It returns `nil` because this is the terminating condition for your recursion, i.e. `when` will evaluate to `nil` when you exhausted the list of `rest`. You can change the terminating condition to be a test for single last element instead. – wvxvw Aug 21 '18 at 11:58

1 Answers1

1

There are many options, but here's one approach:

(defmacro csetq (&rest pairs)
  "For each SYMBOL VALUE pair, calls either `custom-set' or `set-default'."
  (let (forms)
    (while pairs
      (let ((variable (pop pairs))
            (value (pop pairs)))
        (push `(funcall (or (get ',variable 'custom-set) 'set-default)
                        ',variable ,value)
              forms)))
    `(progn ,@(nreverse forms))))
phils
  • 48,657
  • 3
  • 76
  • 115
  • While for illustration purposes this is OK, in principle, this requires storing the value of evaluation of `,variable` and reusing it. It may be an expression, not necessarily a symbol, in which case you may get inconsistent results. – wvxvw Aug 21 '18 at 12:01
  • It's a good point, but I don't think it's an issue here in practice. I believe the intention was that it would always be a symbol; and in any case `(get ',variable 'custom-set)` necessitates that the value of `variable` is a symbol, no? – phils Aug 21 '18 at 13:10
  • yes @phils is right, just as `setq` auto-quotes the variable argument, this macro does the same. – Prgrm.celeritas Aug 21 '18 at 15:14