What could go wrong when I define a macro and just use a rare enough name for a temporary variable?

Let the Lambda Chapter 3 of the Unwanted Grab Section read:

โ€œOf course, we can think of rare enough names so that the problem never appears. Yes, in many cases, packages and smart name names can solve the problem of variable capture. However, most serious errors with variable capture do not occur in code directly created by the programmer. Most "Capture only has variable problems when other macros use your macro (in combination with your macro) in ways you did not expect. "

and then it does not give me an example for the bold part. What would be one such example? Imagine a hypothetical Lisp development team where its crazy boss forbade the use of gensym or anything that creates uninterrupted characters, and programmers simply resort to throwing alphanumeric dice to come up with random variable names, like temp-27s63f8sk2n or sum-3t84hj4df, when they miss gensym. What could be an example when a team gets into trouble?

Speaking of which, Emacs 24.3.1 defines bunkers and dolists without the use of non-integer characters. Weird

+8
scope macros lisp
source share
2 answers

Well, then I would suggest automating this "throwing alphanumeric dice" process. Of course, this should not be random; you can just use a counter. In addition, it would be nice to specify a prefix for debugging. Oh wait, thatโ€™s exactly what gensym does.

+2
source share

The problem arises when you reuse your own macro in some other context, and your smart variables with names are efficiently redundant then, since they are all in the same namespace.

I can come up with an example when a closure is used that accesses the variable in the application (let) , but is passed to a macro that also uses a closure (let) that defines a "safe" variable with a name conflict. This is a contrived example, sorry, I canโ€™t think about the real world right now.

 (defmacro my/a (x) (let ((my/safe-name x)) `(progn ,(my/b (lambda () my/safe-name)) ,my/safe-name))) (defmacro my/b (f) `(let ((my/safe-name 4)) (when (evenp (funcall ,f)) (print "F is even!")))) (my/a 3) ; will print "F is even", but it shouldn't 
+1
source share

All Articles