Emacs 24 will have actual lexical binding, but until that becomes the standard, we've got to satisfy ourselves with
lexical-let form, a codewalker which does some magical things to simulate lexical scope. Today I discovered the following corner case when combining lexical and dynamic scope on variables with the same name. Consider:
(setq x "Hi there") (defun return-x () x) (return-x) -> "Hi there" (let ((x "Yo.")) (return-x)) -> "Yo." ; Dynamic scope in action, 'x is shadowed. (lexical-let ((x "Yo.")) (return-x)) -> "Hi there." ; lexical-let doesn't create a dynamic binding, so x ; is not shadowed (lexical-let ((x "Yo.")) (let ((x x)) (return-x))) -> "Hi there", but should be "Yo." ; This is unexpected behavior.
What is the problem? The
let expression in the last example is rewritten by the codewalker, which replaces the x in the binding form with a hidden name. This prevents
x from being dynamically bound, even though the
let should shadow the
return-x. I am not sure if there is a way around this that isn't incredibly baroque. Probably best to just be aware of it.