(defmacro ++ ...)

TorgoX on 2006-07-07T10:21:52

Dear Log,

Today's inane new elisp macro of mine:

(defmacro ++ (x)
  "increment the value of symbol X, returning the new value"
  `(setq ,x (1+ ,x))
)

So this:

(++ lines)

is a handy shorthand that expands to this:

(setq lines (1+ lines))
  ; returns new value of the variable


your macro

jjore on 2006-07-08T18:03:31

You've just evaluated x twice when the person writing (++ x) expected x to be evaluated once.

I consulted the manual and came up with this which doesn't work because the original x isn't getting updated anymore.

(defmacro ++ (x)
    "Increment the value of symbol X, returning the new value"
    (let ((xt (make-symbol "quoted-x")))
        `(let ((,xt (quote ,x)))
              (set ,xt (+ 1 (eval ,xt))))))

This fixes three bugs. x is evaluated only once. I'm getting a new variable QUOTED-X to store my temp stuff in and not letting it sneak out. I'm treating expression as quoted on the left side and executing it on the right. Um... I *hope* that's sufficient to remove the bugs.

Macros are stupidly hard.

Re:your macro

TorgoX on 2006-07-09T02:24:25

You've just evaluated x twice when the person writing (++ x) expected x to be evaluated once.

Oh, I didn't think of that! I was only thinking of passing in a symbol constant. But now I see what you mean.

As to the general hardness of Lisp macros: I'm glad it's not just me that thinks that.

Maybe there's just some kind of magic syntax-highlighty thing in (e)lisp mode that will turn on all the happy macro easiness or something.

Emacs is a pathless land.

Re:your macro

jjore on 2006-07-09T03:36:39

I goofed slightly. I'd written an earlier version which didn't work and it looks like I left the text that mentioned that it didn't work. The one I eventually posted does work.

As for making macros easier, I'm sure the Scheme folks have stuff on this. I'm a novice at this but I could guess that you might write something to check that each value is only used once. Something to do with data flows maybe.

incf?

arc on 2006-07-17T15:34:47

See also the incf macro from cl.el:

(incf x)
(incf (car x))
(incf x 23)

It's definitely too hard to write such things from scratch in Lisp. cl.el also has callf and define-modify-macro macros which help somewhat.