How to read user input in Lisp
Asked Answered
C

2

6

I'm very new to Lisp and am trying to write a program that simply asks a user to enter 3 numbers and then sums them and prints the output.

I've read that you can you a function like:

(defvar a)

(setq a (read))

To set a variable in Lisp, but when I try to compile my code using LispWorks I get the following error:

End of file while reading stream #<Concatenated Stream, Streams = ()>

I feel like this should be relatively simple and have no idea where I'm going wrong.

Cyclopropane answered 3/10, 2014 at 1:7 Comment(1)
It's hard for us to help you if we can't see your code.Disengage
L
6

I've not worked with LispWorks, so it's only a guess.

When compiler traverses your code it gets to the line (setq a (read)), it tries to read input, but there is no input stream while compiling, thus you get an error.

Write a function:

(defvar a)

(defun my-function ()
  (setq a (read))

It should work.

Lethargy answered 3/10, 2014 at 4:57 Comment(1)
why should a compiler execute code, instead of compiling it?Demythologize
K
5

This should evaluate properly in your Lisp:

(defun read-3-numbers-&-format-sum ()
  (flet ((prompt (string)
           (format t "~&~a: " string)
           (finish-output)
           (read nil 'eof nil)))
    (let ((x (prompt "first number"))
          (y (prompt "second number"))
          (z (prompt "third number")))
      (format t "~&the sum of ~a, ~a, & ~a is:~%~%~a~%"
              x y z (+ x y z)))))

Simply evaluate the above function definition, then run the form:

(read-3-numbers-&-format-sum)

at your LispWorks interpreter.

Kiruna answered 3/10, 2014 at 18:45 Comment(9)
You'll notice that I don't set any variables on the global scope with a special form such as SETQ or DEFVAR. To do so, in short, would be bad programming. I'll be happy to write a walkthrough of this code, should it become of interest to anyone.Kiruna
Changing values of special variables is not 'bad programming' per se. State is necessary in many applications and in OP's case it is not bad, since his/her program is just a test.Lethargy
I have no idea what you mean by 'special variables' but I think you are probably confused by my use of the term special form which is used by advanced lisp hackers to refer to forms such as those utilizing SETF, a pseudo-function representative of all such special forms & regions of functionality that comprise the highest levels of any given lisp dialect. The syntax for such forms is usually something like (function something-weird arguments) i.e. You cannot rewrite SETF as a function, because, among other reasons, it takes a symbol-name as its first pseudo-argument.Kiruna
In the case @Mark that I'm incorrect in declaring stay away from recklessly using special forms for global non-functional assignment, especially when local scope will suffice, I'd be very interested to hear in detail about why and how I'm wrong, along with what it is I'm failing to understand as a core concept of high-level functional languages such as Common Lisp.Kiruna
A grateful nod to @uselpa for editing my original reply as to properly handle the indentation; I see from the edit how it is to be done and will make use of this knowledge. I thank you sincerely.Kiruna
You can find information about basic terminology here. I'm sorry if I offended you in some way, I didn't mean it. defvar and defparameter are in language not as historical garbage, global (a.k.a special) variables are part of the language, and people do modify them quite often. Yes, Common Lisp is a functional language, but you must admit that Common Lisp is not pure language. In fact, it is far more imperative then Clojure for example, not to mention Haskell. Thus, it is OK to use assignment in some cases, especially for such toy programs.Lethargy
Please note that I didn't say that your code is bad or you're wrong. I only said that 'Changing values of special variables is not 'bad programming' per se.' for reasons that I've described above.Lethargy
Thanks for the link @Mark, it is very good information, as is the whole of PCL. Often, someone interested in Common Lisp will request function definition for something like #'hello-world or #'read-3-numbers-&-format-sum. I try to supply a definition that is clean, efficient and readable, but that also looks ashamed of itself for having been defined. It seems to me that if you need to pull 3 numbers from the stdin and format their sum to the stdout, you probably aren't the type of hacker that needs Lisp as his tool. I'd love to develop a standard methodology for handling requests like this.Kiruna
Do you see what I mean at all? ..that, people using Common Lisp for the first time often ask for help doing something that might be the first assignment in a tutorial on the C programming language, but would likely never come up, let alone serve as first introduction, in a tutorial on Lisp. What do you think is the best thing to do for these people? Perhaps to supply them with an answer for their inquiry along with to recommend another exercise, or link to series of exercises? Really I don't know the best way to respond and I'm open to suggestions.Kiruna

© 2022 - 2024 — McMap. All rights reserved.