1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-30 00:40:20 +02:00
guile/module/srfi/srfi-45.scm
Mark H Weaver edb6de0bec Add missing 'cond-expand' feature identifiers; remove srfi-6 from core list.
* module/ice-9/boot-9.scm (%cond-expand-features): Remove redundant list
  of feature identifiers in the comment.  Explain more clearly what
  belongs in this list.  Remove srfi-6.

* module/srfi/srfi-4.scm, module/srfi/srfi-27.scm,
  module/srfi/srfi-31.scm, module/srfi/srfi-38.scm,
  module/srfi/srfi-39.scm, module/srfi/srfi-42.scm,
  module/srfi/srfi-45.scm, module/srfi/srfi-67.scm: Add missing
  'cond-expand-provide'.

* module/srfi/srfi-69.scm: Fix erroneous 'cond-expand-provide'.

* doc/ref/srfi-modules.texi (SRFI-0): Update the list of features in
  Guile core.
2013-03-21 12:50:04 -04:00

80 lines
3 KiB
Scheme

;;; srfi-45.scm -- Primitives for Expressing Iterative Lazy Algorithms
;; Copyright (C) 2010, 2011, 2013 Free Software Foundation, Inc.
;; Copyright (C) 2003 André van Tonder. All Rights Reserved.
;; Permission is hereby granted, free of charge, to any person
;; obtaining a copy of this software and associated documentation
;; files (the "Software"), to deal in the Software without
;; restriction, including without limitation the rights to use, copy,
;; modify, merge, publish, distribute, sublicense, and/or sell copies
;; of the Software, and to permit persons to whom the Software is
;; furnished to do so, subject to the following conditions:
;; The above copyright notice and this permission notice shall be
;; included in all copies or substantial portions of the Software.
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;; SOFTWARE.
;;; Commentary:
;; This is the code of the reference implementation of SRFI-45,
;; modified to use SRFI-9 and to support multiple values.
;; This module is documented in the Guile Reference Manual.
;;; Code:
(define-module (srfi srfi-45)
#:export (delay
lazy
force
eager
promise?)
#:replace (delay force promise?)
#:use-module (srfi srfi-9))
(cond-expand-provide (current-module) '(srfi-45))
(define-record-type promise (make-promise val) promise?
(val promise-val promise-val-set!))
(define-record-type value (make-value tag proc) value?
(tag value-tag value-tag-set!)
(proc value-proc value-proc-set!))
(define-syntax-rule (lazy exp)
(make-promise (make-value 'lazy (lambda () exp))))
(define (eager . xs)
(make-promise (make-value 'eager xs)))
(define-syntax-rule (delay exp)
(lazy (call-with-values
(lambda () exp)
eager)))
(define (force promise)
(let ((content (promise-val promise)))
(case (value-tag content)
((eager) (apply values (value-proc content)))
((lazy) (let* ((promise* ((value-proc content)))
(content (promise-val promise))) ; *
(if (not (eqv? (value-tag content) 'eager)) ; *
(begin (value-tag-set! content
(value-tag (promise-val promise*)))
(value-proc-set! content
(value-proc (promise-val promise*)))
(promise-val-set! promise* content)))
(force promise))))))
;; (*) These two lines re-fetch and check the original promise in case
;; the first line of the let* caused it to be forced. For an example
;; where this happens, see reentrancy test 3 below.