For the life of me, I cannot determine how to accept two numbers from a
user! I am using Allegro CL, and desperately need to know how to accept two
user input numbers and store them to a variable so I can peform several
functions on them.
Thanks:
Pat
(read)
should be what you're looking for :)
-Drew
> For the life of me, I cannot determine how to accept two numbers from a
> user! I am using Allegro CL, and desperately need to know how to accept
two
> user input numbers and store them to a variable so I can peform several
> functions on them.
>
> Thanks:
>
> Pat
"Patrick Lacsina" <········@home.com> writes:
> For the life of me, I cannot determine how to accept two numbers from a
> user! I am using Allegro CL, and desperately need to know how to accept two
> user input numbers and store them to a variable so I can peform several
> functions on them.
Note: I am *very* rusty: currently practicing gurus will probably
laugh at this.
;; a little function which asks for a number, verifies it is a number
;; and returns it, else prompts again
(defun readanumber (prompt)
"prompt for a number and return it"
(format t " ~s ] " prompt)
(do ((x (read)
(progn
(format t "~S wasn't a number, try again ] " x)) (read)))
((numberp x) x)))
'do' is an iteration macro which takes as it's first argument a list
of tuples (variable initial-binding iterative-binding) as it's
second argument a pair (exit-condition exit-value), and as the rest
of its arguments (if any - none in this case) arbitrary forms to
evaluate at each iteration. 'progn' just evaluates each of it's
forms in turn and returns the value of the last one.
OK, so now you've got a method of prompting the user for numbers. Now
you want to prompt for two numbers and read them into one variable. No
problem:
(setq numbers (mapcar #'readanumber '("enter a number" "and another")))
'mapcar' applies the function which is its first argument to each of
the elements of the list which is its second argument in turn and
collects the results into a list. 'setq' is old lisper's form of
assignment. Probably most people would now use setf, but I'm not yet
comfortable with it.
Fine. Now you want to apply functions to those numbers:
(apply #'+ numbers)
(apply #'/ numbers)
'apply' is part of the basic evaluator; it applies the function
which is it's first argument to the argument list which is it's
second argument, so that
(apply #'+ '(4 5))
is exactly the same as
(+ 4 5)
So far so good, but wouldn't it be nice if the user could type
expressions as well as numbers? Replace (read) with (eval (read)) and
they can, because a number evaluates to itself; but what if they type
something whose evaluation causes an error? Well, we want to ignore
that, of course, so we use (ignore-errors (eval (read))):
;; a little function which asks for a number, evaluates it,
;; verifies it is a number and returns it, else prompts again
(defun readanumber (prompt)
"prompt for a number and return it"
(format t " ~s ] " prompt)
(do ((x (ignore-errors (eval (read)))
(progn
(format t "~S wasn't a number, try again ] " x)
(ignore-errors (eval (read))))))
((numberp x) x)))
'eval' is the evaluator. It follows these rules (forgive me if I
forget any):
* an atom evaluates to it's variable binding, if any (else an
error is thrown)
* t evaluates to t
* nil evaluates to nil
* any number evaluates to itself
* any string evaluates to itself
* a list evaluates to the result of applying the function binding
of the car of the list to the argument list which is the cdr of
the list. If the car of the list is not an atom with a function
binding, an error is thrown.
'ignore-errors' is a macro (I think) which returns nil if an error
occurs in any of its forms, but otherwise behaves like progn
Better, but do you want always to have to specify the prompt?
;; a little function which asks for a number, evaluates it,
;; verifies it is a number and returns it, else prompts again
(defun readanumber (&optional prompt)
"prompt for a number and return it"
(format t " ~s ] " (or prompt "Enter a number"))
(do ((x (ignore-errors (eval (read)))
(progn
(format t "~S wasn't a number, try again ] " x)
(ignore-errors (eval (read))))))
((numberp x) x)))
Hope this helps you; it helped me!
--
·····@jasmine.org.uk (Simon Brooke) http://www.jasmine.org.uk/~simon/
;; I'd rather live in sybar-space
Patrick Lacsina wrote:
>
> For the life of me, I cannot determine how to accept two numbers from a
> user! I am using Allegro CL, and desperately need to know how to accept two
> user input numbers and store them to a variable so I can peform several
> functions on them.
The simplest way to input anything would be just to call read.
Allegro CL Enterprise Edition 5.0.1 [DEC Alpha] (9/22/99 10:12)
<1> (defun sum () (+ (read) (read)))
SUM
<2> (sum)
2 3
5
<3>