Will ' affect the evaluation of special forms? Example: (function 'function-name). If this doesn't work, why?
'name is read to (quote name).
FUNCTION expects a name for a function, a list (setf some-name) or a lambda expression.
(quote name) is neither. So it is an error to use it.
Related
I'm a Lisp beginner and I'm struggling to understand why the following code gives me an error.
(dolist (elem '(mapcar
mapcon))
(when (fboundp `',elem) (print "hello")))
Thanks.
Edit:
A bit more context. I wrote the following in Elisp and I don't know how to fix it.
(dolist (ui-elem '(menu-bar-mode
tool-bar-mode
tooltip-mode
scroll-bar-mode
horizontal-scroll-bar-mode))
(when (fboundp `',ui-elem) (ui-elem -1)))
Note
In your question you mix common-lisp and elisp, but they are two different languages. The question however touches on concepts that are identical in both languages.
The need to quote symbols
The code you want to write checks if a symbol is bound to a function.
What you already know probably is that you can call fboundp on a symbol to determines this:
(fboundp 'menu-bar-mode)
=> t
When you evalute the above form, 'menu-bar-mode is the same as (quote menu-bar-mode), and is evaluated as the symbol object menu-bar-mode. This is the value that is given as an argument to fboundp.
In you example you want to iterate over a list of symbols, call fboundp on it and call the function if the symbol denotes a function. You can do this as follows:
(dolist (s '(menu-bar-mode and other symbols))
(when (fboundp s)
(funcall s -1)))
The list of symbols '(menu-bar-mode and other symbols) is quoted, which means that when dolist evaluates it, it sees a list of symbols. The value to which s is bound at each iteration of the loop is a symbol object, there is no need to quote them.
Quoting a symbol is something you have to do when writing them in your code so that they are not interpreted as variables. When you iterate over a list of symbols, you already manipulate symbols.
Note also that both Common Lisp and Emacs Lisp are "Lisp-2", meanings that you have to use (funcall ui-elem -1) instead of writing (ui-elem -1). When you write the latter form, that means calling the function literally named ui-elem because for function application, the first symbol in the list is not evaluated, it is taken literally.
Too many levels of quoting
The actual error I have when I execute your code is:
(wrong-type-argument symbolp 'mapcar)
It may look like 'mapcar denotes a symbol, because when you want the interpreter to evaluate some code as a symbol, you need to quote it. However, Lisp printers write objects in a way that they can be read back to "similar" objects. The error message that is printed if I expect a symbol to be a number is the following, where symbol foo is printed unquoted:
(+ 'foo 3)
;; error: (wrong-type-argument number-or-marker-p foo)
In your error message, the form that you are trying to use as a symbol is (quote mapcar). Recall that when you directly call fboundp:
(fboundp 'mapcar)
It is the same as-if you wrote:
(fboundp (quote mapcar))
First, (quote mapcar) is evaluated, as the symbol mapcar. Then, fboundp is applied to that value.
But when you write the following, while ui-elem is bound to symbol mapcar:
(fboundp `',ui-elem)
This is equivalent to:
(fboundp `(quote ,ui-elem))
The argument to fboundp is evaluated as (quote mapcar). You have one extra level of quoting. You could write instead:
(fboundp `,ui-elem)
But then, you don't need to use backquote/comma, you can directly write:
(fboundp ui-elem)
Like the title says this list throws an error
and: bad syntax in: and
but how to write it then, need and in that list?
Best
You cannot use and other than at the beginning of an s-expr because it is a reserved word, it seems.
So outside of that in other positions, you can use it only with quote, else it gives bad syntax error.
The only possibility to let it appear in the end of a list - thus - is:
`(test ,'and)
;; '(test and)
In addition, Racket makes a syntax-check (check whether a variable is bound or not) before evaluating. (And not when evaluating the expression like Common Lisp does).
(if '() whatever 3) ;; `whatever` being a variable not defined before.
;; common-lisp: 3
;; racket: whatever: unbound identifier in module in: whatever
In Common Lisp, since it is a Lisp-2 (different namespaces between function and variable), you can even create/keep a variable with the name and:
;; CL: a variable with the name 'and'
(defvar and 3)
(list 1 and)
;; => (1 3)
However, also in Common Lisp, redefinition of a function and is not allowed:
;; CL: redefine function 'and' - doesn't work:
(defun and (&rest args) (apply #'or args))
;; *** - DEFUN/DEFMACRO: AND is a special operator and may not be redefined.
In Racket, it is impossible to bind sth to a reserved word like and.
So, since Racket is Lisp-1, any redefinition of and is not allowed (neither as variable name nor as a function name), and since Racket does syntax checking for bound variables before evaluating an s-expr - be it a special form/macro or a function - and in any other position than at the beginning of an s-expression cannot occur in Racket without a quote/'.
When you construct lists, you need to quote each element.
Welcome to Racket v6.12.
> (list 'test 'and)
'(test and)
In specified conditions I want to print name of fuction in this function. but I don't know how to get it.
In C++ I can use preprocessor macro __FUNCTION__. I something simmilar in AutoLISP?
This is definitely possible. Let's look at two situations:
1) You're writing the function.
This should be easy, just define a variable that has the same name as the function and you're good to go. (As discussed in the comments above.)
You could even use something more descriptive than the actual name of the function. (defun af () ...) could be called "Awesome Function" instead of "af".
I would also recommend using standard constant value formatting: Capital letters with underscores to separate words. (setq FUNCTION_NAME "AwesomeFunction"). (This is just like PI which is set for you and you shouldn't change it - it's a constant.)
2) You're calling a function that you might not know the name of until the code runs.
Some examples of this:
(apply someFunctionInThisVariable '(1 2 3))
(mapcar 'printTheNameOfAFunction '(+ setq 1+ foreach lambda))
(eval 'anotherFunctionInAVariable)
To print the name of a function stored in a variable - like this (setq function 'myFunction) - you need to use the (vl-princ-to-string) function.
(vl-princ-to-string function) ;; Returns "MYFUNCTION"
(strcase (vl-princ-to-string function) T) ;; Returns "myfunction"
(princ
(strcase
(vl-princ-to-string function)
T
)
) ;; Command line reads: myfunction
The (vl-princ-to-string) function can be used on any type that can be printed and will always return a string. It's great if you don't know whether you have a number or a word, etc.
Hope that helps!
P.S. I first used this technique when I was writing a testing function. Send it a function and an expected value and it would test to see if it worked as expected - including printing the function's name out as part of a string. Very useful if you have the time to setup the tests.
I try to do this directly to the interpret:
(setf example (coerce "blablabla" 'list))
and works fine. Infact (car example) returns #\b
but if I try this:
(defun myfun (string) ( (setf example (coerce string 'list))))
(myfun "blablabla")
I don't get the same!
How can I fix?
Remove the extra parentheses around the setf in the defun:
(defun myfun (string)
(setf example (coerce string 'list)))
Now you'll get the same. Note that the outer parenthesis have meaning. In Lisp, either it is quoted, or must be a function call. If the first element is, as in this case, a list, it cannot be a function to call, hence the error.
My code looks like this:
(eval `(setf (fdefinition name-funct)(lambda ............)))
To create my funct I have used the quote... but name-funct is a variable... How can I get say to the interprets if I use the quote? Does exist a way to do what I want?
* EDIT *
with comma I have this situation
Error: The variable REAL-NAME is unbound.
So I need that the contens of name-funct must be the name of my lambda that I created. But with the comma operator that Greg Hewgill suggest to me Lisp looks for the content of name-funct that is real-name like another variable.
Use the comma:
(eval `(setf (fdefinition ,name-funct)(lambda ............))