1 ;;; srfi-11.scm --- let-values and let*-values
3 ;; Copyright (C) 2000, 2001, 2002, 2004, 2006, 2009 Free Software Foundation, Inc.
5 ;; This library is free software; you can redistribute it and/or
6 ;; modify it under the terms of the GNU Lesser General Public
7 ;; License as published by the Free Software Foundation; either
8 ;; version 3 of the License, or (at your option) any later version.
10 ;; This library is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ;; Lesser General Public License for more details.
15 ;; You should have received a copy of the GNU Lesser General Public
16 ;; License along with this library; if not, write to the Free Software
17 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;; This module exports two syntax forms: let-values and let*-values.
25 ;; (let-values (((x y . z) (foo a b))
29 ;; This binds `x' and `y' to the first to values returned by `foo',
30 ;; `z' to the rest of the values from `foo', and `p' and `q' to the
31 ;; values returned by `bar'. All of these are available to `baz'.
33 ;; let*-values : let-values :: let* : let
35 ;; This module is fully documented in the Guile Reference Manual.
39 (define-module (srfi srfi-11)
40 :export-syntax (let-values let*-values))
42 (cond-expand-provide (current-module) '(srfi-11))
47 ;; Current approach is to translate
49 ;; (let-values (((x y . z) (foo a b))
55 ;; (call-with-values (lambda () (foo a b))
56 ;; (lambda (<tmp-x> <tmp-y> . <tmp-z>)
57 ;; (call-with-values (lambda () (bar c))
58 ;; (lambda (<tmp-p> <tmp-q>)
64 ;; (baz x y z p q))))))
66 ;; We could really use quasisyntax here...
67 (define-syntax let-values
70 ((_ ((binds exp)) b0 b1 ...)
71 (syntax (call-with-values (lambda () exp)
72 (lambda binds b0 b1 ...))))
73 ((_ (clause ...) b0 b1 ...)
74 (let lp ((clauses (syntax (clause ...)))
78 (with-syntax (((id ...) ids)
80 (syntax (let ((id tmp) ...)
82 (syntax-case (car clauses) ()
84 (with-syntax (((new-tmp ...) (generate-temporaries
88 (with-syntax ((inner (lp (cdr clauses)
89 (syntax (var ... id ...))
90 (syntax (new-tmp ... tmp ...)))))
91 (syntax (call-with-values (lambda () exp)
92 (lambda (new-tmp ...) inner))))))
94 (with-syntax ((((new-tmp . new-var) ...)
95 (let lp ((vars (syntax vars)))
100 (generate-temporaries (syntax (id))))
102 (id (acons (syntax id)
104 (generate-temporaries (syntax (id))))
108 (with-syntax ((inner (lp (cdr clauses)
109 (syntax (new-var ... id ...))
110 (syntax (new-tmp ... tmp ...))))
111 (args (let lp ((tmps (syntax (new-tmp ...))))
114 ((id . rest) (cons (syntax id)
115 (lp (syntax rest))))))))
116 (syntax (call-with-values (lambda () exp)
117 (lambda args inner)))))))))))))
122 ;; Current approach is to translate
124 ;; (let*-values (((x y z) (foo a b))
130 ;; (call-with-values (lambda () (foo a b))
132 ;; (call-with-values (lambda (bar c))
134 ;; (baz x y z p q)))))
136 (define-syntax let*-values
138 ((let*-values () body ...)
140 ((let*-values ((vars-1 binding-1) (vars-2 binding-2) ...) body ...)
141 (call-with-values (lambda () binding-1)
143 (let*-values ((vars-2 binding-2) ...)
146 ;;; srfi-11.scm ends here