I want to use a step function to see how it went to the expected output, but it's not working.
Like this simple example:
(STEP (IF (ODDP 3) 'YES 'NO))
but nothing happens.
Is there any optimization that makes me can't see the trace steps ???
How to turn it off?
Thanks!
It's because CL:STEP is not implemented on CCL that I implemented com.informatimago.common-lisp.lisp.stepper.
You can get it with quicklisp.
The documentation is at: https://gitorious.org/com-informatimago/com-informatimago/source/2b53ae44e8fa4d040fafcf4d93976500a8e464dc:common-lisp/lisp/stepper-packages.lisp#L146
STEP is not supported in CCL.
Solution for TRACE:
When a (globally named) function FOO is defined with DEFUN, the compiler is allowed to assume that functional references to that function name refer to the function being defined (unless they're lexically shadowed); it can therefore skip the implicit SYMBOL-FUNCTION ("call whatever is in the function cell of FOO") on a self-call (a call to FOO from within FOO.) This saves an instruction or two on those calls, but (since TRACE works by changing what SYMBOL-FUNCTION returns) those inlined self-calls can't be traced.
However, the compiler can't do this (can't even assume that something defined by DEFUN won't be redefined later) if the function name is declared NOTINLINE at the point of the self call:
example:
? (defun fact (x acc)
(declare (notinline fact))
(if (= x 0)
acc
(fact (- x 1) (* x acc))))
? (trace fact)
NIL
? (fact 3 1)
0> Calling (FACT 3 1)
1> Calling (FACT 2 3)
2> Calling (FACT 1 6)
3> Calling (FACT 0 6)
<3 FACT returned 6
<2 FACT returned 6
<1 FACT returned 6
<0 FACT returned 6
? (step (fact 3 1))
0> Calling (FACT 3 1)
1> Calling (FACT 2 3)
2> Calling (FACT 1 6)
3> Calling (FACT 0 6)
<3 FACT returned 6
<2 FACT returned 6
<1 FACT returned 6
<0 FACT returned 6
That's the way to say to the compiler, "as a matter of policy, I'd rather have the ability to trace functions which call themselves and are defined with DEFUN and don't care about saving a few cycles per self-call".
from: DebugWithOpenMCL
or Evaluate the following form:
(DECLAIM (OPTIMIZE (DEBUG 3)))
before defining any function to be traced.
I don't think Clozure CL supports stepping. IIRC nobody has funded this feature yet. It would need some work, since Clozure CL lacks an interpreter (where stepping could be supported relatively painless).
Other implementations support stepping.
This library is not distributed on quicklisp anymore however it builds successfully when installed as a local quicklisp project.
use cl-stepper:step instead of cl-user:step , 'cause Clozure CL don't support it.
if you have already installed quicklisp, try to install it : like this.
(ql:quickload "com.informatimago.common-lisp.lisp.stepper")
(defpackage :test (:use :cl-stepper))
(in-package :test)
(def bar (hoge)
;; define some function
)
(step (bar 3))
Related
SBCL generates spurious style warnings about undefined functions. (The functions are defined, just later in the file.) I want to solve this problem once and for all. Fortunately, there is a way to do this:
(declaim (sb-ext:muffle-conditions style-warning))
The downside is that CCL, for obvious reasons, barfs on a program containing the above. I try to solve this problem with a conditional:
(#+sbcl (declaim (sb-ext:muffle-conditions style-warning)))
but now SBCL is unhappy: "illegal function call".
How do you put such a declaim into a portable program?
Note that while the existing answer is right, disabling warnings is not a good practice. In your case, it is probably not necessary.
Common Lisp has a notion of compilation unit, where multiple definitions are grouped together. This gives a chance for the compiler/interpreter to take care of cross-references among functions (an interpreter could collect warnings and keep only those that are not found later, for example).
For example, in file #P"/tmp/foo.pl":
(defun mut-rec-foo (x)
(when (plusp x)
(mut-rec-bar (1- x))))
(defun mut-rec-bar (x)
(print x)
(mut-rec-foo (1- x)))
Do not evaluate anything in the file; instead do:
(compile-file #P"/tmp/foo.pl")
; compiling (DEFUN MUT-REC-FOO ...)
; compiling (DEFUN MUT-REC-BAR ...)
; /tmp/foo.fasl written
; compilation finished in 0:00:00.002
No warning. You can then call (load #P"/tmp/foo.fasl") to have the definitions in your current lisp environment, without warnings.
Typically, ASDF and by extension Quicklisp use COMPILE-FILE, so your problem should disappear as soon as you bundle your files into a system.
You can also do:
(with-compilation-unit ()
(defun mut-rec-foo/bis (x)
(when (plusp x)
(mut-rec-bar/bis (1- x))))
(defun mut-rec-bar/bis (x)
(print x)
(mut-rec-foo/bis (1- x))))
Evaluating the whole block shows no warning for *EVALUATOR-MODE* being both :COMPILE or :INTERPRET.
What you witnessed happens when you evaluate each expression one after the other (or maybe one region after another one). There, the compiler has no way to know that the function already exists. Silencing the warning is the worse option, because you might actually have made an error.
If you know in advance that a function will exist, but not in your compilation unit (maybe it is only defined at runtime), the you can declaim that fact, as follows:
(declaim (ftype function my-function))
The above says that my-function must be assumed to be fbound to an object of type function. You could also give more information by refining what kind of function you claim it to be:
(declaim (ftype (function (number) (values string &optional)) num-to-string))
... for a function that accepts a number and returns exactly one value, a string.
(declaim (ftype (function () nil) forever-loop))
... for a function that accepts nothing and never return a value (loop or signals an error).
Omit the outer pair of parentheses:
#+sbcl (declaim (sb-ext:muffle-conditions style-warning))
As you are using declaim, I assume, that the declaration appears at the top-level of a compilation unit. If you need to group multiple top-level statements, you can wrap them all with a progn (which doesn't change the "top-level"-ness).
The reason SBCL did complain is, that its reader reads
((declaim (sb-ext:muffle-conditions style-warning)))
(as the :SBCL feature is present), which is simply a syntax error. CCL does not complain, because its reader reads
()
which is simply another way to spell nil.
I've been trying to write a recursive loop in clojure that will print me out the very last number in the list. The point is not that I need to get the last number (for which I'm sure there's a built in function for that) but that I want to better understand recursion and macros in clojure. So I have this macro...
(defmacro loop-do [the-list]
`(if (= (count '~the-list) 1)
(println (first '~the-list))
(loop-do (rest '~the-list))))
But I get a stackoverflow error. What am I doing wrong?
How will people use your macro?
Somewhere, someone will call:
(loop-do list)
As a piece of code, those are only two symbols in a list. The first one is recognized as your macro, and the second one, list, is a symbol that represents a variable that will be bound at runtime. But your macro only knows that this is a symbol.
The same goes for:
(loop-do (compute-something))
The argument is a form, but you do not want to get the last element of that form, only the last element of the list obtained after evaluating the code.
So: you only know that in your macro, the-list will be bound to an expression that, at runtime, will have to be a list. You cannot use the-list as-if it was a list itself: neither (count 'list) nor (count '(compute-something)) does what you want.
You could expand into (count list) or (count (compute-something)), though, but the result would only be computed at runtime. The job of the macro is only to produce code.
Recursive macros
Macros are not recursive: they expand into recursive calls.
(and a b c)
might expand as:
(let [a0 a] (if a0 a0 (and b c)))
The macroexpansion process is a fixpoint that should terminate, but the macro does not call itself (what would that mean, would you expand the code while defining the macro?). A macro that is "recursive" as-in "expands into recursive invocations" should have a base case where it does not expand into itself (independently of what will, or will not, happen at runtime).
(loop-do x)
... will be replaced by:
(loop-do (rest 'x))
... and that will be expanded again.
That's why the comments say the size actually grows, and that's why you have a stackoverflow error: macroexpansion never finds a fixpoint.
Debugging macros
You have a stackoverflow error. How do you debug that?
Use macroexpand-1, which only performs one pass of macroexpansion:
(macroexpand-1 '(loop-do x))
=> (if (clojure.core/= (clojure.core/count (quote x)) 1)
(clojure.core/println (clojure.core/first (quote x)))
(user/loop-do (clojure.core/rest (quote x))))
You can see that the generated code still contains a call to usr/loop-do , but that the argument is (clojure.core/rest (quote x)). That's the symptom you should be looking for.
I thought I would be able to find this through Google, SO, or the books I'm reading, but it is proving elusive.
In the implementation I'm learning with, I can do the following at the top-level:
(defvar *foo* 4)
(set 'bar 3)
If I then call (describe '*foo*) and (describe 'bar), I get a description saying that *foo* is special and bar is non-special (among other details).
Is there a function that takes a symbol variable as an argument and returns true or false if it is special? If so, is describe probably implemented in part by calling it?
Context: I'm learning Common Lisp, but at work I have a system with a dialect of Lisp similar to Common Lisp, but the describe function is unimplemented. There's sort of an XY thing going on here, but I'm also trying to grok Lisp and CL.
Many Common Lisp implementations provide the function variable-information in some system dependent package.
Here in SBCL:
* (require :sb-cltl2)
NIL
* (sb-cltl2:variable-information '*standard-output*)
:SPECIAL
NIL
((TYPE . STREAM))
This function was proposed as part of some other functionality to be included into ANSI CL, but didn't make it into the standard. Still many implementations have it. For documentation see: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node102.html
A non-special variable's environment will be captured when you create a closure over it:
(let ((x 1))
(let ((f (lambda () x)))
(let ((x 2))
(eql 2 (funcall f)))))
;;=> NIL
A special variable's lexical environment will not:
(defvar *x*) ; *x* is special
(let ((*x* 1))
(let ((f (lambda () *x*)))
(let ((*x* 2))
(eql 2 (funcall f)))))
;;=> T
Using this approach, you could easily define a macro that will expand to code like the previous that will let you determine whether a symbol is globally proclaimed special:
(defmacro specialp (symbol)
(let ((f (gensym "FUNC-")))
`(let ((,symbol 1))
(let ((,f (lambda () ,symbol)))
(let ((,symbol 2))
(eql 2 (funcall ,f)))))))
(specialp x) ;=> NIL
(specialp *x*) ;=> T
Note that this isn't a function, it's a macro. That means that the macro function for specialp is getting called with the symbols X and *X*. This is important, because we have to construct code that uses these symbols. You can't do this with a function, because there'd be no (portable) way to take a symbol and create a lexical environment that has a lexical variable with that name and a lambda function that refers to it.
This also has some risks if you try to use it with certain symbols. For instance, in SBCL, if you try to bind, e.g., *standard-output* to something that isn't a stream or a stream designator, you'll get an error:
CL-USER> (specialp *standard-output*)
; in: SPECIALP *STANDARD-OUTPUT*
; (LET ((*STANDARD-OUTPUT* 1))
; (LET ((#:FUNC-1038 (LAMBDA # *STANDARD-OUTPUT*)))
; (LET ((*STANDARD-OUTPUT* 2))
; (EQL 2 (FUNCALL #:FUNC-1038)))))
;
; caught WARNING:
; Constant 1 conflicts with its asserted type STREAM.
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
Defining globals with set or setq is not supported. There are 2 common ways to define globals:
(defparameter *par* 20) ; notice the earmuffs in the name!
(defvar *var* 30) ; notice the earmuffs in the name!
All global variables are special. Lexically scoped variables (not special) are not possible to get described. E.g.
(let ((x 10))
(describe 'x)) ; ==> X is the symbol X
It describes not the lexical variable but the symbol representation. It really doesn't matter since you probably never need to know in run time since you know this when you're writing if it's a bound lexical variable or global special by conforming to the earmuffs naming convention for global variables.
I believe the only way to get this information at run time* is by either using an extension to CL, as Rainer noted, or to use eval.
(defun specialp (x)
(or (boundp x)
(eval `(let (,x)
(declare (ignorable ,x))
(boundp ',x)))))
(Defect warning: If the variable is unbound but declared to be a type incompatible with nil, this could raise an error. Thanks Joshua for pointing it out in his answer.)
* The macro approach determines which symbol it is checking at macro expansion time, and whether that symbol is lexical or special at compile time. That's fine for checking the status of a variable at the repl. If you wanted to e.g. print all of the special variables exported by a package, though, you would find that to use the macro version you would end up having to use eval at the call site:
(loop for s being the external-symbols of :cl-ppcre
when (eval `(specialp-macro ,s)) do (print s))
I'm curious to learn the reason for this since set seems unique. For instance:
(set 'nm 3) ;; set evaluates its first argument, a symbol, has to be quoted
nm ;; ==> evaluates to 3
(set 'nm 'nn) ;; assigns nn to the value cell of nm
nm ;; ==> evaluates to nn
nn ;; ==> ERROR. no value
(set nm 3) ;; since nm evaluates to nn ...
nm ;; evaluates to nn
nn ;; evaluates to 3
To achieve similar behavior, I've only been able to use setf:
(setq tu 'ty) ;;
(symbol-value 'tu) ;; returns ty
(setq (symbol-value 'tu) 5) ;; ERROR. setq expects a symbol
(setf (symbol-value tu) 5) ;; has to be unquoted to access the value cell
tu ;; ==> evaluates to ty
ty ;; ==> evaluates to 3
In other programming languages the reason(s) for demotion are pretty clear: inefficient, bug prone, or insecure come to mind. I wonder what the criteria for deprecation for set was at the time. All I've been able to glean from the web is this, which is laughable. Thanks.
The main reason set is deprecated is that its use can lead to errors when it is used on bound variables (e.g., in functions):
(set 'a 10)
==> 10
a
==> 10
(let ((a 1)) ; new lexical binding
(set 'a 15) ; modification of the value slot of the global symbol, not the lexical variable
a) ; access the lexical variable
==> 1 ; nope, not 15!
a
==> 15
set is a legacy function from the times when Lisp was "the language of symbols and lists". Lisp has matured since then; direct operations on symbol slots are relatively rare, and there is no reason to use set instead of the more explicit (setf symbol-value).
In your example:
(set nm 'nn) ;; assigns nn to the value cell of nm
nm ;; ==> evaluates to nn
This is completely wrong and the main reason why it's deprecated. It's the symbol you get when evaluating nm that is bound to nn. Unfortunately in your example that is the number 3 and it will signal an error at run time since you cannot use numbers as variables. If you were to write (setq 3 'nn) the error can be seen at compile time.
With set there is an additional reason. It's very difficult to compile when you don't know what symbol is to be bound and the compiler cannot optimize it.
Scheme didn't have automatic quoting either in it's first version and they didn't even have a quoted macro like setq. Instead it stated that set' would suffice. It's obvious that it didn't since Scheme no longer have set but only define.
I personally disagree that it should be removed (deprecation results in removal eventually) but like eval it should be avoided and only used as a last resort.
I've tried to reduce it to the minimal example. The code runs without an error, producing the expected output. But it gives me a warning that my first variable is undefined. It seems that the second statement of progn doesn't "see" the results of the first statement. Thanks for the help!
(I originally did not have the progn construct in the code at all, but after getting this error I added it to see if that would force execution in order -- but the error is the same.)
Here's the code:
(let ((input (open "input.lisp")))
(progn (defvar var1 (read input))
(defvar arr1 (make-array var1 :initial-contents (read input))))
(close input))
(print var1)
(print arr1)
These are the contents of the file "input.lisp":
9
(10 8 6 4 2 4 6 8 10)
And this is the output I get from sbcl after executing (load "test.lisp"):
; in: DEFVAR ARR1
; (MAKE-ARRAY VAR1 :INITIAL-CONTENTS (READ INPUT))
;
; caught WARNING:
; undefined variable: VAR1
;
; compilation unit finished
; Undefined variable:
; VAR1
; caught 1 WARNING condition
9
#(10 8 6 4 2 4 6 8 10)
T
So, it seems to me that both definition statements are executing, but the second doesn't "see" the results of the first. It still constructs the array correctly because it's filled with the given initial-contents. But why isn't var1 already defined?
See the documentation for defvar in the Hyperspec:
If a defvar or defparameter form appears as a top level form, the compiler must recognize that the name has been proclaimed special.
This implies (and it seems to be the case for SBCL) that if a defvar appears as a non-top-level form, then the compiler need not recognize that the name has been declared. So how come your defvars are not being compiled as top level forms? See section 3.2.3.1, Processing of Top Level Forms (point 6) for the answer: the let surrounding your code causes it to be compiled as non-top-level forms.
So you need to defvar your variables at top level, and then assign them later on with setf inside the let.
Like this. It's also usually simpler to use with-open-file rather than open and close.
(defvar var1)
(defvar arr1)
(with-open-file (input "input.lisp" :direction :input)
(setf var1 (read input))
(setf arr1 (make-array var1 :initial-contents (read input))))
(print var1)
(print arr1)
The reason that you are having this trouble is that you are placing your code at top level in the file. This is a slightly unusual thing to do: the normal Lisp coding style is to put most of your code in function definitions, and then to call those functions when you need to run them.
For example, this would be a more typical way to write this kind of code, with the initialization code in its own function.
(defvar *var1* nil "Documentation for var1.")
(defvar *arr1* nil "Documentation for arr1.")
(defun init-from-file (file)
"Read *var1* and *arr1* from file."
(with-open-file (input file :direction :input)
(setf *var1* (read input))
(setf *arr1* (make-array *var1* :initial-contents (read input)))))
(when (null *var1*) (init-from-file "input.lisp"))