Add reduce
Broken
diff --git a/lib/lisp/std/list-functions.lisp b/lib/lisp/std/list-functions.lisp
index a777401..7bb22a7 100644
--- a/lib/lisp/std/list-functions.lisp
+++ b/lib/lisp/std/list-functions.lisp
@@ -1,5 +1,35 @@
(defun mapcar (fun list)
+ "Maps over the cars of `list` by running `fun` on each one.
+List must be a cons-list, other sequences are not supported."
(if list
(cons (funcall fun (car list))
(mapcar fun (cdr list)))
nil))
+
+(defun remove-if (predicate list)
+ "Returns a copy of `list` with elements satisfying `predicate`
+removed."
+ (if (not list)
+ nil
+ (if (funcall predicate (car list))
+ (remove-if predicate (cdr list))
+ (cons (car list)
+ (remove-if predicate (cdr list))))))
+
+(defun remove-if-not (predicate list)
+ "Returns a copy of `list` with elements not satisfying `predicate`
+removed."
+ (remove-if (lambda (val)
+ (not (funcall predicate val)))
+ list))
+
+(defun reduce (fun list (initial-value nil))
+ "Combines elements of `list` into one element using `fun`. `fun` must
+accept two arguments and return the result of combining those
+arguments. The first argument will be the result so far and the second
+will be the n-th item of the list. For the first item of the list, the
+result so far will be `initial-value`, or `nil` by default."
+ (if (not list)
+ initial-value
+ (reduce fun (cdr list)
+ (funcall fun initial-value (car list)))))
diff --git a/lib/lisp/std/std.lisp b/lib/lisp/std/std.lisp
index d995f0e..56e8294 100644
--- a/lib/lisp/std/std.lisp
+++ b/lib/lisp/std/std.lisp
@@ -21,9 +21,8 @@
-;; Instead of a function this is a macro for a slight performance increase
-(defmacro not (val)
- (list 'nilp val))
+(defun not (val)
+ (nilp val))
;; TODO: make tail recursive (for this `flet` would be nice)
(defun length (list)
@@ -51,5 +50,9 @@
(if (not stream)
(read-stdin)))
-(print "Loading list functions")
-(print (load "list-functions.lisp"))
+(defun funcall (fun & list)
+ (print fun)
+ (print list)
+ (apply fun list))
+
+(load "list-functions.lisp")