⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srfi1.scm

📁 A framework written in Java for implementing high-level and dynamic languages, compiling them into J
💻 SCM
📖 第 1 页 / 共 4 页
字号:
		     (values l lis))		; Done.		    (else (lp l (cdr l)))))))))|#;;; Inline us, please.(define (remove  pred l) (filter  (lambda (x) (not (pred x))) l))(define (remove! pred l) (filter! (lambda (x) (not (pred x))) l));;; Here's the taxonomy for the DELETE/ASSOC/MEMBER functions.;;; (I don't actually think these are the world's most important;;; functions -- the procedural FILTER/REMOVE/FIND/FIND-TAIL variants;;; are far more general.);;;;;; Function			Action;;; ---------------------------------------------------------------------------;;; remove pred lis		Delete by general predicate;;; delete x lis [=]		Delete by element comparison;;;					     ;;; find pred lis		Search by general predicate;;; find-tail pred lis		Search by general predicate;;; member x lis [=]		Search by element comparison;;;;;; assoc key lis [=]		Search alist by key comparison;;; alist-delete key alist [=]	Alist-delete by key comparison(define (delete x lis #!optional (maybe-= equal?))   (filter (lambda (y) (not (maybe-= x y))) lis))(define (delete! x lis #!optional (maybe-= equal?))  (filter! (lambda (y) (not (maybe-= x y))) lis));;; Extended from R4RS to take an optional comparison argument.; In kawa.lib.lists.;(define (member x lis #!optional (maybe-= equal?));  (find-tail (lambda (y) (maybe-= x y)) lis));;; R4RS, hence we don't bother to define.;;; The MEMBER and then FIND-TAIL call should definitely;;; be inlined for MEMQ & MEMV.;(define (memq    x lis) (member x lis eq?));(define (memv    x lis) (member x lis eqv?));;; right-duplicate deletion;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; delete-duplicates delete-duplicates!;;;;;; Beware -- these are N^2 algorithms. To efficiently remove duplicates;;; in long lists, sort the list to bring duplicates together, then use a ;;; linear-time algorithm to kill the dups. Or use an algorithm based on;;; element-marking. The former gives you O(n lg n), the latter is linear.(define (delete-duplicates lis #!optional (maybe-= :: <procedure> equal?))  (let recur ((lis lis))    (if (null-list? lis) lis	(let* ((x (car lis))	       (tail (cdr lis))	       (new-tail (recur (delete x tail maybe-=))))	  (if (eq? tail new-tail) lis (cons x new-tail))))))(define (delete-duplicates! lis #!optional (maybe-= :: <procedure> equal?))  (let recur ((lis lis))    (if (null-list? lis) lis	(let* ((x (car lis))	       (tail (cdr lis))	       (new-tail (recur (delete! x tail maybe-=))))	  (if (eq? tail new-tail) lis (cons x new-tail))))));;; alist stuff;;;;;;;;;;;;;;;;;; Extended from R4RS to take an optional comparison argument.;; In kawa.lib.lists.;;(define (assoc x lis #!optional (maybe-= equal?));;   (find (lambda (entry) (maybe-= x (car entry))) lis))(define (alist-cons key datum alist) (cons (cons key datum) alist))(define (alist-copy alist)  (map (lambda (elt) (cons (car elt) (cdr elt)))       alist))(define (alist-delete key alist #!optional (maybe-= equal?))  (filter (lambda (elt) (not (maybe-= key (car elt)))) alist))(define (alist-delete! key alist #!optional (maybe-= equal?))  (filter! (lambda (elt) (not (maybe-= key (car elt)))) alist));;; find find-tail take-while drop-while span break any every list-index;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(define (find pred list)  (cond ((find-tail pred list) => car)	(else #f)))(define (find-tail pred :: <procedure> list)  (let lp ((list list))    (and (not (null-list? list))	 (if (pred (car list)) list	     (lp (cdr list))))))(define (take-while pred :: <procedure> lis)  (let recur ((lis lis))    (if (null-list? lis) '()	(let ((x (car lis)))	  (if (pred x)	      (cons x (recur (cdr lis)))	      '())))))(define (drop-while pred :: <procedure> lis)  (let lp ((lis lis))    (if (null-list? lis) '()	(if (pred (car lis))	    (lp (cdr lis))	    lis))))(define (take-while! pred :: <procedure> lis)  (if (or (null-list? lis) (not (pred (car lis)))) '()      (begin (let lp ((prev lis) (rest (cdr lis)))	       (if (pair? rest)		   (let ((x (car rest)))		     (if (pred x) (lp rest (cdr rest))			 (set-cdr! prev '())))))	     lis)))(define (span pred :: <procedure> lis)  (let loop ((lis lis) (res '()))    (if (null-list? lis)        (values (reverse! res) lis)        (let ((head (car lis)))          (if (pred head)              (loop (cdr lis) (cons head res))              (values (reverse! res) lis))))))(define (span! pred :: <procedure> lis)  (if (or (null-list? lis) (not (pred (car lis)))) (values '() lis)      (let ((suffix (let lp ((prev lis) (rest (cdr lis)))		      (if (null-list? rest) rest			  (let ((x (car rest)))			    (if (pred x) (lp rest (cdr rest))				(begin (set-cdr! prev '())				       rest)))))))	(values lis suffix))))  (define (break  pred lis) (span  (lambda (x) (not (pred x))) lis))(define (break! pred lis) (span! (lambda (x) (not (pred x))) lis))(define (any pred :: <procedure> lis1 . lists)  (if (pair? lists)      ;; N-ary case      (receive (heads tails) (%cars+cdrs (cons lis1 lists))	(and (pair? heads)	     (let lp ((heads heads) (tails tails))               (let* ((split (%cars+cdrs/pair tails))                      (next-heads (car split))                      (next-tails (cdr split)))		 (if (pair? next-heads)		     (or (apply pred heads) (lp next-heads next-tails))		     (apply pred heads)))))) ; Last PRED app is tail call.      ;; Fast path      (and (not (null-list? lis1))	   (let lp ((head (car lis1)) (tail (cdr lis1)))	     (if (null-list? tail)		 (pred head)		; Last PRED app is tail call.		 (or (pred head) (lp (car tail) (cdr tail))))))));(define (every pred list)              ; Simple definition.;  (let lp ((list list))                ; Doesn't return the last PRED value.;    (or (not (pair? list));        (and (pred (car list));             (lp (cdr list))))))(define (every pred :: <procedure> lis1 . lists)  (if (pair? lists)      ;; N-ary case      (receive (heads tails) (%cars+cdrs (cons lis1 lists))	(or (not (pair? heads))	    (let lp ((heads heads) (tails tails))	      (receive (next-heads next-tails) (%cars+cdrs tails)		(if (pair? next-heads)		    (and (apply pred heads) (lp next-heads next-tails))		    (apply pred heads)))))) ; Last PRED app is tail call.      ;; Fast path      (or (null-list? lis1)	  (let lp ((head (car lis1))  (tail (cdr lis1)))	    (if (null-list? tail)		(pred head)	; Last PRED app is tail call.		(and (pred head) (lp (car tail) (cdr tail))))))))(define-syntax %every  (syntax-rules ()		((%every pred lis1)		 (let lp ((head (car lis1))  (tail (cdr lis1)))		   (and  (null-list? tail) (pred head) (lp (car tail) (cdr tail)))))))(define (list-index pred :: <procedure> lis1 . lists)  (if (pair? lists)      ;; N-ary case      (let lp ((lists (cons lis1 lists)) (n 0))	(receive (heads tails) (%cars+cdrs lists)	  (and (pair? heads)	       (if (apply pred heads) n		   (lp tails (+ n 1))))))      ;; Fast path      (let lp ((lis lis1) (n 0))	(and (not (null-list? lis))	     (if (pred (car lis)) n (lp (cdr lis) (+ n 1)))))));;; Reverse;;;;;;;;;;;;R4RS, so not defined here.;(define (reverse lis) (fold cons '() lis))				      ;(define (reverse! lis);  (pair-fold (lambda (pair tail) (set-cdr! pair tail) pair) '() lis));(define (reverse! lis)  ;; Kawa primitive;  (let lp ((lis lis) (ans '()));    (if (null-list? lis) ans;        (let ((tail (cdr lis)));          (set-cdr! lis ans);          (lp tail lis)))));;; Lists-as-sets;;;;;;;;;;;;;;;;;;;; This is carefully tuned code; do not modify casually.;;; - It is careful to share storage when possible;;;; - Side-effecting code tries not to perform redundant writes.;;; - It tries to avoid linear-time scans in special cases where constant-time;;;   computations can be performed.;;; - It relies on similar properties from the other list-lib procs it calls.;;;   For example, it uses the fact that the implementations of MEMBER and;;;   FILTER in this source code share longest common tails between args;;;   and results to get structure sharing in the lset procedures.(define-private (%lset2<= = lis1 lis2) (every (lambda (x) (member x lis2 =)) lis1))(define (lset<= = :: <procedure> . lists)  (or (not (pair? lists)) ; 0-ary case      (let lp ((s1 (car lists)) (rest (cdr lists)))	(or (not (pair? rest))	    (let ((s2 (car rest))  (rest (cdr rest)))	      (and (or (eq? s2 s1)	; Fast path		       (%lset2<= = s1 s2)) ; Real test		   (lp s2 rest)))))))(define (lset= = :: <procedure> . lists)  (or (not (pair? lists)) ; 0-ary case      (let lp ((s1 (car lists)) (rest (cdr lists)))	(or (not (pair? rest))	    (let ((s2   (car rest))		  (rest (cdr rest)))	      (and (or (eq? s1 s2)	; Fast path		       (and (%lset2<= = s1 s2) (%lset2<= = s2 s1))) ; Real test		   (lp s2 rest)))))))(define (lset-adjoin = :: <procedure> lis . elts)  (fold (lambda (elt ans) (if (member elt ans =) ans (cons elt ans)))	lis elts))(define (lset-union = :: <procedure> . lists)  (reduce (lambda (lis ans)		; Compute ANS + LIS.	    (cond ((null? lis) ans)	; Don't copy any lists		  ((null? ans) lis) 	; if we don't have to.		  ((eq? lis ans) ans)		  (else		   (fold (lambda (elt ans) (if (any (lambda (x) (= x elt)) ans)					       ans					       (cons elt ans)))			 ans lis))))	  '() lists))(define (lset-union! = :: <procedure> . lists)  (reduce (lambda (lis ans)		; Splice new elts of LIS onto the front of ANS.	    (cond ((null? lis) ans)	; Don't copy any lists		  ((null? ans) lis) 	; if we don't have to.		  ((eq? lis ans) ans)		  (else		   (pair-fold (lambda (pair ans)				(let ((elt (car pair)))				  (if (any (lambda (x) (= x elt)) ans)				      ans				      (begin (set-cdr! pair ans) pair))))			      ans lis))))	  '() lists))(define (lset-intersection = :: <procedure> lis1 . lists)  (let ((lists (delete lis1 lists eq?))) ; Throw out any LIS1 vals.    (cond ((any null-list? lists) '())		; Short cut	  ((null? lists)          lis1)		; Short cut	  (else (filter (lambda (x)			  (every (lambda (lis) (member x lis =)) lists))			lis1)))))(define (lset-intersection! = :: <procedure> lis1 . lists)  (let ((lists (delete lis1 lists eq?))) ; Throw out any LIS1 vals.    (cond ((any null-list? lists) '())		; Short cut	  ((null? lists)          lis1)		; Short cut	  (else (filter! (lambda (x)			   (every (lambda (lis) (member x lis =)) lists))			 lis1)))))(define (lset-difference = :: <procedure> lis1 . lists)  (let ((lists (filter pair? lists)))	; Throw out empty lists.    (cond ((null? lists)     lis1)	; Short cut	  ((memq lis1 lists) '())	; Short cut	  (else (filter (lambda (x)			  (every (lambda (lis) (not (member x lis =)))				 lists))			lis1)))))(define (lset-difference! = :: <procedure> lis1 . lists)  (let ((lists (filter pair? lists)))	; Throw out empty lists.    (cond ((null? lists)     lis1)	; Short cut	  ((memq lis1 lists) '())	; Short cut	  (else (filter! (lambda (x)			   (every (lambda (lis) (not (member x lis =)))				  lists))			 lis1)))))(define (lset-xor = :: <procedure> . lists)  (reduce (lambda (b a)			; Compute A xor B:	    ;; Note that this code relies on the constant-time	    ;; short-cuts provided by LSET-DIFF+INTERSECTION,	    ;; LSET-DIFFERENCE & APPEND to provide constant-time short	    ;; cuts for the cases A = (), B = (), and A eq? B. It takes	    ;; a careful case analysis to see it, but it's carefully	    ;; built in.	    ;; Compute a-b and a^b, then compute b-(a^b) and	    ;; cons it onto the front of a-b.	    (receive (a-b a-int-b)   (lset-diff+intersection = a b)	      (cond ((null? a-b)     (lset-difference = b a))		    ((null? a-int-b) (append b a))		    (else (fold (lambda (xb ans)				  (if (member xb a-int-b =) ans (cons xb ans)))				a-b				b)))))	  '() lists))(define (lset-xor! = :: <procedure> . lists)  (reduce (lambda (b a)			; Compute A xor B:	    ;; Note that this code relies on the constant-time	    ;; short-cuts provided by LSET-DIFF+INTERSECTION,	    ;; LSET-DIFFERENCE & APPEND to provide constant-time short	    ;; cuts for the cases A = (), B = (), and A eq? B. It takes	    ;; a careful case analysis to see it, but it's carefully	    ;; built in.	    ;; Compute a-b and a^b, then compute b-(a^b) and	    ;; cons it onto the front of a-b.	    (receive (a-b a-int-b)   (lset-diff+intersection! = a b)	      (cond ((null? a-b)     (lset-difference! = b a))		    ((null? a-int-b) (append! b a))		    (else (pair-fold (lambda (b-pair ans)				       (if (member (car b-pair) a-int-b =) ans					   (begin (set-cdr! b-pair ans) b-pair)))				     a-b				     b)))))	  '() lists))(define (lset-diff+intersection = :: <procedure> lis1 . lists)  (cond ((every null-list? lists) (values lis1 '()))	; Short cut	((memq lis1 lists)        (values '() lis1))	; Short cut	(else (partition (lambda (elt)			   (not (any (lambda (lis) (member elt lis =))				     lists)))			 lis1))))(define (lset-diff+intersection! = :: <procedure> lis1 . lists)  (cond ((every null-list? lists) (values lis1 '()))	; Short cut	((memq lis1 lists)        (values '() lis1))	; Short cut	(else (partition! (lambda (elt)			    (not (any (lambda (lis) (member elt lis =))				      lists)))			  lis1))))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -