diff options
Diffstat (limited to 'ps07_amb/funco.scm')
| -rw-r--r-- | ps07_amb/funco.scm | 223 | 
1 files changed, 223 insertions, 0 deletions
| diff --git a/ps07_amb/funco.scm b/ps07_amb/funco.scm new file mode 100644 index 0000000..73fb947 --- /dev/null +++ b/ps07_amb/funco.scm @@ -0,0 +1,223 @@ +;;;; Fun with Continuations + +#| Adapted from MIT/GNU Scheme Reference Manual [Section 12.4]: + +(call-with-current-continuation + (lambda (exit) +   (for-each (lambda (x) +	       (if (negative? x) +		   (exit x))) +	     '(54 0 37 -3 245 -19))	; ** +   #t)) +;Value: -3 + +|# + +;;; Continuations as Non-Local Exits + +(define (funco:first-negative list-of-numbers) +  (call-with-current-continuation +   (lambda (k_exit) +     (or (call-with-current-continuation +	  (lambda (k_shortcut) +	    (for-each (lambda (n) +			(cond ((not (number? n)) +			       (pp `(not-a-number: ,n)) +			       (k_exit #f)) +			      ((negative? n) +			       (k_shortcut n)) +			      (else +			       ':keep-looking))) +		      list-of-numbers) +	    #f ;; Fall-through sentinel:  no negatives found. +	    )) +	 ':no-negatives-found)))) + +#| +(funco:first-negative '(54 0 37 -3 245 -19)) +;Value: -3 + +(funco:first-negative '(54 0 37  3 245  19)) +;Value: :no-negatives-found + +(funco:first-negative '(54 0 37 no 245 boo)) +(not-a-number: no) +;Value: #f +|# + +;;; Continuations for Proceeding (Suspend/Resume Backtracking) + +(define (funco:first-negative-n-proceed list-of-numbers) ;;; ** +  (call-with-current-continuation +   (lambda (k_exit) +     (or (call-with-current-continuation +	  (lambda (k_shortcut) +	    (for-each (lambda (n) +			(pp				 ;;; ** +			 (call-with-current-continuation ;;; ** +			  (lambda (k_proceed)		 ;;; ** +			    (cond ((not (number? n)) +				   (pp `(not-a-number: ,n)) +				   (k_exit +				    (cons n k_proceed))) ;;; ** +				  ((negative? n) +				   (k_shortcut +				    (cons n k_proceed))) ;;; ** +				  (else +				   ':keep-looking))) +			  )))				 ;;; ** +		      list-of-numbers) +	    #f ;; Fall-through sentinel:  no negatives found. +	    )) +	 ':no-negatives-found)))) + +(define (funco:first-negative-n-proceed-more?      smore) (pair? smore)) +(define (funco:first-negative-n-proceed-more/found smore) (car   smore)) +(define (funco:first-negative-n-proceed-more/k     smore) (cdr   smore)) +(define (funco:first-negative-n-proceed-more/next  smore) +       ((funco:first-negative-n-proceed-more/k     smore) +	(funco:first-negative-n-proceed-more/found smore))) + +#| +;;;           ------------ +(define funco:first-of-two +  (funco:first-negative-n-proceed '(54 0 37 -3 245 -19))) +:keep-looking +:keep-looking +:keep-looking +;Value: funco:first-of-two + +(funco:first-negative-n-proceed-more?		funco:first-of-two) +;Value: #t + +(funco:first-negative-n-proceed-more/found	funco:first-of-two) +;Value: -3 + +(funco:first-negative-n-proceed-more/next	funco:first-of-two) +-3 +:keep-looking +;Value: funco:first-of-two + +(funco:first-negative-n-proceed-more?		funco:first-of-two) +;Value: #t + +(funco:first-negative-n-proceed-more/found	funco:first-of-two) +;Value: -19 + +(funco:first-negative-n-proceed-more/next	funco:first-of-two) +-19 +;Value: funco:first-of-two + +(funco:first-negative-n-proceed-more?		funco:first-of-two) +;Value: #f + +funco:first-of-two +;Value: :no-negatives-found +|# + +#| +;;;           ---- +(define funco:nada +  (funco:first-negative-n-proceed '(54 0 37  3 245  19))) +:keep-looking +:keep-looking +:keep-looking +:keep-looking +:keep-looking +:keep-looking +;Value: funco:nada + +(funco:first-negative-n-proceed-more? funco:nada) +;Value: #f + +funco:nada +;Value: :no-negatives-found +|# + +#| +;;;           ---- +(define funco:nans +  (funco:first-negative-n-proceed '(54 0 37 no 245 boo))) +:keep-looking +:keep-looking +:keep-looking +(not-a-number: no) +;Value: funco:nans + +(funco:first-negative-n-proceed-more?		funco:nans) +;Value: #t + +(funco:first-negative-n-proceed-more/found	funco:nans) +;Value: no + +(funco:first-negative-n-proceed-more/next	funco:nans) +no +:keep-looking +(not-a-number: boo) +;Value: funco:nans + +(funco:first-negative-n-proceed-more?		funco:nans) +;Value: #t + +(funco:first-negative-n-proceed-more/next	funco:nans) +boo +;Value: funco:nans + +(funco:first-negative-n-proceed-more?		funco:nans) +;Value: #f + +funco:nans +;Value: :no-negatives-found +|# + +;;; Continuations for Backtracking (Re-entrant 1st-Class Continuations) + +(define *k_re-funco*) +(define       funco) + +#| +(begin +  (set! funco (+ 2 (call-with-current-continuation +		    (lambda (k_re-funco) +		      (set! *k_re-funco* k_re-funco) +		      3)))) +  ':ok) +;Value: :ok + +funco +;Value: 5 + +(*k_re-funco* 4) +;Value: :ok + +funco +;Value: 6 + +(*k_re-funco* 5) +;Value: :ok + +funco +;Value: 7 +|# + +;;; Dynamic Contexts and Within-Continuation + +(define (funco:test-k-thunk k-thunk) +  (let ((*foo* 2))			;----------------------. +    (define (foo-thunk) *foo*)		; *foo* is 2 out here. : +    (call-with-current-continuation	;                      : +     (lambda (k)			;                      : +       (fluid-let ((*foo* 3))	;---------------------.        : +	 (k-thunk k foo-thunk)	; *foo* is 3 in here. :        : +	 )			;---------------------'        : +       ))				; *foo* is 2 out here. : +    ))					;----------------------' +#| +(funco:test-k-thunk (lambda (k thunk) +		      (k (thunk)))) +;Value: 3 + +(funco:test-k-thunk (lambda (k thunk) +		      (within-continuation k thunk))) +;Value: 2 +|# | 
