Achieve (format nil ...) with princ - common-lisp

Here's the behavior of a few format and princ calls:
(format nil "a")
"a"
CL-USER>
(format t "a")
a
NIL
CL-USER>
(princ "a" nil)
a
"a"
CL-USER>
(princ "a" t)
a
"a"
CL-USER>
I would have thought that the (princ "a" nil) call would have returned "a", but not printed "a" to stdout, but it still prints "a" to stdout. Also I'm not sure why there's not a difference between the first and second princ calls.
I tried browsing the hyperspec, but I can't find the information I need.
I assume my misunderstanding is because nil and t are not streams, but format translates them to the return stream (whatever that is) and stdout. If that's the case, how can I get a (format nil ...) effect with (princ ... ?)

The function FORMAT is different from other output functions in that it accepts NIL to mean "return the output in a string instead of writing it". The general solution as suggested by Rainer is to use WITH-OUTPUT-TO-STRING.
Usually, there are special versions of the print functions that return the output as a string instead. In this particular case, what you want is the function PRINC-TO-STRING which does the same thing as PRINC but returns a string.

CL-USER 25 > (with-output-to-string (stream)
(princ "a" stream))
"a"

Related

keyword symbol enclosed by two pipes

Suppose a function fun in the code below, my goal is evaluating expr2 below.
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
(defparameter expr2 (list 'fun (intern "x" "KEYWORD") 2))
As expected, (eval expr1) gives 2, but (eval expr2) gives an error like
*** - FUN: illegal keyword/value pair :|x|, 2 in argument list.
The allowed keywords are (:X) The following restarts are available: ABORT :R1 Abort main loop
Why does this error occurs? and How can I fix it?
The reason is that normally in Common Lisp every symbol is translated to uppercase letters when read (this is the standard behaviour, and can be changed), so that:
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
is actually read as:
(DEFUN FUN (&KEY (X NIL)) X)
(DEFPARAMETER EXPR1 (LIST 'FUN :X 2))
while intern gets a string as first parameter and does not transform it, so that in your example "x" is interned as the symbol :x, which is different from the symbol :X (and this is the reason of the error). Note that when a symbol with lowercase letters is printed in REPL, it is surrounded by pipe characters (|), like in |x|, so that, when read again, lowercase characters are unchanged:
CL-USER> :x
:X
CL-USER> :|x|
:|x|
CL-USER> (format t "~a" :|x|)
x
NIL
To solve your problem, you can simply write the string directly in uppercase:
(defparameter expr2 (list 'fun (intern "X" "KEYWORD") 2))
and then (eval expr2) works as intended.
Note that \ and | are escape characters in symbols:
? 'foo\xBAR
FOO\xBAR
? '|This is a symbol|
|This is a symbol|
? ':|This is a keyword symbol with spaces and Capital letters!!!|
:|This is a keyword symbol with spaces and Capital letters!!!|
? 'what|? wow |this| also works|?
|WHAT? wow THIS also works?|

Getting "common-lisp:setf common-lisp:list* is undefined" in common lisp

I am a common-lisp novice. I am having some troubles with the following macro:
What I have:
Suppose I have a global variable *JAN2018* which is:
(:NAME "*JAN2018*" :MONTH "Jan" :YEAR 2018 :EXPENSES (:VALUE NIL :TAGS NIL))
If I run
(setf (getf *jan2018* :expenses) '(:value 23 :tags '("a" "b")))
I get for *jan2018*
(:NAME "*JAN2018*" :MONTH "Jan" :YEAR 2018 :EXPENSES
(:VALUE 23 :TAGS '("a" "b")))
The problem:
Now I have the macro:
(defmacro test (sym)
(setf `(getf ,sym :expenses) '(:value 23 :tags '("a" "b"))))
If I run
(test *jan2018*)
I get (using SBCL)
*The function (COMMON-LISP:SETF COMMON-LISP:LIST*) is undefined.
[Condition of type UNDEFINED-FUNCTION]*
What I am trying to do is pass a symbol and update one of its fields. Why I am getting this error, and how can I proceed to update the list?
Your immediate problem
To debug a macro, use macroexpand:
(macroexpand-1 '(test *jan2018*))
*** - FUNCTION: undefined function (SETF CONS)
This is because you are trying to execute (setf (list 'getf *jan2018* ...) ...) at macro expansion time.
I am afraid I cannot offer any specific suggestions because it is not clear what exactly you are trying to accomplish by the macro.
Your actual problem
You are using an incorrect facility.
Use function instead of macro:
(defun test (sym)
(setf (getf sym :expenses) '(:value 23 :tags '("a" "b"))))

Does FORMAT provide a counter for lists iteration

I often want to output lists and also print their position in the list e.g.
'(a b c) would become "1:A 2:B 3:C"
As FORMAT already supports iterating over a given list, I was wondering whether it also provides some sort of counting directive?
E.g. the FORMAT string could look like this: "~{~#C:~a~}" whereas ~#C would be the counter.
If you want a boring answer, here you go:
(format T "~:{~a:~a ~}" (loop for i from 0 for e in '(x y z) collect (list i e)))
And now for a more interesting one! Similarly to #Renzo's answer, this uses the Tilde directive to achieve its work.
(defvar *count* 0)
(defvar *printer* "~a")
(defun iterate-counting (stream arg c at)
(declare (ignore c))
(let ((*count* (if at -1 0)))
(destructuring-bind (*printer* delimiter &rest args) arg
(format stream (format NIL "~~{~~/iterate-piece/~~^~a~~}" delimiter) args))))
(defun iterate-piece (stream arg &rest dc)
(declare (ignore dc))
(incf *count*)
(format stream *printer* *count* arg))
This uses two special variables to make it both thread-safe and to allow nesting. I won't say that it's handy to use though. The first item of the argument to list has to be a format string that denotes how to print the argument and counter. For such a format list, the first argument is the counter, and the second argument is the actual item to list. You can switch those around if you need to using the asterisk directive. The second item should be a string to print as the delimiter between each item. Finally, the rest of the list has to be the actual items to print.
(format T "~/iterate-counting/" '("~a:~a" " " x y z))
=> 1:X 2:Y 3:Z
(format T "~/iterate-counting/" '("~a:~/iterate-counting/" " " ("~a>~a" "," 0 1 2) ("~a>~a" "," a b c) ("~a>~a" "," x y z)))
=> 1:1>0,2>1,3>2 2:1>A,2>B,3>C 3:1>X,2>Y,3>Z
If you want it to start counting from zero, add an # modifier to the iterate-counting:
(format T "~#/iterate-counting/" '("~a:~a" " " x y z))
=> 0:X 1:Y 2:Z
I wouldn't personally use this, as it's far less than obvious what is going on if you stumble across the directive uninitiated. It would probably be much less confusing for the potential future reader to write a tailored function for this, than trying to ab/use format.
A not so simple but reusable way of producing a numbered list is by using the ~/ directive (Tilde Slash: Call Function) with a user-defined function. For instance:
(let ((position 0))
(defun init-pos(str arg col at)
(declare (ignore str arg col at))
(setf position 0))
(defun with-pos(str arg col at)
(declare (ignore col at))
(format str "~a:~a" (incf position) arg)))
and then write format like this one:
(format nil "~/init-pos/~{~/with-pos/~^ ~}" nil '(a b c))
Note that, as said in a comment, this solution has two limitations:
You cannot use it if you need to format objects in concurrent threads, and
you cannot use it for nested lists.

Pass a "variable name" to defvar

I've been struggling with this for two days now, and I can't find the answer.
What I want is to define three variables, a, b, and c each with a value of 0.
Naive:
(dolist (lbl '(a b c)) (defvar lbl 0))
Doesn't do what I want. a, b, and c remain undefined, and lbl now has a value of 0.
I think I may understand why this can't work: defvar is a macro, not a function, and as such I am passing it the form lbl, not the current value of label (which is a, b, c in turn). I think.
But in the resulting macroexpansion, shouldn't lbl eventually be linked-up(?) or evaluated(?) to the value I'm intending? Obviously not, either because it can't be done or I'm doing it wrong.
I want to understand:
How to make this work: (dolist (lbl '(a b c)) (defvar lbl 0))
What's going wrong under the hood. I have a feeling it has something to do with symbols or the mechanics of the quote operator.
Here are a few options:
With eval, by building a defvar expression:
(dolist (lbl '(a b c))
(eval `(defvar ,lbl 0))
With proclaim and setf of symbol-value (note: set is deprecated, since 1994 for what it's worth):
(dolist (lbl '(a b c))
(proclaim `(special ,lbl))
(setf (symbol-value lbl) 0))
This is actually mostly what defvar does (see notes in the linked page), but each Lisp implementation usually also records source file location, as they do for other defining macros.
Under the hood, defvar is a macro that makes the variable special (i.e. with dynamic extent bindings in the current dynamic environment; note: there's no portable undoing for this!), and optionally initializes it if it's not yet bound.
The fact that it's a macro means it doesn't evaluate its arguments, so it can take the variable name literally, and it does so. As such, (defvar lbl 0) will define the variable lbl, not the symbol stored in a lbl variable.
The fact that it optionally initializes the variable means that the initializing expression will not even be evaluated if the variable is boundp. So, its secondary effects won't happen if the variable is already initialized. This might or might not be expected.
Note that this expression isn't actually evaluated at macro-expansion time, it's left for evaluation when the expansion is evaluated, which in a REPL means right after macro expansion (and possibly after compilation, depending on the Lisp implementation; read more about evaluation and compilation, it's quite interesting).
Similar:
(dolist (lbl '(a b c))
(let ((lbl 0))
(print lbl)))
Why is lbl 0 and not some of a, b, c?
Because LET binds the symbol lbl and not its value.
Similar with (DEFVAR FOO 3).
Imagine following code:
(DEFVAR FOO 3)
(LET ((FOO 3)) ...)
Now, if we compile this code, the Lisp compiler recognizes the DEFVAR declaration and now knows that FOO is a special global variable. Thus in the let form FOO will be dynamically bound.
Compare this code:
(dolist (v '(FOO)) (eval `(DEFVAR ,v 3)))
(LET ((FOO 3)) ...)
The compiler won't see the DEFVAR and does not know that it should be a global special variable. In the LET form, FOO will have a lexical binding.
Thus DEFVAR needs to be a macro which knows the symbol at compile time (!) and which expands into a form that informs the compiler that the symbol is a special global variable. The form also sets the value when executed.
Thus the best way to create multiple DEFVAR declarations from a list of variables is to write a macro, which expands into a PROGN form with multiple DEFVARs. Inside the PROGN, the compiler will still recognize them.
CL-USER 21 > (pprint (macroexpand '(defvar* (a b c) 0)))
(PROGN (DEFVAR A 0) (DEFVAR B 0) (DEFVAR C 0))
Implemented as:
(defmacro defvar* (vars initial-value)
`(progn
,#(loop for var in vars
do (check-type var symbol)
collect `(defvar ,var ,initial-value))))
Note that it makes sense to check that the variables are really provided as symbols.
defvar is a special form which makes sure the symbol of it's first argument is a bound variable. If the variable is not bound the evaluated expression of the second argument becomes the bound variables value. Thus:
(defvar *x* 10) ; if *x* was not bound it's now 10
(defvar *x* 20) ; since *x* is defined nothing happens
Notice that *x* is not evaluated but is used unevaluated. In order to get the same functionality by using a variable that evaluates to a symbol which you want to exist as a variable in global scope you need to do something like this:
(defvar b 10)
(dolist (lbl '(a b c))
(when (not (boundp lbl))
(setf (symbol-value lbl) 0)))
Still, neither of the ones not already bound becomes special like with defvar, but at least you get the same behaviour:
(list a b c) ; => (0 10 0)
Perhaps you should just do:
(defvar *a* 0)
(defvar *b* 0)
(defvar *c* 0)
If you have a lot of variables you need to do this with you can do:
(defmacro defvars (lst value)
(loop :for e :in lst
:collect `(defvar ,e ,value) :into result
:finally (return (cons 'progn result))))
(defparameter *w* 10)
(defvars (*q* *w* *e*) 1)
(list *q* *w* *e* ; ==> (1 10 1)
Also, it's really important to earmuff your global variables. Once special it will follow dynamic binding. eg.
(defun test ()
(let ((*b* 15))
(test2)))
(defun test2 ()
*b*)
(test) ; ==> 15
Reimplementing DEFVAR
You can approximate the behavior of defvar with a function like this:
(defun %defvar (symbol value documentation)
"Define a global special variable.
symbol---a symbol
value---nil or a function of zero arguments
documentation---nil or a documentation string
returns symbol
Proclaim SYMBOL globally as a special variable. If VALUE is non-nil,
then if SYMBOL is not already bound, SYMBOL is assigned the value
returned by calling VALUE. DOCUMENATION is assigned as the
documentation of type variable to for SYMBOL."
(prog1 symbol
;; make it globally special
(proclaim (list 'special symbol))
;; if a value is provided, and symbol isn't
;; already bound, set its value to the result
;; of calling the value-function
(when (not (null value))
(unless (boundp symbol)
(setf (symbol-value symbol)
(funcall value))))
;; set the documentation
(setf (documentation symbol 'variable) documentation)))
Then you can do, e.g.,
CL-USER> (%defvar '*the-answer* (lambda () 42) "the answer")
*THE-ANSWER*
CL-USER> *the-answer*
42
CL-USER> (documentation '*the-answer* 'variable)
"the answer"
And with your original code, you could do something like:
(dolist (lbl '(a b c)) (%defvar lbl (lambda () 0)))
Now, how does this relate to what defvar actually does? Well, you could now implement a defvar like macro by doing:
(defmacro define-var (symbol &optional (value nil value-p) documentation)
`(%defvar
',symbol
,(if value-p `(lambda () ,value) 'nil)
,documentation))
This expands as we'd expect:
CL-USER> (macroexpand-1 '(define-var *the-answer* 42 "the answer"))
(%DEFVAR '*THE-ANSWER* (LAMBDA () 42) "the answer")
You can actually use macroexpand to look at what an implementation does, too. E.g., in SBCL:
CL-USER> (macroexpand-1 '(defvar *the-answer* 42 "the answer"))
(PROGN
(EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-IMPL::%COMPILER-DEFVAR '*THE-ANSWER*))
(SB-IMPL::%DEFVAR '*THE-ANSWER* (UNLESS (BOUNDP '*THE-ANSWER*) 42) 'T
"the answer" 'T (SB-C:SOURCE-LOCATION)))
This isn't too much different from what we wrote above, though it's handling the non-evaluation of the form when the variable is already bound in a slightly different way, and it's also got some handling for recording a source location. The general idea is the same, though.
Why things don't get "linked up"
But in the resulting macroexpansion, shouldn't lbl eventually be
linked-up(?) or evaluated(?) to the value I'm intending?
The original code is:
(dolist (lbl '(a b c)) (defvar lbl 0))
We can macroexpand this to see what it becomes (in SBCL):
CL-USER> (macroexpand '(dolist (lbl '(a b c)) (defvar lbl 0)))
(BLOCK NIL
(LET ((#:N-LIST1022 '(A B C)))
(TAGBODY
#:START1023
(UNLESS (ENDP #:N-LIST1022)
(LET ((LBL (TRULY-THE (MEMBER C B A) (CAR #:N-LIST1022))))
(SETQ #:N-LIST1022 (CDR #:N-LIST1022))
(TAGBODY (DEFVAR LBL 0)))
(GO #:START1023))))
NIL)
T
Now, we can still see LBL in two places, including in (defvar LBL 0). So why don't things get "matched up"? To see that, we need to remember that the defvar inside the let will also be macroexpanded. To what? This:
CL-USER> (macroexpand '(DEFVAR LBL 0))
(PROGN
(EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-IMPL::%COMPILER-DEFVAR 'LBL))
(SB-IMPL::%DEFVAR 'LBL (UNLESS (BOUNDP 'LBL) 0) 'T NIL 'NIL
(SB-C:SOURCE-LOCATION)))
But now we see that SBCL's internals are getting the symbol named "LBL"; the call (sb-impl::%defvar 'lbl …) is calling the function sb-impl::%defvar with the symbol lbl, and there's no connection between that symbol and the lexical variable that happens to be represented in the source by the same symbol. After all, if you write:
CL-USER> (let ((a 89))
(list 'a a))
(A 89)
You want to be able to get the symbol a and the number 89, right? The macroexpansion of defvar includes a call to a function with the quotation of one of the arguments to macro.

What's the canonical way to join strings in a list?

I want to convert ("USERID=XYZ" "USERPWD=123") to "USERID=XYZ&USERPWD=123". I tried
(apply #'concatenate 'string '("USERID=XYZ" "USERPWD=123"))
which will return ""USERID=XYZUSERPWD=123".
But i do not know how to insert '&'? The following function works but seems a bit complicated.
(defun join (list &optional (delim "&"))
(with-output-to-string (s)
(when list
(format s "~A" (first list))
(dolist (element (rest list))
(format s "~A~A" delim element)))))
Use FORMAT.
~{ and ~} denote iteration, ~A denotes aesthetic printing, and ~^ (aka Tilde Circumflex in the docs) denotes printing the , only when something follows it.
* (format nil "~{~A~^, ~}" '( 1 2 3 4 ))
"1, 2, 3, 4"
*
This solution allows us to use FORMAT to produce a string and to have a variable delimiter. The aim is not to cons a new format string for each call of this function. A good Common Lisp compiler also may want to compile a given fixed format string - which is defeated when the format string is constructed at runtime. See the macro formatter.
(defun %d (stream &rest args)
"internal function, writing the dynamic value of the variable
DELIM to the output STREAM. To be called from inside JOIN."
(declare (ignore args)
(special delim))
(princ delim stream))
(defun join (list delim)
"creates a string, with the elements of list printed and each
element separated by DELIM"
(declare (special delim))
(format nil "~{~a~^~/%d/~:*~}" list))
Explanation:
"~{ iteration start
~a print element
~^ exit iteration if no more elements
~/%d/ call function %d with one element
~:* move one element backwards
~}" end of iteration command
%d is just an 'internal' function, which should not be called outside join. As a marker for that, it has the % prefix.
~/foo/ is a way to call a function foo from a format string.
The variables delim are declared special, so that there can be a value for the delimiter transferred into the %d function. Since we can't make Lisp call the %d function from FORMAT with a delimiter argument, we need to get it from somewhere else - here from a dynamic binding introduced by the join function.
The only purpose of the function %d is to write a delimiter - it ignores the arguments passed by format - it only uses the stream argument.
Melpa hosts the package s ("The long lost Emacs string manipulation library"), which provides many simple string utilities, including a string joiner:
(require 's)
(s-join ", " (list "a" "b" "c"))
"a, b, c"
For what it's worth, very thinly under the hood, it's using a couple lisp functions from fns.c, namely mapconcat and identity:
(mapconcat 'identity (list "a" "b" "c") ", ")
"a, b, c"
A bit late to the party, but reduce works fine:
(reduce (lambda (acc x)
(if (zerop (length acc))
x
(concatenate 'string acc "&" x)))
(list "name=slappy" "friends=none" "eats=dogpoo")
:initial-value "")
Assuming a list of strings and a single character delimiter, the following should work efficiently for frequent invocation on short lists:
(defun join (list &optional (delimiter #\&))
(with-output-to-string (stream)
(join-to-stream stream list delimiter)))
(defun join-to-stream (stream list &optional (delimiter #\&))
(destructuring-bind (&optional first &rest rest) list
(when first
(write-string first stream)
(when rest
(write-char delimiter stream)
(join-to-stream stream rest delimiter)))))
With the newish and simple str library:
(ql:quickload "str")
(str:join "&" '("USERID=XYZ" "USERPWD=123"))
It uses format like explained in the other answers:
(defun join (separator strings)
" "
(let ((separator (replace-all "~" "~~" separator)))
(format nil
(concatenate 'string "~{~a~^" separator "~}")
strings)))
(author of it, to make simple things like this simple).

Resources