diff options
author | IOhannes m zmölnig <zmoelnig@umlautQ.umlaeute.mur.at> | 2016-10-24 13:57:11 +0200 |
---|---|---|
committer | IOhannes m zmölnig <zmoelnig@umlautQ.umlaeute.mur.at> | 2016-10-24 13:57:11 +0200 |
commit | f81bd20a17bbbccde1154046c6ec70805e4be71b (patch) | |
tree | 4781df323969a2466984abd9fe69b1bc01b69ec1 /s7test.scm | |
parent | a91adfdf373f6914bfec9901421cba0e99746b0b (diff) |
New upstream version 16.9
Diffstat (limited to 's7test.scm')
-rw-r--r-- | s7test.scm | 774 |
1 files changed, 652 insertions, 122 deletions
@@ -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)" "") |