summaryrefslogtreecommitdiff
path: root/s7test.scm
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@umlautQ.umlaeute.mur.at>2016-10-24 13:57:11 +0200
committerIOhannes m zmölnig <zmoelnig@umlautQ.umlaeute.mur.at>2016-10-24 13:57:11 +0200
commitf81bd20a17bbbccde1154046c6ec70805e4be71b (patch)
tree4781df323969a2466984abd9fe69b1bc01b69ec1 /s7test.scm
parenta91adfdf373f6914bfec9901421cba0e99746b0b (diff)
New upstream version 16.9
Diffstat (limited to 's7test.scm')
-rw-r--r--s7test.scm774
1 files changed, 652 insertions, 122 deletions
diff --git a/s7test.scm b/s7test.scm
index c558998..c2dca6d 100644
--- a/s7test.scm
+++ b/s7test.scm
@@ -258,6 +258,7 @@
;; `(ok? ',tst (lambda () (values ,tst)) ,expected))
;; `(ok? ',tst (lambda () (define (_s7_ _a_) _a_) (_s7_ ,tst)) ,expected))
;; `(ok? ',tst (lambda () (define* (_s7_ (_a_ #f)) (or _a_)) (_s7_ ,tst)) ,expected))
+ ;; `(ok? ',tst (lambda () (caadr (catch 'receive (lambda () (throw 'receive ,tst)) (lambda any any)))) ,expected))
({list} 'ok? ({list} quote tst) ({list} lambda () tst) expected))
#|
`(let ((_result_ #f))
@@ -5857,7 +5858,7 @@ zzy" (lambda (p) (eval (read p))))) 32)
(test (equal? (byte-vector 1 0 3) #u8(1 0 3)) #t)
(test (byte-vector? bv) #t)
(test (equal? (make-byte-vector 3) #u8(0 0 0)) #t)
- (test (string-ref #u8(64 65 66) 1) #\A)
+ (test (string-ref #u8(64 65 66) 1) 65)
(test (let ((nbv (copy bv))) (equal? nbv bv)) #t)
(test (let ((rbv (reverse bv))) (equal? rbv #u8(3 0 1))) #t)
(test (length bv) 3)
@@ -23060,7 +23061,7 @@ in s7:
(test (apply (cons 1 2) '(0)) 1) ; ! (apply (cons 1 2) '(1)) is an error
(test (procedure? apply) #t)
(test (help apply) "(apply func ...) applies func to the rest of the arguments")
-(let ((lst (list 'values 'procedure? #t))) ; values rather than #t since (+ (apply values '(1 2))) -> 3
+(let ((lst (list 'values '(procedure? sequence?) #t))) ; values rather than #t since (+ (apply values '(1 2))) -> 3
(set-cdr! (cddr lst) (cddr lst))
(test (equal? lst (procedure-signature apply)) #t))
@@ -23394,6 +23395,7 @@ in s7:
(test (let () (define (hi) (1) . "hi")) 'error)
(test (let () (define (f f) f) (f 0)) 0)
+(test (let () (define (f . f) f) (f 1 2)) '(1 2))
(test (let () (define (f f) (define* (f1 (f f)) f) (f1)) (f 0)) 0)
(test (let () (define (f1 f) (define* (f (f f)) f) (f)) (procedure? (f1 0))) #t) ; ?? see comment in s7.c -- this might also return 0
(test (let () (define (f f) (define* (f (f f)) f) (f)) (procedure? (f 0))) #t)
@@ -23606,6 +23608,16 @@ in s7:
(> (abs (- (cadr lst1) (sqrt 3))) .0001))
(format-logged #t ";cholesky decomp: ~A~%" lst))))
+(let () ; from Programming Praxis
+ (define (A k x1 x2 x3 x4 x5)
+ (define (B)
+ (set! k (- k 1))
+ (A k B x1 x2 x3 x4))
+ (if (<= k 0)
+ (+ (x4) (x5))
+ (B)))
+ (test (A 10 (lambda () 1) (lambda () -1) (lambda () -1) (lambda () 1) (lambda () 0)) -67))
+
(let ()
(define* (a1 (b (let ()
(define* (a1 (b 32)) b)
@@ -28451,7 +28463,7 @@ who says the continuation has to restart the map from the top?
;;; --------------------------------------------------------------------------------
;;; keyword?
-;;; make-keyword
+;;; string->keyword
;;; keyword->symbol
;;; symbol->keyword
@@ -28478,16 +28490,16 @@ who says the continuation has to restart the map from the top?
;;; bizarre...
(test (keyword? (symbol ":#(1 #\\a (3))")) #t)
-(test (keyword? (make-keyword (object->string #(1 #\a (3)) #f))) #t)
+(test (keyword? (string->keyword (object->string #(1 #\a (3)) #f))) #t)
(test (keyword? begin) #f)
(test (keyword? if) #f)
-(let ((kw (make-keyword "hiho")))
+(let ((kw (string->keyword "hiho")))
(test (keyword? kw) #t)
(test (keyword->symbol kw) 'hiho)
(test (symbol->keyword 'hiho) kw)
(test (keyword->symbol (symbol->keyword 'key)) 'key)
- (test (symbol->keyword (keyword->symbol (make-keyword "hi"))) :hi)
+ (test (symbol->keyword (keyword->symbol (string->keyword "hi"))) :hi)
(test (keyword? :a-key) #t)
(test (keyword? ':a-key) #t)
(test (keyword? ':a-key:) #t)
@@ -28500,7 +28512,7 @@ who says the continuation has to restart the map from the top?
(test ((lambda (arg) (keyword? arg)) 'hiho) #f)
(test ((lambda (arg) (keyword? arg)) kw) #t)
(test ((lambda (arg) (keyword? arg)) (symbol->keyword 'hiho)) #t)
- (test (make-keyword "3") :3)
+ (test (string->keyword "3") :3)
(test (keyword? :3) #t)
(test (keyword? ':3) #t)
(test (eq? (keyword->symbol :hi) (keyword->symbol hi:)) #t)
@@ -28508,6 +28520,10 @@ who says the continuation has to restart the map from the top?
(test (equal? (keyword->symbol :3) 3) #f)
(test (equal? (symbol->value (keyword->symbol :3)) 3) #f) ; 3 as a symbol has value #<undefined>
+ (test (keyword? (keyword->symbol :n:)) #t)
+ (test (keyword? (keyword->symbol (keyword->symbol :n:))) #f)
+ (test (symbol->keyword n:) :n:)
+
#|
(let ()
(apply define (symbol "3") '(32))
@@ -28533,13 +28549,13 @@ who says the continuation has to restart the map from the top?
(test (keyword->symbol ::) ':)
(test (symbol->string (keyword->symbol hi:)) "hi")
(test (symbol->string (keyword->symbol :hi)) "hi")
- (test (keyword? (make-keyword (string #\x (integer->char 128) #\x))) #t)
- (test (keyword? (make-keyword (string #\x (integer->char 200) #\x))) #t)
- (test (keyword? (make-keyword (string #\x (integer->char 255) #\x))) #t)
- (test (make-keyword ":") ::)
- (test (make-keyword (string #\")) (symbol ":\""))
- (test (keyword? (make-keyword (string #\"))) #t)
- (test (keyword->symbol (make-keyword (string #\"))) (symbol "\""))
+ (test (keyword? (string->keyword (string #\x (integer->char 128) #\x))) #t)
+ (test (keyword? (string->keyword (string #\x (integer->char 200) #\x))) #t)
+ (test (keyword? (string->keyword (string #\x (integer->char 255) #\x))) #t)
+ (test (string->keyword ":") ::)
+ (test (string->keyword (string #\")) (symbol ":\""))
+ (test (keyword? (string->keyword (string #\"))) #t)
+ (test (keyword->symbol (string->keyword (string #\"))) (symbol "\""))
)
(test (symbol->keyword 'begin) :begin)
@@ -28562,10 +28578,10 @@ who says the continuation has to restart the map from the top?
(do ((k 0 (+ k 1)))
((= k strlen))
(set! (str k) (integer->char (+ 1 (random 255)))))
- (let ((key (make-keyword str)))
+ (let ((key (string->keyword str)))
(let ((newstr (symbol->string (keyword->symbol key))))
(if (not (string=? newstr str))
- (format-logged #t ";make-keyword -> string: ~S -> ~A -> ~S~%" str key newstr)))))))
+ (format-logged #t ";string->keyword -> string: ~S -> ~A -> ~S~%" str key newstr)))))))
(let ()
(define* (hi a b) (+ a b))
@@ -28575,7 +28591,7 @@ who says the continuation has to restart the map from the top?
(for-each
(lambda (arg)
- (test (make-keyword arg) 'error))
+ (test (string->keyword arg) 'error))
(list -1 #\a 1 'a-symbol #(1 2 3) 3.14 3/4 1.0+1.0i #t #f () #(()) (list 1 2 3) '(1 . 2)))
(for-each
@@ -28590,8 +28606,8 @@ who says the continuation has to restart the map from the top?
(test (keyword?) 'error)
(test (keyword? 1 2) 'error)
-(test (make-keyword) 'error)
-(test (make-keyword 'hi 'ho) 'error)
+(test (string->keyword) 'error)
+(test (string->keyword 'hi 'ho) 'error)
(test (keyword->symbol) 'error)
(test (keyword->symbol :hi :ho) 'error)
(test (symbol->keyword) 'error)
@@ -31745,12 +31761,14 @@ or better (define-macro (prog vars . body) `(call-with-exit (lambda (return) (ta
(test (procedure-signature =) (let ((L (list 'boolean? 'number?))) (set-cdr! (cdr L) (cdr L)) L))
(test (procedure-signature >) (let ((L (list 'boolean? 'real?))) (set-cdr! (cdr L) (cdr L)) L))
(test (procedure-signature symbol->keyword) '(keyword? symbol?))
-(test (procedure-signature close-input-port) '(#t input-port?))
+(test (procedure-signature close-input-port) '(unspecified? input-port?))
(test (procedure-signature string-append) (let ((L (list 'string?))) (set-cdr! L L) L))
(test (procedure-signature caar) '(#t pair?))
(test (procedure-signature make-polar) '(number? real? real?))
(test (procedure-signature provided?) '(boolean? symbol?))
(test (procedure-signature make-byte-vector) (let ((L (list 'byte-vector? 'integer?))) (set-cdr! (cdr L) (cdr L)) L))
+(test (procedure-signature byte-vector-ref) '(integer? byte-vector? integer?))
+(test (procedure-signature byte-vector-set!) '(integer? byte-vector? integer? integer?))
(test (procedure-signature string-copy) '(string? string?))
(test (procedure-signature append) (let ((L (list #t))) (set-cdr! L L) L))
(test (procedure-signature cosh) (let ((L (list 'number?))) (set-cdr! L L) L))
@@ -31846,7 +31864,7 @@ or better (define-macro (prog vars . body) `(call-with-exit (lambda (return) (ta
(test (procedure-signature string-position) '((integer? boolean?) string? string? integer?))
(test (procedure-signature integer-decode-float) '(pair? float?))
(test (procedure-signature acos) (let ((L (list 'number?))) (set-cdr! L L) L))
-(test (procedure-signature make-keyword) '(keyword? string?))
+(test (procedure-signature string->keyword) '(keyword? string?))
(test (procedure-signature write-char) '(char? char? output-port?))
(test (procedure-signature float-vector-ref) (let ((L (list 'float? 'float-vector? 'integer?))) (set-cdr! (cddr L) (cddr L)) L))
(test (procedure-signature cyclic-sequences) '(proper-list? #t))
@@ -31886,7 +31904,7 @@ or better (define-macro (prog vars . body) `(call-with-exit (lambda (return) (ta
(test (procedure-signature vector-length) '(integer? vector?))
(test (procedure-signature read) '(#t input-port?))
(test (procedure-signature vector-fill!) (let ((L (list #t 'vector? #t 'integer?))) (set-cdr! (cdddr L) (cdddr L)) L))
-(test (procedure-signature for-each) (let ((L (list #t 'procedure? 'sequence?))) (set-cdr! (cddr L) (cddr L)) L))
+(test (procedure-signature for-each) (let ((L (list 'unspecified? 'procedure? 'sequence?))) (set-cdr! (cddr L) (cddr L)) L))
(test (procedure-signature memq) '((pair? boolean?) #t list?))
(test (procedure-signature int-vector-set!) (let ((L (list 'integer? 'int-vector? 'integer?))) (set-cdr! (cddr L) (cddr L)) L))
(test (procedure-signature call-with-input-file) '(#t string? procedure?))
@@ -32020,13 +32038,13 @@ or better (define-macro (prog vars . body) `(call-with-exit (lambda (return) (ta
(test (procedure-signature ceiling) '(integer? real?))
(test (procedure-signature char-lower-case?) '(boolean? char?))
(test (procedure-signature call-with-current-continuation) '(values procedure?))
-(test (procedure-signature newline) '(#t output-port?))
+(test (procedure-signature newline) '(unspecified? output-port?))
(test (procedure-signature symbol-table) '(vector?))
(test (procedure-signature set-current-error-port) '(output-port? output-port?))
(test (procedure-signature char-numeric?) '(boolean? char?))
(test (procedure-signature string-upcase) (let ((L (list 'string?))) (set-cdr! L L) L))
(test (procedure-signature member) '((pair? boolean?) #t list? procedure?))
-(test (procedure-signature close-output-port) '(#t output-port?))
+(test (procedure-signature close-output-port) '(unspecified? output-port?))
(test (procedure-signature byte-vector) (let ((L (list 'byte-vector? 'integer?))) (set-cdr! (cdr L) (cdr L)) L))
(test (procedure-signature cadar) '(#t pair?))
(test (procedure-signature morally-equal?) (let ((L (list 'boolean? #t))) (set-cdr! (cdr L) (cdr L)) L))
@@ -32064,7 +32082,7 @@ or better (define-macro (prog vars . body) `(call-with-exit (lambda (return) (ta
(test (procedure-signature openlet?) '(boolean? #t))
(test (procedure-signature char=?) (let ((L (list 'boolean? 'char?))) (set-cdr! (cdr L) (cdr L)) L))
(test (procedure-signature cadddr) '(#t pair?))
-(test (procedure-signature apply) (let ((L (list 'values 'procedure? #t))) (set-cdr! (cddr L) (cddr L)) L))
+(test (procedure-signature apply) (let ((L (list 'values '(procedure? sequence?) #t))) (set-cdr! (cddr L) (cddr L)) L))
(test (procedure-signature inexact?) '(boolean? number?))
(test (procedure-signature open-output-file) '(output-port? string? string?))
(test (procedure-signature rationalize) '(rational? real? real?))
@@ -34172,7 +34190,75 @@ func
(test (symbol-access :rest) #f)
(test (set! (symbol-access :allow-other-keys) #f) 'error)
+(let ()
+ (define v_a_r 32)
+ (let ((x #(1 2 3)))
+ (set! (symbol-access 'v_a_r)
+ (lambda (sym val)
+ (set! (x 1) val)
+ (+ val 2))))
+ (do ((i 0 (+ i 1)))
+ ((= i 5))
+ (set! v_a_r (+ i 33))
+ (test v_a_r (+ i 33 2))
+ (gc)))
+
+(define v_a_r 32)
+(let ((x #(1 2 3)))
+ (set! (symbol-access 'v_a_r)
+ (lambda (sym val)
+ (set! (x 1) val)
+ (+ val 1))))
+(do ((i 0 (+ i 1)))
+ ((= i 5))
+ (set! v_a_r (+ i 33))
+ (test v_a_r (+ i 33 1))
+ (gc))
+
+(let ((x (vector 1 2 3)))
+ (let ((y (list 4 5 6)))
+ (set! (symbol-access 'v_a_r)
+ (lambda (sym val)
+ (+ (x val) (y val)))))
+ (set! v_a_r 1)
+ (test v_a_r 7))
+(set! v_a_r 0)
+(test v_a_r 5)
+(gc) (gc)
+(set! v_a_r 2)
+(test v_a_r 9)
+(gc) (gc)
+(let ((err #f))
+ (catch #t (lambda () (set! v_a_r 3)) (lambda args (set! err #t)))
+ (test v_a_r 9)
+ (if (not err) (format *stderr* "no error in symbol accessor!")))
+
+(define v_a_r_1 0)
+(let ((v_a_r_1 43)
+ (x #(1 2 3)))
+ (set! (symbol-access 'v_a_r_1) (lambda (sym val) (x val)))
+ (set! v_a_r_1 0)
+ (test v_a_r_1 1))
+(catch #t (lambda () (set! v_a_r_1 2)) (lambda args (apply format *stderr* (cadr args))))
+(test v_a_r_1 2)
+
+(let ((x (vector 1 2 3)))
+ (let ((y 32))
+ (let ((e1 (curlet))
+ (y 31))
+ (let ((e2 (curlet)))
+ (set! (symbol-access 'y e1)
+ (lambda (sym val)
+ (+ val (x 1)))))
+ (set! y 3)
+ (test y 3))
+ (set! y 2)
+ (test y 4)))
+
+
+
+;;; ----------------------------------------
#|
;;; these tests are problematic -- they might not fail as hoped, or they might generate unwanted troubles
(let ((bad-ideas "
@@ -34218,6 +34304,7 @@ func
;(test (quit 0) 'error)
+;;; ----------------------------------------
;;; macroexpand
(let ()
(define-macro (hi a) `(+ ,a 1))
@@ -82429,7 +82516,7 @@ etc
(test (string (openlet (inlet 'c #\a 'string (baser-method string)))) "a")
(test (rational? (openlet (inlet 'c 1/9223372036854775807 'rational? (baser-method rational?)))) #t)
(unless pure-s7 (test (string-copy (openlet (inlet 'c #u8(104 105 52 53 53) 'string-copy (baser-method string-copy)))) "hi455"))
- (test (make-keyword (openlet (inlet 'c #u8(104 105 52 53 53) 'make-keyword (baser-method make-keyword)))) :hi455)
+ (test (string->keyword (openlet (inlet 'c #u8(104 105 52 53 53) 'string->keyword (baser-method string->keyword)))) :hi455)
(test (inexact? (openlet (inlet 'c 1.5+1i 'inexact? (baser-method inexact?)))) #t)
(test (char? (openlet (inlet 'c #\a 'char? (baser-method char?)))) #t)
(test (exact? (openlet (inlet 'c 1/9223372036854775807 'exact? (baser-method exact?)))) #t)
@@ -82463,7 +82550,7 @@ etc
(test (remainder 1/9223372036854775807 (openlet (inlet 'c 1/9223372036854775807 'remainder (baser-method remainder)))) 0)
(if (not pure-s7) (test (string-ci>? #u8(0 0 0 0 0) (openlet (inlet 'c #u8(0) 'string-ci>? (baser-method string-ci>?)))) #t))
(if (not pure-s7) (test (string-ci=? #u8(0 0 0 0 0) (openlet (inlet 'c #u8(0 0 0 0 0) 'string-ci=? (baser-method string-ci=?)))) #t))
- (test (string-ref #u8(0 0 0 0 0) (openlet (inlet 'c '0 'string-ref (baser-method string-ref)))) #\null)
+ (test (string-ref #u8(0 0 0 0 0) (openlet (inlet 'c '0 'string-ref (baser-method string-ref)))) 0)
(test (string-position #u8(0 0 0 0 0) (openlet (inlet 'c #u8(0 0 0 0 0) 'string-position (baser-method string-position)))) 0)
(test (string>? #u8(0 0 0 0 0) (openlet (inlet 'c #u8(0) 'string>? (baser-method string>?)))) #t)
(test (string>=? #u8(52 53 104 105 53) #u8(52 53 104 105 53) (openlet (inlet 'c #u8(52 53 104 105 53) 'string>=? (baser-method string>=?)))) #t)
@@ -82784,7 +82871,7 @@ etc
(test (string-upcase s) "ABC")
(test (string->symbol s) 'ABc)
(test (gensym? (gensym s)) #t)
- (test (make-keyword s) :ABc)
+ (test (string->keyword s) :ABc)
(test (map values s) '(#\A #\B #\c))
(test (string>? s "ABC") #t)
(test (string-ci>? s "ABC") #f)
@@ -85391,7 +85478,6 @@ etc
(lint-test "(+ (log x) (log 3))" "") ; oops...
(lint-test "(+ x 0 (+ 0 0))" " +: perhaps (+ x 0 (+ 0 0)) -> x")
(lint-test "(+ x #(0))" " +: in (+ x #(0)), +'s argument 2 should be a number, but #(0) is a vector?")
- (lint-test "(+ x (if y #() 0))" " +: in (+ x (if y #() 0)), +'s argument 2 should be a number, but #() is a vector?")
(lint-test "(+ x 2.0 -2)" " +: perhaps (+ x 2.0 -2) -> (* x 1)") ; ??
(lint-test "(+ x (+ y z) (+ a b))" " +: perhaps (+ x (+ y z) (+ a b)) -> (+ x y z a b)")
(lint-test "(+ (- x) y)" " +: perhaps (+ (- x) y) -> (- y x)")
@@ -85431,6 +85517,22 @@ etc
(lint-test "(+ -1 (* x -2) 3 (* 4 x x x))" " +: perhaps (+ -1 (* x -2) 3 (* 4 x x x)) -> (+ 2 (* x (+ -2 (* x (* x 4)))))")
(lint-test "(+ (* x 65536) (* x 256) x)" " +: perhaps (+ (* x 65536) (* x 256) x) -> (* x 65793)")
(lint-test "(+ x x x x)" " +: perhaps (+ x x x x) -> (* x 4)")
+ (lint-test "(+ n (if (= 0 m) 0 1))" " +: perhaps (+ n (if (= 0 m) 0 1)) -> (if (= 0 m) n (+ n 1))")
+ (lint-test "(if (= m 0) n (+ n 1))" "")
+ (lint-test "(+ n (if x 0 y))" " +: perhaps (+ n (if x 0 y)) -> (if x n (+ n y))")
+ (lint-test "(+ n (if x y 0))" " +: perhaps (+ n (if x y 0)) -> (if x (+ n y) n)")
+ (lint-test "(+ (if x 0 y) n)" " +: perhaps (+ (if x 0 y) n) -> (if x n (+ y n))")
+ (lint-test "(+ (if x y 0) n)" " +: perhaps (+ (if x y 0) n) -> (if x (+ y n) n)")
+ (lint-test "(+ x (if y #() 0))"
+ " +: in (+ x (if y #() 0)), +'s argument 2 should be a number, but #() is a vector?
+ +: perhaps (+ x (if y #() 0)) -> (if y (+ x #()) x)")
+ (lint-test "(+ 1 (if x 0 #()))"
+ " +: in (+ 1 (if x 0 #())), +'s argument 2 should be a number, but #() is a vector?
+ +: perhaps (+ 1 (if x 0 #())) -> (if x 1 (+ 1 #()))")
+ (lint-test "(+ 1 (if x #() 0))"
+ " +: in (+ 1 (if x #() 0)), +'s argument 2 should be a number, but #() is a vector?
+ +: perhaps (+ 1 (if x #() 0)) -> (if x (+ 1 #()) 1)")
+ (lint-test "(+ n (make-rectangular 0.0 0.0))" " +: perhaps (+ n (make-rectangular 0.0 0.0)) -> (+ n 0.0)")
(lint-test "(* 2 3)" " *: perhaps (* 2 3) -> 6")
(lint-test "(* 2 (+))" " *: perhaps (* 2 (+)) -> 0")
@@ -85464,6 +85566,18 @@ etc
(lint-test "(* (/ x y) z (/ y x))" " *: perhaps (* (/ x y) z (/ y x)) -> z")
(lint-test "(* (/ x y z) z (/ y x))" " *: perhaps (* (/ x y z) z (/ y x)) -> 1")
(lint-test "(* (/ x a) z (/ y x))" " *: perhaps (* (/ x a) z (/ y x)) -> (/ (* z y) a)")
+ (lint-test "(* n (if x 0 1))" " *: perhaps (* n (if x 0 1)) -> (if x 0 (* n 1))")
+ (lint-test "(* n (if x y 1))" " *: perhaps (* n (if x y 1)) -> (if x (* n y) n)")
+ (lint-test "(* n (if x y 0))" " *: perhaps (* n (if x y 0)) -> (if x (* n y) 0)")
+ (lint-test "(* n (if x 0 y))" " *: perhaps (* n (if x 0 y)) -> (if x 0 (* n y))")
+ (lint-test "(* n (if x 1 y))" " *: perhaps (* n (if x 1 y)) -> (if x n (* n y))")
+ (lint-test "(* (if x 0 y) n)" " *: perhaps (* (if x 0 y) n) -> (if x 0 (* y n))")
+ (lint-test "(* (if x y 0) n)" " *: perhaps (* (if x y 0) n) -> (if x (* y n) 0)")
+ (lint-test "(* (if x 1 y) n)" " *: perhaps (* (if x 1 y) n) -> (if x n (* y n))")
+ (lint-test "(* (if x y 1) n)" " *: perhaps (* (if x y 1) n) -> (if x (* y n) n)")
+ (lint-test "(* (if x w y) n)" "")
+ (lint-test "(* x (if y 0 z) w)" " *: perhaps (* x (if y 0 z) w) -> (if y 0 (* z x w))")
+ (lint-test "(* (if y z 0) x w)" " *: perhaps (* (if y z 0) x w) -> (if y (* z x w) 0)")
(lint-test "(- 1 2)" " -: perhaps (- 1 2) -> -1")
(lint-test "(- 1 (- 1 2))" " -: perhaps (- 1 (- 1 2)) -> 2")
@@ -85489,6 +85603,8 @@ etc
(lint-test "(- (- x y) z w)" " -: perhaps (- (- x y) z w) -> (- x y z w)")
(lint-test "(- (- x y) (+ z w))" " -: perhaps (- (- x y) (+ z w)) -> (- x y z w)")
(lint-test "(- x -1)" " -: perhaps (- x -1) -> (+ x 1)")
+ (lint-test "(- x (if y 0 z))" " -: perhaps (- x (if y 0 z)) -> (if y x (- x z))")
+ (lint-test "(- x (if y z 0))" " -: perhaps (- x (if y z 0)) -> (if y (- x z) x)")
(lint-test "(/ 2 3)" " /: perhaps (/ 2 3) -> 2/3")
(lint-test "(/ 1 x)" " /: perhaps (/ 1 x) -> (/ x)")
@@ -85606,6 +85722,8 @@ etc
(lint-test "(inexact->exact (random 10))" " inexact->exact: perhaps (inexact->exact (random 10)) -> (random 10)")
(lint-test "(exact->inexact (random 10))" "") ; this can't be changed to (random 10.0)
(lint-test "(inexact->exact (floor x))" " inexact->exact: perhaps (inexact->exact (floor x)) -> (floor x)")
+ (lint-test "(exact (round x))" " exact: perhaps (exact (round x)) -> (round x)")
+ (lint-test "(inexact (+ 1.0 x))" " inexact: perhaps (inexact (+ 1.0 x)) -> (+ 1.0 x)")
(lint-test "(abs (magnitude 1+i))" " abs: perhaps (abs (magnitude 1+1i)) -> (magnitude 1+1i)")
(lint-test "(magnitude 2/3)" " magnitude: perhaps use abs here: (magnitude 2/3) magnitude: perhaps (magnitude 2/3) -> 2/3")
@@ -85702,6 +85820,7 @@ etc
(lint-test "(logxor 2 4 1)" " logxor: perhaps (logxor 2 4 1) -> 7")
(lint-test "(logxor x)" " logxor: perhaps (logxor x) -> x")
(lint-test "(logxor x x)" " logxor: perhaps (logxor x x) -> 0")
+ (lint-test "(integer-length 1)" " integer-length: perhaps (integer-length 1) -> 1")
(lint-test "(gcd x (gcd x y))" " gcd: perhaps (gcd x (gcd x y)) -> (gcd x y)")
(lint-test "(lcm x (lcm x y))" " lcm: perhaps (lcm x (lcm x y)) -> (lcm x y)")
@@ -85907,7 +86026,7 @@ etc
(lint-test "(if y)" " if: if has too few clauses: (if y)")
(lint-test "(if y z a b)" " if: if has too many clauses: (if y z a b)")
(lint-test "(if x y (if z y))" " if: perhaps (if x y (if z y)) -> (if (or x z) y)")
- (lint-test "(if x y (if x y))" " if: perhaps (if x y (if x y)) -> (if x y) if: perhaps (if x y (if x y)) -> (if x y)")
+ (lint-test "(if x y (if x y))" " if: perhaps (if x y (if x y)) -> (if x y) if: weird repetition! perhaps (if x y (if x y)) -> (if x y)")
(lint-test "(if x (if x y))" " if: perhaps (if x (if x y)) -> (if x y)")
(lint-test "(if x (set! y #t) (set! y #f))" " if: perhaps (if x (set! y #t) (set! y #f)) -> (set! y x)")
(lint-test "(if x (f 1 2 1) (f 1 2 2))" " if: perhaps (if x (f 1 2 1) (f 1 2 2)) -> (f 1 2 (if x 1 2))")
@@ -85915,6 +86034,7 @@ etc
(lint-test "(if x (f (+ x 1) (* y 2) (+ x 1)) (f (+ x 1) (+ x 1) (+ x 1)))"
" if: perhaps (if x (f (+ x 1) (* y 2) (+ x 1)) (f (+ x 1) (+ x 1) (+ x 1))) -> (f (+ x 1) (if x (* y 2) (+ x 1)) (+ x 1))")
(lint-test "(if (and (= x y) z) (+ x 1) #f)" " if: perhaps (if (and (= x y) z) (+ x 1) #f) -> (and (= x y) z (+ x 1))")
+ (lint-test "(if x (f y) (else z))" " if: else (as car of false branch of if) makes no sense: (if x (f y) (else z))")
(lint-test "(if x (set! y #f) (set! y #t))" " if: perhaps (if x (set! y #f) (set! y #t)) -> (set! y (not x))")
(lint-test "(if x (set! y x) (set! y 21))" " if: perhaps (if x (set! y x) (set! y 21)) -> (set! y (or x 21))")
@@ -85966,6 +86086,12 @@ etc
" if: perhaps (if a (if (not b) A B) (if (not b) B A)) -> (if (eq? (not a) (not b)) B A)")
(lint-test "(if a (if b A B) (if b A B))"
" if: if is not needed here: (if a (if b A B) (if b A B)) -> (if b A B)")
+ (lint-test "(if test (< a b) (> b a))" " if: if is not needed here: (if test (< a b) (> b a)) -> (< a b)")
+ (lint-test "(if test (< a b c) (> c b a))" " if: if is not needed here: (if test (< a b c) (> c b a)) -> (< a b c)")
+ (lint-test "(if test (* a b) (* b a))" " if: if is not needed here: (if test (* a b) (* b a)) -> (* a b)")
+ (lint-test "(if test (< a b) (not (>= a b)))"
+ " if: if is not needed here: (if test (< a b) (not (>= a b))) -> (< a b)
+ if: perhaps (not (>= a b)) -> (< a b)")
(lint-test "(if A (if B C #f) #f)" " if: perhaps (if A (if B C #f) #f) -> (and A B C) if: perhaps (if B C #f) -> (and B C)")
(lint-test "(if A (if B #f D) #f)" " if: perhaps (if A (if B #f D) #f) -> (and A (not B) D) if: perhaps (if B #f D) -> (and (not B) D)")
@@ -85983,7 +86109,9 @@ etc
(lint-test "(if x x)" " if: perhaps (if x x) -> (or x #<unspecified>)")
(lint-test "(if (> x 1) (> x 1))" " if: perhaps (if (> x 1) (> x 1)) -> (or (> x 1) #<unspecified>)")
(lint-test "(if (display x) (display x) y)" "")
- (lint-test "(if (= x 1) 2 (if (= x 3) 2 3))" " if: perhaps (if (= x 1) 2 (if (= x 3) 2 3)) -> (if (member x '(1 3) =) 2 3)")
+ (lint-test "(if (= x 1) 2 (if (= x 3) 2 3))"
+ "if: perhaps (if (= x 1) 2 (if (= x 3) 2 3)) -> (case x ((1) 2) ((3) 2) (else 3))
+ if: perhaps (if (= x 1) 2 (if (= x 3) 2 3)) -> (if (member x '(1 3) =) 2 3)")
(lint-test "(if a b (if c d (if e f g)))" " if: perhaps use cond: (if a b (if c d (if e f g))) -> (cond (a b) (c d) (e f) (else g))")
(lint-test "(if a b (if c d (if e f)))" " if: perhaps use cond: (if a b (if c d (if e f))) -> (cond (a b) (c d) (e f))")
(lint-test "(if a (begin (b) c) (if d e (if f g (begin (h) i))))"
@@ -86006,7 +86134,7 @@ etc
(lint-test "(if (= x y) y x)" " if: perhaps (if (= x y) y x) -> x")
(lint-test "(if (pair? x) #t #f)" " if: perhaps (if (pair? x) #t #f) -> (pair? x)")
(lint-test "(if (pair? x) #t z)" " if: perhaps (if (pair? x) #t z) -> (or (pair? x) z)")
- (lint-test "(if x (not y) (not z))" " if: perhaps (if x (not y) (not z)) -> (not (if x y z))")
+ (lint-test "(if x (not y) (not z))" "")
(lint-test "(if (> (vector-ref ind i) (vector-ref ind j)) (vector-set! ind i (vector-ref ind j)))"
" if: perhaps (if (> (vector-ref ind i) (vector-ref ind j)) (vector-set! ind i... ->
@@ -86139,7 +86267,19 @@ etc
" if: perhaps (if x (let ((y (abs x))) (display z) y) (let ((y (log x))) (display z) y)) ->
(let ((y ((if x abs log) x))) (display z) y)")
(lint-test "(if x (let loop1 ((x y)) (if (null? x) 1 (loop1 (cdr x)))) (let loop2 ((x z)) (if (null? x) 1 (loop2 (cdr x)))))"
- "") ; TODO: leaving aside free vars loop2: loop2 is the same as loop1
+ " loop1: perhaps (let loop1 ((x y)) (if (null? x) 1 (loop1 (cdr x)))) -> (do ((x y (cdr x))) ((null? x) 1))
+ loop2: perhaps (let loop2 ((x z)) (if (null? x) 1 (loop2 (cdr x)))) -> (do ((x z (cdr x))) ((null? x) 1))")
+ (lint-test "(let loop ((x y)) (case x ((1) (display b)) (else (display c) (loop (+ x 1)))))"
+ " loop: perhaps (let loop ((x y)) (case x ((1) (display b)) (else (display c) (loop (+ x 1))))) ->
+ (do ((x y (+ x 1))) ((memv x '(1)) (display b)) (display c))")
+ (lint-test "(let loop ((x y)) (when (zero? x) (loop (- x 1))))"
+ " loop: perhaps (let loop ((x y)) (when (zero? x) (loop (- x 1)))) -> (do ((x y (- x 1))) ((not (zero? x))))")
+ (lint-test "(let loop ((x y)) (unless (zero? x) (loop (- x 1))))"
+ " loop: perhaps (let loop ((x y)) (unless (zero? x) (loop (- x 1)))) -> (do ((x y (- x 1))) ((zero? x)))")
+ (lint-test "(let loop ((x y)) (when (zero? x) (display b) (loop (- x 1)) x))" "")
+ (lint-test "(let loop ((x y)) (when (zero? x) (display b) (loop (- x 1))))"
+ " loop: perhaps (let loop ((x y)) (when (zero? x) (display b) (loop (- x 1)))) -> (do ((x y (- x 1))) ((not (zero? x))) (display b))")
+
(lint-test "(if polar
(let ((vals (parse-polar-coordinates points 3d)))
(set! (bezier-x xpath) (car vals))
@@ -86167,13 +86307,45 @@ etc
if: perhaps (let ((a 32) (b 31) (c 11)) (f a b c)) -> (f 32 31 11)")
(lint-test "(if x (for-each (lambda (x) (display (+ x a))) (f y)) (for-each (lambda (x) (display (+ x a))) (g y)))"
" if: perhaps (if x (for-each (lambda (x) (display (+ x a))) (f y)) (for-each (lambda... ->
- (let ((_1_ x)) (for-each (lambda (x) (display (+ x a))) ((if _1_ f g) y)))") ; overly cautious
+ (for-each (lambda (x) (display (+ x a))) ((if x f g) y))")
(lint-test "(cond (x (for-each (lambda (x) (display (+ x a))) (f y))) (else (for-each (lambda (x) (display (+ x a))) (g y))))"
" cond: perhaps (cond (x (for-each (lambda (x) (display (+ x a))) (f y))) (else (for-each... ->
(for-each (lambda (x) (display (+ x a))) (if x (f y) (g y)))")
(lint-test "(if x (for-each (lambda (x) (display (+ x a))) (f y)) (for-each (lambda (x) (display (+ x b))) (f y)))"
" if: perhaps (if x (for-each (lambda (x) (display (+ x a))) (f y)) (for-each (lambda... ->
- (let ((_1_ x)) (for-each (lambda (x) (display (+ x (if _1_ a b)))) (f y)))")
+ (for-each (lambda (x) (display (+ x (if x a b)))) (f y))")
+ (lint-test "(let loop ((lst x) (res ())) (if (null? lst) (reverse res) (loop (cdr lst) (cons (car lst) res))))"
+ " loop: perhaps (let loop ((lst x) (res ())) (if (null? lst) (reverse res) (loop (cdr lst)... -> (copy x)")
+ (lint-test "(let loop ((lst x) (res ())) (if (not (pair? lst)) (reverse res) (loop (cdr lst) (cons (caar lst) res))))"
+ " loop: perhaps (let loop ((lst x) (res ())) (if (not (pair? lst)) (reverse res) (loop... -> (map car x)")
+ (lint-test "(let loop ((lst x) (res ())) (if (not (pair? lst)) (reverse res) (loop (cdr lst) (append (z w (car lst) v) res))))"
+ " loop: perhaps (let loop ((lst x) (res ())) (if (not (pair? lst)) (reverse res) (loop... -> (map (lambda (_1_) (apply values (z w _1_ v))) x)")
+ (lint-test "(let loop ((lst x) (res ())) (if (not (pair? lst)) (reverse res) (loop (cons (caar lst) res) (cdr lst))))" "") ; reversed loop args so nothing to rewrite
+ (lint-test "(let loop ((res ()) (lst x)) (if (pair? lst) (loop (let ((a (g (car lst)))) (cons a res)) (cdr lst)) (reverse! res)))"
+ " loop: perhaps (let loop ((res ()) (lst x)) (if (pair? lst) (loop (let ((a (g (car... -> (map (lambda (_1_) (let ((a (g _1_))) a)) x)
+ loop: perhaps (let ((a (g (car lst)))) (cons a res)) -> (cons (g (car lst)) res)")
+ (lint-test "(let loop ((res ()) (lst x)) (if (pair? lst) (loop (let ((a (g (cadar lst)))) (if (g a) (cons a res) res)) (cdr lst)) (reverse! res)))"
+ " loop: perhaps (let loop ((res ()) (lst x)) (if (pair? lst) (loop (let ((a (g (cadar... ->
+ (map (lambda (_1_) (let ((a (g (cadr _1_)))) (if (g a) a (values)))) x)")
+ (lint-test "(let loop ((lst x) (res ())) (if (null? lst) (reverse res) (loop (cdr lst) (if (g z) res (cons (car lst) res)))))"
+ " loop: perhaps (let loop ((lst x) (res ())) (if (null? lst) (reverse res) (loop (cdr lst)... -> (map (lambda (_1_) (if (g z) (values) _1_)) x)")
+ (lint-test "(let loop ((lst x) (res ())) (cond ((null? lst) (reverse res)) (else (loop (cdr lst) (cons (car lst) res)))))"
+ " loop: perhaps (let loop ((lst x) (res ())) (cond ((null? lst) (reverse res)) (else (loop... -> (copy x)")
+ (lint-test "(let loop ((x y)) (if (null? x) () (let ((p (car x))) (cons p (loop (cdr x))))))"
+ " loop: perhaps (let loop ((x y)) (if (null? x) () (let ((p (car x))) (cons p (loop (cdr x)))))) -> (copy y)")
+
+ (lint-test "(if (char=? (str i) #\\]) (set! (str i) #\\)) (if (char=? (str i) #\\[) (set! (str i) #\\()))"
+ " if: perhaps (if (char=? (str i) #\\]) (set! (str i) #\\)) (if (char=? (str i) #\\[) (set!... ->
+ (case (str i) ((#\\]) (set! (str i) #\\))) ((#\\[) (set! (str i) #\\()))")
+ (lint-test "(if (char=? (str i) #\\]) (set! (str i) #\\)) (if (char=? (str i) #\\[) (set! (str i) #\\() (set! x y)))"
+ " if: perhaps (if (char=? (str i) #\\]) (set! (str i) #\\)) (if (char=? (str i) #\\[) (set!... ->
+ (case (str i) ((#\\]) (set! (str i) #\\))) ((#\\[) (set! (str i) #\\()) (else (set! x y)))")
+ (lint-test "(if (char=? (str i) #\\]) (set! (str i) #\\)) (if (char=? (str i) #\\[) (set! (str i) #\\() (if (char=? (str i) #\\a) (set! x y))))"
+ " if: perhaps use cond: (if (char=? (str i) #\\]) (set! (str i) #\\)) (if (char=? (str i) #\\[) (set!... ->
+ (cond ((char=? (str i) #\\]) (set! (str i) #\\))) ((char=? (str i) #\\[) (set! (str i) #\\()) ((char=? (str i) #\\a) (set! x y)))
+ if: perhaps (if (char=? (str i) #\\]) (set! (str i) #\\)) (if (char=? (str i) #\\[) (set!... ->
+ (case (str i) ((#\\]) (set! (str i) #\\))) ((#\\[) (set! (str i) #\\()) ((#\\a) (set! x y)))")
+ (lint-test "(if (= x 1) 2 (if (= x 3) 3 4))" " if: perhaps (if (= x 1) 2 (if (= x 3) 3 4)) -> (case x ((1) 2) ((3) 3) (else 4))")
(lint-test "(begin (if A (f B) (g C)) (if (and A D) (g Z)) X)"
" begin: perhaps (... (if A (f B) (g C)) (if (and A D) (g Z)) ...) -> (... (if A (begin (f B) (when D (g Z))) (g C)) ...)")
@@ -86221,11 +86393,16 @@ etc
" if: perhaps (if x (begin (display y) (set! y z) (display x)) (begin (display y) (set!... ->
(begin (display y) (if x (set! y z) (set! z y)) (display x))")
- (lint-test "(if A (let () (display x)))" " if: perhaps (if A (let () (display x))) -> (when A (display x))")
- (lint-test "(if A B (let () (display x)))" " if: perhaps (if A B (let () (display x))) -> (if A B (begin (display x)))")
+ (lint-test "(if A (let () (display x)))"
+ " if: perhaps (if A (let () (display x))) -> (when A (display x))
+ if: pointless let: (let () (display x))")
+ (lint-test "(if A B (let () (display x)))"
+ " if: perhaps (if A B (let () (display x))) -> (if A B (begin (display x)))
+ if: pointless let: (let () (display x))")
(lint-test "(if A (let () (set! x z) (display x)) (let () (write y)))"
- " if: perhaps (if A (let () (set! x z) (display x)) (let () (write y))) -> (if A (begin (set! x z) (display x)) (begin (write y)))")
-
+ " if: perhaps (if A (let () (set! x z) (display x)) (let () (write y))) -> (if A (begin (set! x z) (display x)) (begin (write y)))
+ if: let could be begin: (let () (set! x z) (display x)) -> (begin (set! x z) (display x))
+ if: pointless let: (let () (write y))")
(lint-test "(if A (if B (+ x 1)) (if B (- x 1)))"
" if: perhaps (if A (if B (+ x 1)) (if B (- x 1))) -> (if B (if A (+ x 1) (- x 1)))")
(lint-test "(if A (begin (f x) (g y)) (begin (f x) (g z)))"
@@ -86608,6 +86785,8 @@ etc
(lint-test "(cond (A #f) (B) (else C))" " cond: perhaps (cond (A #f) (B) (else C)) -> (and (not A) (or B C))")
(lint-test "(cond (A) (B C) (else #f))" " cond: perhaps (cond (A) (B C) (else #f)) -> (or A (and B C))")
(lint-test "(cond ((getenv s) x) ((= y z) w))" " cond: cond test (getenv s) is never false: (cond ((getenv s) x) ((= y z) w))")
+ (lint-test "(cond (A #f) (B #f))" " cond: perhaps (cond (A #f) (B #f)) -> (if (or A B) #f)")
+ (lint-test "(cond (A C) (B C))" " cond: perhaps (cond (A C) (B C)) -> (if (or A B) C)")
(lint-test "(cond ((and (pair? x) (pair? y) (pair? z)) 32) ((and (pair? x) (pair? y) (pair? w)) 12) ((and (pair? x) (pair? y) (pair? v)) 2))"
" cond: perhaps
@@ -86726,6 +86905,7 @@ etc
(lint-test "(> x (- y 1))" "") ; only optimizable if x and y are known to be integers
(lint-test "(< x 1 2 y)" "")
(lint-test "(< x 1 y)" "")
+ (lint-test "(< 0 (floor x) 1)" " <: perhaps (< 0 (floor x) 1) -> #f")
(lint-test "(< x x)" " <: this looks odd: (< x x)")
(lint-test "(< x y x)" " <: it looks odd to have repeated arguments in (< x y x) <: perhaps (< x y x) -> #f")
(lint-test "(< x x y)" " <: it looks odd to have repeated arguments in (< x x y) <: perhaps (< x x y) -> #f")
@@ -86737,6 +86917,14 @@ etc
(lint-test "(< (char->integer x) 95)" " <: perhaps (< (char->integer x) 95) -> (char<? x #\\_)")
(lint-test "(>= (char->integer x) 90 (char->integer y))" " >=: perhaps (>= (char->integer x) 90 (char->integer y)) -> (char>=? x #\\Z y)")
(lint-test "(> (abs x) -1)" " >: abs can't be negative: (> (abs x) -1)")
+ (lint-test "(or (= (denominator n) 1) (= (denominator n) 0))"
+ " or: perhaps (or (= (denominator n) 1) (= (denominator n) 0)) -> (member (denominator n) '(1 0) =)
+ or: perhaps (= (denominator n) 1) -> (integer? n)
+ or: denominator is never 0: (= (denominator n) 0)")
+ (lint-test "(or (> (denominator n) 0) (<= (denominator n) 0))"
+ " or: perhaps (or (> (denominator n) 0) (<= (denominator n) 0)) -> #t
+ or: denominator is always > than 0: (> (denominator n) 0)
+ or: denominator is never <= than 0: (<= (denominator n) 0)")
(lint-test "(string>? \"a\" x \"b\" y)" " string>?: this comparison can't be true: (string>? \"a\" x \"b\" y)")
(lint-test "(copy (copy x))" " copy: (copy (copy x)) could be (copy x)")
@@ -86754,6 +86942,7 @@ etc
(lint-test "(string-ref x (cons 1 2))"
" string-ref: in (string-ref x (cons 1 2)), string-ref's argument 2 should be an integer, but (cons 1 2) is a pair?")
(lint-test "(string-copy (string-copy x))" " string-copy: (string-copy (string-copy x)) could be (string-copy x)")
+
(lint-test "(string-append x)" " string-append: perhaps (string-append x) -> x, or use copy")
(lint-test "(string-append \"\" \"\" x)" " string-append: perhaps (string-append \"\" \"\" x) -> x, or use copy")
(lint-test "(string-append \"\" \"\")" " string-append: perhaps (string-append \"\" \"\") -> \"\"")
@@ -86761,10 +86950,13 @@ etc
(lint-test "(string-append \"123\" \"456\")" " string-append: perhaps (string-append \"123\" \"456\") -> \"123456\"")
(lint-test "(string-append x (string-append y z))" " string-append: perhaps (string-append x (string-append y z)) -> (string-append x y z)")
(lint-test "(string-append x \"a\" \"bc\" y)" " string-append: perhaps (string-append x \"a\" \"bc\" y) -> (string-append x \"abc\" y)")
- (lint-test "(vector-append)" " vector-append: perhaps (vector-append) -> #()")
- (lint-test "(vector-append x)" " vector-append: perhaps (vector-append x) -> (copy x)")
+
+ (lint-test "(vector-append)" " vector-append: perhaps (vector-append) -> #()")
+ (lint-test "(vector-append x)" " vector-append: perhaps (vector-append x) -> (copy x)")
(lint-test "(vector-append #(1 2) (vector-append #(3)))" " vector-append: perhaps (vector-append #(1 2) (vector-append #(3))) -> #(1 2 3)")
(lint-test "(vector-append x (vector-append y z))" " vector-append: perhaps (vector-append x (vector-append y z)) -> (vector-append x y z)")
+ (lint-test "(vector-append v1 (apply vector-append vs))"
+ " vector-append: perhaps (vector-append v1 (apply vector-append vs)) -> (vector-append v1 (apply values vs))")
(lint-test "(object->string (object->string x))" " object->string: (object->string (object->string x)) could be (object->string x)")
(lint-test "(object->string x :else)" " object->string: bad second argument: :else")
@@ -86841,7 +87033,7 @@ etc
(lint-test "(list->vector (sort! (vector->list x) y))" " list->vector: perhaps (list->vector (sort! (vector->list x) y)) -> (sort! x y)")
(lint-test "(list->string (sort! (string->list x) y))" " list->string: perhaps (list->string (sort! (string->list x) y)) -> (sort! x y)")
(lint-test "(string->list x y y)" " string->list: these string->list indices make no sense: (string->list x y y)")
- (lint-test "(symbol->keyword (string->symbol x))" " symbol->keyword: perhaps (symbol->keyword (string->symbol x)) -> (make-keyword x)")
+ (lint-test "(symbol->keyword (string->symbol x))" " symbol->keyword: perhaps (symbol->keyword (string->symbol x)) -> (string->keyword x)")
(lint-test "(vector->list (vector a b c))" " vector->list: perhaps (vector->list (vector a b c)) -> (list a b c)")
(lint-test "(vector->list (vector-copy v start end))" " vector->list: perhaps (vector->list (vector-copy v start end)) -> (vector->list v start end)")
(lint-test "(string->list (string a b c))" " string->list: perhaps (string->list (string a b c)) -> (list a b c)")
@@ -86906,6 +87098,24 @@ etc
" begin: perhaps (set! x (append x y)) (set! x (append x z w)) -> (set! x (append x y z w))")
(lint-test "(append x (copy y) z)" " append: perhaps (append x (copy y) z) -> (append x y z)")
(lint-test "(append x (copy y))" "")
+ (lint-test "(append (cons x y) z)" " append: perhaps (append (cons x y) z) -> (cons x (append y z))")
+ (lint-test "(append (list x y) (list z))" " append: perhaps (append (list x y) (list z)) -> (list x y z)")
+ (lint-test "(append (list x y) (cons z ()))"
+ " append: perhaps (append (list x y) (cons z ())) -> (list x y z)
+ append: perhaps (cons z ()) -> (list z)")
+ (lint-test "(append (list w) (list x y) (list z))" " append: perhaps (append (list w) (list x y) (list z)) -> (list w x y z)")
+ (lint-test "(append (list w) (list x y) (cons z ()))"
+ " append: perhaps (append (list w) (list x y) (cons z ())) -> (list w x y z)
+ append: perhaps (cons z ()) -> (list z)")
+ (lint-test "(append (cons x ()) (list y w z))"
+ " append: perhaps (append (cons x ()) (list y w z)) -> (list x y w z)
+ append: perhaps (cons x ()) -> (list x)")
+ (lint-test "(append (cons a ()) c)"
+ " append: perhaps (append (cons a ()) c) -> (cons a c)
+ append: perhaps (cons a ()) -> (list a)")
+ (lint-test "(append (list a b) (cons c d))" " append: perhaps (append (list a b) (cons c d)) -> (cons a (cons b (cons c d)))")
+ (lint-test "(append (apply append x) y)" " append: perhaps (append (apply append x) y) -> (append (apply values x) y)")
+ (lint-test "(append (cons x y) z w)" " append: perhaps (append (cons x y) z w) -> (cons x (append y z w))")
(lint-test "(cons x (list y z))" " cons: perhaps (cons x (list y z)) -> (list x y z)")
(lint-test "(cons x (list))" " cons: perhaps (cons x (list)) -> (list x)")
@@ -86924,7 +87134,8 @@ etc
(lint-test "(cons 'x (or y (list 'z)))" "") ; quote for list here is incorrect
(lint-test "`(,@x ,@(map (lambda (z) `(,z ,@z)) y))"
- " {list}: perhaps ({list} ({apply_values} x) ({apply_values} (map (lambda (z) ({list} z... -> (append x (map (lambda (z) (cons z z)) y))")
+ " {list}: perhaps ({list} ({apply_values} x) ({apply_values} (map (lambda (z) ({list} z... -> (append x (map (lambda (z) (cons z z)) y))
+ {list}: perhaps ({list} z ({apply_values} z)) -> (cons z z)")
(lint-test "`(,@x ,@(map (lambda (z) `(,@z ,@z)) y))"
" {list}: perhaps ({list} ({apply_values} x) ({apply_values} (map (lambda (z) ({list}... -> (append x (map (lambda (z) (append z z)) y))
{list}: perhaps ({list} ({apply_values} z) ({apply_values} z)) -> (append z z)")
@@ -86936,6 +87147,11 @@ etc
(lint-test "(values `(,x ,@y) z)" " values: perhaps (values ({list} x ({apply_values} y)) z) -> (values (cons x y) z)")
(lint-test "(values `(,@x ,@y) `(,x z))"
" values: perhaps (values ({list} ({apply_values} x) ({apply_values} y)) ({list} x 'z)) -> (values (append x y) (list x 'z))")
+ (lint-test "(define (g x) `(+ ,y ,@(map f x)))" " g: perhaps ({list} '+ y ({apply_values} (map f x))) -> (cons '+ (cons y (map f x)))")
+ (lint-test "(define (g x) `(+ ,@(map f x)))" " g: perhaps ({list} '+ ({apply_values} (map f x))) -> (cons '+ (map f x))")
+ (lint-test "(define (g x) `(,e ,@(map f x)))" " g: perhaps ({list} e ({apply_values} (map f x))) -> (cons e (map f x))")
+ (lint-test "(define (g x) `(f ,@x ,@y))" " g: perhaps ({list} 'f ({apply_values} x) ({apply_values} y)) -> (cons 'f (append x y))")
+ (lint-test "(define (g x) `(display ,(map f x)))" " g: perhaps ({list} 'display (map f x)) -> (list 'display (map f x))")
(lint-test "(sort! x abs)" " sort!: abs is a questionable sort! function")
(lint-test "(sort! x (lambda (a b) (< a b)))" " sort!: perhaps (lambda (a b) (< a b)) -> <")
@@ -87112,7 +87328,7 @@ etc
(lint-test "(let ((x (f y))) (cond (x (set-cdr! x y)) (else y)))"
" in (cond (x (set-cdr! x y)) (else y)), perhaps change x to (pair? x)")
(lint-test "(let () (let ((a x)) (+ a 1)))"
- " let: pointless let: (let () (let ((a x)) (+ a 1))) -> (let ((a x)) (+ a 1))
+ " let: pointless let: (let () (let ((a x)) (+ a 1)))
let: perhaps (let () (let ((a x)) (+ a 1))) -> (let ((a x)) (+ a 1))
let: perhaps (let ((a x)) (+ a 1)) -> (+ x 1)
let: assuming we see all set!s, the binding (a x) is pointless: perhaps (let ((a x)) (+ a 1)) -> (let () (+ x 1))")
@@ -87143,6 +87359,15 @@ etc
(lint-test "(let ((x (undo-edit))) (set! y (or y x)))"
" let: perhaps, ignoring short-circuit issues, (let ((x (undo-edit))) (set! y (or y x))) -> (set! y (or y (undo-edit)))
let: perhaps (set! y (or y x)) -> (if (not y) (set! y x))")
+ (lint-test "(let ((x #(0 0))) (fill! x 1) (f x (x 1)))"
+ " let: perhaps (let ((x #(0 0))) (fill! x 1) (f x (x 1))) -> (let ((x #(1 1))) (f x (x 1)))")
+ (lint-test "(let ((x (make-vector 3))) (fill! x 1) (f x (x 1)))"
+ " let: perhaps (let ((x (make-vector 3))) (fill! x 1) (f x (x 1))) -> (let ((x (make-vector 3 1))) (f x (x 1)))")
+ (lint-test "(let ((x (make-list 3 9))) (fill! x 1) (f x (x 1)))"
+ " let: perhaps (let ((x (make-list 3 9))) (fill! x 1) (f x (x 1))) -> (let ((x (make-list 3 1))) (f x (x 1)))")
+ (lint-test "(let ((v (make-vector 3))) (vector-fill! v 3))"
+ " let: perhaps (let ((v (make-vector 3))) (vector-fill! v 3)) -> (vector-fill! (make-vector 3) 3)
+ let: perhaps (let ((v (make-vector 3))) (vector-fill! v 3)) -> (let () 3)")
(lint-test "(let ((x 1)) (set! x 2) (+ x 1))"
" let: perhaps (let ((x 1)) (set! x 2) (+ x 1)) -> (let ((x 2)) (+ x 1))")
@@ -87170,9 +87395,12 @@ etc
(lint-test "(let ((a 0)) (display x) (set! a 2) (+ a 1))"
" let: perhaps change a's initial value to 2, and remove (set! a 2) in (let ((a 0)) (display x) (set! a 2) (+ a 1))")
- (lint-test "(let () (error 'oops \"an error\") #t)" " let: (error 'oops \"an error\") makes this pointless: #t")
+ (lint-test "(let () (error 'oops \"an error\") #t)"
+ " let: let could be begin: (let () (error 'oops \"an error\") #t) -> (begin (error 'oops \"an error\") #t)
+ let: (error 'oops \"an error\") makes this pointless: #t")
(lint-test "(let () (error 'oops \"an error\") (display \"oops\") #t)"
- " let: (error 'oops \"an error\") makes the rest of the body unreachable: (... (display \"oops\") ...)")
+ " let: let could be begin: (let () (error 'oops \"an error\") (display \"oops\") #t) -> (begin (error 'oops \"an error\") (display \"oops\") #t)
+ let: (error 'oops \"an error\") makes the rest of the body unreachable: (... (display \"oops\") ...)")
(lint-test "(let ((a 1)) (let ((b 2)) (let ((c 3)) (let ((d 4)) (+ a b c d)))))"
" let: perhaps (let ((d 4)) (+ a b c d)) -> (+ a b c 4)
let: perhaps (let ((c 3)) (let ((d 4)) (+ a b c d))) -> (let ((c 3) (d 4)) (+ a b c d))
@@ -87193,16 +87421,19 @@ etc
let: assuming we see all set!s, the binding (y x) is pointless: perhaps (let ((x 1) (y x)) (+ x y)) -> (let ((x 1)) (+ x x))")
(lint-test "(let ((x 0)) (define* (f52 (a 2)) (if (zero? a) x (f52 (- a 1)))) (display x) (if (zero? x) (+ 1 (f52 x))))"
" let: perhaps (... (define* (f52 (a 2)) (if (zero? a) x (f52 (- a 1)))) (display x) (if... ->
- (... (display x) (if (zero? x) (+ 1 (let* f52 ((a x)) (if (zero? a) x (f52 (- a 1)))))))
+ (... (display x) (if (zero? x) (+ 1 (let* f52 ((a x)) (if (zero? a) x (f52 (- a 1)))))))
+ f52: perhaps (define* (f52 (a 2)) (if (zero? a) x (f52 (- a 1)))) -> (define* (f52 (a 2)) (do ((a a (- a 1))) ((zero? a) x)))
let: x is 0, so (zero? x) is #t")
(lint-test "(let ((x 0)) (define (f52) (if (zero? a) x (f52))) (f52))"
" let: perhaps (... (define (f52) (if (zero? a) x (f52))) (f52)) -> (... (let f52 () (if (zero? a) x (f52))))
x is used only in f52")
(lint-test "(let ((x 0)) (define (f52 x) (if (zero? a) x (f52 x))) (f52 x))"
- " let: perhaps (... (define (f52 x) (if (zero? a) x (f52 x))) (f52 x)) -> (... (let f52 ((x x)) (if (zero? a) x (f52 x))))")
+ " let: perhaps (... (define (f52 x) (if (zero? a) x (f52 x))) (f52 x)) -> (... (let f52 ((x x)) (if (zero? a) x (f52 x))))
+ f52: perhaps (define (f52 x) (if (zero? a) x (f52 x))) -> (define (f52 x) (do ((x x)) ((zero? a) x)))")
(lint-test "(let ((x 0)) (define* (f52 (a 2)) (if (zero? a) x (f52 (- a 1)))) (if (zero? x) (+ 1 (f52 x))))"
" let: perhaps (... (define* (f52 (a 2)) (if (zero? a) x (f52 (- a 1)))) (if (zero? x) (+... ->
- (... (if (zero? x) (+ 1 (let* f52 ((a x)) (if (zero? a) x (f52 (- a 1)))))))
+ (... (if (zero? x) (+ 1 (let* f52 ((a x)) (if (zero? a) x (f52 (- a 1)))))))
+ f52: perhaps (define* (f52 (a 2)) (if (zero? a) x (f52 (- a 1)))) -> (define* (f52 (a 2)) (do ((a a (- a 1))) ((zero? a) x)))
let: x is 0, so (zero? x) is #t")
(lint-test "(define (f x) (let ((y 2)) (set! x (+ x y)) (set! y (+ y 1)) (set! x (+ x 1)) (display x)))"
" f: (set! y (+ y 1)) in (let ((y 2)) (set! x (+ x y)) (set! y (+ y 1)) (set! x (+ x 1)) (display x)) could be omitted
@@ -87214,7 +87445,9 @@ etc
(set! x (+ x 1)) ...")
(lint-test "(define (f a) (let ((x 1) (y 2) (z (vector 3))) (vector-set! z 0 (+ x 1)) (display y) (newline) (+ y (vector-ref z 0))))"
- " f: x is only used in expression 1 (of 4), (vector-set! z 0 (+ x 1)) of
+ " f: y can probably be moved to f's closure
+ f: x can be moved to f's closure
+ f: x is only used in expression 1 (of 4), (vector-set! z 0 (+ x 1)) of
(let ((x 1) (y 2) (z (vector 3))) (vector-set! z 0 (+ x 1)) (display y)...
f: the scope of x could be reduced:
(let ((x 1) (y 2) (z (vector 3))) (vector-set! z 0 (+ x 1)) (display y)... ->
@@ -87225,9 +87458,10 @@ etc
(display y)
...)")
(lint-test "(define (f a) (let ((x 1) (y 2) (z (vector 3 4))) (vector-set! z 0 (+ x 1)) (display (vector-ref z x)) (set! y (+ y 1)) (newline) (+ y 1)))"
- " f: x is only used in expressions 1 and 2 (of 5), (vector-set! z 0 (+ x 1)) (display (vector-ref z x)) of
+ "f: x can be moved to f's closure
+ f: x is only used in expressions 1 and 2 (of 5), (vector-set! z 0 (+ x 1)) (display (vector-ref z x)) of
(let ((x 1) (y 2) (z (vector 3 4))) (vector-set! z 0 (+ x 1)) (display...
- f: the scope of x, z could be reduced:
+ f: the scope of x, z could be reduced:
(let ((x 1) (y 2) (z (vector 3 4))) (vector-set! z 0 (+ x 1)) (display... ->
(let ((y 2))
(let ((x 1)
@@ -87237,9 +87471,9 @@ etc
(set! y (+ y 1))
...)")
(lint-test "(define (f a) (let* ((x 1) (y (+ x 2)) (z (vector 3))) (vector-set! z 0 (+ x 1)) (display y) (newline) (+ y x)))"
- " f: perhaps split this let*: (let* ((x 1) (y (+ x 2)) (z (vector 3))) (vector-set! z 0 (+ x 1))... ->
+ "f: perhaps split this let*: (let* ((x 1) (y (+ x 2)) (z (vector 3))) (vector-set! z 0 (+ x 1))... ->
(let ((x 1)) (let ((y (+ x 2)) (z (vector 3))) ...))
- f: the scope of z could be reduced:
+ f: the scope of z could be reduced:
(let* ((x 1) (y (+ x 2)) (z (vector 3))) (vector-set! z 0 (+ x 1))... ->
(let* ((x 1)
(y (+ x 2)))
@@ -87294,6 +87528,16 @@ etc
" let: perhaps move the let into the '((0) (display (g a b))) branch:
(let ((a (car x))) (case b ((0) (display (g a b))) (else (set! y z)... ->
(case b ((0) (let ((a (car x))) (display (g a b)))) ...)")
+ (lint-test "(if z (let () (* 2 y)))"
+ " if: perhaps (if z (let () (* 2 y))) -> (when z (* 2 y))
+ if: pointless let: (let () (* 2 y))
+ if: perhaps (let () (* 2 y)) -> (* 2 y)")
+ (lint-test "(if z (let () (display y) (* 2 y)))"
+ " if: perhaps (if z (let () (display y) (* 2 y))) -> (when z (display y) (* 2 y))
+ if: let could be begin: (let () (display y) (* 2 y)) -> (begin (display y) (* 2 y))")
+
+ (lint-test "(let ((v 3)) v)" " let: perhaps (let ((v 3)) v) -> 3") ; this aimed at a lint bug
+ (lint-test "(let ((v (make-vector 3))) #f)" " let: v not used, initially: (make-vector 3) from let") ; also same bug
(lint-test "(eq? x '())" " eq?: perhaps (eq? x '()) -> (null? x) eq?: quote is not needed here: '()")
(lint-test "(equal? x '#())" " equal?: quote is not needed here: '#()")
@@ -87448,31 +87692,48 @@ etc
(lint-test "(quote 3 4)" " quote: quote has too many arguments: (quote 3 4)")
(lint-test "'#(0)" " quote: quote is not needed here: '#(0)")
- (lint-test "(let () (when a (+ x 1)) y)" " let: this could be omitted: (when a (+ x 1))")
- (lint-test "(let () (unless a (+ x 1)) y)" " let: this could be omitted: (unless a (+ x 1))")
- (lint-test "(let () (cond ((< x y) 3) ((< y z) 4)) (+ x 1))" " let: this could be omitted: (cond ((< x y) 3) ((< y z) 4))")
+ (lint-test "(let () (when a (+ x 1)) y)"
+ " let: let could be begin: (let () (when a (+ x 1)) y) -> (begin (when a (+ x 1)) y)
+ let: this could be omitted: (when a (+ x 1))")
+ (lint-test "(let () (unless a (+ x 1)) y)"
+ " let: let could be begin: (let () (unless a (+ x 1)) y) -> (begin (unless a (+ x 1)) y)
+ let: this could be omitted: (unless a (+ x 1))")
+ (lint-test "(let () (cond ((< x y) 3) ((< y z) 4)) (+ x 1))"
+ " let: let could be begin: (let () (cond ((< x y) 3) ((< y z) 4)) (+ x 1)) -> (begin (cond ((< x y) 3) ((< y z) 4)) (+ x 1))
+ let: this could be omitted: (cond ((< x y) 3) ((< y z) 4))")
(lint-test "(let () (case x ((0) 1) (else 2)) x)"
- " let: this could be omitted: (case x ((0) 1) (else 2))
+ " let: let could be begin: (let () (case x ((0) 1) (else 2)) x) -> (begin (case x ((0) 1) (else 2)) x)
+ let: this could be omitted: (case x ((0) 1) (else 2))
let: perhaps (case x ((0) 1) (else 2)) -> (if (eqv? x 0) 1 2)")
(lint-test "(begin (let ((a (+ x 1)) (b 2)) (+ a b)) 32)"
" begin: perhaps (begin (let ((a (+ x 1)) (b 2)) (+ a b)) 32) -> (let ((a (+ x 1)) (b 2)) (+ a b) 32)
begin: this could be omitted: (let ((a (+ x 1)) (b 2)) (+ a b))
begin: perhaps (let ((a (+ x 1)) (b 2)) (+ a b)) -> (+ (+ x 1) 2)")
- (lint-test "(begin (if x y z) a)" " begin: this could be omitted: (if x y z)")
- (lint-test "(lambda (a) (if x y z) a)" " lambda: this could be omitted: (if x y z)")
+ (lint-test "(begin (if x y z) a)" " begin: this could be omitted: (if x y z)")
+ (lint-test "(lambda (a) (if x y z) a)" " lambda: this could be omitted: (if x y z)")
(lint-test "(lambda (a) (case x ((0) 1) (else x)) a)"
" lambda: this could be omitted: (case x ((0) 1) (else x))
lambda: perhaps (case x ((0) 1) (else x)) -> (if (eqv? x 0) 1 x)")
(lint-test "(let () (do ((i 0 (+ i 1))) ((= i 1))) x)"
- " let: this could be omitted: (do ((i 0 (+ i 1))) ((= i 1))) let: this do-loop could be replaced by (): (do ((i 0 (+ i 1))) ((= i 1)))")
+ " let: let could be begin: (let () (do ((i 0 (+ i 1))) ((= i 1))) x) -> (begin (do ((i 0 (+ i 1))) ((= i 1))) x)
+ let: this could be omitted: (do ((i 0 (+ i 1))) ((= i 1)))
+ let: this do-loop could be replaced by (): (do ((i 0 (+ i 1))) ((= i 1)))")
(lint-test "(let () (write-byte i) (write-byte i) (write-byte i) (write-byte i) (write-byte i) (newline))"
- " let: perhaps (write-byte i)... -> (do ((_1_ 0 (+ _1_ 1))) ((= _1_ 5)) (write-byte i))")
+ " let: let could be begin: (let () (write-byte i) (write-byte i) (write-byte i) (write-byte i)... ->
+ (begin (write-byte i) (write-byte i) (write-byte i) (write-byte i)...
+ let: perhaps (write-byte i)... -> (do ((_1_ 0 (+ _1_ 1))) ((= _1_ 5)) (write-byte i))")
(lint-test "(let () (write-byte 0) (write-byte 0) (write-byte 0) (write-byte 0) (write-byte 0))"
- " let: perhaps (write-byte 0)... -> (do ((i 0 (+ i 1))) ((= i 5)) (write-byte 0))")
+ " let: let could be begin: (let () (write-byte 0) (write-byte 0) (write-byte 0) (write-byte 0)... ->
+ (begin (write-byte 0) (write-byte 0) (write-byte 0) (write-byte 0)...
+ let: perhaps (write-byte 0)... -> (do ((i 0 (+ i 1))) ((= i 5)) (write-byte 0))")
(lint-test "(let () (write-byte 0) (write-byte 1) (write-byte 2) (write-byte 3) (write-byte 4))"
- " let: perhaps (write-byte 0)... -> (for-each write-byte '(0 1 2 3 4))")
+ " let: let could be begin: (let () (write-byte 0) (write-byte 1) (write-byte 2) (write-byte 3)... ->
+ (begin (write-byte 0) (write-byte 1) (write-byte 2) (write-byte 3)...
+ let: perhaps (write-byte 0)... -> (for-each write-byte '(0 1 2 3 4))")
(lint-test "(let () (write-byte 0) (write-byte 1) (write-byte 2) (write-byte 3) (write-byte (* x 2)))"
- " let: perhaps (write-byte 0)... -> (for-each write-byte (vector 0 1 2 3 (* x 2)))")
+ " let: let could be begin: (let () (write-byte 0) (write-byte 1) (write-byte 2) (write-byte 3)... ->
+ (begin (write-byte 0) (write-byte 1) (write-byte 2) (write-byte 3)...
+ let: perhaps (write-byte 0)... -> (for-each write-byte (vector 0 1 2 3 (* x 2)))")
(lint-test "(let () (writ 0) (writ 1) (writ 2) (writ 3) (writ (* x 2)))"
" let: assuming writ is not a macro, perhaps (... (writ 0) ...) -> (for-each writ (vector 0 1 2 3 (* x 2)))")
(lint-test "(let () (writ 0) (writ 1) (writ) (writ 3) (writ (* x 2)))" "")
@@ -87682,14 +87943,16 @@ etc
(display (+ i j))
(_1_ j i (+ k 1)))))")
(lint-test "(do ((i 0 (+ i 1))) ((= i 3)) (let ((a 12)) (set! a (+ a i)) (display a)))"
- " do: perhaps (do ((i 0 (+ i 1))) ((= i 3)) (let ((a 12)) (set! a (+ a i)) (display a))) ->
+ " do: perhaps (let ((a 12)) (set! a (+ a i)) (display a)) -> (let ((a (+ 12 i))) (display a))
+ do: perhaps (do ((i 0 (+ i 1))) ((= i 3)) (let ((a 12)) (set! a (+ a i)) (display a))) ->
(do ((i 0 (+ i 1)) (a 12 12)) ((= i 3)) (set! a (+ a i)) ...)")
(lint-test "(do ((i 0 (+ i 1))) ((= i 3)) (let () (set! a (+ a i)) (display a)))"
" do: pointless let: (let () (set! a (+ a i)) (display a))
do: perhaps (do ((i 0 (+ i 1))) ((= i 3)) (let () (set! a (+ a i)) (display a))) ->
(do ((i 0 (+ i 1))) ((= i 3)) (set! a (+ a i)) ...)")
(lint-test "(do () ((= i 3)) (let ((a 12)) (set! a (+ a i)) (display a)))"
- " do: perhaps (do () ((= i 3)) (let ((a 12)) (set! a (+ a i)) (display a))) ->
+ " do: perhaps (let ((a 12)) (set! a (+ a i)) (display a)) -> (let ((a (+ 12 i))) (display a))
+ do: perhaps (do () ((= i 3)) (let ((a 12)) (set! a (+ a i)) (display a))) ->
(do ((a 12 12)) ((= i 3)) (set! a (+ a i)) ...)")
(lint-test "(do ((i 0 (+ i 1))) ((= i 3)) (let ((a 12) (b 1)) (set! a (+ a b i)) (display a)))"
" do: perhaps (do ((i 0 (+ i 1))) ((= i 3)) (let ((a 12) (b 1)) (set! a (+ a b i))... ->
@@ -87751,7 +88014,21 @@ etc
(... (let ((z (f x))) (do ((i z (+ i 1)) (j 0)) ((= i 3)) (display (+ z i)))))
let: j not used, initially: 0 from do")
+ (lint-test "(let ((x (make-vector 3 0)) (y (* 2 x))) (set! x (reverse x)) (vector-ref x y))"
+ " let: x in (y (* 2 x)) does not appear to be defined in the calling environment")
+ (lint-test "(let ((x (make-vector 3 0)) (y (* 2 z))) (set! x (reverse x)) (vector-ref x y))"
+ " let: perhaps (let ((x (make-vector 3 0)) (y (* 2 z))) (set! x (reverse x)) (vector-ref x y)) ->
+ (let ((x (reverse (make-vector 3 0))) (y (* 2 z))) (vector-ref x y))")
+ (lint-test "(let ((x (make-vector 3 0)) (y (* 2 z))) (set! x (f x y x)) (vector-ref x y))" "")
+ (lint-test "(let ((x (make-vector 3 0)) (y (* 2 z))) (set! x (f x y)))"
+ " let: perhaps (let ((x (make-vector 3 0)) (y (* 2 z))) (set! x (f x y))) -> (let ((x (make-vector 3 0)) (y (* 2 z))) (f x y))
+ let: set! is pointless in (set! x (f x y)): use (f x y)")
+ (lint-test "(let ((x (make-vector 3 0))) (set! x (f x y)))"
+ " let: perhaps (let ((x (make-vector 3 0))) (set! x (f x y))) -> (f (make-vector 3 0) y)
+ let: set! is pointless in (set! x (f x y)): use (f x y)")
+
;(lint-test "(byte-vector 3213)" " byte-vector: byte-vector's argument should be a byte?: 3213: (byte-vector 3213)")
+ (lint-test "(make-byte-vector 0)" " make-byte-vector: perhaps (make-byte-vector 0) -> #u8()")
(lint-test "(let ())" " let: let is messed up: (let ())")
(lint-test "(let ((x (lambda (a) (x 1)))) x)"
" let: let variable x is called in its binding? Perhaps let should be letrec: ((x (lambda (a) (x 1))))
@@ -87815,7 +88092,7 @@ etc
let: perhaps (let ((x 1) (y 2)) (set! x (* y x)) x) -> (let ((x 1) (y 2)) (* y x))")
(lint-test "(let ((x 1)) (set! x (* 2 x)) x)"
" let: set! returns the new value, so this could be omitted: x
- let: perhaps (let ((x 1)) (set! x (* 2 x)) x) -> (let ((x 1)) (* 2 x))")
+ let: perhaps (let ((x 1)) (set! x (* 2 x)) x) -> (let ((x (* 2 1))) x)")
(lint-test "(let ((x 1)) (set! x 2) x)"
" let: set! returns the new value, so this could be omitted: x
let: perhaps (let ((x 1)) (set! x 2) x) -> (let ((x 2)) x)")
@@ -87843,7 +88120,9 @@ etc
(lint-test "(let ((x y) (a (* 2 y))) (+ (f a (+ a 1)) (* 3 y x)))"
" let: assuming we see all set!s, the binding (x y) is pointless: perhaps (let ((x y) (a (* 2 y))) (+ (f a (+ a 1)) (* 3 y x))) ->
(let ((a (* 2 y))) (+ (f a (+ a 1)) (* 3 y y)))")
- (lint-test "(let ((x y) (a (* 2 y))) (set! x (* 3 x)) (+ (f a (+ a 1)) (* 3 x)))" "")
+ (lint-test "(let ((x y) (a (* 2 y))) (set! x (* 3 x)) (+ (f a (+ a 1)) (* 3 x)))"
+ " let: perhaps (let ((x y) (a (* 2 y))) (set! x (* 3 x)) (+ (f a (+ a 1)) (* 3 x))) ->
+ (let ((x (* 3 y)) (a (* 2 y))) (+ (f a (+ a 1)) (* 3 x)))")
(lint-test "(let ((x y) (a (* 2 y))) (set! y (* 3 x)) (+ (f a (+ a 1)) (* 3 x)))"
" let: x is not set, and is always accessed via (* 3 x) so its binding could probably be (x (* 3 y)) in
(let ((x y) (a (* 2 y))) (set! y (* 3 x)) (+ (f a (+ a 1)) (* 3 x)))")
@@ -87865,6 +88144,15 @@ etc
" let: perhaps use let-temporarily here: (let ((old-p (*s7* 'print-length))) (set! (*s7* 'print-length) 32)... ->
(let-temporarily (((*s7* 'print-length) 32)) (display x))")
+ (lint-test "(null? (let ((p (lambda (x) (not ((if (path? obj) path? picture?) x))))) (filt p (cons obj more-objs))))"
+ " null?: perhaps (null? (let ((p (lambda (x) (not ((if (path? obj) path? picture?) x)))))... ->
+ (let ... (null? (filt p (cons obj more-objs))))")
+
+ (lint-test "(let () (define-constant _cons_ 32) (define (_cons_ a_) (+ 1 a)))"
+ " let: _cons_ in (define (_cons_ a_) (+ 1 a)) is already a constant, defined 32
+ let: let variable _cons_ is declared twice
+ let: _cons_ not used, initially: 32 from define-constant")
+
(lint-test "(let* ((x (log y)) (a (+ x 1)) (a (* x 2))) (+ a 1))"
" let*: let* variable a is declared twice
let*: a not used, initially: (+ x 1) from let*
@@ -88000,12 +88288,14 @@ etc
(lint-test "(begin 1 #f)" " begin: this could be omitted: 1")
(lint-test "(begin (+ x y) 3)" " begin: this could be omitted: (+ x y)")
(lint-test "(begin (display 1) (begin #f))" " begin: redundant begin: (begin #f) begin: begin could be omitted: (begin #f)")
- (lint-test "(let () (display 1) (begin (display 1) #f))" " let: redundant begin: (begin (display 1) #f)")
+ (lint-test "(let () (display 1) (begin (display 1) #f))"
+ " let: let could be begin: (let () (display 1) (begin (display 1) #f)) -> (begin (display 1) (begin (display 1) #f))
+ let: redundant begin: (begin (display 1) #f)")
(lint-test "(if (< x 1) (begin x) y)" " if: begin could be omitted: (begin x)")
(lint-test "(if (< x 1) (begin (display 1) x) y)" "")
(lint-test "(format)" " format: format needs at least 1 argument: (format) format: format has too few arguments: (format)")
- (lint-test " (format \"buffer?\")" " format: perhaps (format \"buffer?\") -> \"buffer?\"")
+ (lint-test "(format \"buffer?\")" " format: perhaps (format \"buffer?\") -> \"buffer?\"")
(lint-test "(format (format #f str))" " format: redundant format: (format (format #f str))")
(lint-test "(format #f \"~H\" 1)" " format: unrecognized format directive: H in \"~H\", (format #f \"~H\" 1)")
(lint-test "(format #f \"~^\")" " format: ~^ has ~^ outside ~{~}?")
@@ -88027,7 +88317,9 @@ etc
(lint-test "(format #f \"~32T\")" "")
(lint-test "(format #f \"~a\\x00b\" x)"
" format: #\\null in a format control string will confuse both lint and format: \"~a\\x00b\" in (format #f \"~a\\x00b\" x)")
- (lint-test "(let () (format #t \"~A\" x) x)" " let: perhaps use () with format since the string value is discarded: (format () \"~A\" x)")
+ (lint-test "(let () (format #t \"~A\" x) x)"
+ " let: let could be begin: (let () (format #t \"~A\" x) x) -> (begin (format #t \"~A\" x) x)
+ let: perhaps use () with format since the string value is discarded: (format () \"~A\" x)")
(lint-test "(format #f \"~A\" (number->string x))" " format: format arg (number->string x) could be x")
(lint-test "(format #f \"~A\" (number->string x 16))"
" format: format arg (number->string x 16) could use the format directive ~X and change the argument to x")
@@ -88038,6 +88330,7 @@ etc
(lint-test "(format #f \"~A\" (make-string len #\\space))"
" format: format arg (make-string len #\\space) could use the format directive ~NC and change the argument to ... len #\\space ...")
(lint-test "(f \"*****************************\")" " f: perhaps \"*****************************\" -> (format #f \"~NC\" 29 #\\*)")
+ (lint-test "(format #f \"~A~%\" (apply string-append x))" " format: use ~{...~} rather than string-append: (apply string-append x)")
(lint-test "(for-each (lambda (x) (display x)) args)"
" for-each: perhaps (for-each (lambda (x) (display x)) args) -> (format () \"~{~A~}\" args) for-each: perhaps (lambda (x) (display x)) -> display")
@@ -88348,6 +88641,8 @@ etc
(lint-test "(or (not x) (< x 1))" " in (or (not x) (< x 1)), perhaps change (not x) to (not (real? x))")
(lint-test "(or (not x) (boolean? x))" " or: perhaps (or (not x) (boolean? x)) -> (boolean? x)")
(lint-test "(or (not x) (< x 1) y)" " in (or (not x) (< x 1) y), perhaps change (not x) to (not (real? x))")
+ (lint-test "(or (not (eq? val1 val2)) (not (eq? val2 val3)))" ; don't combine here into one eq?
+ " or: perhaps (or (not (eq? val1 val2)) (not (eq? val2 val3))) -> (not (and (eq? val1 val2) (eq? val2 val3)))")
(lint-test "(and x (x))" " in (and x (x)), perhaps change x to (procedure? x)")
(lint-test "(if x (x))" " in (if x (x)), perhaps change x to (procedure? x)")
@@ -88535,6 +88830,8 @@ etc
(lint-test "(and (number? x) (even? x))" " in (and (number? x) (even? x)), perhaps change (number? x) to (integer? x)")
(lint-test "(and (list? arg2) (pair? arg2) (memq (car arg2) '(x y)))"
" and: perhaps (and (list? arg2) (pair? arg2) (memq (car arg2) '(x y))) -> (and (pair? arg2) (memq (car arg2) '(x y)))")
+ (lint-test "(and (eq? val1 val2) (eq? val2 val3))" "") ; don't combine these!
+ (lint-test "(and (equal? val1 val2) (equal? val2 val3))" "")
(lint-test "(cond ((number? x) (< x 1)) ((number? y) (display (abs y))))"
" in (cond ((number? x) (< x 1)) ((number? y) (display (abs y)))), perhaps change (number? x) to (real? x)
@@ -88571,34 +88868,41 @@ etc
(lint-test "(string-append x (if y z) x)"
" string-append: in (string-append x (if y z) x), string-append's argument 2 should be a string, but #<unspecified> is untyped")
(lint-test "(string-append x (if y z w) x)" "")
-
- (lint-test "(car (car x))" " car: perhaps (car (car x)) -> (caar x)")
- (lint-test "(cdr (cadr x))" " cdr: perhaps (cdr (cadr x)) -> (cdadr x)")
- (lint-test "(car (car (cdr x)))" " car: perhaps (car (car (cdr x))) -> (caadr x)")
- (lint-test "(car (car (cdr (cdr x))))" " car: perhaps (car (car (cdr (cdr x)))) -> (caaddr x)")
- (lint-test "(car (cadr (cdr x)))" " car: perhaps (car (cadr (cdr x))) -> (caaddr x)")
- (lint-test "(cddar (car x))" " cddar: perhaps (cddar (car x)) -> (cddaar x)")
- (lint-test "(cadr (car (cdr x)))" " cadr: perhaps (cadr (car (cdr x))) -> (cadadr x)")
- (lint-test "(cddddr (cddr x))" " cddddr: perhaps (cddddr (cddr x)) -> (list-tail x 6)")
- (lint-test "(car (cddddr (cddr x)))" " car: perhaps (car (cddddr (cddr x))) -> (list-ref x 6)")
- (lint-test "(cadr (cddr (cdddr x)))" " cadr: perhaps (cadr (cddr (cdddr x))) -> (list-ref x 6)")
+ (lint-test "(string-append str (apply string-append strs))"
+ " string-append: perhaps (string-append str (apply string-append strs)) -> (string-append str (apply values strs))")
+ (lint-test "(string-append (apply string-append strs) str1 str2)"
+ " string-append: perhaps (string-append (apply string-append strs) str1 str2) -> (string-append (apply values strs) str1 str2)")
+
+ (lint-test "(car (car x))" " car: perhaps (car (car x)) -> (caar x)")
+ (lint-test "(cdr (cadr x))" " cdr: perhaps (cdr (cadr x)) -> (cdadr x)")
+ (lint-test "(car (car (cdr x)))" " car: perhaps (car (car (cdr x))) -> (caadr x)")
+ (lint-test "(car (car (cdr (cdr x))))" " car: perhaps (car (car (cdr (cdr x)))) -> (caaddr x)")
+ (lint-test "(car (cadr (cdr x)))" " car: perhaps (car (cadr (cdr x))) -> (caaddr x)")
+ (lint-test "(cddar (car x))" " cddar: perhaps (cddar (car x)) -> (cddaar x)")
+ (lint-test "(cadr (car (cdr x)))" " cadr: perhaps (cadr (car (cdr x))) -> (cadadr x)")
+ (lint-test "(cddddr (cddr x))" " cddddr: perhaps (cddddr (cddr x)) -> (list-tail x 6)")
+ (lint-test "(car (cddddr (cddr x)))" " car: perhaps (car (cddddr (cddr x))) -> (list-ref x 6)")
+ (lint-test "(cadr (cddr (cdddr x)))" " cadr: perhaps (cadr (cddr (cdddr x))) -> (list-ref x 6)")
(lint-test "(cadr (cddr (cdddr (cdr x))))" " cadr: perhaps (cadr (cddr (cdddr (cdr x)))) -> (list-ref x 7)")
- (lint-test "(cddddr (cdddr (cddddr x)))" " cddddr: perhaps (cddddr (cdddr (cddddr x))) -> (list-tail x 11)")
+ (lint-test "(cddddr (cdddr (cddddr x)))" " cddddr: perhaps (cddddr (cdddr (cddddr x))) -> (list-tail x 11)")
(lint-test "(let ((x 3) (y 5)) (set! x (+ x y)) (+ x y))" " let: set! returns the new value, so this could be omitted: (+ x y)")
(lint-test "(let ((x 3)) (set! x (+ x 1)) x)"
" let: set! returns the new value, so this could be omitted: x
- let: perhaps (let ((x 3)) (set! x (+ x 1)) x) -> (let ((x 3)) (+ x 1))")
+ let: perhaps (let ((x 3)) (set! x (+ x 1)) x) -> (let ((x (+ 3 1))) x)")
(lint-test "(let ((x (list 1 2))) (set-car! x 3) (car x))" " let: set-car! returns the new value, so this could be omitted: (car x)")
(lint-test "(let ((x (list 1 2))) (set-cdr! x 3) (cdr y))" "")
+ (lint-test "(let ((g (make-oscil)) (v (make-vector 3))) (fill! v g) (oscil-bank v))" "")
(lint-test "(begin (vector-set! x 0 32) (vector-ref x 0))"
" begin: vector-set! returns the new value, so this could be omitted: (vector-ref x 0)")
(lint-test "(begin (list-set! x (* y 2) 32) (list-ref x (* y 2)))"
" begin: list-set! returns the new value, so this could be omitted: (list-ref x (* y 2))")
(lint-test "(let () (vector-set! x 0 32) (vector-ref x 0))"
- " let: vector-set! returns the new value, so this could be omitted: (vector-ref x 0)")
+ " let: let could be begin: (let () (vector-set! x 0 32) (vector-ref x 0)) -> (begin (vector-set! x 0 32) (vector-ref x 0))
+ let: vector-set! returns the new value, so this could be omitted: (vector-ref x 0)")
(lint-test "(let () (list-set! x (* y 2) 32) (list-ref x (* y 2)))"
- " let: list-set! returns the new value, so this could be omitted: (list-ref x (* y 2))")
+ " let: let could be begin: (let () (list-set! x (* y 2) 32) (list-ref x (* y 2))) -> (begin (list-set! x (* y 2) 32) (list-ref x (* y 2)))
+ let: list-set! returns the new value, so this could be omitted: (list-ref x (* y 2))")
(lint-test "(begin (vector-set! x 0 (* y 2)) (* y 2))"
" begin: vector-set! returns the new value, so this could be omitted: (* y 2)")
(lint-test "(begin (z 1) (do ((i 0 (+ i 1))) ((= i n) 32)))"
@@ -88627,8 +88931,6 @@ etc
" string: perhaps (string (char-downcase (string-ref x 1)) (char-downcase (string-ref x 2))) ->
(string-downcase (string (string-ref x 1) (string-ref x 2)))")
- (lint-test "(+ 1 (if x 0 #()))" " +: in (+ 1 (if x 0 #())), +'s argument 2 should be a number, but #() is a vector?")
- (lint-test "(+ 1 (if x #() 0))" " +: in (+ 1 (if x #() 0)), +'s argument 2 should be a number, but #() is a vector?")
(lint-test "(+ 1 (dynamic-wind (lambda () #f) (lambda () #()) (lambda () #f)))"
" +: in (+ 1 (dynamic-wind (lambda () #f) (lambda () #()) (lambda () #f))), +'s argument 2 should be a number, but #() is a vector?
+: this dynamic-wind is pointless, (dynamic-wind (lambda () #f) (lambda () #()) (lambda () #f)) -> #()")
@@ -88665,6 +88967,18 @@ etc
(lint-test "(call-with-input-file \"file\" (lambda (p) (read-char p)))"
" call-with-input-file: perhaps (call-with-input-file \"file\" (lambda (p) (read-char p))) -> (call-with-input-file \"file\" read-char)")
+ (lint-test "(with-output-to-string (lambda () (display object)))"
+ " with-output-to-string: perhaps (with-output-to-string (lambda () (display object))) -> (object->string object #f)")
+ (lint-test "(with-output-to-string (lambda () (write (car defs)) (newline)))"
+ " with-output-to-string: perhaps (with-output-to-string (lambda () (write (car defs)) (newline))) -> (format #f \"~S~%\" (car defs))")
+ (lint-test "(with-output-to-string (lambda () (write answer)))"
+ " with-output-to-string: perhaps (with-output-to-string (lambda () (write answer))) -> (object->string answer)")
+ (lint-test "(call-with-output-string (lambda (p) (display object p)))"
+ " call-with-output-string: perhaps (call-with-output-string (lambda (p) (display object p))) -> (object->string object #f)")
+
+ (lint-test "(format #f \"~A\" x)" " format: perhaps (format #f \"~A\" x) -> (object->string x #f)")
+ (lint-test "(format #f \"~S\" x)" " format: perhaps (format #f \"~S\" x) -> (object->string x)")
+
(lint-test "(quasiquote 1 2)" " quasiquote: quasiquote has too many arguments: (quasiquote 1 2)")
(lint-test "(apply + 1)" " apply: last argument should be a list: (apply + 1)")
(lint-test "(apply (lambda (x) (abs x)) y)"
@@ -88704,11 +89018,16 @@ etc
(lint-test "(apply car x)" " apply: perhaps (apply car x) -> (car (car x))")
(lint-test "(apply string (map char-downcase x))"
" apply: perhaps, assuming x is a list, (apply string (map char-downcase x)) -> (string-downcase (apply string x))")
- (lint-test "(apply f `(x ,y ,@z))" " apply: perhaps (apply f ({list} 'x y ({apply_values} z))) -> (apply f 'x y z)")
+ (lint-test "(apply f `(x ,y ,@z))"
+ " apply: perhaps (apply f ({list} 'x y ({apply_values} z))) -> (apply f 'x y z)
+ apply: perhaps ({list} 'x y ({apply_values} z)) -> (cons 'x (cons y z))")
(lint-test "(apply f `(,@(list x y)))" " apply: perhaps (apply f ({list} ({apply_values} (list x y)))) -> (apply f (list x y))")
(lint-test "(apply f `(x (,y 1) ,z))" " apply: perhaps (apply f ({list} 'x ({list} y 1) z)) -> (f 'x (list y 1) z)")
- (lint-test "(apply make-string tcnt initializer)" " apply: perhaps (apply make-string tcnt initializer) -> (make-string tcnt (car initializer))")
+ (lint-test "(apply make-string tcnt initializer)" "")
+ (lint-test "(apply cons x y)" " apply: perhaps (apply cons x y) -> (cons x (car y))")
(lint-test "(apply string (make-list pad #\\null))" " apply: perhaps (apply string (make-list pad #\\null)) -> (make-string pad #\\null)")
+ (lint-test "(let ((v (vector 1 2 3))) (apply v (make-list 1 0)))" ; don't complain here that v is not a procedure!
+ " let: perhaps (let ((v (vector 1 2 3))) (apply v (make-list 1 0))) -> (apply (vector 1 2 3) (make-list 1 0))")
(lint-test "(eval '(+ 1 2))" " eval: perhaps (eval '(+ 1 2)) -> (+ 1 2)")
(lint-test "(eval 32)" " eval: this eval is pointless; perhaps (eval 32) -> 32")
@@ -88733,8 +89052,14 @@ etc
(lint-test "(round (integer->char 96))"
" round: in (round (integer->char 96)), round's argument should be real, but (integer->char 96) is a char?
round: perhaps (integer->char 96) -> #\\`")
+
(lint-test "(integer->char (+ (char->integer #\\space) 215))"
" integer->char: perhaps (integer->char (+ (char->integer #\\space) 215)) -> #\\xf7")
+ (lint-test "(char->integer (read-char p))"
+ " char->integer: in (char->integer (read-char p)), char->integer's argument should be a char, but (read-char p) might also be eof-object?
+ char->integer: perhaps (char->integer (read-char p)) -> (read-byte p)")
+ (lint-test "(write-char (integer->char c))" " write-char: perhaps (write-char (integer->char c)) -> (write-byte c)")
+
(lint-test "(let ((v (make-vector 3))) (vector-set! v 3.14 #\\a))"
"let: perhaps (let ((v (make-vector 3))) (vector-set! v 3.14 #\\a)) -> (vector-set! (make-vector 3) 3.14 #\\a)
let: in (vector-set! v 3.14 #\\a), vector-set!'s argument 2 should be an integer, but 3.14 is real?")
@@ -88836,13 +89161,15 @@ etc
dynamic-wind: perhaps (lambda () (list)) -> list")
(lint-test "(lambda args (apply + args))" " lambda: perhaps (lambda args (apply + args)) -> +")
(lint-test "(let ((x 1) (y '(1 2))) `(,x ,@y))"
- " let: perhaps (let ((x 1) (y '(1 2))) ({list} x ({apply_values} y))) -> ({list} 1 ({apply_values} '(1 2)))")
+ " let: perhaps (let ((x 1) (y '(1 2))) ({list} x ({apply_values} y))) -> ({list} 1 ({apply_values} '(1 2)))
+ let: perhaps ({list} x ({apply_values} y)) -> (cons x y)")
(lint-test "(display #\\escape)" "")
;; these tickled a lint bug
(lint-test "(define :xxx 321)" " define: keywords are constants :xxx")
(lint-test "(define (:yyy a) a)" " define: keywords are constants :yyy")
(lint-test "(cons ((pair? x) 2) y)" " cons: cons's argument ((pair? x) 2) looks odd: pair? returns boolean? which is not applicable")
+ (lint-test "(cons ((g x) y) (else #f))" " cons: else (as car of second argument to cons) makes no sense: (cons ((g x) y) (else #f))")
(lint-test "(let ((r (make-random-state 123 432))) (random 1.0 r))"
" let: make-random-state is deprecated; use random-state
@@ -88927,6 +89254,12 @@ etc
let: assuming we see all set!s, the binding (+ *) is pointless: perhaps (let ((a 1) (+ *)) (+ a (m2 a))) -> (let ((a 1)) (* a (m2 a)))")
(lint-test "(let () (define-macro (m3 b) `(let ((a 12)) (+ (symbol->value ,b) a))) (let ((a 1)) (+ a (m3 'a))))"
" let: possible problematic macro expansion: (m3 'a) could conceivably collide with subsequently defined 'a")
+ (lint-test "(define-macro (f . x) `(+ ,@x))"
+ " define-macro: perhaps (define-macro (f . x) ({list} '+ ({apply_values} x))) -> (define f +)
+ f: perhaps ({list} '+ ({apply_values} x)) -> (cons '+ x)")
+ (lint-test "(define-macro (f a . x) `(+ ,a ,@x))"
+ " define-macro: perhaps (define-macro (f a . x) ({list} '+ a ({apply_values} x))) -> (define f +)
+ f: perhaps ({list} '+ a ({apply_values} x)) -> (cons '+ (cons a x))")
(lint-test "(define pi (acos -1))" " define: (acos -1) is one of its many names, but pi is a predefined constant in s7 pi: perhaps (acos -1) -> pi")
(lint-test "(+ x (atan 0 -1))" " +: perhaps (+ x (atan 0 -1)) -> (+ x pi)")
@@ -89153,7 +89486,7 @@ etc
(lint-test "(begin (define (f23 x) (+ y 1)) (define (f24 x) (f23 (+ x 1))) (f24 0))"
" f24: f23's parameter 1 is not used, but a value is passed: (+ x 1)")
(lint-test "(begin (define x 1) `#(,x))" ; this can be expanded: (lambda (x) #((unquote x)))
- " begin: quasiquoted vectors are not supported: #((unquote x))")
+ " begin: quasiquoted vectors are not supported: #((unquote x)) perhaps use `(vector ...) rather than `#(...)")
(lint-test "(begin (define-macro (m1 x y) `(+ ,y 1)) (m1 a b))"
" begin: perhaps (define-macro (m1 x y) ({list} '+ y 1)) -> (define (m1 x y) (+ y 1))
begin: m1's parameter 1 is not used, but a value is passed: a")
@@ -89304,7 +89637,7 @@ etc
(lint-test "(car (member x y))"
" car: in (car (member x y)), car's argument should be a pair, but (member x y) might also be boolean?
car: (car (member x y)) is x, or an error")
-; (lint-test "(if (and x (pair? x) (symbol? (cadr x))) x)" "")
+ (lint-test "(if (and x (pair? x) (symbol? (cadr x))) x)" " if: perhaps (and x (pair? x) (symbol? (cadr x))) -> (and (pair? x) (symbol? (cadr x)))")
(lint-test "(catch #t (lambda () (char=? (read-char p) #\\newline)) (lambda arg 'error))" "")
(lint-test "(if (and (<= 12 x) (<= x 15)) 2 3)" " if: perhaps (and (<= 12 x) (<= x 15)) -> (<= 12 x 15)")
(lint-test "(and x (set! x (zero? (random 2))) (not x))" "")
@@ -89316,7 +89649,7 @@ etc
(lint-test "(let () (define (f x) (if (pair? x) (reverse! x))) (f (vector 1 2)))"
" let: perhaps (... (define (f x) (if (pair? x) (reverse! x))) (f (vector 1 2))) -> (... (let ((x (vector 1 2))) (if (pair? x) (reverse! x))))
f: if x (a function argument) is a pair, (reverse! x) is ill-advised")
-; (lint-test "(if (and (list? x) (car x)) 3)" "")
+ (lint-test "(if (and (list? x) (car x)) 3)" " in (and (list? x) (car x)), perhaps change (list? x) to (pair? x)")
(lint-test "(if (and (list? x) (not (null? x)) (car x)) 3)" " if: perhaps (and (list? x) (not (null? x)) (car x)) -> (and (pair? x) (car x))")
(lint-test "(and (pair? obj) (not (null? obj)) (pair? x))" " and: perhaps (and (pair? obj) (not (null? obj)) (pair? x)) -> (and (pair? obj) (pair? x))")
@@ -89356,6 +89689,9 @@ etc
" string=?: perhaps (string=? \"#\" (string (string-ref s 0))) -> (char=? #\\# (string-ref s 0))
string=?: perhaps (string (string-ref s 0)) -> (substring s 0 1)")
(lint-test "(string=? \"\" (string-copy \"\"))" " string=?: perhaps (string=? \"\" (string-copy \"\")) -> (string=? \"\" \"\")")
+ (lint-test "(string-copy x 1 y)"
+ " string-copy: string-copy has too many arguments: (string-copy x 1 y)
+ string-copy: perhaps (string-copy x 1 y) -> (substring x 1 y)")
(lint-test "(char=? #\\a (char-downcase x))" " char=?: perhaps (char=? #\\a (char-downcase x)) -> (char-ci=? #\\a x)")
(lint-test "(string=? x (string-downcase y))" "")
@@ -89369,6 +89705,56 @@ etc
" for-each: perhaps (for-each write (append b (list 1 a #\\newline))) -> (format () \"~{~S~}\" (append b (list 1 a #\\newline)))")
(lint-test "(for-each write-char (append b (list a #\\newline)))"
" for-each: perhaps (for-each write-char (append b (list a #\\newline))) -> (format () \"~{~A~}\" (append b (list a #\\newline)))")
+
+ ;; recursion->for-each
+ (lint-test "(let f ((v (list 0 1 2))) (if (pair? v) (begin (g (car v)) (f (cdr v)))))"
+ " f: perhaps (let f ((v (list 0 1 2))) (if (pair? v) (begin (g (car v)) (f (cdr v))))) -> (for-each g (list 0 1 2))")
+ (lint-test "(define (f v) (if (pair? v) (begin (g (car v)) (f (cdr v)))))"
+ " f: perhaps (define (f v) (if (pair? v) (begin (g (car v)) (f (cdr v))))) -> (define (f v) (for-each g v))")
+ (lint-test "(let f ((v (list 0 1 2))) (when (pair? v) (g (car v)) (f (cdr v))))"
+ " f: perhaps (let f ((v (list 0 1 2))) (when (pair? v) (g (car v)) (f (cdr v)))) -> (for-each g (list 0 1 2))")
+ (lint-test "(define (f v) (when (not (null? v)) (g (cadar v)) (f (cdr v))))"
+ " f: perhaps (define (f v) (when (not (null? v)) (g (cadar v)) (f (cdr v)))) ->
+ (define (f v) (for-each (lambda (_1_) (g (cadr _1_))) v))
+ f: perhaps (when (not (null? v)) (g (cadar v)) (f (cdr v))) ->
+ (unless (null? v) (g (cadar v)) (f (cdr v)))")
+ (lint-test "(let f ((v (list 0 1 2))) (when (pair? v) (let ((g (car v))) (display g) (f (cdr v)))))"
+ " f: perhaps (let f ((v (list 0 1 2))) (when (pair? v) (let ((g (car v))) (display g)... ->
+ (for-each (lambda (_1_) (let ((g _1_)) (display g))) (list 0 1 2))")
+
+ ;; recursion->do
+ (lint-test "(let f ((v ()) (i 0)) (if (= i 3) (reverse v) (f (cons x v) (+ i 1))))"
+ " f: perhaps (let f ((v ()) (i 0)) (if (= i 3) (reverse v) (f (cons x v) (+ i 1)))) ->
+ (do ((v () (cons x v)) (i 0 (+ i 1))) ((= i 3) (reverse v)))")
+ (lint-test "(define (lref lst ind) (if (zero? ind) (car lst) (lref (cdr lst) (- ind 1))))"
+ " lref: perhaps (define (lref lst ind) (if (zero? ind) (car lst) (lref (cdr lst) (- ind 1)))) ->
+ (define (lref lst ind) (do ((lst lst (cdr lst)) (ind ind (- ind 1))) ((zero? ind) (car lst))))")
+ (lint-test "(let loop ((a b) (c d)) (if (> a 1) (begin (display c) (loop (- a 1) (cdr c))) (+ a 1)))"
+ " loop: perhaps (let loop ((a b) (c d)) (if (> a 1) (begin (display c) (loop (- a 1) (cdr... ->
+ (do ((a b (- a 1)) (c d (cdr c))) ((<= a 1) (+ a 1)) (display c))")
+ (lint-test "(let loop ((a b) (c d)) (if (< a 1) (+ a 1) (begin (display c) (loop (- a 1) (cdr c)))))"
+ " loop: perhaps (let loop ((a b) (c d)) (if (< a 1) (+ a 1) (begin (display c) (loop (- a... ->
+ (do ((a b (- a 1)) (c d (cdr c))) ((< a 1) (+ a 1)) (display c))")
+ (lint-test "(define (loop a) (if (< a 0) (car c) (loop (f1 a))))"
+ " loop: perhaps (define (loop a) (if (< a 0) (car c) (loop (f1 a)))) ->
+ (define (loop a) (do ((a a (f1 a))) ((< a 0) (car c))))")
+ (lint-test "(let loop ((a b) (c d)) (if (> a 1) (begin (display c) (loop (- a 1) c)) (+ a 1)))"
+ " loop: perhaps (let loop ((a b) (c d)) (if (> a 1) (begin (display c) (loop (- a 1) c))... ->
+ (do ((a b (- a 1)) (c d)) ((<= a 1) (+ a 1)) (display c))")
+ (lint-test "(let loop ((a b) (c d)) (if (< a 1) (+ a 1) (begin (display c) (loop (- a c) (abs c)))))" "")
+ (lint-test "(define (f12 x y) (if (positive? x) (+ x y) (f12 1 x)))" "")
+ (lint-test "(define loop (lambda (a . b) (if (< a 0) (car c) (loop (f11 a b)))))" "")
+ (lint-test "(define loop (lambda (a) (if (< a 0) (car c) (loop (f1 a)))))"
+ " loop: perhaps (lambda (a) (if (< a 0) (car c) (loop (f1 a)))) -> (lambda (a) (do ((a a (f1 a))) ((< a 0) (car c))))")
+ (lint-test "(define* (f52 (a 2)) (if (zero? a) x (f52 (- a 1))))"
+ " f52: perhaps (define* (f52 (a 2)) (if (zero? a) x (f52 (- a 1)))) -> (define* (f52 (a 2)) (do ((a a (- a 1))) ((zero? a) x)))")
+ (lint-test "(define (loop a) (if (< a 0) (car c) (or (pair? a) (loop (f1 a)))))" "")
+ (lint-test "(define (loop a) (cond ((< a 0) (car c)) (else (loop (f1 a)))))"
+ " loop: perhaps (define (loop a) (cond ((< a 0) (car c)) (else (loop (f1 a))))) ->
+ (define (loop a) (do ((a a (f1 a))) ((< a 0) (car c))))")
+ (lint-test "(define (loop a) (cond ((< a 0)) (else (loop (f1 a)))))"
+ " loop: perhaps (define (loop a) (cond ((< a 0)) (else (loop (f1 a))))) -> (define (loop a) (do ((a a (f1 a))) ((< a 0) #t)))
+ loop: perhaps (cond ((< a 0)) (else (loop (f1 a)))) -> (or (< a 0) (loop (f1 a)))")
;; this is a write.scm lint-pp bug regression test
(lint-test "(define (any-random amount e) (letrec ((next-random (lambda () (let ((x 32)) (if (<= y (envelope-interp x e)) (next-random)))))) (next-random)))"
@@ -89376,7 +89762,8 @@ etc
(let next-random ()
(let ((x 32))
(if (<= y (envelope-interp x e))
- (next-random))))")
+ (next-random))))
+ any-random: x can probably be moved to any-random's closure")
(lint-test "(let ()
(define (f11 a b) (if (positive? a) (+ a b) b))
@@ -89389,8 +89776,8 @@ etc
(lint-test "(let ((x (let () (define (f11 a b) (if (positive? a) (+ a b) b)) (f11 1 2))))
(define (f14 x y) (if (positive? x) (+ x y) y))
(+ x (f14 1 2)))"
- " let: perhaps (... (define (f11 a b) (if (positive? a) (+ a b) b)) (f11 1 2)) -> (... (let ((a 1) (b 2)) (if (positive? a) (+ a b) b)))
- let: perhaps (... (define (f14 x y) (if (positive? x) (+ x y) y)) (+ x (f14 1 2))) -> (... (+ x (let ((x 1) (y 2)) (if (positive? x) (+ x y) y))))
+ " let (line 2): perhaps (... (define (f11 a b) (if (positive? a) (+ a b) b)) (f11 1 2)) -> (... (let ((a 1) (b 2)) (if (positive? a) (+ a b) b)))
+ let (line 2): perhaps (... (define (f14 x y) (if (positive? x) (+ x y) y)) (+ x (f14 1 2))) -> (... (+ x (let ((x 1) (y 2)) (if (positive? x) (+ x y) y))))
f14 (line 1): f14 is the same as f11")
(lint-test "(let ()
(define (f11 a b) (define (f12 a b) (if (positive? a) (+ a b) b)) (f12 a b))
@@ -89479,7 +89866,8 @@ etc
(define (f14 x y) (let ((w (+ x 1)) (ww 1)) (if (positive? w) (+ x y) y)))
(+ (f11 1 2) (f14 1 2)))"
" f11 (line 1): perhaps (let ((z (+ a 1))) (if (positive? z) (+ a b) b)) -> (if (positive? (+ a 1)) (+ a b) b)
- f14 (line 2): ww not used, initially: 1 from let")
+ f14 (line 2): ww not used, initially: 1 from let
+ f14 (line 2): ww can be moved to f14's closure")
(lint-test "(let ()
(define (f12 a b) (let* ((z (+ a 1)) (zz z)) (if (positive? z) (+ a b) zz)))
(define (f15 x y) (let* ((w (+ x 1)) (ww w)) (if (positive? w) (+ x y) ww)))
@@ -89495,10 +89883,10 @@ etc
(lint-test "(let ()
(define (f18 a b) (let ((z (lambda (c) (+ c 1)))) (if (positive? (z 1)) (+ a b) b)))
(define (f19 x y) (let ((w (lambda (d) (+ d 1)))) (if (positive? (w 1)) (+ x y) y)))
- (+ (f18 1 2) (f19 1 2)))"
+ (+ (f18 1 2) (f19 1 2)))"
" f18 (line 1): perhaps (let ((z (lambda (c) (+ c 1)))) (if (positive? (z 1)) (+ a b) b)) -> (if (positive? (let ((c 1)) (+ c 1))) (+ a b) b)
+ f19 (line 2): f19 could be (define f19 f18)
f19 (line 2): perhaps (let ((w (lambda (d) (+ d 1)))) (if (positive? (w 1)) (+ x y) y)) -> (if (positive? (let ((d 1)) (+ d 1))) (+ x y) y)")
- ; TODO: f19 (line 2): f19 could be (define f19 f18)
(lint-test "(let ()
(define (f20 a) (define (f20a b) (+ (* 2 b) a)) (f20a a))
@@ -89561,7 +89949,8 @@ etc
let: perhaps (let ((xx 1)) (set! xx 2) (abs xx) xx) -> (let ((xx 2)) (abs xx) ...)")
(lint-test "(let () (define (f32) (let ((xx 1)) (set! xxx 2) (+ xx 1))) (f32) 3)"
" let: perhaps (... (define (f32) (let ((xx 1)) (set! xxx 2) (+ xx 1))) (f32) 3) ->
- (... (let ((xx 1)) (set! xxx 2) (+ xx 1)) 3)")
+ (... (let ((xx 1)) (set! xxx 2) (+ xx 1)) 3)
+ f32: xx can be moved to f32's closure")
(lint-test "(let () (define (f32 x) (let ((xx (car x))) (vector-set! xx 0 2) xx)) (f32 (list (vector 1))) 3)"
" let: perhaps (... (define (f32 x) (let ((xx (car x))) (vector-set! xx 0 2) xx)) (f32... ->
(... (let ((x (list (vector 1)))) (let ((xx (car x))) (vector-set! xx 0 2) xx)) 3)")
@@ -89627,7 +90016,7 @@ etc
define: perhaps (define f43 (letrec ((f0 (lambda (a) (+ a 1)))) (lambda (b) (if (> b 0)... ->
(define (f43 b) (if (> b 0) (let f0 ((a (+ b 1))) (+ a 1))))")
- (lint-test "(lambda (c) (letrec ((f0 (lambda (a) (+ a 1)))) (f0 (+ c 1))))"
+ (lint-test "(lambda (c) (letrec ((f0 (lambda (a) (+ a 1)))) (f0 (+ c 1))))"
" lambda: letrec could be let: (letrec ((f0 (lambda (a) (+ a 1)))) (f0 (+ c 1)))
lambda: perhaps (letrec ((f0 (lambda (a) (+ a 1)))) (f0 (+ c 1))) -> (let f0 ((a (+ c 1))) (+ a 1))")
(lint-test "(lambda (c) (letrec ((f0 (lambda (a) (+ a c 1)))) (let ((c 32)) (f0 (+ c 1)))))"
@@ -89641,13 +90030,16 @@ etc
(lint-test "(let () (define f60 (let ((a (lambda (x) (* 2 x)))) a)) (+ 1 (f60 y)))"
" f60: perhaps (let ((a (lambda (x) (* 2 x)))) a) -> (lambda (x) (* 2 x))")
(lint-test "(let ((x 2)) (let loop ((y x)) (if (positive? y) (loop (- y 1)) 0)))"
- " let: perhaps (let ((x 2)) (let loop ((y x)) (if (positive? y) (loop (- y 1)) 0))) -> (let loop ((y 2)) (if (positive? y) (loop (- y 1)) 0))")
+ " loop: perhaps (let loop ((y x)) (if (positive? y) (loop (- y 1)) 0)) -> (do ((y x (- y 1))) ((not (positive? y)) 0))
+ let: perhaps (let ((x 2)) (let loop ((y x)) (if (positive? y) (loop (- y 1)) 0))) -> (let loop ((y 2)) (if (positive? y) (loop (- y 1)) 0))")
(lint-test "(let ((f60 (lambda (x) (* 2 x)))) (+ 1 (f60 y)))"
" let: perhaps (let ((f60 (lambda (x) (* 2 x)))) (+ 1 (f60 y))) -> (+ 1 (let ((x y)) (* 2 x)))")
(lint-test "(define (f61 x) (let loop ((y x)) (if (positive? y) (loop (- y 1)) 0)))"
- " define: perhaps (define (f61 x) (let loop ((y x)) (if (positive? y) (loop (- y 1)) 0))) -> (define (f61 y) (if (positive? y) (f61 (- y 1)) 0))")
+ " define: perhaps (define (f61 x) (let loop ((y x)) (if (positive? y) (loop (- y 1)) 0))) -> (define (f61 y) (if (positive? y) (f61 (- y 1)) 0))
+ loop: perhaps (let loop ((y x)) (if (positive? y) (loop (- y 1)) 0)) -> (do ((y x (- y 1))) ((not (positive? y)) 0))")
(lint-test "(define (f61 x) (let loop ((x x)) (if (positive? x) (loop (- x 1)) 0)))"
- " define: perhaps (define (f61 x) (let loop ((x x)) (if (positive? x) (loop (- x 1)) 0))) -> (define (f61 x) (if (positive? x) (f61 (- x 1)) 0))")
+ " define: perhaps (define (f61 x) (let loop ((x x)) (if (positive? x) (loop (- x 1)) 0))) -> (define (f61 x) (if (positive? x) (f61 (- x 1)) 0))
+ loop: perhaps (let loop ((x x)) (if (positive? x) (loop (- x 1)) 0)) -> (do ((x x (- x 1))) ((not (positive? x)) 0))")
(lint-test "(define (f61) (let loop () (if (positive? x) (loop) 0)))"
" define: perhaps (define (f61) (let loop () (if (positive? x) (loop) 0))) -> (define (f61) (if (positive? x) (f61) 0))")
@@ -89744,11 +90136,58 @@ etc
(lint-test "(define (f x) (define y (g x)) (define z (lambda (a) (if w (z (- a 1))))) (z (+ y x)))"
" f: perhaps (... (define y (g x)) (define z (lambda (a) (if w (z (- a 1))))) (z (+ y x))) -> (... (let ((y (g x))) ...))
f: the scope of z could be reduced:
- (... (define z (lambda (a) (if w (z (- a 1))))) (z (+ y x))) -> (... (letrec ((z (lambda (a) (if w (z (- a 1)))))) (z (+ y x))))")
+ (... (define z (lambda (a) (if w (z (- a 1))))) (z (+ y x))) -> (... (letrec ((z (lambda (a) (if w (z (- a 1)))))) (z (+ y x))))
+ z: perhaps (lambda (a) (if w (z (- a 1)))) -> (lambda (a) (do ((a a (- a 1))) ((not w))))")
(lint-test "(define (f x) (define y (g x)) (define z (lambda (a) (if y (z (- a 1))))) (z (+ y x)))"
" f: perhaps (... (define y (g x)) (define z (lambda (a) (if y (z (- a 1))))) (z (+ y x))) -> (... (let ((y (g x))) ...))
f: the scope of z could be reduced:
- (... (define z (lambda (a) (if y (z (- a 1))))) (z (+ y x))) -> (... (letrec ((z (lambda (a) (if y (z (- a 1)))))) (z (+ y x))))")
+ (... (define z (lambda (a) (if y (z (- a 1))))) (z (+ y x))) -> (... (letrec ((z (lambda (a) (if y (z (- a 1)))))) (z (+ y x))))
+ z: perhaps (lambda (a) (if y (z (- a 1)))) -> (lambda (a) (do ((a a (- a 1))) ((not y))))")
+
+ (lint-test "(lambda (a . opt) (let ((ip (if (null? opt) (current-input-port) (car opt)))) (read ip)))"
+ " :lambda: perhaps (lambda (a . opt) (let ((ip (if (null? opt) (current-input-port) (car... -> (lambda* (a (ip (current-input-port))) ...)
+ lambda: perhaps (let ((ip (if (null? opt) (current-input-port) (car opt)))) (read ip)) -> (read (if (null? opt) (current-input-port) (car opt)))")
+ (lint-test "(lambda opt (let ((ip (if (null? opt) (current-input-port) (car opt)))) (read ip)))"
+ " :lambda: perhaps (lambda opt (let ((ip (if (null? opt) (current-input-port) (car opt))))... -> (lambda* ((ip (current-input-port))) ...)
+ lambda: perhaps (let ((ip (if (null? opt) (current-input-port) (car opt)))) (read ip)) -> (read (if (null? opt) (current-input-port) (car opt)))")
+ (lint-test "(define (f204 b . opt) (let ((ip (if (null? opt) (current-input-port) (car opt)))) (read ip)))"
+ " f204: perhaps (define (f204 b . opt) (let ((ip (if (null? opt) (current-input-port) (car... -> (define* (f204 b (ip (current-input-port))) ...)
+ f204: perhaps (let ((ip (if (null? opt) (current-input-port) (car opt)))) (read ip)) -> (read (if (null? opt) (current-input-port) (car opt)))")
+ (lint-test "(define (f205 b . opt) (let ((ip (if (null? opt) #f (car opt)))) (read ip)))"
+ " f205: perhaps (define (f205 b . opt) (let ((ip (if (null? opt) #f (car opt)))) (read ip))) -> (define* (f205 b ip) ...)
+ f205: perhaps (if (null? opt) #f (car opt)) -> (and (not (null? opt)) (car opt))
+ f205: perhaps (let ((ip (if (null? opt) #f (car opt)))) (read ip)) -> (read (if (null? opt) #f (car opt)))")
+ (lint-test "(define f206 (lambda (c . opt) (let ((ip (if (null? opt) (current-input-port) (car opt)))) (read ip))))"
+ " :lambda: perhaps (lambda (c . opt) (let ((ip (if (null? opt) (current-input-port) (car... -> (lambda* (c (ip (current-input-port))) ...)
+ f206: perhaps (let ((ip (if (null? opt) (current-input-port) (car opt)))) (read ip)) -> (read (if (null? opt) (current-input-port) (car opt)))")
+ (lint-test "(define (f207 b . opt) (let* ((ip (if (null? opt) #f (car opt))) (op (port? ip))) (read ip)))"
+ " f207: perhaps (define (f207 b . opt) (let* ((ip (if (null? opt) #f (car opt))) (op... -> (define* (f207 b ip) (let ((op (port? ip))) ...))
+ f207: perhaps (if (null? opt) #f (car opt)) -> (and (not (null? opt)) (car opt))
+ f207: op not used, initially: (port? ip) from let*")
+ (lint-test "(define (f208 b . opt) (let* ((ip (if (null? opt) #f (car opt))) (op (port? ip)) (op2 op)) (read ip)))"
+ " f208: perhaps (define (f208 b . opt) (let* ((ip (if (null? opt) #f (car opt))) (op... -> (define* (f208 b ip) (let* ((op (port? ip)) (op2 op)) ...))
+ f208: perhaps (if (null? opt) #f (car opt)) -> (and (not (null? opt)) (car opt))
+ f208: perhaps restrict op which is not used in the let* body
+ (let* ((ip (if (null? opt) #f (car opt))) (op (port? ip)) (op2 op)) (read ip)) ->
+ (let* ((ip (if (null? opt) #f (car opt))) (op2 (let ((op (port? ip))) op))) ...)
+ f208: op2 not used, initially: op from let*
+ f208: perhaps substitute op into op2:
+ (let* ((ip (if (null? opt) #f (car opt))) (op (port? ip)) (op2 op)) (read ip)) ->
+ (let* ((ip (if (null? opt) #f (car opt))) (op2 (port? ip))) ...)")
+ (lint-test "(define (f210 b . opt) (let ((ip (if (null? opt) 0 (car opt)))) (g ip) (f ip)))"
+ " f210: perhaps (define (f210 b . opt) (let ((ip (if (null? opt) 0 (car opt)))) (g ip) (f ip))) -> (define* (f210 b (ip 0)) ...)")
+ (lint-test "(define (f210 b . opt) (let ((ip (if (not (pair? opt)) 0 (car opt)))) (g ip) (f ip)))"
+ " f210: perhaps (define (f210 b . opt) (let ((ip (if (not (pair? opt)) 0 (car opt)))) (g... -> (define* (f210 b (ip 0)) ...)")
+ (lint-test "(define (f210 b . opt) (let ((ip (if (pair? opt) (car opt) 0))) (g ip) (f ip)))"
+ " f210: perhaps (define (f210 b . opt) (let ((ip (if (pair? opt) (car opt) 0))) (g ip) (f ip))) -> (define* (f210 b (ip 0)) ...)")
+ (lint-test "(define (f210 b . opt) (let ((ip (if (not (null? opt)) (car opt) 0))) (g ip) (f ip)))"
+ " f210: perhaps (define (f210 b . opt) (let ((ip (if (not (null? opt)) (car opt) 0))) (g... -> (define* (f210 b (ip 0)) ...)
+ f210: perhaps (if (not (null? opt)) (car opt) 0) -> (if (null? opt) 0 (car opt))")
+ (lint-test "(define (f210 . opt) (let ((ip (if (null? opt) 0 (car opt)))) (g ip) (f ip)))"
+ " f210: perhaps (define (f210 . opt) (let ((ip (if (null? opt) 0 (car opt)))) (g ip) (f ip))) -> (define* (f210 (ip 0)) ...)")
+ (lint-test "(define (f210 . opt) (let ((ip (if (null? opt) #f (car opt)))) (g ip) (f ip)))"
+ " f210: perhaps (define (f210 . opt) (let ((ip (if (null? opt) #f (car opt)))) (g ip) (f ip))) -> (define* (f210 ip) ...)
+ f210: perhaps (if (null? opt) #f (car opt)) -> (and (not (null? opt)) (car opt))")
(let-temporarily ((*report-clobbered-function-return-value* #t))
(lint-test "(let ((v #f)) (define (f80) (display v) \"a string\") (set! v (f80)) (string-set! v 0 #\\a))"
@@ -89805,6 +90244,11 @@ etc
(lint-test "(let () (define (f80? x) (if z (display x) (string-append x y z))) (display x) f80?)"
" let: f80? looks boolean, but it can return (string-append x y z)"))
+ (let-temporarily (((*lint* '*report-nested-if*) 3))
+ (lint-test "(if (< x y) (display z) (if (> x y) (+ w 1) (when (= x y) 0)))"
+ " if: perhaps (if (< x y) (display z) (if (> x y) (+ w 1) (when (= x y) 0))) ->
+ (cond ((< x y) (display z)) ((> x y) (+ w 1)) (else (when (= x y) 0)))"))
+
(lint-test "(let () (define x 2) (display x) (set! y 32) (display y) (* y (log y)))"
" let: perhaps (... (define x 2) (display x) (set! y 32) (display y) (* y (log y))) -> (... (let ((x 2)) ...))
let: the scope of x could be reduced: (... (define x 2) (display x) ...) -> (... (let ((x 2)) (display x)) ...)")
@@ -89834,6 +90278,10 @@ etc
(lint-test "(list (throw 'oops) 1 (read-byte))"
" list: order of evaluation of list's arguments is unspecified, so (list (throw 'oops) 1 (read-byte)) is trouble")
+ (lint-test "(call-with-input-file caaaar)"
+ " call-with-input-file: call-with-input-file needs 2 arguments: (call-with-input-file caaaar)
+ call-with-input-file: in (call-with-input-file caaaar), call-with-input-file's argument should be a string, but caaaar is a procedure?")
+
(lint-test "(and (< 0 x) (< x 1))" " and: perhaps (and (< 0 x) (< x 1)) -> (< 0 x 1)")
(lint-test "(and (< 1 x) (< x 1))" " and: perhaps (and (< 1 x) (< x 1)) -> #f")
(lint-test "(and (< 1 x) (< x 0))" " and: perhaps (and (< 1 x) (< x 0)) -> #f")
@@ -89952,6 +90400,20 @@ etc
" let: perhaps move the x binding to replace (set! x (+ x 1)):
(let ((x 32)) (set! y (f 1)) (a y) (f y) (g y) (h y) (i y) (set! x (+ x... ->
(let () ... (let ((x (+ 32 1))) ...))")
+
+ (lint-test "(let loop ((x y)) (if (null? x) () (cons (car x) (loop (cdr x)))))"
+ " loop: perhaps (let loop ((x y)) (if (null? x) () (cons (car x) (loop (cdr x))))) -> (copy y)")
+ (lint-test "(let loop ((x y)) (if (null? x) () (cons (string (car x)) (loop (cdr x)))))"
+ " loop: perhaps (let loop ((x y)) (if (null? x) () (cons (string (car x)) (loop (cdr x))))) -> (map string y)")
+ (lint-test "(let loop ((x y)) (cond ((null? x) ()) (else (cons (abs (car x)) (loop (cdr x))))))"
+ " loop: perhaps (let loop ((x y)) (cond ((null? x) ()) (else (cons (abs (car x)) (loop... -> (map abs y)")
+ (lint-test "(let loop ((x y)) (when (pair? x) (display (car x)) (loop (cdr x))))"
+ " loop: perhaps (let loop ((x y)) (when (pair? x) (display (car x)) (loop (cdr x)))) -> (for-each display y)")
+ (lint-test "(let loop ((x y)) (unless (null? x) (display (car x)) (loop (cdr x))))"
+ " loop: perhaps (let loop ((x y)) (unless (null? x) (display (car x)) (loop (cdr x)))) -> (for-each display y)")
+ (lint-test "(let loop ((x y)) (case x ((0 1) x) (else (loop (+ x 1)))))"
+ " loop: perhaps (let loop ((x y)) (case x ((0 1) x) (else (loop (+ x 1))))) -> (do ((x y (+ x 1))) ((memv x '(0 1)) x))
+ loop: perhaps (case x ((0 1) x) (else (loop (+ x 1)))) -> (if (memv x '(0 1)) x (loop (+ x 1)))")
(lint-test "(if (or (eq? x abs) (eq? x case) (eq? x null?)) 3 2)" "")
(lint-test "(cond ((eq? x begin) 1) ((eq? x reader-cond) 2) ((eq? x lint) 3))" "")
@@ -89965,7 +90427,8 @@ etc
(lint-test "(and-let* ((x (f y))) (abs x))" " and-let*: perhaps (and-let* ((x (f y))) (abs x)) -> (cond ((f y) => abs))")
(lint-test "(let () (define* (f51 (a 3)) (if (zero? a) 3 (f51 (- a 1)))) (f51 -1))"
" let: perhaps (... (define* (f51 (a 3)) (if (zero? a) 3 (f51 (- a 1)))) (f51 -1)) ->
- (... (let* f51 ((a -1)) (if (zero? a) 3 (f51 (- a 1)))))")
+ (... (let* f51 ((a -1)) (if (zero? a) 3 (f51 (- a 1)))))
+ f51: perhaps (define* (f51 (a 3)) (if (zero? a) 3 (f51 (- a 1)))) -> (define* (f51 (a 3)) (do ((a a (- a 1))) ((zero? a) 3)))")
(lint-test "(let () (define* (f51 (a 3) b) (if (zero? a) 3 (f51 (- a 1)))) (f51 -1))"
" let: perhaps (... (define* (f51 (a 3) b) (if (zero? a) 3 (f51 (- a 1)))) (f51 -1)) ->
(... (let* f51 ((a -1) (b #f)) (if (zero? a) 3 (f51 (- a 1)))))")
@@ -89982,6 +90445,15 @@ etc
let: this could be omitted: (f i)
let: perhaps (do ((i 0 (+ i 1))) ((= i 10)) (f i)) -> (do ((i 0 (+ i 1))) ((= i 10)) (abs (* 2 i)))")
+ (lint-test "(let () (define (f202 x) (x 1 2)) (f202 (lambda (a b) a)) (f202 (lambda (a b) (+ a 1))))"
+ " let: f202 parameter x is a function whose parameter 2 is never used")
+ (lint-test "(let () (define (f202 x) (x 1 2)) (f202 (lambda (a b) a)) (f202 (lambda (c d) (+ c 1))))"
+ " let: f202 parameter x is a function whose parameter 2 is never used")
+ (lint-test "(let () (define (f202 x) (x 1 2)) (f202 (lambda (a b) a)) (f202 (lambda (c d) (+ d 1))))" "")
+ (lint-test "(let () (define (f200 x) (x 32)) (f200 (lambda (a) (+ a 1))) (f200 (lambda (a) (+ a 1))) (f200 (lambda (a) (+ a 1))))"
+ " let: f200's 'x parameter is always (lambda (a) (+ a 1)) (3 calls)")
+ (lint-test "(let () (define (f201 x) (g (f x))) (f201 1) (f201 1) (f201 1))" " let: f201's 'x parameter is always 1 (3 calls)")
+
(lint-test "(string->symbol (let ((s (copy vstr))) (set! (s (+ pos 1)) #\\s) s))"
" string->symbol: perhaps
(string->symbol (let ((s (copy vstr))) (set! (s (+ pos 1)) #\\s) s)) ->
@@ -90042,7 +90514,9 @@ etc
" let: perhaps (... (define (f50 abs) (positive? abs)) (f50 -1)) -> (... (let ((abs -1)) (positive? abs)))
f50: f50 could be (define f50 positive?)
f50: f50 parameter named abs is asking for trouble")
- (lint-test "(let append ((x y)) (if (null? x) () (append (cdr y))))" " let: let variable named append is asking for trouble"))
+ (lint-test "(let append ((x y)) (if (null? x) () (append (cdr y))))"
+ " append: perhaps (let append ((x y)) (if (null? x) () (append (cdr y)))) -> (do ((x y (cdr y))) ((null? x) ()))
+ let: let variable named append is asking for trouble"))
(lint-test "(error 'error \"ERROR SOMEWHERE UP TO HERE\")" " error: There's no need to shout: (error 'error \"ERROR SOMEWHERE UP TO HERE\")")
(lint-test "(display \"ERROR: oops\" port)" " display: There's no need to shout: (display \"ERROR: oops\" port)")
@@ -90070,12 +90544,19 @@ etc
(cond ((string=? x \"a\") 1) ((string=? \"b\" x) 2) ((string=? x \"c\") 3))")
(lint-test "(cond ((< x 3) 1) ((> 2 x) 2) ((< x 1) 3))" "")
(let-temporarily ((*report-unused-parameters* #t))
- (lint-test "(define (f74 x) (let ((lst (list 1 2 3 4 5 6 7 8))) (list-ref lst 2)))" " f74: x not used")
- (lint-test "(let () (define (f75 x) (let ((lst (list 1 2 3 4 5 6 7 8))) (list-ref lst 2))) (f75 2))"
- " let: perhaps (... (define (f75 x) (let ((lst (list 1 2 3 4 5 6 7 8))) (list-ref lst... ->
- (... (let ((x 2)) (let ((lst (list 1 2 3 4 5 6 7 8))) (list-ref lst 2))))
- f75: x not used
- let: f75's parameter 1 is not used, but a value is passed: 2"))
+ (lint-test "(define (f74 x) (let ((lst (list 1 2 3 4 5 6 7 8))) (list-ref lst 2)))" " f74: x not used")
+ (lint-test "(let () (define (f75 x) (let ((lst (list 1 2 3 4 5 6 7 8))) (list-ref lst 2))) (f75 2))"
+ " let: perhaps (... (define (f75 x) (let ((lst (list 1 2 3 4 5 6 7 8))) (list-ref lst... ->
+ (... (let ((x 2)) (let ((lst (list 1 2 3 4 5 6 7 8))) (list-ref lst 2))))
+ f75: x not used
+ let: f75's parameter 1 is not used, but a value is passed: 2"))
+
+ (let-temporarily ((*report-loaded-files* #t))
+ (call-with-output-file "tmp1.r5rs"
+ (lambda (p)
+ (format p "(define (f x) (and (< x 3) (> x 0)))~%")))
+ (lint-test "(load \"tmp1.r5rs\")" " --------------------- ;tmp1.r5rs f (line 1): perhaps (and (< x 3) (> x 0)) -> (< 0 x 3)"))
+
(lint-test "(or (< x 3) (> 3 x))" " or: perhaps (or (< x 3) (> 3 x)) -> (< x 3)")
(lint-test "(and (< x 3) (> 3 x))" " and: perhaps (and (< x 3) (> 3 x)) -> (< x 3)")
(lint-test "(case x ((1) (f 1)) ((2) (f 2)) (else (f 3)))"
@@ -90094,6 +90575,11 @@ etc
" let: in (let ((p #f)) (if x (set! p (open-output-file str))) (display 32 p) x)
perhaps p is opened via (set! p (open-output-file str)), but never closed")
+ (lint-test "(define (listtail x k) (if (zero? k) x (listtail (cdr x) (- k 1))))"
+ " listtail: perhaps (define (listtail x k) (if (zero? k) x (listtail (cdr x) (- k 1)))) ->
+ (define (listtail x k) (do ((x x (cdr x)) (k k (- k 1))) ((zero? k) x)))
+ listtail: listtail is the same as the built-in function list-tail")
+
(lint-test "(cdr '(a))" " cdr: perhaps (cdr '(a)) -> ()")
(lint-test "(char-upcase #\\a)" " char-upcase: perhaps (char-upcase #\\a) -> #\\A")
(lint-test "(char-upper-case? #\\a)" " char-upper-case?: perhaps (char-upper-case? #\\a) -> #f")
@@ -90107,9 +90593,13 @@ etc
(lint-test "(write-char #\\newline)" " write-char: perhaps (write-char #\\newline) -> (newline)")
(lint-test "(write-char #\\newline port)" " write-char: perhaps (write-char #\\newline port) -> (newline port)")
(lint-test "(write-string \"\n\")" " write-string (line 1): perhaps (write-string \"\n\") -> (newline)")
- (lint-test "(define (listtail x k) (if (zero? k) x (listtail (cdr x) (- k 1))))" " listtail: listtail is the same as the built-in function list-tail")
+ (lint-test "(write-string \"\")" " write-string: (write-string \"\") is pointless")
(lint-test "(char? #\\a)" " char?: perhaps (char? #\\a) -> #t")
(lint-test "(symbol->string (keyword->symbol :hi))" " symbol->string: perhaps (keyword->symbol :hi) -> 'hi")
+ (lint-test "(string->keyword (string-append \":\" z))" " string->keyword: string->keyword prepends #\\: for you: (string->keyword (string-append \":\" z))")
+ (lint-test "(string->keyword (symbol->string sym))" " string->keyword: perhaps (string->keyword (symbol->string sym)) -> (symbol->keyword sym)")
+ (lint-test "(keyword->symbol (string->keyword str))" " keyword->symbol: perhaps (keyword->symbol (string->keyword str)) -> (string->symbol str)")
+ (lint-test "(symbol->keyword (string->symbol str))" " symbol->keyword: perhaps (symbol->keyword (string->symbol str)) -> (string->keyword str)")
(lint-test "(keyword->symbol :hi)" " keyword->symbol: perhaps (keyword->symbol :hi) -> 'hi")
(lint-test "(symbol->keyword 'hiho)" " symbol->keyword: perhaps (symbol->keyword 'hiho) -> :hiho")
(lint-test "(positive? 1.0)" " positive?: perhaps (positive? 1.0) -> #t")
@@ -90145,7 +90635,47 @@ etc
(lint-test " (dilambda 1 2)"
" dilambda: in (dilambda 1 2), dilambda's argument 1 should be a procedure, but 1 is an integer?
dilambda: in (dilambda 1 2), dilambda's argument 2 should be a procedure, but 2 is an integer?")
-
+ (lint-test "(let ((v (float-vector 1 2 3))) (vector-set! v 0 12) v)" " let: v is a float-vector, so perhaps use float-vector-set!, not vector-set!")
+ (lint-test "(let ((v (int-vector 1 2 3))) (+ (vector-ref v 1) (int-vector-ref v 0)))" " let: v is an int-vector, so perhaps use int-vector-ref, not vector-ref")
+ (lint-test "(let ((v (vector 1 2 3))) (float-vector-set! v 0 12) v)" " let: v is a vector, so use vector-set!, not float-vector-set!")
+ (lint-test "(nth 1 lst)" " nth: perhaps (nth 1 lst) -> (list-ref lst 1)")
+ (lint-test "(sort lst <)" " sort: perhaps (sort lst <) -> (sort! (copy lst) <)")
+ (lint-test "(sort (map car lst) (lambda (a b) (< (car a) (car b))))" " sort: use sort! here: (sort (map car lst) (lambda (a b) (< (car a) (car b))))")
+ (lint-test "(display x (newline))" " display: in (display x (newline)), display's argument 2 should be an output-port, but (newline) is untyped")
+ (lint-test "(let ((p (open-input-string str))) (display x))"
+ " let: in (let ((p (open-input-string str))) (display x)) perhaps p is opened via (open-input-string str), but never closed
+ let: p not used, initially: (open-input-string str) from let")
+ (lint-test "(let ((p (open-output-string))) (display x))"
+ " let: in (let ((p (open-output-string))) (display x)) perhaps p is opened via (open-output-string), but never closed
+ let: p not used, initially: (open-output-string) from let")
+ (lint-test "(let ((p (open-input-string str))) (display x) (close-output-port p))"
+ " let: in (let ((p (open-input-string str))) (display x) (close-output-port p)) p is opened and closed, but never used
+ let: p is an input-port, but close-output-port in (close-output-port p) wants an output-port?")
+ (lint-test "(let ((p (open-output-string))) (display x) (close-input-port p))"
+ " let: in (let ((p (open-output-string))) (display x) (close-input-port p)) p is opened and closed, but never used
+ let: p is an output-port, but close-input-port in (close-input-port p) wants an input-port?")
+ (lint-test "(let ((p (open-output-string))) (display x) (close-output-port p))"
+ " let: in (let ((p (open-output-string))) (display x) (close-output-port p)) p is opened and closed, but never used")
+ (lint-test "(let ((p (open-input-string str))) (display x) (close-input-port p))"
+ " let: in (let ((p (open-input-string str))) (display x) (close-input-port p)) p is opened and closed, but never used")
+ (lint-test "(let ((p (open-output-string))) (display val p) (close-output-port p))"
+ " p: (let ((p (open-output-string))) (display val p) (close-output-port p)) is missing get-output-string")
+ (lint-test "(let ((p (open-output-string))) (display val p) (fos val (close-output-port p)))"
+ " p: (let ((p (open-output-string))) (display val p) (fos val... is missing get-output-string")
+ (lint-test "(let ((s (open-output-string))) (write obj s) (let ((result (get-output-string s))) (close-output-port s) result))"
+ " s: perhaps (let ((s (open-output-string))) (write obj s) (let ((result... -> (object->string obj)")
+ (lint-test "(let ((x '(1 2 3))) (display (car x)) (display (list-ref x y)) (list-ref x 1))" " let: x could be a vector, rather than a list")
+ (lint-test "(let ((x '(1 2 3))) (display (car x)) (display (x y)) (x 1))" " let: x could be a vector, rather than a list")
+ (lint-test "(define (func x) (if (or x 1/0+i) 3))" " func: perhaps (or x nan+1i) -> (or x nan+1i)") ; infinite loop
+ (lint-test "(if (and x 1/0) 3)" " if: perhaps (and x nan.0) -> (and x nan.0)")
+ (lint-test "(define (func x) (if (* (call/cc (lambda (go) (go 9) 0)) '((1 (2)) (((3) 4))) 1(/ )) (iterator-sequence 1-)))"
+ " func: if test is never false: (if (* (call/cc (lambda (go) (go 9) 0)) '((1 (2)) (((3) 4))) 1 (/))...
+ func: in (* (call/cc (lambda (go) (go 9) 0)) '((1 (2)) (((3) 4))) 1 (/)), *'s argument 2 should be a number, but '((1 (2)) (((3) 4))) is a list?
+ func: perhaps (* (call/cc (lambda (go) (go 9) 0)) '((1 (2)) (((3) 4))) 1 (/)) -> (* (call/cc (lambda (go) (go 9) 0)) '((1 (2)) (((3) 4))) (/))
+ func: perhaps call/cc could be call-with-exit: (call/cc (lambda (go) (go 9) 0))
+ func: (go 9) makes this pointless: 0
+ func: / needs at least 1 argument: (/)")
+
(when (provided? 'snd)
(lint-test "(begin (cond ((find-sound \"test.snd\") => close-sound)) (display x))" "")
(lint-test "(if (real? (oscil x)) 1.0 0.0)" " if: perhaps (if (real? (oscil x)) 1.0 0.0) -> 1.0")
@@ -90158,10 +90688,10 @@ etc
(lint-test "(set! (print-length) 9)" "")
(lint-test "(set! (show-indices) 32)" " set!: show-indices: new value should be a boolean?: integer?: (set! (show-indices) 32)")
(lint-test "(set! (show-indices) #t)" "")
- (lint-test "(let () (mus-header-type-name 121))" " let: mus-header-type-name's argument, 121, should be an integer between 1 and 70")
- (lint-test "(let () (mus-header-type-name 2))" "")
- (lint-test "(let () (mus-header-type-name 3.5))" " let: in (mus-header-type-name 3.5), mus-header-type-name's argument should be an integer, but 3.5 is real?")
- (lint-test "(let () (mus-header-type-name mus-aiff))" "")
+ (lint-test "(mus-header-type-name 121)" " mus-header-type-name: mus-header-type-name's argument, 121, should be an integer between 1 and 70")
+ (lint-test "(mus-header-type-name 2)" "")
+ (lint-test "(mus-header-type-name 3.5)" " mus-header-type-name: in (mus-header-type-name 3.5), mus-header-type-name's argument should be an integer, but 3.5 is real?")
+ (lint-test "(mus-header-type-name mus-aiff)" "")
(when (provided? 'snd-gtk)
(lint-test "(gtk_scale_set_value_pos (GTK_SCALE scale) GTK_POS_TOP)" "")