X-Git-Url: http://git.kpe.io/?p=pipes.git;a=blobdiff_plain;f=pipes.lisp;fp=pipes.lisp;h=1450ca309819ec38b1330eab6394c7668f981837;hp=9b6b4c772da8589c008fc0325c0d9e51bffd6660;hb=eaad3792a9bf28ec7bfe579f9f0955d213e014f0;hpb=108cf113175bc41454b5b028d78fe00e67c37d83 diff --git a/pipes.lisp b/pipes.lisp index 9b6b4c7..1450ca3 100644 --- a/pipes.lisp +++ b/pipes.lisp @@ -7,7 +7,7 @@ ;;;; Programmers: Kevin M. Rosenberg and Peter Norvig ;;;; Date Started: Apr 2000 ;;;; -;;;; $Id: pipes.lisp,v 1.1 2002/11/02 17:49:10 kevin Exp $ +;;;; $Id: pipes.lisp,v 1.2 2002/11/07 20:26:13 kevin Exp $ ;;;; ;;;; This file is Copyright (c) 2000-2002 by Kevin M. Rosenberg and ;;;; Copyright (c) 1998-2002 by Peter Norvig. @@ -23,104 +23,107 @@ (defconstant +empty-pipe+ nil) (defmacro make-pipe (head tail) - "create a pipe by eval'ing head and delaying tail." + "Create a pipe by evaluating head and delaying tail." `(cons ,head #'(lambda () ,tail))) (defun pipe-tail (pipe) - "return tail of pipe or list, and destructively update + "Return tail of pipe or list, and destructively update the tail if it is a function." - ;; pipes should never contain functions as values (if (functionp (rest pipe)) (setf (rest pipe) (funcall (rest pipe))) (rest pipe))) (defun pipe-head (pipe) (first pipe)) -(defun pipe-elt (pipe n) - "nth element of pipe, 0 based." - (if (= n 0) (pipe-head pipe) - (pipe-elt (pipe-tail pipe) (- n 1)))) +(defun pipe-elt (pipe i) + "The i-th element of pipe, 0-based." + (if (= i 0) + (pipe-head pipe) + (pipe-elt (pipe-tail pipe) (- i 1)))) -(defun enumerate (pipe &key count key (result pipe)) - "go through all or count elements of pipe, - possibly applying the key function. " +(defun pipe-enumerate (pipe &key count key (result pipe)) + "Go through all (or count) elements of pipe, + possibly applying the KEY function. (Try PRINT.)" + ;; Returns RESULT, which defaults to the pipe itself. (if (or (eq pipe +empty-pipe+) (eql count 0)) result (progn (unless (null key) (funcall key (pipe-head pipe))) - (enumerate (pipe-tail pipe) + (pipe-enumerate (pipe-tail pipe) :count (if count (1- count)) - :key key - :result result)))) + :key key :result result)))) -(defun pipe-display (pipe &optional count) - (enumerate pipe :count count)) +(defun pipe-values (pipe &optional count) + "Simple wrapper to return values of a pipe" + (pipe-enumerate pipe :count count)) (defun pipe-force (pipe) - (enumerate pipe)) + "Force the enumeration of all of the pipe. Never returns +if the pipe is infinite in length." + (pipe-enumerate pipe)) (defun pipe-filter (predicate pipe) - "keep only items in (non-null) pipe satisfying predicate" - (if (eq pipe +empty-pipe+) + "Keep only items in pipe satisfying predicate." + (if (eq pipe +empty-pipe+) +empty-pipe+ - (let ((head (pipe-head pipe)) - (tail (pipe-tail pipe))) + (let ((head (pipe-head pipe)) + (tail (pipe-tail pipe))) (if (funcall predicate head) - (make-pipe head (pipe-filter predicate tail)) + (make-pipe head (pipe-filter predicate tail)) (pipe-filter predicate tail))))) (defun pipe-map (fn pipe) - "Map fn over pipe, delaying all but the first fn call, - collecting res