How do you go about solving this problem?
Suppose I want to write a function that does the following: if the user has library X installed, then use function X-function, otherwise - skip?
What I tried:
(when (symbol-function 'X-function)
(X-function))
I'm getting a warning for this code - so what is the right way?
How about this:
(when (fboundp 'X-function)
(X-function))
The docs at http://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Cells.html says about symbol-function
If the symbol's function cell is void, a void-function error is signaled.
I'm guessing that is what you are seeing. On the other hand, fboundp just returns t or nil depending on whether the function exists.
The way to suppress this compiler warning is with something like:
(declare-function X-function "ext:X-library.el")
(when (fboundp 'X-function)
(X-function))
Here X-library is the name of the library that X-function is defined in when the library is there. The byte-compiler will then do the following:
It will look for the library in the load path.
If it finds it, it will check that the function has been defined.
If it does not find the library it will assume that it will be when the library is there and pass on without error.
Thus if there is no X-library it won't complain, but if there is one and it does not define the function then it will. This means that if an updated version of the library does not contain X-function then you will know when you try to re-compile your code.
If you look up the documentation for declare-function you will find that it can also check the argument list of functions.
Incidentally If you get similar warnings about undeclared variables you can suppress these with:
(defvar X-variable)
However it is important not to set the variable even if you know what value the library sets it to as this could change in a later version.
This gives you one version of the program that works whether or not X-library is present. You might prefer to have two versions, one for when X-library is present and one for when it is not. This can be done with a macro:
(defmacro run? (function &rest args)
"Expand to function call if function exists."
(when (fboundp `,function)
`(,function ,#args)))
Now instead of a call like:
(X-function a1 a2 a3)
You write:
(run? X-function a1 a2 a3)
If you compile it with X-library present this expands to the call to X-function. If the library is not present then it expands to nothing at all. You will not need the declare-function in any case. This gives two different versions, but it should be more efficient because the decisions as to whether the library is there or not are taken at compile time not run time.
One small caveat. If you go for this second solution you must either compile the whole program in the X-library environment or outside it. If you try loading the library half way through the program then when interpreted it will work as you might expect with the macro expanding differently before and after the load. But in a compiled program a macro is only expanded once. The test test for the library is in code that does the expanding not in the expansion, so the macro will not work the same before and after the load.
Another case when you can get the warning that a function cannot be found is when you define a function programmatically and use fset to set it. The following example illustrates this and what to do about it:
(eval-and-compile
(fset 'my-function1 (lambda () nil)))
(my-function1)
(fset 'my-function2 (lambda () nil))
(my-function2)
(my-function3)
(eval-and-compile
(fset 'my-function3 (lambda () nil)))
If you compile this you get the warnings:
Warning: the function `my-function2' is not known to be defined.
and:
Warning: the function `my-function3' might not be defined at runtime.
The second warning goes away if you re-compile the code a second time in the same Emacs session, but the first doesn't.
What is happening here is this: When the compiler sees eval-and-compile, it first evaluates the body of the in the current Emacs session and then compiles it. Having evaluated the code, Emacs knows about the programmatically defined function.
In the case of function1, the byte compiler sees the function call after Emacs has evaluated the form and so you don't get any warnings.
In the case of function2 the byte compiler never knows the functions is defined so you always get a warning.
In the case of function3, the first time round, the bite compiler doesn't know the function exists when it sees the function call. By the end of the compilation it knows the function exists but it isn't intelligent enough to work out how it knows so you get a different warning. However, if you re-compile it in the same Emacs session, it does know so the warning goes away.
Note that eval-and-compile, like eval-with-compile, look like a progn to the Emacs interpreter.
Related
i don't know why NOT is defined as function but macro.i've heard that function call may be cache-unfriendly.
will it be better if NOT is a macro?the only reason i can think of is that a NOT function can be passed as value by adding #'.
grateful for your answers!
not has the semantics of a function: its argument is evaluated perfectly normally (unlike, say, and and so on). It should therefore be a function: macros should be used only for things which cannot semantically be functions.
Making not a function has benefits: simply because it is a function you don't need to write your own version every time you need a function with the semantics of not. Making not a function also has zero cost since the semantics of CL leave a compiler or interpreter entirely free to never actually call the function but rather generate inline code.
Indeed you can see, for instance, in the SBCL sources that this is happening: in src/code/pred.lisp you will find
(defun not (object)
"Return T if X is NIL, otherwise return NIL."
(not object))
You can do this yourself, pretty much:
(declaim (inline neg))
(defun neg (x)
(if x nil t))
(And if you are really feeling your oats define a compiler macro as well, although I can't see any strong reason to do that here.)
Is it possible to expand a macro at run time in a compiled lisp executable? I would expect it to be impossible as macro expansion can only happen pre-compilation yet when i call macroexpand in compiled code i get output.
A macro is a function that's normally called automatically during compilation or evaluation, and whose return value is then compiled or evaluated in place of the original expression.
But since it's just a function, there's nothing preventing it from being called explicitly during run time as well, and that's what MACROEXPAND and MACROEXPAND-1 do.
It's roughly equivalent to:
(defun macroexpand-1 (form &optional env)
(if (and (listp form) (car form)) ;; list expression
(let ((macfun (macro-function (car form)))
(if macfun
(funcall macfun form env)
form))
form))
(Note that this definition doesn't handle symbol macros or use *MACROEXPAND-HOOK*, to keep it simple.)
It's possible to use EVAL-WHEN when defining the macro to make the macro definition only available in the compilation environment. If you do that, trying to expand at run time will fail.
In Lisp, the terms "run time" and "compile time" are situations in which a particular piece of code is being processed, not absolutes like in some static languages. If we evaluate (compile nil '(lambda ())), this is the compile function's run-time, but the lambda form's compile time: both times are happening at the same time.
The entire language is available in all situations. When you build a self-contained executable, that image contains not only support for expanding macros, but for compiling code. Your Lisp application can call compile-file to compile Lisp source to object form, and load to load the resulting object code.
The process of removing garbage, and unused functionality from a Lisp application image to make it smaller is called "tree shaking". If you don't want the compiler or macro expander in your application, find out whether/how they can be removed with your implementation's tree shaking support.
(defmacro create-function (function-name)
`(defun ,function-name ()
"Say hello to world."
(interactive)
;; A heavy function body here
(message ,(symbol-name function-name))))
It demonstrates a macro defining a function.
I am writing a package to let user create a function with desired name and corresponding usage. The function created will be used globally (in other words, it is not mode specific). However, the user may or may not really need the function. But once they need, the function needs to be available.
(create-function foobar1)
(create-function foobar2)
;; ....................
(create-function foobar20)
This (create-function x) is likely to be put in user's config file and expanded at startup time so that the function is prepared. So, I think autoloading the macro is meaningless.
However, the function created may not be always needed and there is no pattern when the user need. In addition, the function is not use very often, say, only use three of them per session. So, my idea is to autoload the function.
Unlike normal function, this functions are defined in a macro body. Autoload may not be able to find the function definition at runtime.
I also tried to make a prototype macro like this:
(defmacro create-function-prototype (function-name)
`(defun ,function-name ()
(interactive)
(create-function ,function-name)
(call-interactively (quote ,function-name)))
My another idea is to create a blank function with no function body first. It seems to be working. Does the flow work as expected?
To sum up, there are three questions
Is autoloading this macro meaningful?
Can I autolaod function defined in a marco?
Is the prototype method working?
Here's the setup:
(defun square (x)
(* x x))
;; square
(symbol-function 'square)
;; (lambda (x) (* x x))
(byte-compile 'square)
;; #[(x) "\211_\207" [x] 2]
(symbol-function 'square)
;; #[(x) "\211_\207" [x] 2]
Is there a way to get the source (lambda (x) (* x x)) after square has been byte-compiled?
The two uses that I can think of are inlining the current function call
and doing a debug-step-in.
I've tried messing with find-definition-noselect to get the source,
but I wonder if there's a better way, because it sometimes raises
(error "Don't know where ... is defined")
Emacs keeps track of which function name is defined in which file (this info is kept in load-history). To find the definition, Emacs looks in load-history and if the function is listed there, it looks for the corresponding source file and then in that file looks for something that looks like a likely definition of the function (using regexps). That's what find-definition-noselect does.
As for the source code, no in general Emacs does not keep the source definition. If you define the function with cl-defsubst, then the source is kept around, but otherwise it isn't. For Edebugging, having the source wouldn't help anyway (because Edebug needs not just the source cod but also the precise location of each sub-expression); for plain debugging the source is not really needed either (you can always click on the function's name to jump to the source); for inlining the source is not needed either (the byte-compiler can inline at the source-code level, indeed, but it can just as well inline at the byte-code level).
There is no way to obtain the source of a function object. Byte compilation is no injective function, so you cannot revert it. Even disregarding macro expansion, there is no direct mapping from opcodes to Lisp expressions.
I do not see use cases for this anyway.
Debugging
To step into functions for debugging, navigate to its definition (i.e. find-definition) and instrument the definition for debugging (e.g. with edebug). That's the only way to reasonably debug Emacs Lisp functions. You can't use the contents of the function cell for debugging, because it's subject to macro expansion.
As such, the function cell may look completely different from the actual definition. If you find a bug in the function cell, you'll struggle to find the same bug in the actual function definition.
Inlining
For inlining, use macros or defsubst to define inline functions in Emacs Lisp. However, be careful to not accidentally expose these on the public interface of your library, since compile time inline functions impose a compile time dependency onto your library, so a dependent library needs to be recompiled for every release of your library. And since package.el doesn't support that yet, macros and substitutions can easily cause havoc.
Byte compiling emacs lisp is pretty useful, as it generates compiler warnings that, though sometimes cryptic, always point at an error or unfinished tasks, such as missing imports or unimplemented functions.
However, I cannot find a way to generate custom compiler-warnings that integrate well with the *Compile-Log* buffer, i.e. that show the position of the error like
mymodule.el:247:1:Warning: Unused lexical variable `file-name'
E.g. I'm using the subsequent code for placing todo items that raise compile-time messages:
(eval-when-compile
(defmacro TODO (string)
`(eval-when-compile
(message "TODO: %s" ,string))))
However, I cannot find a way to add information (at compile-time) on
file name
line-number
At load-time the variable load-file-name is available, but it is nil at compile-time. The variable default-directory is defined at compile-time but doesn't help in this case.
For the line-number I know no method at all.
When using (warn ...) instead, I get something like
Warning (emacs): TODO: Complete or remove
i.e. no position information at all. If I use (error ...), I get the line number etc displayed automatically, but compilation stops instead of showing all errors and warnings, so it is not a viable solution either.
Update
A partial solution seems to be
(funcall (if byte-compile-current-file 'byte-compile-warn 'warn) FORMAT [ARGS ...])
You need to use the internal variables byte-compile-current-file (the name of the file being compiled) and byte-compile-read-position (the character position at the start of the last read).
Alternatively, you can try the function byte-compile-warning-prefix which inserts the file:line prefix in the *Warnings* buffer.
Either way, you are on your own, messing with the Emacs internals; SO is your only friend. :-)
Indeed, that was a problem. And even byte-compile-read-position is fairly poor because it's not yet up-to-date when the macro is expanded. In Emacs's trunk there is macroexp--warn-and-return, tho as the -- implies, it's currently still considered internal. E.g.
(defmacro TODO (string)
(macroexp--warn-and-return
(format "TODO: %s" string)
nil))
To understand how to use it, you have to understand that it works by returning a special piece of code which makes the byte-compiler later on (when the line-info is available) emit the message.