srfi-5.scm 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; Rewritten, simplified, and corrected from the SRFI document.
  4. ;
  5. ; The SRFI implementation gets the scoping wrong for the name. It is visible
  6. ; to the arguments and should not be.
  7. (define-syntax let
  8. (syntax-rules ()
  9. ; If no name we go straight to the standard LET.
  10. ((let () body ...)
  11. (standard-let () body ...))
  12. ((let ((variable value) ...) body ...)
  13. (standard-let ((variable value) ...) body ...))
  14. ; Rest binding
  15. ((let ((var val) . bindings) body ...)
  16. (let-loop #f bindings (var) (val) (body ...)))
  17. ;; Signature-style and standard named LET.
  18. ((let (name bindings ...) body ...)
  19. (let-loop name (bindings ...) () () (body ...)))
  20. ((let name bindings body ...)
  21. (let-loop name bindings () () (body ...)))))
  22. ; A loop to walk down the list of bindings.
  23. (define-syntax let-loop
  24. (syntax-rules ()
  25. ; No more bindings - make a LETREC.
  26. ((let-loop name () (vars ...) (vals ...) body)
  27. ((letrec ((name (lambda (vars ...) . body)))
  28. name)
  29. vals ...))
  30. ; Rest binding, no name
  31. ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body)
  32. (standard-let ((var val) ... (rest-var (list rest-val ...))) . body))
  33. ; Process a (var val) pair.
  34. ((let-loop name ((var val) more ...) (vars ...) (vals ...) body)
  35. (let-loop name (more ...) (vars ... var) (vals ... val) body))
  36. ; End with a rest variable - make a LETREC.
  37. ((let-loop name (rest-var rest-vals ...) (vars ...) (vals ...) body)
  38. ((letrec ((name (lambda (vars ... . rest-var) . body)))
  39. name)
  40. vals ... rest-vals ...))))
  41. ; Four loops - normal and `signature-style', each with and without a rest
  42. ; binding.
  43. ;
  44. ;(let fibonacci ((n 10) (i 0) (f0 0) (f1 1))
  45. ; (if (= i n)
  46. ; f0
  47. ; (fibonacci n (+ i 1) f1 (+ f0 f1))))
  48. ;
  49. ;(let (fibonacci (n 10) (i 0) (f0 0) (f1 1))
  50. ; (if (= i n)
  51. ; f0
  52. ; (fibonacci n (+ i 1) f1 (+ f0 f1))))
  53. ;
  54. ;(let fibonacci ((n 10) (i 0) . (f 0 1))
  55. ; (if (= i n)
  56. ; (car f)
  57. ; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f)))))
  58. ;
  59. ;(let (fibonacci (n 10) (i 0) . (f 0 1))
  60. ; (if (= i n)
  61. ; (car f)
  62. ; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f)))))