3

I am familiar with the basic template for collecting the Lisp objects from a file, as in:

(with-open-file (stream "filename.lisp")
    (loop for object = (read stream nil 'eof)
          until (eq object 'eof)
          collect object))

But I'm not sure how to translate this into collecting the objects from a string, for example using read-from-string. Do you then have to keep track of the index where you left off in the string? Also, how do you avoid a name conflict with eof or any other legitimate Lisp object like nil or t in the input?

1

1 Answer 1

5

You can use with-input-from-string to read from a string.

To prevent a conflict with the eof symbol, you can use an uninterned symbol or some other object that's created dynamically.

(with-input-from-string (stream "this is a (list of 3 things)")
  (loop with eof-marker = '#:eof
        for object = (read stream nil eof-marker)
        until (eq object eof-marker)
        collect object))
Sign up to request clarification or add additional context in comments.

4 Comments

In another answer, sds pointed out that some people typically use the stream object itself: (read stream nil stream).
I get an undefined variable #:eof. Will everything still work properly with (make-symbol "eof")?
What I don't quite understand yet is that since the eof-marker is created before the string is read, why there couldn't be a variable conflict while reading from the string, for example while reading from "#:eof". Is it because the eof-marker is not interned?
Yes, it's because it's not interned. So it's not possible for the reader to return that same symbol -- every time it reads #:eof it creates a new, non-interned symbol.

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.