X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;ds=sidebyside;f=pipes.lisp;fp=pipes.lisp;h=0000000000000000000000000000000000000000;hb=439ba38fc06701c4db33f9aaf5ab17a0c88ea6ca;hp=68a9b2ff61852a15ab9558dac1bc4c936dbce4f5;hpb=318bc76da7e8bd15e84af24ab87757c10208c7a7;p=pipes.git diff --git a/pipes.lisp b/pipes.lisp deleted file mode 100644 index 68a9b2f..0000000 --- a/pipes.lisp +++ /dev/null @@ -1,125 +0,0 @@ -;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*- -;;;; ************************************************************************* -;;;; FILE IDENTIFICATION -;;;; -;;;; Name: pipes.lisp -;;;; Purpose: Pipes based on ideas from Norvig's PAIP book -;;;; Programmers: Kevin M. Rosenberg and Peter Norvig -;;;; Date Started: Apr 2000 -;;;; -;;;; $Id: pipes.lisp,v 1.3 2002/11/08 16:51:40 kevin Exp $ -;;;; -;;;; This file is Copyright (c) 2000-2002 by Kevin M. Rosenberg and -;;;; Copyright (c) 1998-2002 by Peter Norvig. -;;;; ************************************************************************* - -(in-package :pipes) - - -(defconstant +empty-pipe+ nil) - -(defmacro make-pipe (head 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 - the tail if it is a function." - (if (functionp (rest pipe)) - (setf (rest pipe) (funcall (rest pipe))) - (rest pipe))) - -(defun pipe-head (pipe) (first pipe)) - -(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 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))) - (pipe-enumerate (pipe-tail pipe) - :count (if count (1- count)) - :key key :result result)))) - -(defun pipe-values (pipe &optional count) - "Simple wrapper to return values of a pipe" - (pipe-enumerate pipe :count count)) - -(defun pipe-force (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 pipe satisfying predicate." - (if (eq pipe +empty-pipe+) - +empty-pipe+ - (let ((head (pipe-head pipe)) - (tail (pipe-tail pipe))) - (if (funcall predicate head) - (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." - (if (eq pipe +empty-pipe+) - +empty-pipe+ - (make-pipe (funcall fn (pipe-head pipe)) - (pipe-map fn (pipe-tail pipe))))) - - -(defun pipe-map-filtering (fn pipe &optional filter-pred) - "Map fn over pipe, delaying all but the first fn call, - while filtering results." - (if (eq pipe +empty-pipe+) - +empty-pipe+ - (let* ((head (pipe-head pipe)) - (tail (pipe-tail pipe)) - (result (funcall fn head))) - (if (or (and filter-pred (funcall filter-pred result)) - result) - (make-pipe result (pipe-map-filtering fn tail filter-pred)) - (pipe-map-filtering fn tail filter-pred))))) - - -(defun pipe-append (x y) - "Return a pipe that appends the elements of x and y." - (if (eq x +empty-pipe+) - y - (make-pipe (pipe-head x) - (pipe-append (pipe-tail x) y)))) - - -(defun pipe-mappend (fn pipe) - "Lazily map fn over pipe, appending results." - (if (eq pipe +empty-pipe+) - +empty-pipe+ - (let ((x (funcall fn (pipe-head pipe)))) - (make-pipe (pipe-head x) - (pipe-append (pipe-tail x) - (pipe-mappend fn (pipe-tail pipe))))))) - -(defun pipe-mappend-filtering (fn pipe &optional filter-pred) - "Map fn over pipe, delaying all but the first fn call, - appending results while filtering." - (if (eq pipe +empty-pipe+) - +empty-pipe+ - (let* ((head (pipe-head pipe)) - (tail (pipe-tail pipe)) - (result (funcall fn head))) - (if (or (and filter-pred (funcall filter-pred result)) - result) - (make-pipe (pipe-head result) - (pipe-append (pipe-tail result) - (pipe-mappend-filtering fn tail filter-pred))) - (pipe-mappend-filtering fn tail filter-pred)))))