Subtle Compiler Warning in SBCL When Compiling a Lambda Expression - common-lisp

I'd like some help with understanding an SBCL compiler warning message, which occurs when compiling a lambda expression. The lambda expression is temporarily stored as the symbol-value of a user-defined name, and the compiled function is subsequently stored under the name's symbol-function.
* (compile nil (symbol-value 'activate-connector-if!))
; in: LAMBDA (STATE ?CONNECTOR)
; (APPLY #'SOME
; (LAMBDA (WOULDWORK-PKG::?T1 WOULDWORK-PKG::?T2)
; (AND
; (GETHASH (+ 126 # #)
; (WOULDWORK-PKG::PROBLEM-STATE.IDB WOULDWORK-PKG::STATE))
; (GETHASH (+ 126 # #)
; (WOULDWORK-PKG::PROBLEM-STATE.IDB WOULDWORK-PKG::STATE))
; (LET (#)
; (WHEN VALUES #))
; (LET (#)
; (WHEN VALUES #))
; (NOT (EQL WOULDWORK-PKG::$HUE1 WOULDWORK-PKG::$HUE2))))
; NIL NIL)
; --> MULTIPLE-VALUE-CALL SB-C::%FUNCALL SOME LET BLOCK SB-INT:DX-FLET FLET
; --> #:WRAPPER102 BLOCK LET
; ==>
; (SB-C::%FUNCALL #:G100 #:G99)
;
; caught WARNING:
; function called with one argument, but wants exactly two
; See also:
; The ANSI Standard, Section 3.2.2.3
;
; compilation unit finished
; caught 1 WARNING condition
#<FUNCTION (LAMBDA (STATE ?CONNECTOR)) {1002E32AAB}>
T
T
The warning corresponds to the two required arguments, but there is no information about where the function is being called from. However, there is only one possible place it can be called from, and a check verifies that it is being called with two arguments.
Since the program runs fine on all test cases in spite of this warning, at first I thought it meant the function is never being called. But a trace verifies it is being called properly a number of times with the correct arguments.
Is there any other way to get at what is generating the warning?

(LAMBDA (WOULDWORK-PKG::?T1 WOULDWORK-PKG::?T2) ...) requires 2 arguments, but it's being called with just 1 argument by SOME. When you convert the APPLY call to a normal function call, it looks like:
(some (lambda (?t1 ?t2) ...) '())
There need to be as many sequence arguments as arguments to the predicate function, but there's only one sequence and two arguments.
Maybe you meant to use FUNCALL rather than APPLY? APPLY treats its last argument as a list of arguments, so NIL is spread into no arguments.

Related

How to use variables from the creator in an asynchronously called lambda in elisp? [duplicate]

I have never been able to come up with a method to penetrate the set-process-sentinel hierarchy with let-bound variables defined at the outset of the function -- only buffer-local or global variables can penetrate it. Let-bound variables can reach the first start-process, but that is as far as they can penetrate without being rejected due to being unrecognized -- let-bound variables defined at the outset of the function do not appear to be able to penetrate the section that begins with (lambda (p e) . . .. Can anyone think of a way to do it, including penetrating nested sentinels like in the example below?
(set-process-sentinel
(start-process
"my-process-name-one"
"*OUTPUT-BUFFER*"
"/path/to/executable"
"argument-one"
"argument-two"
"argument-three")
(lambda (p e) (when (= 0 (process-exit-status p))
(set-process-sentinel
(start-process
"my-process-name-two"
nil ;; example of not using an output buffer
"/path/to/executable"
"argument-one"
"argument-two"
"argument-three")
(lambda (p e) (when (= 0 (process-exit-status p))
(set-process-sentinel
(start-process . . . ))))))))
The problem is that Emacs Lisp variable bindings are dynamic by default. That is, when a function is evaluated, bound variables are looked up not in the environment where the function was defined, but in the environment where the function was called.
Emacs 24 or later supports lexical binding (that is, the function sees the variables that were bound around the function definition) natively, but since it alters the semantics of existing code you need to enable it explicitly. Usually this is done by adding a file local variable setting to the first line of the .el file:
;; -*- lexical-binding: t; -*-
Another alternative is to use lexical-let from the cl library. This works in earlier Emacs versions as well. Note that in this way you explicitly specify which variables should have lexical binding, so code such as (lexical-let ((foo foo)) ...) is not uncommon — foo is an existing variable which needs to be "carried over" into the function.
The following is an example using dynamic bindings:
(defun example-dynamic-fn ()
"Doc-string"
(interactive)
(let ((test-variable "Hello-world!"))
(set-process-sentinel
(start-process "process-one" "*one*" "echo" test-variable)
`(lambda (p e) (when (= 0 (process-exit-status p))
(set-process-sentinel
(start-process "process-two" "*two*" "echo" ,test-variable)
'(lambda (p e) (when (= 0 (process-exit-status p))
(start-process "process-three" "*three*" "echo" ,test-variable)
(set-process-sentinel
(start-process "process-four" "*four*" "echo" ,test-variable)
'(lambda (p e) (when (= 0 (process-exit-status p))
(set-process-sentinel
(start-process "process-five" "*five*" "echo" ,test-variable)
'(lambda (p e) (when (= 0 (process-exit-status p))
(message "test-variable: %s" ,test-variable)))))))))))))))
OK, I think I've got this now. The link above provides a good example; here's another in case anyone else has this difficulty:
;;; ensure VAR1 has no binding
(makunbound 'VAR1)
;;;
(defun f1 (&optional VAR1)
(interactive)
(unless VAR1
(set 'VAR1 "variable1"))
(pop-to-buffer "*test*")
; (lexical-let ( (VAR1 VAR1) ) ;;;
(set-process-sentinel
(start-process-shell-command "test"
"*test*"
(concat "echo " VAR1))
(lambda (process event)
(condition-case err
(when (string-match-p "finished" event)
(f2 VAR1))
(error
(princ
(format "Sentinel error: %s" err))))))
; ) ;;;
)
;;;
(defun f2 (&optional VAR2)
(interactive)
(unless VAR2
(set 'VAR2 "VARIABLE2"))
(print VAR2))
We load everything (with the lines in (f1) commented out) and run (f1). The value of VAR1 is passed to (f2) before the error occurs. The error (void-variable VAR1) appears to come from the scoping environment of (set-process sentinel PROCESS SENTINEL); VAR1 is not defined there even though it remains in scope for the SENTINEL ((lambda)) function.
Also using (set ) as above is not best practice when a variable is only meant to have scope local to the function.
If we uncomment the lines marked with ; then everything works as expected. Happily, we can pass the value through to another function, which prevents a long series of (set-process sentinel )s building up. It also allows us to generate processes with additional sub-processes, if required.
One of my mistakes was naming the SENTINEL as a discrete function, rather than keeping it inside the (lexical-let ) function. While the lexical-binding: t; approach is attractive, it will tend to break working code which relies on the standard (let ).

How to require keyword arguments in Common Lisp?

Given
(defun show-arg (a)
(format t "a is ~a~%" a))
(defun show-key (&key a)
(format t "a is ~a~%" a))
evaluating
(show-arg)
will lead to an error saying "invalid number of arguments: 0", where
(show-key)
will display a is NIL
How can I get SHOW-KEY to signal an error like SHOW-ARG does? Is there a way other than using (unless a (error "a is required")) in the function body? I am very fond of keyword arguments and use them constantly, and almost always want them to be required.
Keyword arguments are always optional, so you do need to manually check if they're given and signal an error if needed. It would be better to not require keyword arguments though. The compiler won't recognize them as required and thus won't given you an error message for missing arguments at compile time.
If you do want to require them, you can specify the arguments with a three element list; the first element being the argument, the second is the default value and the third is a variable that will be true if the argument was given. Checking the third element is better than checking the keyword itself, because then you can tell the difference between a NIL that was the default, and a NIL that the user gave as an argument.
(defun foo (&key (keyarg nil keyargp))
(unless keyargp (error "KEYARG is required."))
(* keyarg 2))
Edit
Now that I think about this a bit more, there actually is a way to get compile time errors for missing keyword arguments. Define a compiler macro for the function:
(defun foo (&key a b c d)
(* a b c d))
(define-compiler-macro foo (&whole whole &key (a nil ap) (b nil bp)
(c nil cp) (d nil dp))
(declare (ignore a b c d))
(unless (and ap bp cp dp)
(error "Missing arguments..."))
whole)
One possibility would be:
(defun foo (&key (arg1 (error "missing arg1 in call to function foo")))
arg1)
Using it:
CL-USER 80 > (foo)
Error: missing arg1 in call to function foo
1 (abort) Return to level 0.
2 Return to top loop level 0.
This will give an error at runtime, unfortunately not at compile time.

SBCL warning that a variable is defined but never used

I'm getting a warning from the sbcl compiler, that a variable has been defined but is not used. And the compiler is right. I want to get rid of the warning, but don't know how to do it. Here is an example:
(defun worker-1 (context p)
;; check context (make use of context argument)
(if context
(print p)))
(defun worker-2 (context p)
;; don't care about context
;; will throw a warning about unused argument
(print p))
;;
;; calls a given worker with context and p
;; doesn't know which arguments will be used by the
;; implementation of the called worker
(defun do-cmd (workerFn context p)
(funcall workerFn context p))
(defun main ()
(let ((context ()))
(do-cmd #'worker-1 context "A")
(do-cmd #'worker-2 context "A")))
The do-cmd-function expects worker-functions that implement a specific interface f(context p).
The sbcl compiler throws the following warning:
in: DEFUN WORKER-2
; (DEFUN WORKER-2 (CONTEXT P) (PRINT P))
;
; caught STYLE-WARNING:
; The variable CONTEXT is defined but never used.
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
You need to declare that the parameter is intentionally ignored.
(defun worker-2 (context p)
(declare (ignore context))
(print p))
ignore will also signal a warning if you do use the variable. To suppress warnings in both cases, you can use the declaration ignorable, but this should only be used in macros and other such cases where it's not possible to determine whether the variable will be used at the point of its declaration.
In case you are not yet familiar with declare, note that it is not an operator, and instead can only appear in certain locations; in particular, it must be located before all forms in the defun body, though it can be either above or below a documentation string.

Lisp: How to MAPCAR "#x" over a list of HEX?

Using #x... like below one obtains the decimal of hex value
> #xB1
177
> #xA5
165
> #xFF
255
Say we have a list of hex, what is the correct syntax using mapcar #x... over the list? Below doesn't work:
> (mapcar #'(lambda (hex) `(#x,hex)) '(B1 A5 FF))
Reader error: Malformed number in a #b/#o/#x/#r macro.
[Condition of type SIMPLE-ERROR]
Thanks.
The #x is what's called a "reader macro". It is very similar to using quotations (ie "") to represent strings. They are executed when the code is read/compiled. What you actually want is a procedure which can convert from hexadecimal strings at run time. The procedure you are looking for is parse-integer, which takes a string and returns the value it represents. The mapcar with it should look something like this:
(mapcar (lambda (hex)
(parse-integer hex :radix 16))
'("B1" "A5" "FF"))
Note that this is using strings, if you want to use symbols as in your suggestion you would have to do something like this:
(mapcar (lambda (hex)
(parse-integer (symbol-name hex) :radix 16))
'(B1 A5 FF))
If you don't know the difference between a symbol and a string, I would suggest reading this: What exactly is a symbol in lisp/scheme?
It occurs to me that while the best solution for this problem is probably one using parse-integer as mentioned in malisper's answer, there is a sense in which this could be solved with a mapping based approach.
When we write something like #xB1, we're not explicitly invoking a function. Instead, we're using the fact that # is a dispatching read macro character, and that there's a function installed for the subcharacter x that reads numbers written in hexadecimal. That means that by the time the evaluator or compiler gets a form, the number is already there. However, we do have access to the function that is doing the processing of the hexadecimal string, using get-dispatch-macro-character. Viz.:
CL-USER> (get-dispatch-macro-character #\# #\x)
#<FUNCTION SB-IMPL::SHARP-X> ; in SBCL
CL-USER> (get-dispatch-macro-character #\# #\x)
#<SYSTEM-FUNCTION SYSTEM::HEXADECIMAL-READER> ; in CLISP
What can we do with that function? How would we use it?
2.1.4.4 Macro Characters
… If a character is a dispatching macro character C1, its reader macro
function is a function supplied by the implementation. This function
reads decimal digit characters until a non-digit C2 is read. If any
digits were read, they are converted into a corresponding integer
infix parameter P; otherwise, the infix parameter P is nil. The
terminating non-digit C2 is a character (sometimes called a
``sub-character'' to emphasize its subordinate role in the
dispatching) that is looked up in the dispatch table associated with
the dispatching macro character C1. The reader macro function
associated with the sub-character C2 is invoked with three arguments:
the stream, the sub-character C2, and the infix parameter P. For more
information about dispatch characters, see the function
set-dispatch-macro-character.
That means that when we write something like #xB1, the function above is getting called with a stream from which it can read B1, the character x, and nil. We can try calling that function with arguments like that, although we can't be quite sure what will happen, because implementations might make different assumptions about where the function will be called from.
For instance, this works without a problem in CLISP, but SBCL assumes that the function should be called recursively from read (which we're not doing):
CL-USER> (funcall (get-dispatch-macro-character #\# #\x)
(make-string-input-stream "B1")
#\x
nil)
177 ; in CLISP
CL-USER> (funcall (get-dispatch-macro-character #\# #\x)
(make-string-input-stream "B1")
#\x
nil)
; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR "~A was invoked
; with RECURSIVE-P being true outside of a recursive read operation."
; {1005F245B3}>. ; in SBCL
That said, for implementations where this will work, we can easily write a mapcar-like function to extract a dispatch macro character function and map it over some strings. Thus, in an implementation where this works:
(defun map-dispatch-macro-character (disp-char
sub-char
list
&optional (readtable *readtable*))
"Retrieve the dispatch macro character for DISP-CHAR and SUB-CHAR and
map it over the elements in LIST. Each element in LIST is either a
string designator or a two-element list of a string-designator and a
prefix argument."
(flet ((to-list (x)
(if (listp x) x
(list x))))
(let ((fn (get-dispatch-macro-character disp-char sub-char readtable)))
(mapcar (lambda (x)
(destructuring-bind (str &optional prefix) (to-list x)
(with-input-from-string (in (string str))
(funcall fn in sub-char prefix))))
list))))
CL-USER> (map-dispatch-macro-character #\# #\x '(B1 "A5" (FF nil)))
(177 165 255)
And of course, if you really want to be able to write #x, you could of course define a version that just extracts the characters from a string of length two, so that you could do:
CL-USER> (map-dispatch-macro-character* "#x" '(B1 A5 FF))
(177 165 255)

why every common lisp returns what's being defined

I'm wondering why every common lisp function/macro definitions returns what's being defined? It could return nil or the function itself. Why return the defined symbol? Is there anything I could do about it?
> (defun foo ()) => foo
> (defmacro bar ()) => bar
I would expect that every defining form in Lisp either returns the name of what has been defined (like in DEFUN) or the object that has been defined (like in DEFCLASS).
That's a useful value which later can be used. In a Lisp interaction, the variable *, ** and *** have the last values. Thus you can do in a Lisp with interpreter and compiler:
CLISP:
[1]> (defun foo-with-a-long-name (a) (+ a 42))
FOO-WITH-A-LONG-NAME
compiling the function is then just:
[2]> (compile *)
FOO-WITH-A-LONG-NAME ;
NIL ;
NIL
No errors. Let's see the disassembly:
[3]> (disassemble *)
Disassembly of function FOO-WITH-A-LONG-NAME
(CONST 0) = 42
1 required argument
0 optional arguments
No rest parameter
No keyword parameters
4 byte-code instructions:
0 (CONST&PUSH 0) ; 42
1 (LOAD&PUSH 2)
2 (CALLSR 2 55) ; +
5 (SKIP&RET 2)
NIL
Okay, looks good.
The reason every form returns something is how it's made by design. In a read-eval-print-loop this is useful so you get a confirmation even when it's not used.
What is returned is not important other than CL have it specified in its specification so that every CL is doing the same.
Remember it's only in the REPL it displays whats returned. When you run a script, only things you print will display.
The other main dialect, Scheme, is said not to return anything when it mutates.. How it really is is that implementations return a special object that only the REPL ignore. If you (display (set! X 6)) you will get something printed.

Resources