Standard Library

Prelude

Helper functions written in clisp

Math

; Math
(def (pi) 3.1415)
(def (add1 z) (+ z 1))
(def (sub1 z) (- z 1))
(def (sign x) (cond ((positive? x) 1) ((negative? x) -1) (#t 0)))
(def (double b) (* b 2))
(def (triple b) (* b 3))
(def (fib n) (cond ((< n 0) 0) ((eq n 1) 1) (#t (+ (fib (- n 1)) (fib (- n 2))))))
(def (fact n) (if (<= n 0) 1 (* n (fact (- n 1)))))

List

; List
(def (reverse xs) (if (empty? xs) [] (append (reverse (tail xs)) (head xs))))
(def (nth n xs) (cond ((empty? xs) []) ((<= n 1) (head xs)) (#t (nth (- n 1) (tail xs)))))
(def (last xs) (nth (length xs) xs))
(def (first xs) (nth 1 xs))
(def (remove v xs) (filter (fn (t) (ne t v)) xs))

(def (map f xs) (if (empty? xs) [] (append (list (f (head xs))) (map f (tail xs)))))
(def (fold f acc xs) (cond ((empty? xs) acc) (#t (fold f (f acc (head xs)) (tail xs)))))
(def (reduce f xs) (if (empty? xs) (head xs) (fold f (head xs) (tail xs))))
(def (filter f xs) (cond ((empty? xs) []) ((f (head xs)) (append (list (head xs)) (filter f (tail xs)))) (#t (filter f (tail xs)))))
(def (for-each f xs) (cond ((> (length xs) 0) (when (#t (f (head xs))) (#t (for-each f (tail xs)))))))

(def (flatten xs) (cond ((empty? xs) []) ((list? (head xs)) (append (flatten (head xs)) (flatten (tail xs)))) (#t (append (list (head xs)) (flatten (tail xs))))))
(def (zip xs ys) (cond ((empty? xs) []) ((empty? ys) []) (#t (append (list (list (head xs) (head ys))) (zip (tail xs) (tail ys))))))

(def (range s e) (cond ((> s e) []) (#t (append (list s) (range (+ s 1) e)))))
(def (range-step s e st) (cond ((> s e) []) (#t (append (list s) (range-step (+ s st) e st)))))
(def (repeat t n) (map (fn (a) t) (range 1 n)))
(def (all xs) (if (empty? xs) #f (fold and (head xs) (tail xs))))
(def (any xs) (if (empty? xs) #f (fold or (head xs) (tail xs))))

(def (take n xs) (cond ((empty? xs) []) ((eq n 0) []) (#t (append (list (head xs)) (take (- n 1) (tail xs))))))
(def (drop n xs) (cond ((empty? xs) []) ((eq n 0) (append (list (head xs)) (drop 0 (tail xs)))) (#t (drop (- n 1) (tail xs)))))
(def (takeWhile f xs) (cond ((empty? xs) []) ((f (head xs)) (append (list (head xs)) (takeWhile f (tail xs)))) (#t [])))
(def (dropWhile f xs) (cond ((empty? xs) []) ((f (head xs)) (dropWhile f (tail xs))) (#t xs)))
(def (takeFirst f xs) (cond ((empty? xs) []) ((f (head xs)) (head xs)) (#t (takeFirst f (tail xs)))))
(def (takeLast f xs) (takeFirst f (reverse xs)))
(def (slice s e xs) (take e (drop s xs)))

(def (sum xs) (reduce + xs))
(def (multiply xs) (reduce * xs))
(def (max xs) (reduce (fn (acc v) (if (>= acc v) acc v)) xs))

Unit test

Helper functions to write your own tests

(def (check-eq? f s m) (cond ((ne f s) (error m))))
(def (check-not-eq? f s m) (cond ((eq f s) (error m))))
(def (check-true? b m) (cond ((ne b #t) (error m))))
(def (check-false? b m) (cond ((ne b #f) (error m))))
(def (check-count? xs c m) (cond ((ne (length xs) c) (error m))))
(def (check-eqv? f s e m) (cond ((> (abs (- f s)) e) (error m))))

(def (check-bool? t1 m) (cond ((not (bool? t1)) (error m))))
(def (check-error? t1 m) (cond ((not (error? t1)) (error m))))
(def (check-list? t1 m) (cond ((not (list? t1)) (error m))))
(def (check-number? t1 m) (cond ((not (number? t1)) (error m))))
(def (check-string? t1 m) (cond ((not (string? t1)) (error m))))
(def (check-type? t1 t2 m) (cond ((ne (type t1) t2) (error m))))

Examples

(load "stl/unittest.clisp")

(test-suite "Boolean suite case")

; Check type
(test-case "Test Bool? without args" (check-error? (bool?) "Arg should be error"))
(test-case "Test Bool? using boolean" (check-true? (bool? #f) "Arg should be boolean"))
(test-case "Test Bool? using number" (check-false? (bool? 1) "Arg should be boolean"))