Disclaimer: I do not know Emacs Lisp, but I know Lisp.
I believe that you are working, this is a confusion of reading / printing with non-integer characters. That is, I suspect that (make-symbol ...) in Emacs Lisp, like a similar function in other dialects such as Common Lisp, creates a new symbol object that has nothing to do with the symbol of the same name that is being scanned from printed notation (from file, terminal, line, buffer editing, ...).
Your code works when you grab the printed output of your code generation function (also called an S-expression), because the printed notation of the four character is read in Lisp and interned, which causes the notation to become the same object as the name of the four function .
But (make-symbol "four") is another symbol object. When you use eval for code that exits your function, you use the data structure directly, and therefore, your error is not covered by reducing the code to text and reading it. The character is not converted to the four token and back to the four object through internment. eval will see your original character that came from make-symbol : the same machine pointer to the same piece of memory.
(In general, Lisp, the "uninterterned" character coming from (make-symbol "four") is usually printed using a hash point, such as #:four so you can find them. (Actually, #: means a symbol without a home package, not uninterned, but this is a very obscure Common Lisp subtlety.))
In any case, find a function called intern . (intern "four") will search for an existing character with this name and return it, rather than creating a new one.
;; two symbol interns for same name result in the same object ;; we are comparing the same pointer to itself (eq (intern "foo") (intern "foo")) -> t ;; two symbol constructions result in two different object ;; two different pointers to separately allocated objects (eq (make-symbol "foo") (make-symbol "foo")) -> nil
Also:
You really need to learn backquote if you want to write code that generates code. Otherwise, you do this in 1960, and not in modern 1970:
;; don't let your friends do this: (defun makeplusser (x) (list 'defun (make-symbol (format "%s+" x)) '(y) (list '+ (list x) 'y))) ;; teach them this: (defun makeplusser (x) `(defun ,(intern (format "%s+" x)) (y) (+ (,x) y))) ;; even more clearly, perhaps (defun makeplusser (func-to-call) (let ((func-name (format "%s+" x))) `(defun ,func-name (arg) (+ (,func-to-call) arg))))
When to use make-symbol
Use make-symbol when you need to create a guaranteed unique symbol (not the same object as any other symbol), even if it has the same name as other symbols. Other Lisp dialects also have a function called gensym , which is similar to make-symbol , but also adds an incremental digital mark to the name so that it is easier to distinguish between these "gensyms" when several occur in the same context. gensym much more commonly used than make-symbol in Lisps that use it. Unique characters are useful when generating code (macros) to create unique shortcuts for things that should be completely invisible to the surrounding code, such as temporary local variables in the built-in code block. Your function argument must be a unique character:
;; even more clearly, perhaps (defun makeplusser (func-to-call) (let ((func-name (format "%s+" x)) (arg-sym (make-symbol "arg")) `(defun ,func-name (,arg) (+ (,func-to-call) ,arg))))
The reason is this: Emacs Lisp has a dynamic scope. If we call the argument y , there is a risk that the function called by the user, for example (four) , may contain a reference to y , where the programmer's intention is to achieve his own variable y . But your generated function accidentally captures the link!
Using gensym for an argument, we avoid this problem; there is no chance that the user code may refer to an argument: we have achieved "hygiene" or "transparency."