I'm looking for an expression that will cause the interpreter to exit when it is evaluated.
I've found lots of implementation-specific ones but none in the HyperSpec, and I was wondering if there were any that I wasn't seeing defined in the specification. I've found that (quit) is recognized by both CLISP and SLIME, and (exit) is recognized only by CLISP, but I can't find any documentation that references either of these.
Since most Lisps import a quit function into CL-USER, CL-USER::QUIT is a good guess without knowing the implementation specific package where it is.
(cl-user::quit)
Note the two colons, since QUIT does not need to be exported from the CL-USER package.
As far as I know, this is not covered by the Spec, and you will have to use the implementation-specific solutions, or maybe try and look if someone has already written a trivial-quit lib (or start one on CLiki).
If you only care about interactive use, ,q in SLIME will always do the right thing. Otherwise, you may use read-time conditionals like this:
(defun my-quit ()
#+sbcl (sb-ext:quit)
#+clisp (ext:exit)
#+ccl (ccl:quit)
#+allegro (excl:exit)) ;; and so on ...
#+ checks, if the following symbol is in *features*. If not, the following form will be treated as white-space. (There is also #- for the opposite).
There is no standard way to exit a CL environment. To find out how to do it in the implementation you're using, read its documentation.
In sbcl, (sb-ext:quit) will do the trick. For clisp, it's (ext:exit). The clisp documentation for the command is at http://clisp.sourceforge.net/impnotes.html#quit
There is an ASDF library called shut-it-down that provides a quit function that works by just having cases for the common CL implementations.
You can use (uiop:quit). This is included in most lisps.
Related
I am interested in creating an emacs extension that delegates the work to an external program.
I have my logic as a library, however, written in Common Lisp. If I can directly call the CL library from Elisp, that would be simpler for me; otherwise, I can use a client/server architecture.
I have looked into emacs LSP implementation, but I couldn't find a simple entry on how to do it.
You could build a binary of your CL app and call it from the Elisp side. It seems to suit you fine, so here are more pointers:
How to build a Common Lisp executable
short answer: see https://lispcookbook.github.io/cl-cookbook/scripting.html
Building a binary is done by calling sb-ext:save-lisp-and-die from the terminal (and not from a running image). Note that this function name changes on the different implementations.
ASDF has a directive that allows to do it declaratively, and portably (for all implementations). You add 3 lines in your .asd file and you mention what is your program's entry point. For example:
;; myprogram.asd
:build-operation "program-op" ;; leave this as is.
:build-pathname "myprogram"
:entry-point "myprogram::main" ;; up to you to write main.
Now, call (asdf:make :myprogram).
See a more complete example in the Cookboo.
Call it from Elisp
See https://wikemacs.org/wiki/Emacs_Lisp_Cookbook#Processes
This returns the output as a string:
(shell-command-to-string "seq 8 12 | sort")
Full documentation: https://www.gnu.org/software/emacs/manual/html_node/elisp/Synchronous-Processes.html
Other approaches
Other approaches are discussed here: https://www.reddit.com/r/lisp/comments/kce20l/what_is_the_best_way_to_call_common_lisp_inside/
For example, one could start a lisp process with Slime and execute CL code with slime-eval.
Tried to use the persp-mode https://github.com/Bad-ptr/persp-mode.el/blob/master/persp-mode.el to retrieve the emacs windows session after restart. Unable to get it working.
So trying to understand the datastructure used to store the state of the emacs by reading the source code.
The following is the function which is used to store the session state.
(defun* persp-save-state-to-file (&optional (fname persp-auto-save-fname)
(phash *persp-hash*)
respect-persp-file-parameter)
(interactive (list (read-file-name "Save perspectives to file: "
persp-save-dir)))
In the above function two unusual things are observed using edebug (unusual according to my current understanding of elisp).
The optional argument expressions are evaluated.
The expression "(interactive..." is evaluated first and then the optional argument expressions are evaluated.
Any ideas how to debug the code. Also the emacs documentation says "defun*" is related to common-lisp, but no further information is available in emacs docs on how defun* is different from defun. Is there a quick tutorial oh what defun* does without having to learn common-lisp.
Emacs says:
Define NAME as a function. Like normal `defun', except ARGLIST allows
full Common Lisp conventions, and BODY is implicitly surrounded by
(cl-block NAME ...).
Common Lisp arglists provide optional, rest, keyword and aux arguments. Historically this comes from Lisp Machine Lisp and Mumble - two earlier Lisp dialects.
For details see: http://www.gnu.org/software/emacs/manual/html_node/cl/Argument-Lists.html
Have a look at this post for a simplistic snippet explaining
how optional works. The gist is that e.g. persp-auto-save-fname will be the value of fname
if none is given.
And obviously interactive has to be run first, because it provides the arguments.
So if interactive doesn't provide a value for fname it will be persp-auto-save-fname.
My package, lispy, uses a function from ace-jump-mode.
I'm still thinking if I should use ;; Package-Requires: cookie
or featurep for it, but the main issue is that I want a clean byte-compile
with emacs -q.
I thought that this should eliminate the byte-compilation warning:
(declare-function ace-jump-char-mode "ext:ace-jump-mode")
But it's not the case. Any thoughts on this?
Exactly, the warning is "the following functions are not known to be defined: ace-jump-char-mode, helm".
If that function is likely to be used in most cases where lispy is used, then you shoud just use something like (require 'ext:ace-jump-mode).
I am byte-compiling a module. It gives me this warning:
Warning: cl package required at runtime
Why is this a warning? I am well aware that I am using the cl package. In fact there is a (require 'cl) statement in the module.
Is there something wrong with using the cl stuff?
If so, is there a list of published workarounds? The main things I use are mapcan and delete-duplicates.
The reason of this warning is a GNU policy which does not want a package cl to be used in Elisp. But it would be foolish as well to prohibit it completely. So they decided to show a warning.
You can find more information here
Just in case someone reads this on his quest for proper use of cl: The methods described here are now deprecated.
As least as of emacs 24, instead of cl you should use cl-lib or, if the macros suffice, cl-macs. These are new versions of cl that work with a clean namespace. E.g. instead of defun* you have cl-defun.
The old cl-package now is only for backward-compatibility and shouldn't be used in new code.
There are namespace clashes between Elisp and Common Lisp but the cl package gets round them by appending an asterisk to the repeated names. For instance it implements the Common Lisp version of defun but calls it defun*. The upshot is that there are no namespaces clashes between cl and Elisp and it is quite safe to (require 'cl).
If you want to get rid of the silly warning, customize the variable byte-compiler-warnings.[1] This will turn off the warning when you compile the code. If you distribute the code the warning will probably came back when someone else compiles it. If you don't want this to happen use the code:
(with-no-warnings
(require 'cl))
You can stop the byte compiler warning about any Lisp form in a similar way.[2] It's probably a not good idea in general, but you may be able to justify it in this case.
The code:
(eval-when-compile
(require 'cl))
will get rid of the warning, but you will only be able to use the macros from the package if you do this. Macros are evaluated at compile time and Elisp does not need to know about them at run time. If you only use the macros from any package, not just cl, then it is a good idea to use eval-when-compile as it will stop unnecessary packages loading at run time, both saving memory and making the code faster. But it seems to me that it's a misuse of the function to use it just to avoid a warning. And, of course, if you do want to use any of the functions from cl, you can't use eval-when-compile anyway.
[1] You may need to add (require 'bytecomp) to your .emacs file to get access to this variable.
[2] In theory, anyway, but there's a bug in with-no-warnings that means it doesn't supress some warnings about lexical variables.
Common Lisp has lots of namespace clashes with elisp, often the functions seem to do the same thing, but differ in some subtle detail. Mixing the two is a risk that is best not done behind the user's back. For this reason, most of the more useful functions in cl.el are defined as macros, so that cl.el can be required at compile time only, and the macros will then only affect the code that uses them in future sessions of Emacs.
I wasn't able to suppress this message after reading the comments before mine.
However, I received the following instruction from a kind person on the GNU emacs mailing list:
Require cl-lib, and then change the call to use cl-remove-if-not,
instead of remove-if-not.
Which proved to be the remedy.
In sum: by 'requiring cl-lib, one must also change the name of the function/macro call.
HTH....
I'm an experienced C++/.NET/Java Windows/web programmer trying to learn (Common) Lisp. I'm reading Practical Common Lisp and using SLIME.
I'm getting the Lisp language easily enough, but I'm having trouble groking the mechanics of development. One of my issues is dealing with Emacs. I have no experience with it and find it generally confusing with hard to find/figure out commands.
Specific questions:
I get the REPL, but I don't quite get how I can use it effectively. When I need to change a function I have to retype the defun and make changes (tedious and error prone). How can I do this better?
How do I get from entering code at the REPL to actually having a program? I'm used to the C model where you have code files that you can review, edit and recompile. I know Lisp has something similar (via the load function), but how does one get a function I just defined and tested into a file to be saved? I'm hoping there's a better method than my current select+copy+paste.
How do you debug errors? Is there any ability to step into code like I would with other languages?
As long as the S-expression is valid, I don't get any errors when entering a (defun ...). It's not until I try to use it that I find out it's not valid. Is there any way to get errors sooner (i.e. compile the code)?
Is there some IDE that would be more familiar to me or allow me to play with the language easier?
Should I switch to learning Scheme instead?
Any tips would be greatly appreciated!
-I get the REPL, but don't quite get how I can use it effectively. When I
need to change a function I have to
retype the defun and make changes
(tedious and error prone). How can I
do this better?
-How do I get from entering code at the REPL to actually having a program?
I'm used to the C model where you have
code files that you can review, edit
and recompile. I know lisp has
something similar (via the load
function), but how does one get a
function I just defined and tested
into a file to be saved? I'm hoping
there's a better method than my
current select+copy+paste.
Load SLIME. Enter code in your .lisp file, and then run slime-eval-buffer to load all your code into Lisp. Then, for a specific function you are hacking on C-e, C-j to redefine it in your running Lisp.
-How do you debug errors? Is there any ability to step into code like I would with other languages?
Yes. (trace 'my-function) - or some variant on that - and when my-function is called, it will break into the debugger.
-As long as the S-expression is valid, I don't get any errors when entering a
(defun ...). It's not until I try to
use it that I find out it's not valid.
Is there any way to get errors sooner
(i.e. compile the code)?
To some degree, that is a characteristic of dynamic languages (Python, Perl, Ruby, Lisp, etc.). Try SBCL for better error-checking.
-Is there some IDE that would be more familiar to me or allow me to play with the language easier?
Emacs is the free IDE for Lisp. Allegro has a free edition I believe; I've never tried it though..
-Should I switch to learning Scheme instead?
Nah, Scheme is not as pragmatic a language.
I'm an experienced C++/.NET/Java Windows/Web programmer trying to learn (Common) Lisp. I'm reading Practical Common Lisp and using SLIME.
One can also use the LispWorks Personal Edition for learning Lisp. It has some limitations and the full product is commercial, but it is quite a bit easier to use.
I get the REPL, but don't quite get how I can use it effectively. When I need to change a function I have to retype the defun and make changes (tedious and error prone). How can I do this better?
The REPL has a history. With keyboard commands you can get back prior input and change it. Other than that just edit a Lisp file and compile code from there. In Lisp you can compile/eval individual expressions and definitions. Typical IDEs like SLIME, LispWorks or Allegro CL allow you to run code also from normal Lisp text windows - additionally to executing expressions in the REPLA (aka Listener).
How do I get from entering code at the REPL to actually having a program? I'm used to the C model where you have code files that you can review, edit and recompile. I know Lisp has something similar (via the load function), but how does one get a function I just defined and tested into a file to be saved? I'm hoping there's a better method than my current select+copy+paste.
Copy and paste in one thing. But the correct way is to work from a text file in an editor window. One can compile/load expressions, the editor buffer or the associated file.
How do you debug errors? Is there any ability to step into code like I would with other languages?
See STEP, TRACE and related. SLIME, LispWorks and Allegro CL have lots of additional features.
As long as the S-expression is valid, I don't get any errors when entering a (defun ...). It's not until I try to use it that I find out it's not valid. Is there any way to get errors sooner (i.e. compile the code)?
For many cases one uses a compiler. The compiler will find a range of errors and also will note when something is unusual (for example a function does not exist or a variable has not been defined).
-Is there some IDE that would be more familiar to me or allow me to play with the language easier?
LispWorks, Allegro CL are the best under Windows. There are some alternatives like Corman Lisp (I don't know it is maintained right now) or even Ufasoft Lisp.
Should I switch to learning Scheme instead?
Not really.
It doesn't sound like you're really using SLIME, or at least not in the way it was intended to be used. ("have to retype the defun", "the C model where you have code files")
I recommend watching some SLIME screencasts (or, even better, watching a Lisp programmer use SLIME for a few minutes, if you have one handy). The SLIME webpage has a couple.
It sounds like you'd really enjoy the DrRacket IDE. Racket is closer to Scheme than to Common Lisp, but you could dip your toes into the Lisp family without the speed bump of the Emacs style of development.