-2

I want to print just the characters from a LISP list, and I need to verify if an atom is not a number, in CLisp. How can I do this?

2 Answers2

2

Here’s how to loop through a list and check for things that aren’t numbers:

(loop for thing in list
   do (if (numberp thing)
          (format nil “I’m a number: ~a~%” thing)
          (format nil “Not a number!~%”)

format is analogous to printf in C. And loop is a macro for iteration in Common Lisp. Explaining how that works beside saying “read the keywords as in English and guess what they mean” is beyond the scope of this answer and there are plenty of explanations of loop online, for example the “Loop for black belts” chapter of Peter Seibel’s Practical Common Lisp with is available free online.

Here is how one can write only the characters in a list. For the sake of variety this one explicitly defines a function and uses higher order list manipulation functions instead of explicit loops. Thus it is probably slower.

(defun print-characters (list)
  (let ((chars (remove-if-not #’characterp list)))
    (mapc #’write-char chars)))

remove-if-not returns a new list with the same contents as the input except it only includes the elements for which the predicate (in this case characterp) returns true. characterp returns true if and only if its input is a character.

mapc applies a function to each element of a list, discarding the return value. In this case write-char which when called with one argument writes a character to *standard-output*.

Dan Robertson
  • 4,315
  • 12
  • 17
1

I'm assuming you're asking: "given a list of items, how do I filter out only the numbers in the list?"

If yes, here's a sample session:

Given a list:

CL-USER 11 > (setq mylist '(4 "foo" 10 'bar 2.5 "baz"))
(4 "foo" 10 (QUOTE BAR) 2.5 "baz")

To get all the numbers:

CL-USER 13 > (remove-if-not #'numberp mylist)
(4 10 2.5)

And (for completeness) to do the opposite (i.e. remove the numbers):

CL-USER 14 > (remove-if #'numberp mylist)
("foo" (QUOTE BAR) "baz")
agam
  • 5,064
  • 6
  • 31
  • 37