more define-syntax-rule usage
[bpt/guile.git] / module / srfi / srfi-45.scm
CommitLineData
f16a2007
AR
1;;; srfi-45.scm -- Primitives for Expressing Iterative Lazy Algorithms
2
0c65f52c 3;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
f16a2007
AR
4;; Copyright (C) 2003 André van Tonder. All Rights Reserved.
5
6;; Permission is hereby granted, free of charge, to any person
7;; obtaining a copy of this software and associated documentation
8;; files (the "Software"), to deal in the Software without
9;; restriction, including without limitation the rights to use, copy,
10;; modify, merge, publish, distribute, sublicense, and/or sell copies
11;; of the Software, and to permit persons to whom the Software is
12;; furnished to do so, subject to the following conditions:
13
14;; The above copyright notice and this permission notice shall be
15;; included in all copies or substantial portions of the Software.
16
17;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24;; SOFTWARE.
25
26;;; Commentary:
27
28;; This is the code of the reference implementation of SRFI-45, slightly
29;; modified to use SRFI-9.
30
31;; This module is documented in the Guile Reference Manual.
32
33;;; Code:
34
35(define-module (srfi srfi-45)
36 #:export (delay
37 lazy
38 force
39 eager)
40 #:replace (delay force)
41 #:use-module (srfi srfi-9))
42
43(define-record-type promise (make-promise val) promise?
44 (val promise-val promise-val-set!))
45
46(define-record-type value (make-value tag proc) value?
47 (tag value-tag value-tag-set!)
48 (proc value-proc value-proc-set!))
49
0c65f52c
AW
50(define-syntax-rule (lazy exp)
51 (make-promise (make-value 'lazy (lambda () exp))))
f16a2007
AR
52
53(define (eager x)
54 (make-promise (make-value 'eager x)))
55
0c65f52c
AW
56(define-syntax-rule (delay exp)
57 (lazy (eager exp)))
f16a2007
AR
58
59(define (force promise)
60 (let ((content (promise-val promise)))
61 (case (value-tag content)
62 ((eager) (value-proc content))
63 ((lazy) (let* ((promise* ((value-proc content)))
64 (content (promise-val promise))) ; *
65 (if (not (eqv? (value-tag content) 'eager)) ; *
66 (begin (value-tag-set! content
67 (value-tag (promise-val promise*)))
68 (value-proc-set! content
69 (value-proc (promise-val promise*)))
70 (promise-val-set! promise* content)))
71 (force promise))))))
72
73;; (*) These two lines re-fetch and check the original promise in case
74;; the first line of the let* caused it to be forced. For an example
75;; where this happens, see reentrancy test 3 below.