1;; 2;; SRFI-5: A compatible let form with signatures and rest arguments 3;; 4 5;; This implementation is based on Andy Gaynor's reference implementation. 6 7(define-module srfi-5 8 (export let)) 9(select-module srfi-5) 10 11(define-syntax let 12 (syntax-rules () 13 ;; standard-compatible lambdas. 14 ((let () body ...) 15 ((lambda () body ...))) 16 ((let ((var val) ...) body ...) 17 ((lambda (var ...) body ...) val ...)) 18 19 ;; let with rest parameter 20 ((let ((var val) . bindings) body ...) 21 (%let-loop #f bindings (var) (val) (body ...))) 22 23 ;; signature-style name. 24 ((let (name binding ...) body ...) 25 (%let-loop name (binding ...) () () (body ...))) 26 27 ;; standrad named let (which may have rest parameter) 28 ((let name bindings body ...) 29 (%let-loop name bindings () () (body ...))) 30 31 ;; error 32 ((let . _) 33 (syntax-error "malformed let:" (let . _))) 34 )) 35 36;; aux macro to collect bindings 37(define-syntax %let-loop 38 (syntax-rules () 39 ((%let-loop name ((var0 val0) binding ...) (var ...) (val ...) body) 40 (%let-loop name (binding ...) (var ... var0) (val ... val0) body)) 41 42 ;; rest binding, no name 43 ((%let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) 44 ((lambda (var ... . rest-var) . body) val ... rest-val ...)) 45 46 ;; no bindings, named 47 ((%let-loop name () (var ...) (val ...) body) 48 ((letrec ((name (lambda (var ...) . body))) 49 name) 50 val ...)) 51 52 ;; rest binding, named 53 ((%let-loop name (rest-var rest-val ...) (var ...) (val ...) body) 54 ((letrec ((name (lambda (var ... . rest-var) . body))) 55 name) 56 val ... rest-val ...)))) 57 58