0

I have been learning Common Lisp for a short while, using the SBCL 2.0.0 REPL on a Windows 10 machine. At one point in time I inputted the 2 following lines into a REPL:

(defvar var-string (print (* 5 10)))
(read-from-string (write-to-string var-string))

which yielded the following output:

50
2

Trying the following, on the other hand:

(defvar foo-string (print (* 5 10 (* 5 5) )))
(read-from-string (write-to-string foo-string))

yields this:

1250
4

In either case the first number outputted makes sense, but what is the reason for, and causal mechanism behind, the second number? Going by the above information, it seems to represent the complexity of the code being interpreted, but I am curious about how this is determined and why it is printed. I would also like to know how to repress its output, if possible, for prettier printing.

3 Answers 3

3

According to the Hyperspec, read-from-string returns two values: object, position. The first number you're seeing is the object read (an integer in both cases), and the second is the position,

an integer greater than or equal to zero, and less than or equal to one more than the length of the string.

It indicates

... the index of the first character in the bounded string that was not read. The position may depend upon the value of preserve-whitespace. If the entire string was read, the position returned is either the length of the string or one greater than the length of the string.

You can use forms like multiple-value-bind to capture extra values returned by a function; many Common Lisp routines use additional values to provide additional information about what they do. Section 3.1.7 of the spec has more information on multiple values.


In a REPL, each value is usually printed on its own separate line. I don't know if SBCL offers a way to hide the secondary values in its.

Sign up to request clarification or add additional context in comments.

Comments

3

I would also like to know how to repress its output, if possible, for prettier printing.

Inside the REPL the printing step usually prints all the returned values. Looking at the source code for SBCL in particular, there is no way to suppress that behavior except by redefining the REPL function. Fundamentally it is just (loop (print (eval (read)))) but a bit more user-friendly, so you could implement your own if you wanted to.

With the existing REPL, you can wrap your expression in a function call, because in function calls, only the primary value of each argument is used. Instead of writing this:

CL-USER> (read-from-string "xyz")
XYZ
3

You can put the expression inside a call to discard 3:

CL-USER> (symbol-name (read-from-string "xyz"))
"XYZ"

Here the function gives another result, but there are no-op functions in Common Lisp. For example, you can use VALUES to build a single value out of the primary return value of an expression:

CL-USER> (values (read-from-string "xyz"))
XYZ

Or you could also use IDENTITY.

I think however that having secondary return values being printed is nice to have. There are definitely cases where its useful to see all the results (here, the remainder of the division is 1):

CL-USER> (truncate 100 3)
33
1

For some operations it doesn't make sense to use the primary return value without the others:

CL-USER> (decode-float 42.0)
0.65625
6
1.0

Comments

2

Examples for returning multiple values in Common Lisp:

CL-USER 8 > (values)              ; returning no value

CL-USER 9 > (values 1)            ; returning one value
1

CL-USER 10 > (values 1 2)         ; returning two values
1
2

CL-USER 11 > (values 'five 'values "returned" '|from| 'values)
FIVE
VALUES
"returned"
|from|
VALUES

CL-USER 12 > multiple-values-limit     ; max numbers of possible values
51

CL-USER 13 > (defun returning-two-values (a b)
               (values (* a b) (/ a b)))
RETURNING-TWO-VALUES

CL-USER 14 > (returning-two-values 30 40)
1200
3/4

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.