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))
Related
Short version:
I want to change the #+ and #- reader macros to apply to all immediately subsequent tokens starting with ##, in addition to the following token. Therefore, the following code...
#+somefeature
##someattribute1
##someattribute2
(defun ...)
...would, in the absence of somefeature, result in no code.
Long version:
I have written my own readtable-macros which apply transformations to subsequent code. For example:
##traced
(defun ...)
This yields a function that writes its arguments and return values to a file, for debugging.
This fails, however, when used in conjunction with the #+ reader macro:
#+somefeature
##traced
(defun ...)
In the absence of somefeature, the function continues to be defined, albeit without the ##traced modification. This is obviously not the desired outcome.
One possible solution would be to use progn, as follows:
#+somefeature
(progn
##traced
(defun ...))
But that's kind of ugly.
I would like to modify the #+ and #- reader macros, such that they may consume more than one token. Something like this:
(defun conditional-syntax-reader (stream subchar arg)
; If the conditional fails, consume subsequent tokens while they
; start with ##, then consume the next token.
)
(setf *readtable* (copy-readtable))
(set-dispatch-macro-character #\# #\+ #'conditional-syntax-reader)
(set-dispatch-macro-character #\# #\- #'conditional-syntax-reader)
The problem is, I don't know how to "delegate" to the original reader macros; and I don't understand enough about how they were implemented to re-implement them myself in their entirety.
A naive approach would be:
(defun consume-tokens-recursively (stream)
(let ((token (read stream t nil t)))
(when (string= "##" (subseq (symbol-string token) 0 2))
(consume-tokens-recursively stream)))) ; recurse
(defun conditional-syntax-reader (stream subchar arg)
(unless (member (read stream t nil t) *features*)
(consume-tokens-recursively stream)))
However, I'm given to believe that this wouldn't be sufficient:
The #+ syntax operates by first reading the feature specification and then skipping over the form if the feature is false. This skipping of a form is a bit tricky because of the possibility of user-defined macro characters and side effects caused by the #. and #, constructions. It is accomplished by binding the variable read-suppress to a non-nil value and then calling the read function.
This seems to imply that I can just let ((*read-suppress* t)) when using read to solve the issue. Is that right?
EDIT 1
Upon further analysis, it seems the problem is caused by not knowing how many tokens to consume. Consider the following attributes:
##export expects one argument: the (defun ...) to export.
##traced expects two arguments: the debug level and the (defun ...) to trace.
Example:
#+somefeature
##export
##traced 3
(defun ...)
It turns out that #+ and #- are capable of suppressing all these tokens; but there is a huge problem!
When under a suppressing #+ or #-, (read) returns NIL!
Example:
(defun annotation-syntax-reader (stream subchar arg)
(case (read stream t nil t)
('export
(let ((defun-form (read stream t nil t)))))
; do something
('traced
(let* ((debug-level (read stream t nil t))
(defun-form (read stream t nil t)))))))
; do something
(setf *readtable* (copy-readtable))
(set-dispatch-macro-character #\# #\# #'annotation-syntax-reader)
#+(or) ##traced 3 (defun ...)
The ##traced token is being suppressed by the #+. In this situation, all the (read) calls in (annotation-syntax-reader) consume real tokens but return NIL!
Therefore, the traced token is consumed, but the case fails. No additional tokens are thus consumed; and control leaves the scope of the #+.
The (defun ...) clause is executed as normal, and the function comes into being. Clearly not the desired outcome.
The standard readtable
Changing the macros for #+ and #- is a bit excessive solution I think, but in any case remember to not actually change the standard readtable (as you did, but its important to repeat in the answer)
The consequences are undefined if an attempt is made to modify the standard readtable. To achieve the effect of altering or extending standard syntax, a copy of the standard readtable can be created; see the function copy-readtable.
§2.1.1.2 The Standard Readtable
Now, maybe I'm missing something (please give us a hint about how your reader macro is defined if so), but I think it is possible to avoid that and write your custom macros in a way that works for your use case.
Reader macro
Let's define a simple macro as follows:
CL-USER> (defun my-reader (stream char)
(declare (ignore char))
(let ((name (read stream)
(form (read stream))
(unless *read-suppress*
`(with-decoration ,name ,form)))
MY-READER
[NB: This was edited to take into account *read-suppress*: the code always read two forms, but returns nil in case it is being ignored. In the comments you say that you may need to read an indefinite number of forms based on the name of the decoration, but with *read-suppress* the recursive calls to read return nil for symbols, so you don't know which decoration is being applied. In that case it might be better to wrap some arguments in a literal list, or parse the stream manually (read-char, etc.). Also, since you are using a dispatching macro, maybe you can add a numerical argument if you want the decoration to be applied to more than one form (#2#inline), but that could be a bad idea when later the decorated code is being modified.]
Here the reader does a minimal job, namely build a form that is intended to be macroexpanded later. I don't even need to define with-decoration for now, as I'm interested in the read step. The intent is to read the next token (presumably a symbol that indicates what decoration is being applied, and a form to decorate).
I'm binding this macro to a unused character:
CL-USER> (set-macro-character #\§ 'my-reader)
T
Here when I test the macro it wraps the following form:
CL-USER> (read-from-string "§test (defun)")
(WITH-DECORATION TEST (DEFUN))
13 (4 bits, #xD, #o15, #b1101)
And here it works with a preceding QUOTE too, the apostrophe reader grabs the next form, which recursively reads two forms:
CL-USER> '§test (defun)
(WITH-DECORATION TEST (DEFUN))
Likewise, a conditional reader macro will ignore all the next lines:
CL-USER> #+(or) t
; No values
CL-USER> #+(or) §test (defun)
; No values
CL-USER> #+(or) §one §two §three (defun)
; No values
Decoration macro
If you use this syntax, you'll have nested decorated forms:
CL-USER> '§one §two (defun test ())
(WITH-DECORATION ONE (WITH-DECORATION TWO (DEFUN TEST ())))
With respect to defun in toplevel positions, you can arrange for your macros to unwrap the nesting (not completely tested, there might be bugs):
(defun unwrap-decorations (form stack)
(etypecase form
(cons (destructuring-bind (head . tail) form
(case head
(with-decoration (destructuring-bind (token form) tail
(unwrap-decorations form (cons token stack))))
(t `(with-decorations ,(reverse stack) ,form)))))))
CL-USER> (unwrap-decorations ** nil)
(WITH-DECORATIONS (ONE TWO) (DEFUN TEST ()))
And in turn, with-decorations might know about DEFUN forms and how to annotate them as necessary.
For the moment, our original macro is only the following (it needs more error checking):
(defmacro with-decoration (&whole whole &rest args)
(unwrap-decorations whole nil))
For the sake of our example, let's define a generic annotation mechanism:
CL-USER> (defgeneric expand-decoration (type name rest))
#<STANDARD-GENERIC-FUNCTION COMMON-LISP-USER::EXPAND-DECORATION (0)>
It is used in with-decorations to dispatch on an appropriate expander for each decoration. Keep in mind that all the efforts here are to keep defun in a top-level positions (under a progn), a recursive annotation would let evaluation happens (in the case of defun, it would result in the name of the function being defined), and the annotation could be done on the result.
The main macro is then here, with a kind of fold (reduce) mechanism where the forms are decorated using the resulting expansion so far. This allows for expanders to place code before or after the main form (or do other fancy things):
(defmacro with-decorations ((&rest decorations) form)
(etypecase form
(cons (destructuring-bind (head . tail) form
(ecase head
(defun (destructuring-bind (name args . body) tail
`(progn
,#(loop
for b = `((defun ,name ,args ,#body)) then forms
for d in decorations
for forms = (expand-decoration d name b)
finally (return forms))))))))))
(nb. here above we only care about defun but the loop should probably be done outside of the dispatching thing, along with a way to indicate to expander methods that a function is being expanded; well, it could be better)
Say, for example, you want to declare a function as inline, then the declaration must happen before (so that the compiler can know the source code must be kept):
(defmethod expand-decoration ((_ (eql 'inline)) name rest)
`((declaim (inline ,name)) ,#rest))
Likewise, if you want to export the name of the function being defined, you can export it after the function is defined (order is not really important here):
(defmethod expand-decoration ((_ (eql 'export)) name rest)
`(,#rest (export ',name)))
The resulting code allows you to have a single (progn ...) form with a defun in toplevel position:
CL-USER> (macroexpand '§inline §export (defun my-test-fn () "hello"))
(PROGN
(DECLAIM (INLINE MY-TEST-FN))
(DEFUN MY-TEST-FN () "hello")
(EXPORT 'MY-TEST-FN))
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 am currently working my way through Graham's On Lisp and find this particular bit difficult to understand:
Binding. Lexical variables must appear directly in the source code. The
first argument to setq is not evaluated, for example, so anything
built on setq must be a macro which expands into a setq, rather than a
function which calls it. Likewise for operators like let, whose
arguments are to appear as parameters in a lambda expression, for
macros like do which expand into lets, and so on. Any new operator
which is to alter the lexical bindings of its arguments must be
written as a macro.
This comes from Chapter 8, which describes when macros should and should not be used in place of functions.
What exactly does he mean in this paragraph? Could someone give a concrete example or two?
Much appreciated!
setq is a special form and does not evaluate its first argument. Thus if you want to make a macro that updates something, you cannot do it like this:
(defun update (what with)
(setq what with))
(defparameter *test* 10)
(update *test* 20) ; what does it do?
*test* ; ==> 10
So inside the function update setq updates the variable what to be 20, but it is a local variable that has the value 10 that gets updated, not *test* itself. In order to update *test* setq must have *test* as first argument. A macro can do that:
(defmacro update (what with)
`(setq ,what ,with))
(update *test* 20) ; what does it do?
*test* ; ==> 20
You can see exactly the resulting code form the macro expansion:
(macroexpand-1 '(update *test* 20))
; ==> (setq *test* 20) ; t
A similar example. You cannot mimic if with cond using a function:
(defun my-if (test then else)
(cond (test then)
(t else)))
(defun fib (n)
(my-if (< 2 n)
n
(+ (fib (- n 1)) (fib (- n 2)))))
(fib 3)
No matter what argument you pass you get an infinite loop that always call the recursive case since all my-if arguments are always evaluated. With cond and if the test gets evaluated and based on that either the then or else is evaluated, but never all unconditionally.
I have the following function (I am a very beginner at Lisp):
(defun my-fun (a b)
(my-commandsend-and-reply-macro (cmd)
(:reply (ok result)
(do-something a b result)))
)
where my-commandsend-and-reply-macro is a macro written by another programmer. I am unable to modify it.
my-commandsend-and-reply-macro sends a command (in this example cmd) to a server process (it is written in another programming language) and then waits for its answer.
The answer is processed then in the macro using the user-given ":reply part of the code". The list (ok result) is a kind of pattern, in the macro a destructuring-bind destructures and binds the proper parts of the answer to ok and result (ok is just a flag). After this the other user-given lines of the ":reply part" are excuted. (for result processing)
I would like to do the following:
1, send a command like to the other process (this is ok)
2, call a function (like do-something) using the result AND using some other parameters which are the actual parameters of my-fun (this part fails...)
How can I do this? I think the problem is that a and b are not evaluated before the macro expansion and when the macro is expanded Lisp searches for a local a and b but there is no a or b. Is there any way to evaluate a and b? (so the macro could treat them like concrete values)
This is the macro def: (written by another programmer)
(defmacro* my-commandsend-and-reply-macro ((cmd &rest args) &body body)
`(progn
(with-request-id ()
(setf (gethash *request-id* *my-callbacks*)
(lambda (status &rest status-args)
(case status
,#(loop for (kind . clause) in body when (eql kind :reply)
collect
(destructuring-bind
((status-flag &rest lambda-form-pattern)
&body action-given-by-user) clause
`(,status-flag
(destructuring-bind ,lambda-form-pattern status-args
,#action-given-by-user))))
((error)
(message "Error: %s" (elt (elt status-args 0) 1))))))
(apply #'send-command-to-process *request-id* cmd args)))))
Def of with-request-id:
(defmacro* with-request-id ((&rest vars) &body body)
"Send `getid' to the server, and call `body' once the response
with the new ID has arrived. By then, global variable `*request-id*'
is bound to the latest request ID."
`(progn
(when (not (server-is-running))
(error "Server isn't running!"))
(when *reqid-queue*
(error "Some internal error occured. Please, restart the program!"))
(lexical-let (,#(loop for var in vars
collect `(,var ,var)))
(setf *reqid-queue* (lambda ()
(unwind-protect
(progn ,#body)
(setf *reqid-queue* nil)))))
(get-id)))
And getting id from the other process:
(defun get-id ()
(send-command-to-process 'getid))
Without looking into your code at all (apologies -- no time) ---
a and b are evaluated by the function my-fun. All functions evaluate their arguments to begin with -- only macros and special forms do not necessarily evaluate all of their arguments.
But those a and b values are not passed to the macro -- the only thing passed to it is the unevaluated sexp that is bound to cmd. And you do not even define cmd in your function!
What you need to do is substitute the values of a and b into the cmd sexp. You have not shown how cmd is defined/constructed, at all. Construct it using the values of a and b, and you should be OK.
To construct the cmd sexp, remember that you can use backquote syntax to simplify things, using comma syntax to pass the values of a and b. E.g.
(let ((cmd `(some funny (expression) that ((uses)) ,a AND ,b)))
code-that-uses-CMD)
This assumes that the code you pass to the macro does not need the variables a and b, and it needs only their values.
When the function my-fun is called the arguments have already been evaluated so it's not clear to me what is the problem you are facing.
The only strange thing I see is that the macro is un-hygienic and so if your arguments are named instead of a and b for example status or status-args you're going to be in trouble because the expression
(do-something <a> <b> results)
will be compiled in a context where those names have been reused by the macro.
If in the REPL I do this:
(dolist (x (1 2 3))
(print x))
then I get an error since in (1 2 3) the digit 1 is not a symbol or a lambda expr.
If I do:
(dolist (x (list 1 2 3))
(print x))
then it works ok.
My question is why the following works:
REPL> (defmacro test (lst)
(dolist (x lst)
(print x)))
=> TEST
REPL> (test (1 2 3))
1
2
3
=>NIL
Why does dolist accept (1 2 3) when it is inside the macro definition but not when directly in the repl?
The assumption:
"Since TEST is a macro ,it does not evaluate its arguments, so (1 2 3) is passed as is to the dolist macro. So dolist must complain like it does when it is passed (1 2 3) in the REPL"
is obviously wrong. But where?
UPDATE: Although the answers help clarify some misunderstandings with macros, my question still stands and i will try to explain why:
We have established that dolist evaluates its list argument(code blocks 1, 2). Well, it doesnt seem to be the case when it is called inside a macro definition and the list argument that is passed to it is one of the defined macro arguments(code block 3). More details:
A macro, when called, does not evaluate its arguments. So my test macro, when it is called, will preserve the list argument and will pass it as it is to the dolist at expansion time. Then at expansion time the dolist will be executed (no backquotes in my test macro def). And it will be executed with (1 2 3) as argument since this is what the test macro call passed to it. So why doesnt it throw an error since dolist tries to evaluate its list argument, and in this case its list argument (1 2 3) is not evaluatable. I hope this clears my confusion a bit.
This form:
(defmacro test (lst)
(dolist (x lst)
(print x)))
defines a macro, which is a "code transformation function" which
gets applied to a form using this macro at macro expansion time. So,
after you have defined this macro, when you evaluate this expression:
(test (1 2 3))
it first gets read to this list:
(test (1 2 3))
Then, since Lisp reads test at the operator position, it gets
macro-expanded by passing the argument, which is the literal list (1
2 3), to the macro expansion function defined above. This means that
the following gets evaluated at macro-expansion time:
(dolist (x '(1 2 3))
(print x))
So, at macro-expansion time, the three values get printed. Finally,
the return value of that form is returned as the code to be compiled
and executed. Dolist returns nil here, so this is the code returned:
nil
Nil evaluates to nil, which is returned.
Generally, such a macro is not very useful. See "Practical Common
Lisp" by Peter Seibel or "On Lisp" by Paul Graham for an introduction
to useful macros.
Update: Perhaps it is useful to recapitulate the order of
reading, expanding, and evaluating Lisp code.
First, the REPL takes in a stream of characters: ( t e s t
( 1 2 3 ) ), which it assembles into
tokens: ( test ( 1 2 3 ) ).
Then, this is translated into a tree of symbols: (test (1 2
3)). There may be so-called reader macros involved in this step.
For example, 'x is translated to (quote x).
Then, from the outside in, each symbol in operator position (i.e., the
first position in a form) is examined. If it names a macro, then the
corresponding macro function is invoked with the code (i.e., the
subtrees of symbols) that is the rest of the form as arguments. The
macro function is supposed to return a new form, i.e. code, which
replaces the macro form. In your case, the macro test gets the code
(1 2 3) as argument, prints each of the symbols contained within
(note that this is even before compile time), and returns nil,
throwing its arguments away (the compiler never even sees your little
list). The returned code is then examined again for possible
macroexpansions.
Finally, the expanded code that does not contain any macro invocations
anymore is evaluated, i.e. compiled and executed. Nil happens to
be a self-evaluating symbol; it evaluates to nil.
This is just a rough sketch, but I hope that it clears some things up.
Your macro test does not return any code. And yes, macro arguments are not evaluated. If you want to see the same error, you have to define your macro as:
(defmacro test (lst)
`(dolist (x ,lst)
(print x)))
Generally when you have questions about macro expansions, referring to MACROEXPAND-1 is a great first step.
* (macroexpand-1 '(test (1 2 3)))
1
2
3
NIL
T
IE, what is happening is that the actual expansion is that sequence of prints.
Nil is what is returned by DOLIST, and is the expanded code.
Macros get their arguments passed unevaluated. They may choose to evaluate them. dolist does that for its list argument. It works with an unquoted list passed in for lst in your macro test:
(defmacro test (lst)
(dolist (x lst)
(print x)))
That's because at macro-expansion time the dolist sees lst as its argument. So when it evaluates it, it gets the list (1 2 3).
lst is a variable, when expand macro test, it also mean eval dolist structure. the first step is to eval the form lst, will get the lisp object (1 2 3).
like follow example:
(defmacro test (a)
(+ a 2))
(test 2) --> 4 ; mean invoke add function, and the first variable a binding a value 2.