The Practical Common Lisp page 25, explains the WITH-STANDARD-IO-SYNTAX as follows. "It ensures that certain variables that affect the behavior of PRINT are set to their standard values".
The usage is as follows.
(with-open-file (...)
(with-standard-io-syntax
(print ...
Should (print) be used in this macro? If not, what would happen?
Various dynamic variables affect the output produced by print. with-standard-io-syntax ensures those variables are set to the default values.
For example:
(let ((list '(1 2 3 4 5 6 7 8 9 10))
(*print-length* 5))
(print list)
(with-standard-io-syntax
(print list)))
Prints:
(1 2 3 4 5 ...)
(1 2 3 4 5 6 7 8 9 10)
It's particularly important if you're printing things with the intention of being able to read them later (like with prin1).
Related
I have been trying to find a method to do a "step" eval. Where I call the a function and it evaluates the most nested list for common lisp.
For example:
'(+ 2 (+ 3 4))
; would eval to:
'(+ 2 7)
In that example it just evaluated 3 + 4 and stopped right there. It did not continue on to eval 2 + 7 like what lisp would normally do.
So I want the code to find the most nested list and eval the most nested list, without evaluating the whole list.
For example:
'(+ 2 3 4 5 (+ 4 5 (- 5 6) 1 (+ 10 8 5 (- 10 11))) 10 7)
It would find the most nested list, (- 10 11), and eval it so:
'(+ 2 3 4 5 (+ 4 5 (- 5 6) 1 (+ 10 8 5 -1)) 10 7)
Again it only evaluates once, and does not evaluate the whole list at once.
Does anybody know how you could go about this to make a step evaluation for the most nested list? To use eval or something to execute the most nested part of the list without evaling the whole list at once? The problem I'm having is that I don't know how to evaluate the most nested list and then put it back together. I don't know how to approach this. Please enlighten me on how a master lisper would do this.
Us use step:
(step (+ 2 (+ 3 4)))
step 1 --> (+ 2 (+ 3 4))
Step 1 [4]> step
step 2 --> 2
Step 2 [5]> step
step 2 ==> value: 2
step 2 --> (+ 3 4)
Step 2 [6]> step
step 3 --> 3
Step 3 [7]> step
step 3 ==> value: 3
step 3 --> 4
Step 3 [8]> step
step 3 ==> value: 4
step 2 ==> value: 7
step 1 ==> value: 9
9
It doesn't do exactly what you want but it is pretty close. The reason is that Common Lisp is required to evaluate the expressions in exactly the order the stepper does it.
The order of evaluation is left-to-right, so it is not exactly right to evaluate the deepest nested list if you want to emulate Common Lisp's behaviour.
You rather have to evaluate the first nested form first. Assuming well-formed input:
(defun step-eval (form)
(let ((sub-index (position-if #'listp form)))
(if sub-index
;; there is a deeper list to step first
(append (subseq form 0 sub-index)
(list (step-eval (nth sub-index form)))
(subseq form (1+ sub-index)))
;; no deeper list, eval this
(eval form))))
This question already has answers here:
How do I splice into a list outside of a macro in Common Lisp?
(2 answers)
Closed 7 years ago.
I have a function that returns something like this:
'(1 4 2 8)
and I want to apply the following type of functions to it:
(name &rest)
for example:
(max '(1 4 2 8))
produces an error, but:
(max 1 4 2 8)
does not.
so I have to "unlist" that list. How may I go about doing that?
The form apply is the traditional way:
(apply 'max '(1 2 3 4))
; => 4
I am experiencing a behavior of the push function that I don't get. Maybe someone could explain to me why Lisp behaves this way.
Supposed I define a list as a global variable, and then try to push a new value to it using the following code:
(defparameter *primes* '(3 5 7 11))
(push 2 *primes*)
Then *primes* is now (2 3 5 7 11). So far, so good.
Now I try to do the same thing, but without the *primes* variable, i.e.:
(push 2 '(3 5 7 11))
The result is an error message:
EVAL: 3 is not a function name; try using a symbol instead
Now I have two questions:
Why does this not work? I would expect that push returns the list (2 3 5 7 11), why does this not happen? Where am I wrong?
Apart from that, I don't get the error message. What is Lisp trying to tell me with 3 is not a function name? Of course, 3 is not a function name, but I don't try to call a function named 3 anywhere, do I?
Any help is appreciated :-)
If you read the CL Hyperspec for PUSH, you will read that push expects a place.
A place is something like a variable, a structure slot, a class slot, an array access, or similar. Since Lisp uses linked cons cells for lists, it does not make sense to push something in front of a cons cell, without a reference for that.
So above is simple: we can't push to a direct list.
Why this error message?
This gets a bit complicated...
(push 2 '(3 5 7 11))
Is actually:
(push 2 (quote (3 5 7 11))
A function can be a place, it then needs a corresponding setter function. Here the setter is thought to be (setf quote) - that's right, Common Lisp can sometimes have lists as function names, not only symbols.
If we look at the macroexpansion of above:
? (pprint (macroexpand '(push 2 (quote (3 5 7 11)))))
(LET* ((#:G328 2) (#:G327 (3 5 7 11)) (#:G326 (CONS #:G328 '#:G327)))
#:G327
#:G326
(FUNCALL #'(SETF QUOTE) #:G326 #:G327))
You can see that it tries to call the setter. But it also thinks that (3 5 7 11) is a Lisp form.
I give you an example, where it actually works, but we don't use quote, but a real accessor function:
CL-USER 40 > (let ((v (vector (list (list 'a 'b 'c) (list 'd 'e 'f))
(list (list 1 2 3) (list 4 5 6)))))
(print v)
(push 42 (first (aref v 1)))
(print v)
(values))
#(((A B C) (D E F)) ((1 2 3) (4 5 6)))
#(((A B C) (D E F)) ((42 1 2 3) (4 5 6)))
In above first is the getter and CL knows the corresponding setter. The form (aref v 1) is the call and returns the index 1 element of the vector. We are then pushing to the first list of the element.
Your call has a similar structure and (3 5 7 11) is at a similar position as (aref v 1). The Lisp system says that in (3 4 7 11) then number 3 is not a valid function. Which is correct. But the real error was about the push operation. Since the macro could not detect the error, the error gets later detected in the macro expanded code.
I have found only the emacs lisp manual push, but I guess it behaves similar for Common Lisp
— Macro: push element listname
This macro creates a new list whose car is element and whose cdr is the list specified by listname, and saves that list in listname.
So it seems push is modifying its argument listname, which isn't possible with a literal list. To do what you have in mind, one would use cons instead.
To the second part 3 is not a function name, I would say push, or some function inside it, tries to evaluate the literal list. Evaluating (3 5 7 11) means, call the function 3 with arguments 5 7 11. Hence the error message.
Again from emacs, Ctrl-h f push
push is a Lisp macro in `cl.el'.
(push X PLACE)
Insert X at the head of the list stored in PLACE.
Analogous to (setf PLACE (cons X PLACE)), though more careful about
evaluating each argument only once and in the right order. PLACE may
be a symbol, or any generalized variable allowed by `setf'.
setf in turn allows place to be a
symbolic references such as (car x) or (aref x i)
which explains, why push evaluates the second argument.
I think you need CONS in second case:
(cons 2 '(3 5 7 11)) => (2 3 5 7 11)
This question already has answers here:
Test if array is inside a list in lisp
(1 answer)
Remove duplicate strings from a list
(1 answer)
Closed 8 years ago.
How do i remove duplicated lists inside a list in common-lisp?
I tried this:
(remove-duplicates '( (1 2 3) (1 2 3)))
But it evaluates to ((1 2 3) (1 2 3)), not ((1 2 3)).
Thanks.
Use the keyword argument :test to specify the function that defines whether or not two items are duplicates of each other. Most lisp functions, including remove-duplicates, use eql to test for equality by default. eql is much stricter than equal, which is what you probably want to be using.
(remove-duplicates '((1 2 3) (1 2 3)) :test #'equal)
This evaluates to '((1 2 3)).
See this post for more detail about the difference between eql and equal.
Try:
(remove-duplicates '((1 2 3) (1 2 3)) :test #'equal)
Is there equivalent of higher-order function filter in Emacs Lisp? Like function from python or Javascript.
(filter-equivalent (lambda (n) (= (% n 2) 0)) '(1 2 3 4 5 6 7 8))
==> (2 4 6 8)
It's cl-remove-if-not. A bit of a mouthful, but it works.
To elaborate a bit, you need
(require 'cl-lib)
to get this function. There's an alias for it, called remove-if-not, but
I prefer not to use it, since it may look like I'm using remove-if-not from cl.
It's a good practice to include the prefix, not doing using namespace std in C++,
but saying std::cout each time.
The third-party dash.el library provides a -filter function as an alternative to cl-remove-if-not.
(-filter 'evenp '(1 2 3 4 5 6 7 8))
;; => (2 4 6 8)