I'm trying to write a function primeify that accepts a symbol and returns the symbol with "-prime" appended to it. My desired output is:
[1] > (primeify 'y)
Y-PRIME
(or y-prime, the case isn't the main point here, although it may become relevant later).
Here's my current (erroneous) implementation:
(defun primeify (sym)
(make-symbol (concatenate 'string (string sym) "-prime")))
However, make-symbol is mangling the output by cluttering it with additional formatting. My output is:
[1]> (primeify 'y)
#:|Y-prime|
Is there any way to avoid this additional processing done by make-symbol, or another function I could use to accomplish this? Is this even possible to accomplish in lisp?
Your symbol:
#:|Y-prime|
This is a non-interned symbol. It is in no package. #: is in front of the symbol because of that.
It is also a symbol name with mixed case. Because of that it is escaped with vertical bars. Remember, by default symbol names are internally stored in UPPERCASE.
(defun primeify (sym)
(let ((name (concatenate 'string
(string sym)
"-PRIME")))
(if (symbol-package sym)
(intern name (symbol-package sym))
(make-symbol name))))
Above function gives the new symbol the same package as the original symbol has, if any.
CL-USER 3 > (primeify 'foo)
FOO-PRIME
NIL
CL-USER 4 > (primeify '#:foo)
#:FOO-PRIME
Related
The Lisp forum thread Define macro alias? has an example of creating function alias using a form such as
(setf (symbol-function 'zero?) #'zerop)
This works fine, making zero? a valid predicate. Is it possible to parametrize this form without resorting to macros? I'd like to be able to call the following and have it create function?:
(define-predicate-alias 'functionp)`
My take was approximately:
(defun defalias (old new)
(setf (symbol-function (make-symbol new))
(symbol-function old)))
(defun define-predicate-alias (predicate-function-name)
(let ((alias (format nil "~A?" (string-right-trim "-pP" predicate-function-name))))
(defalias predicate-function-name alias)))
(define-predicate-alias 'zerop)
(zero? '())
This fails when trying to call zero? saying
The function COMMON-LISP-USER::ZERO? is undefined.
make-symbol creates an uninterned symbol. That's why zero? is undefined.
Replace your (make-symbol new) with e.g. (intern new *package*). (Or you may want to think more carefully in which package to intern your new symbol.)
Your code makes a symbol, via MAKE-SYMBOL, but you don't put it into a package.
Use the function INTERN to add a symbol to a package.
To expand on Lars' answer, choose the right package. In this case the default might be to use the same package from the aliased function:
About style:
Anything that begins with DEF should actually be a macro. If you have a function, don't use a name beginning with "DEF". If you look at the Common Lisp language, all those are macro. For example: With those defining forms, one would typically expect that they have a side-effect during compilation of files: the compiler gets informed about them. A function can't.
If I put something like this in a file
(define-predicate-alias zerop)
(zero? '())
and then compile the file, I would expect to not see any warnings about an undefined ZERO?. Thus a macro needs to expand (define-predicate-alias 'zerop) into something which makes the new ZERO? known into the compile-time environment.
I would also make the new name the first argument.
Thus use something like MAKE-PREDICATE-ALIAS instead of DEFINE-PREDICATE-ALIAS, for the function.
There are already some answers that explain how you can do this, but I'd point out:
Naming conventions, P, and -P
Common Lisp has a naming convention that is mostly adhered to (there are exceptions, even in the standard library), that if a type name is multiple words (contains a -), then its predicate is named with -P suffix, whereas if it doesn't, the suffix is just P. So we'd have keyboardp and lcd-monitor-p. It's good then, that you're using (string-right-trim "-pP" predicate-function-name)), but since the …P and …-P names in the standard, and those generated by, e.g., defstruct, will be using P, not p, you might just use (string-right-trim "-P" predicate-function-name)). Of course, even this has the possible issues with some names (e.g., pop), but I guess that just comes with the territory.
Symbol names, format, and *print-case*
More importantly, using format to create symbol names for subsequent interning is dangerous, because format doesn't always print a symbol's name with the characters in the same case that they actually appear in its name. E.g.,
(let ((*print-case* :downcase))
(list (intern (symbol-name 'foo))
(intern (format nil "~A" 'foo))))
;=> (FOO |foo|) ; first symbol has name "FOO", second has name "foo"
You may be better off using string concatenation and extracting symbol names directly. This means you could write code like (this is slightly different use case, since the other questions already explain how you can do what you're trying to do):
(defmacro defpredicate (symbol)
(flet ((predicate-name (symbol)
(let* ((name (symbol-name symbol))
(suffix (if (find #\- name) "-P" "P")))
(intern (concatenate 'string name suffix)))))
`(defun ,(predicate-name symbol) (x)
(typep x ',symbol)))) ; however you're checking the type
(macroexpand-1 '(defpredicate zero))
;=> (DEFUN ZEROP (X) (TYPEP X 'ZERO))
(macroexpand-1 '(defpredicate lcd-monitor))
;=> (DEFUN LCD-MONITOR-P (X) (TYPEP X 'LCD-MONITOR))
(defmacro flycheck-define-clike-checker (name command modes)
`(flycheck-declare-checker ,(intern (format "flycheck-checker-%s" name))
,(format "A %s checker using %s" name (car command))
:command '(,#command source-inplace)
:error-patterns
'(("^\\(?1:.*\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\): error: \\(?4:.*\\)$"
error)
("^\\(?1:.*\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\): warning: \\(?4:.*\\)$"
warning))
:modes ',modes))
(flycheck-define-clike-checker c
("gcc" "-fsyntax-only" "-Wall" "-Wextra")
c-mode)
Above is the code that i took from https://github.com/jedrz/.emacs.d/blob/master/setup-flycheck.el
It doesn't do anything much apart from defining a checker for flycheck which can be found https://github.com/lunaryorn/flycheck
My problem is trivial and i have already spent a day on it and i am more confused.
The second part of the code uses the defined macro to call flycheck to register a compiler
(flycheck-define-clike-checker c
("gcc" "-fsyntax-only" "-Wall" "-Wextra")
c-mode)
Above code works perfectly.
But since i wanted my compiler to have some dynamic includes et all, I have a variable defined as
(defvar efx-flycheck-c-command '("gcc" "-fsyntax-only" "-Wall" "-Wextra"))
when i pass that to the macro like
(flycheck-define-clike-checker c
efx-flycheck-c-command
c-mode)
i receive a compilation error
Debugger entered--Lisp error: (wrong-type-argument sequencep efx-flycheck-c-command)
append(efx-flycheck-c-command (source-inplace))
(list (quote quote) (append command (quote (source-inplace))))
(list (quote flycheck-declare-checker) (intern (format "flycheck-checker-%s" name)) (format "A %s checker" name) (quote :command) (list (quote quote) (app$
(\` (flycheck-declare-checker (\, (intern (format "flycheck-checker-%s" name))) (\, (format "A %s checker" name)) :command (quote ((\,# command) source-in$
(lambda (name command modes) (\` (flycheck-declare-checker (\, (intern (format "flycheck-checker-%s" name))) (\, (format "A %s checker" name)) :command (q$
(flycheck-define-clike-checker c efx-flycheck-c-command c-mode)
eval((flycheck-define-clike-checker c efx-flycheck-c-command c-mode) nil)
eval-last-sexp-1(nil)
eval-last-sexp(nil)
call-interactively(eval-last-sexp nil nil)
I guess i confused in how the macro expands in elisp.
Please help!
As a general rule, you're better off using a defun than a defmacro, except when defun is really inconvenient/impossible to use. In your case, a defun indeed makes more sense. The only downside is that you need to quote the c and c-mode arguments.
You need to decide whether you want the command argument to be evaluated or unevaluated. An unevaluated argument allows you to type lists without quoting them, i.e. ("gcc" "-Wall") instead of '("gcc" "-Wall"), at the cost of not being able to pass a variable as the argument. An evaluated argument enables you to provide variables (or indeed arbitrary expressions) to the macro, at the cost of having to quote simple lists.
Normally, to evaluate the macro argument in backticks, you'd just use the , operator. However, you're already using the ,# operator, and you're mentioning command twice, so it's better to explicitly evaluate it using eval:
(defmacro flycheck-define-clike-checker (name command modes)
(let ((command (eval command)))
`(flycheck-declare-checker ,(intern (format "flycheck-checker-%s" name))
,(format "A %s checker using %s" name (car command))
:command '(,#command source-inplace)
:error-patterns
'(("^\\(?1:.*\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\): error: \\(?4:.*\\)$"
error)
("^\\(?1:.*\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\): warning: \\(?4:.*\\)$"
warning))
:modes ',modes)))
With the power of defmacro at your disposal, you can even go one step further and define that the macro is evaluates if it is a symbol, otherwise it's used as-is. This would allow you to have your cake and eat it, i.e. be able to pass both variable names and literal lists. The cost of this would be reduced consistency with normal evaluation rules—you would be able to pass a list or a variable, but not an arbitrary expression such as a function call, which would unpleasantly surprise the users of the macro. Because of that the implementation is left as an exercise for the reader.
I realized that a certain section of my code consists of groups of methods that look similar (like I have multiple trios: a helper function that gets called by two other functions meant for the programmer). I'm trying to write a macro that will define these three functions for me so that all I need to do is call the macro. But my attempt results in defuns and function calls that have quoted strings instead of the generated names as new symbols. What am I doing wrong?
Example (incorrect code)
(defmacro def-trio (base-name)
(let
((helper-name (format nil "helper-~a" base-name))
(method-1 (format nil "~a-1" base-name))
(method-2 (format nil "~a-2" base-name)))
`(progn
(defun ,helper-name () 'helper-called)
(defun ,method-1 () (,helper-name) '1-called)
(defun ,method-2 () (,helper-name) '2-called))))
Now the following happens:
(def-trio my-trio)
==>
(PROGN (DEFUN "helper-MY-TRIO" () 'HELPER-CALLED)
(DEFUN "MY-TRIO-1" () ("helper-MY-TRIO") '1-CALLED)
(DEFUN "MY-TRIO-2" () ("helper-MY-TRIO") '2-CALLED))
Also, after I learn how to get this working, are there any extra gotcha's if I had this macro define other macros instead of other functions? I read How do I write a macro-defining macro in common lisp but I think my question is a little different because I'm asking about programmatically generated symbols/names. I'm open to being corrected though :) Thanks!
Try this:
(defmacro def-trio (base-name) ; changes:
(let* ; 3.
((package (symbol-package base-name)) ; 2.
(helper-name (intern (format nil "HELPER-~a" base-name) package)) ; 1. 4.
(method-1 (intern (format nil "~a-1" base-name) package)) ; 1.
(method-2 (intern (format nil "~a-2" base-name) package)) ) ; 1.
`(progn
(defun ,helper-name () 'helper-called)
(defun ,method-1 () (,helper-name) '1-called)
(defun ,method-2 () (,helper-name) '2-called) )))
The following changes were made to your original definition -- the first change is the crucial one:
Interned each of computed symbol names into the same package as the base name using (intern ... package).
Introduced the variable package which is bound to the package of the supplied base-name symbol.
Changed let to let* to allow the newly introduced variable package to be referenced in subsequent variables.
Changed the prefix of the helper method to upper case to match the convention for normal Lisp symbols.
Use INTERN to turn the generated function name strings into symbols.
To be brief. Here is my several tries to intern and use a symbol in clisp.
[1]> (setq sym (intern "foo"))
|foo|
[2]> (eq sym 'foo)
NIL
Why???
[3]> (defun internup (me &optional (package *package*))
(intern (string-upcase me) package))
INTERNUP
[4]> (eq 'abc (internup "abc"))
T
Probably must be upcase.
[12]>(let ((abc 2))
(eval '(+ 2 abc)))
*** - EVAL: variable ABC has no value
The following restarts are available:
ok
[18]> (let ((abc 2))
(eval '(+ 2 'abc)))
*** - +: ABC is not a number
The following restarts are available:
Interesting. Should I set it before.
[14]> (setq a (internup "abc"))
ABC
[15]> (let ((abc 2))
(eval '(+ 2 a)))
*** - +: ABC is not a number
The following restarts are available:
And again wrong. Hmm I must be missing some important fact about interning symbols in LISP. Can you help me ?
Your problem has nothing to do with interning.
The first problem is indeed causes by the fact that the reader will always uppercase the symbols, so you need to call (intern "FOO") in order to get the same result as 'foo.
The problem with EVAL is caused by the fact that LET introduces a lexical binding which is not visible inside EVAL. If you really want this to work you'd have to declare abc to be special, like so:
(let ((abc 2))
(declare (special abc))
(eval '(1+ abc)))
A special declaration will cause the variable to have dynamic binding, instead of lexical binding (the latter means that the binding is limited to the local lexical context, i.e. within the LET form. With the special declaration the variable is available to anything that is called by from that form).
Note that the use of both special declarations and eval is something you should be very careful about and you should probably rethink your use of EVAL in the first place. It is very rare that you actually need to use it. In most cases you're actually looking for the use of lambda functions instead.
Eval evaluates the form in the null lexical environment, i.e. with no lexical bindings. That has nothing to do with the interning of symbols.
The case-sensitivity of the Common Lisp reader is determined by the readtable:
(readtable-case *readtable*)
Typically the reader will initially intern symbols in uppercase (unless you explicitly escape characters). Hence:
(eq (intern "foo") 'foo) => NIL
(eq (intern "FOO") 'foo) => T
(eq (intern "FOo") 'fo\o) => T
You can use backquote syntax to build the form for eval:
(let ((abc 2))
(eval `(+ 2 ,abc)))
=> 4
I'm trying to write a macro in emacs lisp to create some ‘helper functions.’
Ultimately, my helper functions will be more useful than what I have here. I realize that there may be better/more intuitive ways to accomplish the same thing (please post) but my basic question is why won't this work/what am I doing wrong:
(defmacro deftext (functionname texttoinsert)
`(defun ,(make-symbol (concatenate 'string "text-" functionname)) ()
(interactive)
(insert-string ,texttoinsert)))
(deftext "swallow" "What is the flight speed velocity of a laden swallow?")
(deftext "ni" "What is the flight speed velocity of a laden swallow?")
If I take the output of the macroexpand and evaluate that, I get the interactive functions I was intending to get with the macro, but even though the macro runs and appears to evaluate, I can't call M-x text-ni or text-swallow.
This does what you want:
(defmacro deftext (functionname texttoinsert)
(let ((funsymbol (intern (concat "text-" functionname))))
`(defun ,funsymbol () (interactive) (insert-string ,texttoinsert))))
As has been pointed out, the solution is to use intern instead of make-symbol.
It's possible to create multiple independent symbols with the same name, but only one of them can be the canonical symbol for the given name -- i.e. the symbol you will obtain when you refer to it elsewhere.
intern returns the canonical symbol for the given name. It creates a new symbol only if no interned symbol by that name already exists. This means that it will only ever create one symbol for any given name1.
make-symbol, on the other hand, creates a new symbol every time it is called. These are uninterned symbols -- each one is a completely valid and functional symbol, but not the one which will be seen when you refer to a symbol by its name.
See: C-hig (elisp) Creating Symbols RET
Because defun returns the symbol it sets, you can observe what's going on by capturing the return value and using it as a function:
(defalias 'foo (deftext "ni" "What is the flight speed velocity of a laden swallow?"))
M-x text-ni ;; doesn't work
M-x foo ;; works
or similarly:
(call-interactively (deftext "shrubbery" "It is a good shrubbery. I like the laurels particularly."))
The tricky part in all this -- and the reason that evaluating the expanded form did what you wanted, and yet the macro didn't -- is to do with exactly how and when (or indeed if) the lisp reader translates the name of the function into a symbol.
If we write a function foo1:
(defun foo1 (texttoinsert) (insert-string texttoinsert))
The lisp reader reads that as text, and converts it into a lisp object. We can use read-from-string to do the same thing, and we can look at the printed representation of the resulting lisp object:
ELISP> (car (read-from-string "(defun foo1 (texttoinsert) (insert-string texttoinsert))"))
(defun foo1
(texttoinsert)
(insert-string texttoinsert))
Within that object, the function name is the canonical symbol with the name "foo1". Note, however, that the return value we see from read-from-string is only the printed representation of that object, and the canonical symbol is represented only by its name. The printed representation does not enable us to distinguish between interned and uninterned symbols, as all symbols are represented only by their name.
(Skipping ahead momentarily, this is the source of your issue when evaluating the printed expansion of your macro, as that printed form is passed through the lisp reader, and what was once an uninterned symbol becomes an interned symbol.)
If we then move on to macros:
(defmacro deffoo2 ()
`(defun foo2 (texttoinsert) (insert-string texttoinsert)))
ELISP> (car (read-from-string "(defmacro deffoo2 ()
`(defun foo2 (texttoinsert) (insert-string texttoinsert)))"))
(defmacro deffoo2 nil
`(defun foo2
(texttoinsert)
(insert-string texttoinsert)))
This time the reader has read the macro definition into a lisp object, and within that object is the canonical symbol foo2. We can verify this by inspecting the object directly:
ELISP> (eq 'foo2
(cadr (cadr (nth 3
(car (read-from-string "(defmacro deffoo2 ()
`(defun foo2 () (insert-string texttoinsert)))"))))))
t
So for this macro, it is already dealing with that canonical symbol foo2 before any macro call/expansion happens, because the lisp reader established that when reading the macro itself. Unlike our previous simple function definition (in which the function symbol was determined by the lisp reader as the function was defined), when a macro is called & expanded the lisp reader is not utilised. The macro expansion is performed using pre-existing lisp objects -- no reading is necessary.
In this example the function symbol is already present in the macro, and because it is the canonical symbol we could use (foo2) elsewhere in our code to call that function. (Or, had I made the definition interactive, use M-x foo2.)
Finally getting back to the original macro from the question, it's obvious that the lisp reader never encounters a function name symbol for the function it will define:
ELISP> (car (read-from-string "(defmacro deftext (functionname texttoinsert)
`(defun ,(make-symbol (concatenate 'string \"text-\" functionname)) ()
(interactive)
(insert-string ,texttoinsert)))"))
(defmacro deftext
(functionname texttoinsert)
`(defun ,(make-symbol
(concatenate 'string "text-" functionname))
nil
(interactive)
(insert-string ,texttoinsert)))
Instead this object produced by the lisp reader contains the expression ,(make-symbol (concatenate 'string "text-" functionname)); and that backquoted expression will be evaluated at expansion time to create a new uninterned symbol which will be a part of the object created by that expansion.
In our earlier examples the resulting object had a car of defun (interned), and a cadr of foo1 or foo2 (both also interned).
In this last example, the object has a car of defun (interned) but a cadr of an uninterned symbol (with the name resulting from the concatenate expression).
And finally, if you print that object, the printed representation of that uninterned function symbol will be the symbol name, and reading that printed representation back by evaluating it would cause the function cell for the canonical symbol to be defined instead.
1 In fact the unintern function can be used to unintern a symbol, after which calling intern for the same name would naturally create a new symbol; but that's not important for this discussion.
FWIW, if you use lexical-binding, you don't need to use a macro:
(defun deftext (functionname texttoinsert)
(defalias (intern (concat "text-" functionname))
(lambda ()
(interactive)
(insert-string texttoinsert))))
It's been years, but I think you're probably missing an fset to define the function; see the docs if you are wanting it a compile time too.