nobody-famous / alive

Common Lisp Extension for VSCode
The Unlicense
206 stars 19 forks source link

strange warning "bug" #160

Open lewisl opened 1 year ago

lewisl commented 1 year ago

This code works in a single file as top level and shows no warnings or errors:

(defparameter *glob* 99)  ;; you can also use defvar

(setf *glob* 98)

In a larger file there is a warning for the setf: GLOB is unbound.

The larger file is just a bunch of unrelated top-level forms from the Paul Graham book. Maybe I am missing some accidental interdependency:

;;;; some of the examples in chapter 2

(defun my-third (x)
  (car (cdr (cdr x))))

(defun my-fourth (x)
  (car (cdr (cdr (cdr x)))))

(my-third '(1 2 3 4))

(> (+ 1 4) 3)

(defun sum-greater (x y z)
  (> (+ x y) z))

(defun get-greater (x y)
  (if (> x y)
      x
      y))

(sum-greater 1 4 3)

(defun our-member (obj lst)
  (if (null lst)
    nil
      (if (eql (car lst) obj)
        lst
        (our-member obj (cdr lst)))))

(our-member 'b '(a b c))

(our-member 'z '(a b c))

(format t "~A plus ~A equals ~A. ~%" 2 3 (+ 2 3))

(defun askem (string)
    (format t "~A" string)
    (finish-output)  ;; Graham left this out
    (read))

;; introducing local variables
(let ((x 1) (y 2))
    (+ x y))

(defun ask-number ()
  (format t "Please enter a number: ")
  (finish-output)
  (let ((val (read)))
    (if (numberp val)
        val
        (ask-number))))

(defparameter *glob* 99)  ;; you can also use defvar

(setf *glob* 98)

#| defconstant is broken in sbcl--widely acknowledged
    can't do defconstant or deparameter referring to *glob* until after *glob* is defined, 
    even at top
    deleting or commenting the following line generates warnings for the entire file! 
|#

(let ((n 10))
    (setf n 2)
    n)

(setf x (list 'a 'b 'c))  ;; can do this but generates warning, creates new global
(setf (car x) 'n)  ;; set value to that place

;; multiple assignments
(setf a 'b
  c 'd
  e 'f) ;; also generates warning

;; don't modify in place in lisp: safe but often inefficient
(setf lst '(c a r a t))
(remove 'a lst)  ;; returns modified new list, which hasn't been assigned anywhere
(setf x (remove 'a x)) ;; anti-functional programming:  BAD BOY

;; iteration compared to recursion
(defun show-squares (start end)
    (do ((i start (+ i 1)))
        ((> i end) 'done)
      (format t "~A ~A~%" i (* i i))))

(show-squares 2 5)

;; recursive version
(defun show-squares-rec (i end)
    (if (> i end)
        'done
        (progn        ;; unnamed block=>returns value of last statement
          (format t "~A ~A~%" i (* i i))
          (show-squares-rec (+ i 1) end))))

(defun our-length (lst)
    (let ((len 0))
        (dolist (obj lst)
            (setf len (+ len 1)))
        len))

;; recursive version: not tail-recursive so don't do this
(defun our-length-rec (lst)
    (if (null lst)
        0
        (+ (our-length-rec (cdr lst)) 1)))  

#|
first class functions
    but with a 2nd class requirement:  need to use either
    function to return the code as an object or
    the shortcut that quotes a function:  #'
    we do this to refer to the function without executing it
    other languages have the convention that the function only
    only executes with an argument list:   f()
|#
(function +)
#'+
(apply #'+ '(1 2 3))  ; the last argument must be a list

(funcall #'+ 1 2 3)  ; similar but no list required

#| history of lambda: there was no function object; now there is,
    but lambda is still distinct: there is no name for the function
    use it or lose it
    ((x) (+ x 100))   this used to work in old versions
|#
(lambda (x) (+ x 100))

((lambda (x) (+ x 100)) 1)  ;; providing an argument

(defun enigma (x)
    (and (not (null x))
         (or (null (car x))
             (enigma (cdr x)))))

(defun mystery (x y) ;; how many items are ahead of x in y?
  (if (null y)
      nil
      (if (eql (car y) x)
          0
          (let ((z (mystery x (cdr y))))
            (and z (+ z 1))))))

; ex 7, ch. 2
(defun contains-list (x)
  (if (and (listp (car x)) (not (null x)))
      t
      (if (null x)
          nil
          (contains-list (cdr x)))))

; exercise 8 (a), ch. 2
(defun my-dots (x)
  (dotimes (i x (format t "~%"))
    (format t "~A~%" ".")))

(defun my-dots-rec (x)
  (if (eql x 0)
      (format t "~%")
      (progn
       (format t "~A~%" ".")
       (my-dots-rec (- x 1)))))

;; exercise 8 (b), ch. 2
(defun count-sym (lst sym)
  (let ((cnt 0))
    (dolist (item lst cnt)
      (if (eql item sym)
          (incf cnt 1)
          nil))))

(defun count-sym-rec (lst sym)
  (let ((cnt 0))
    (if (null lst)
      cnt
      (progn
         (if (eql (car lst) sym)
            (incf cnt 1)
            nil)
         (count-sym (cdr lst) sym)))))

;; exercise 9, ch. 2
(defun summit-fix (lst)
  (delete nil lst)
  (apply #'+ lst))

(defun summit-broken2 (lst)
    (let ((x (car lst)))
        (if (null x)
            (summit (cdr lst))
            (+ x (summit (cdr lst))))))

(defun summit-fix2 (lst)
  (let ((x (car lst)))
    (if (null x)
        0
        (+ x (summit-fix2 (cdr lst))))))
nobody-famous commented 1 year ago

Where are you seeing the warning? I copied your code and haven't seen that warning.

Although, apparently having a # inside a multi-line comment confuses it. I'll need to fix that.

lewisl commented 1 year ago

Seeing this in the Problems pane of VS Code while Alive is active.