is there any way to prevent the Common Lisp console to print messages after I print out an error?
for example if i use this instruction
(error "Invalid input")
The console prints out
ERROR: Invalid Input"
1 (abort) Return to debug level 3.
2 Return to level 2.
3 Return to debug level 2.
4 Return to level 1.
5 Return to debug level 1.
6 Return to level 0.
7 Return to top loop level 0.
Is there any way to not print anything after the error message?
CL-USER 50 > (setf *debugger-hook*
(lambda (c v)
(format t "~a~%" c)
(abort c)))
#<anonymous interpreted function 4060001CBC>
CL-USER 51 > (error "Invalid input")
Invalid input
Assuming you don't want to disable the debugger globally one way of doing this is to actually handle the error. CL has an extremely comprehensive system for dealing with errors and from restarting from them, but it can be used in pretty simple ways:
(defmacro aborting-from-errors (&body forms)
`(handler-case
(progn
,#forms)
(error (condition)
(format *error-output* "~&error: ~A~%" condition)
(abort condition))))
And now if I have a function like this:
(defun maybe-explode (&optional (raisep nil))
(if raisep
(error "exploded")
t))
Then
> (aborting-from-errors
(format t "~&result ~A~%" (maybe-explode))
'result)
result t
result
> (aborting-from-errors
(format t "~&result ~A~%" (maybe-explode t))
'result)
error: exploded
What is happening here is that, if an error is raised (that is, a condition whose type is error or some subtype of it), then aborting-from-errors will handle that via the handler-case it has wrapped around the code, printing it prettily to *error-output*, and calling abort. What abort does is look for a restart named abort and which is either associated with the particular condition raised or not associated with any condition, and invoke it. And the final bit of the puzzle is that the system arranges for there to be a restart named abort available at the top level.
There are a lot of things you can do with the CL condition system, and in particular restarts are very powerful tools.
Related
When using Emacs, SLIME and Clozure CL I have a minor gripe:
The function signature for aref (I have not yet seen any other instances) is shown only as (aref a).
When I go to source the code in question begins with (defun aref (a &lexpr subs). As far as I know, &lexpr is not a valid CL lambda list keyword. So this indicates that SLIME does not show the correct function signature due to the "weird" keyword.
But when I do the same for svref, say, there is nothing (to me at least) that corroborates the above hypthesis. So maybe SLIME does something, too.
Can anybody point to relevant documentation (I did not find anything relevant in the SLIME manual and in the CCL manual) or does anybody have a workaround/solution?
SVREF does not take a list of array indices, since its first argument is a vector. An array might be multi-dimensional, which explains why there are a variadic number of subscripts. For AREF, the possible sources are:
.../ccl/level-0/l0-array.lisp
#'AREF
.../ccl/compiler/optimizers.lisp
(COMPILER-MACRO AREF)
.../ccl/compiler/nx1.lisp
#'CCL::NX1-AREF
Of those, only the first one has the uncommon &lexpr keyword in its argument list.
An experiment:
CL-USER> (defun foobar (a &lexpr b) (list a b))
;Compiler warnings :
; In FOOBAR: Unused lexical variable &LEXPR
FOOBAR
Let's use the unexported symbol from CCL (auto-completion found it):
CL-USER> (defun foobar (a ccl::&lexpr b) (list a b))
FOOBAR
This times, it works, let's try it:
CL-USER> (foobar 0 1 2 3 4)
(0 17563471524599)
The Evolution of Lisp says (emphasis mine):
MacLisp introduced the LEXPR , which is a type of function that takes
any number of arguments and puts them on the stack;
(see https://www.dreamsongs.com/Files/Hopl2.pdf)
Fix by substitution
You can fix it at the level of Swank, by replacing &lexpr by &rest. You only need to patch ccl.lisp, which provides an implementation for arglist for Clozure:
(defimplementation arglist (fname)
(multiple-value-bind (arglist binding) (let ((*break-on-signals* nil))
(ccl:arglist fname))
(if binding
(substitute '&rest 'ccl::&lexpr arglist)
:not-available)))
More details
In fact, in swank-arglists.lisp you can see that the stuff that is unknown is put in a separate list, called :unknown-junk. To see it in action, do:
CL-USER> (trace swank::decoded-arglist-to-string)
NIL
Then, write (aref and press Space, which triggers a query for the argument list and produces the following trace:
0> Calling (SWANK::DECODED-ARGLIST-TO-STRING #S(SWANK/BACKEND:ARGLIST :PROVIDED-ARGS NIL :REQUIRED-ARGS (CCL::A) :OPTIONAL-ARGS NIL :KEY-P NIL :KEYWORD-ARGS NIL :REST NIL :BODY-P NIL :ALLOW-OTHER-KEYS-P NIL :AUX-ARGS NIL :ANY-P NIL :ANY-ARGS NIL :KNOWN-JUNK NIL :UNKNOWN-JUNK (CCL::&LEXPR CCL::SUBS)) :PRINT-RIGHT-MARGIN 159 :OPERATOR AREF :HIGHLIGHT (0))
<0 SWANK::DECODED-ARGLIST-TO-STRING returned "(aref ===> a <===)"
Notice the :UNKNOWN-JUNK (CCL::&LEXPR CCL::SUBS)) part.
Maybe a better fix is to let Swank learn about &lexpr?
I may be asking for the impossible, but am wondering nonetheless.
Is it possible to obtain an analog of the stack-trace for macros? That is, if one set a break-point inside a certain function, the macro-stack-trace would list all macros (perhaps with their inputs) that were macroexpanded to get to that level in the code.
From what I understand, this is currently impossible, but it may be due to my shallow understanding. Does Allegro or SBCL allow or track this kind of information? It appears that this would be really useful for debugging macros.
Any help or advice is appreciated.
As SBCL is a compiler-only implementation meaning all code is automatically compiled (in contrast to being "interpreted"). Calls to macros are expanded as part of compilation, so the fact that something was a macro call is lost.
(defmacro m (n)
`(/ 10 ,n))
(defun foo (x) (m x))
SBCL:
* (foo 0)
debugger invoked on a DIVISION-BY-ZERO in thread
#<THREAD "main thread" RUNNING {1001E06493}>:
arithmetic error DIVISION-BY-ZERO signalled
Operation was /, operands (10 0).
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
(SB-KERNEL::INTEGER-/-INTEGER 10 0)
0] backtrace
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1001E06493}>
0: (SB-KERNEL::INTEGER-/-INTEGER 10 0)
1: (FOO 0)
2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (FOO 0) #<NULL-LEXENV>)
3: (EVAL (FOO 0))
4: (INTERACTIVE-EVAL (FOO 0) :EVAL NIL)
[...]
Some implementations, e.g. Allegro CL, support both interpreted as well as compiled code, the first being helpful in debugging, the second giving better performance. (I show here the command-line interactions. Allegro also offers a GUI to set breakpoints that I'm not familiar with.)
cl-user(4): (foo 0)
Error: Attempt to divide 10 by zero.
[condition type: division-by-zero]
Restart actions (select using :continue):
0: Return to Top Level (an "abort" restart).
1: Abort entirely from this (lisp) process.
[1] cl-user(5): :zoom
Evaluation stack:
(error division-by-zero :operation ...)
->(/ 10 0)
(foo 0)
(eval (foo 0))
[...]
The zoom command takes many options to be more verbose, this shows the form (block foo (m x)):
[1] cl-user(6): :zoom :all t
Evaluation stack:
... 4 more newer frames ...
((:runsys "lisp_apply"))
[... sys::funcall-tramp ]
(excl::error-from-code 17 nil ...)
(sys::..runtime-operation "integer_divide" :unknown-args)
(excl::/_2op 10 0)
->(/ 10 0)
[... excl::eval-as-progn ]
(block foo (m x))
(foo 0)
(sys::..runtime-operation "comp_to_interp" 0)
[... excl::%eval ]
(eval (foo 0))
When you (compile 'foo) the macro calls will be expanded away (like for SBCL) and not show up in backtraces anymore (but Allegro's source-level debugging could help).
In general when it comes to defining macros, to help debugging try to expand into function calls and not big bodies of code. E.g. instead of:
(defmacro with-foo ((var-x var-y thing) &body body)
`(let ((,var-x (..derive from ,thing ..))
(,var-y (..derive from ,thing ..)))
,#body))
I would write it like:
(defmacro with-foo ((var-x var-y thing) &body body)
`(call-with-foo (lambda (,var-x ,var-y) ,#body) ,thing))
(defun call-with-foo (func thing)
(let ((x (..derive from thing ..)
(y (..derive from thing ..))
(funcall func x y)))
so it ends up in the stack trace and is easy to redefine.
See this great post by Kent Pitman:
Incidentally, too, back to CL, you should know that when I write these
WITH-xxx macros, I almost always accompany them with a CALL-WITH-xxx
so that I can do either kind of call. But I find I almost never use
the CALL-WITH-xxx even when I was the one to provide it as an option.
The main reason I write them is not to use them but to make
redefinition easier, since I can redefine the CALL-WITH-xxx without
redefining the macro, and so I don't have to recompile the callers if
the definition changes.
Yes, AllegroCl supports tracing and in general debugging of macros. Quite an effort for not sure how much benefit, but Franz tends to do good things to make CL more viable. Pro tip: there is a an option to turn off what I think they call source-level debugging of macros, and you will want to do that if your code makes heavy use of macros or compilation times can get crazy. Just turn it back on when you think you need the source debugging.
I am trying to write a macro that would wrap a form or several forms into its body and attempt to execute them. I would like the macro to drop into the debugger, similarly to how it happens when (break) is executed.
The problem is that I am not familiar with Common Lisp's tools for catching errors. What functionality of CL can I use to make this happen?
Example usage:
(break-on-error (start '#:blogdemo :port 8080))
The above comments are correct: the webserver can probably be configured to stop catching and logging errors, and break instead.
But note that BREAK is guaranteed to always enter the debugger, and you can always bind a new handler around a form you want to test. For example, suppose you have this handler that catches errors and log them to standard output:
(defun main ()
(handler-case (my-function)
(error (e)
(print `(:error ,e)))))
Also, let's define my-function:
(defun my-function ()
(if (zerop (random 2))
(print "success")
(error "failure")))
If you call main several times, you will see either "success" or an error being printed to standard output.
If you want to break when my-function fails, despite the handler being established in main, you can redefine my-function as follows:
(defun my-function ()
(handler-bind ((error (lambda (condition) (break))))
(if (zerop (random 2))
(print "success")
(error "failure"))))
The style is not great (the condition is ignored, etc.), but this is only for debugging, after all.
And now, the function will enter the debugger on error.
You can write a macro for that. First, define our handler as an external function (for reuse, etc. Also, the less code in the macro, the better). By the way, this time, the condition is not ignored, it is printed to the user.
(defun break-on-error (condition)
(break "~a" condition))
The macro is then simply:
(defmacro with-active-debugger (&body body)
`(handler-bind ((error #'break-on-error))
,#body))
The function can be rewritten:
(defun my-function ()
(with-active-debugger
(if (zerop (random 2))
(print "success")
(error "failure"))))
Hi newbie here trying to learn lisp and im confused as to why lisp prints out NIL at the end of my output? Is there a way for it to not print NIL or is my if statement not set correctly.
(defun greater (x)
(if (> x 4)
(message "number is greater than 4")))
Get the result:
[2]> (square 10)
number greater than 4
NIL
All top level forms get printed by the Read-Eval-Print-Loop. Here is how to avoid it:
;;; make a main function
(defun main ()
;; all your program top level forms here!
(values)) ; empty values return no value and the REPL will not print anything when your program terminates
;; call main
(main)
Of course in an interactive session you would like the result printed out so that you can enter (+ 2 3) and get 5 back without having to wrap it in a print statement.
That's just the return value of your function. Your REPL (interactive evaluation) displays the result of each expression you enter. The result of calling your greater function is NIL.
I am trying to print out a character based on a conditional statement.
(defvar enctext)
(defun encrypt(enctext)
(if (eq 'A (first enctext))
(princ 'H)))
And here is what I have for executing the function
(load "lisptest.lisp")
;; Loading file lisptest.lisp ...
** - Continuable Error
DEFUN/DEFMACRO(ENCRYPT): #<PACKAGE POSIX> is locked
If you continue (by typing 'continue'): Ignore the lock and proceed
The following restarts are also available:
SKIP :R1 skip (DEFUN ENCRYPT # ...)
RETRY :R2 retry (DEFUN ENCRYPT # ...)
STOP :R3 stop loading file /home/students/cante008/cs351/lisptest.lisp
ABORT :R4 Abort main loop
Break 1 [2]> continue
WARNING: DEFUN/DEFMACRO: redefining function ENCRYPT in
/home/students/cante008/cs351/lisptest.lisp, was defined in C
;; Loaded file lisptest.lisp
T
[3]> (setf x '(A))
(A)
[4]> (encrypt x)
H
H
At the very end the character 'H' prints twice and i'm not sure why that is.
This is my first step to doing a Caesar Cipher
[..] a character [..]
When you write things like 'A or 'H you're not dealing with characters but symbols. Characters are written like this: #\A or #\Space. To compare characters for equality, use char=.
[..] prints twice [..]
Most functions in Lisp return (at least) one value. When you call a function on the REPL (read-evaluate-print-loop), then - as the "P" in "REPL" suggests - the return value(s) of calling that function is printed. The return value of your function is either NIL (when the if is not taken) or whatever princ returns. Looking at the HyperSpec tells us:
princ object &optional output-stream => object
This is to be read as princ takes one required parameter (some object to print) and an optional parameter (the stream to print to) and returns an object, which is (though I couldn't find it written explicitly) the same object that was passed to it.
Thus, the first H is from the princ, the second one from the REPL that automatically prints the return value.
As a final remark: Your usage of defvar probably shows a misunderstanding of variables in Common Lisp: defvar declares the (rough equivalent) to what you might know as "global" variables from other languages. You don't need it for function arguments or passing parameters.
You did not really test it.
CL-USER 3 > (defun test ()
(encrypt '(a))
(encrypt '(a))
(encrypt '(a))
'lalala)
TEST
CL-USER 4 > (test)
HHH
LALALA
CL-USER 5 > (defun test1 ()
(test)
(test)
(test)
'mmmmmm)
TEST1
CL-USER 6 > (test1)
HHHHHHHHH
MMMMMM
You're using a REPL, so the value of each expression is Printed.
The value of (encrypt x) ends up (in this instance) being the value of (princ 'H) which is H.
Additionally, (princ 'H) prints H.
This is the same reason that you see (A) after evaluating (setf x '(A))