Amit Chahar
Amit Chahar

Reputation: 2619

the value 0 is not of type STRING lisp error

i am a newbie to lisp and i am a making a code to multiply two numbers by shifting and adding using sbcl.here is my code

    (
    defun calculator(num1 num2)
    (write-line "In the function")
    (setq res 0)
    (loop for lpr from 0 to 63
        do(progn
                (let ((end-bit (logand num2 1)))
                (if (= end-bit 1)
                    (+ res num1)
                )
                (ash num2 -1)
                (ash num1 1)
            ))
    )
    (write-line res)
)

(write-line "Enter first number : ")
(setq num1 (read))
(write-line "Enter second number : ")
(setq num2 (read))

;;(print num1)
;;(print num2)

(
    if(or (= num1 0) (= num2 0))
    (write-line "result is 0.0")
    (calculator num1 num2)
)

but i am getting this error and have no idea how to remove it.Why this is happening , please explain.

In the function

debugger invoked on a TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {1002A8AF13}>:
  The value 0 is not of type STRING.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(WRITE-LINE 0 1) [tl,external]
0] 

Upvotes: 0

Views: 630

Answers (1)

Svante
Svante

Reputation: 51521

Please indent and space your code in the usual way.

(defun calculator (num1 num2)
  (write-line "In the function")
  (setq res 0)
  (loop for lpr from 0 to 63
        do (progn
             (let ((end-bit (logand num2 1)))
               (if (= end-bit 1)
                   (+ res num1))
               (ash num2 -1)
               (ash num1 1))))
  (write-line res))

(write-line "Enter first number : ")
(setq num1 (read))
(write-line "Enter second number : ")
(setq num2 (read))

(if (or (= num1 0) (= num2 0))
    (write-line "result is 0.0")
    (calculator num1 num2))

Don't setq undeclared variables. Use let to create local bindings instead.

(defun calculator (num1 num2)
  (write-line "In the function")
  (let ((res 0))
    (loop for lpr from 0 to 63
          do (progn
               (let ((end-bit (logand num2 1)))
                 (if (= end-bit 1)
                     (+ res num1))
                 (ash num2 -1)
                 (ash num1 1))))
    (write-line res)))

(let ((num1 (progn
              (write-line "Enter first number : ")
              (read)))
      (num2 (progn
              (write-line "Enter second number : ")
              (read))))
  (if (or (= num1 0) (= num2 0))
      (write-line "result is 0.0")
      (calculator num1 num2)))

You don't need progn after the :do in a loop.

(defun calculator (num1 num2)
  (write-line "In the function")
  (let ((res 0))
    (loop for lpr from 0 to 63
          do (let ((end-bit (logand num2 1)))
               (if (= end-bit 1)
                   (+ res num1))
               (ash num2 -1)
               (ash num1 1)))
    (write-line res)))

(let ((num1 (progn
              (write-line "Enter first number : ")
              (read)))
      (num2 (progn
              (write-line "Enter second number : ")
              (read))))
  (if (or (= num1 0) (= num2 0))
      (write-line "result is 0.0")
      (calculator num1 num2)))

Your mistake: the error explicitly tells you that "the value 0 is not of type string". It also tells you that it encountered this error when trying to invoke write-line. Look up the documentation of write-line: it takes a string as first parameter. You tried to give it a 0 instead somewhere. The only place where that could be is at (write-line res), where you always have a number, not a string.

You could use (format t "result is ~a.~%" res) instead.

(defun calculator (num1 num2)
  (write-line "In the function")
  (let ((res 0))
    (loop for lpr from 0 to 63
          do (let ((end-bit (logand num2 1)))
               (if (= end-bit 1)
                   (+ res num1))
               (ash num2 -1)
               (ash num1 1)))
    (format t "result is ~a.~%" res)))

(let ((num1 (progn
              (write-line "Enter first number : ")
              (read)))
      (num2 (progn
              (write-line "Enter second number : ")
              (read))))
  (if (or (= num1 0) (= num2 0))
      (write-line "result is 0.0")
      (calculator num1 num2)))

You need to flush the output to show the question before waiting for the answer.

(defun calculator (num1 num2)
  (write-line "In the function")
  (let ((res 0))
    (loop for lpr from 0 to 63
          do (let ((end-bit (logand num2 1)))
               (if (= end-bit 1)
                   (+ res num1))
               (ash num2 -1)
               (ash num1 1)))
    (format t "result is ~a.~%" res)))

(let ((num1 (progn
              (write-line "Enter first number: ")
              (finish-output)
              (read)))
      (num2 (progn
              (write-line "Enter second number: ")
              (finish-output)
              (read))))
  (if (or (= num1 0) (= num2 0))
      (write-line "result is 0.0")
      (calculator num1 num2)))

Upvotes: 3

Related Questions