mvlet.scm 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees
  3. ; A version of LET and LET* which allows clauses that return multiple values.
  4. ;
  5. ; MV = multiple-value
  6. ;
  7. ; (mvlet (<clause> ...) <body>)
  8. ; (mvlet* (<clause> ...) <body>)
  9. ;
  10. ; <clause> ::= (<ids> <expression>)
  11. ; <ids> ::= <id> | (<id> ...) | (<id> ... . <id>)
  12. ;
  13. ; A clause of the form (<id> <exp>) is like a normal LET clause. There is no
  14. ; clause equivalent to
  15. ; (call-with-values (lambda () <expression>)
  16. ; (lambda <id> <body>))
  17. (define-syntax mvlet
  18. (syntax-rules ()
  19. ((mvlet () body ...)
  20. (let () body ...))
  21. ((mvlet (clause ...) body ...)
  22. (mvlet-helper (clause ...) () (body ...)))))
  23. (define-syntax mvlet-helper
  24. (syntax-rules ()
  25. ((mvlet-helper () clauses (body ...))
  26. (let clauses body ...))
  27. ((mvlet-helper (((var . more-vars) val) more ...) clauses body)
  28. (copy-vars (var . more-vars) () val (more ...) clauses body))
  29. ((mvlet-helper ((var val) more ...) clauses body)
  30. (mvlet-helper (more ...) ((var val) . clauses) body))))
  31. (define-syntax copy-vars
  32. (syntax-rules ()
  33. ((copy-vars (var . more-vars) (copies ...)
  34. val more clauses body)
  35. (copy-vars more-vars (copies ... x)
  36. val more ((var x) . clauses) body))
  37. ((copy-vars () copies val more clauses body)
  38. (call-with-values
  39. (lambda () val)
  40. (lambda copies
  41. (mvlet-helper more clauses body))))
  42. ((copy-vars last (copies ...) val more clauses body)
  43. (call-with-values
  44. (lambda () val)
  45. (lambda (copies ... . lastx)
  46. (mvlet-helper more ((last lastx) . clauses) body))))))
  47. (define-syntax mvlet*
  48. (syntax-rules ()
  49. ((mvlet* () body ...)
  50. (let () body ...))
  51. ((mvlet* (((vars ...) val) clause ...) body ...)
  52. (call-with-values
  53. (lambda () val)
  54. (lambda (vars ...)
  55. (mvlet* (clause ...) body ...))))
  56. ((mvlet* ((var val) clause ...) body ...)
  57. (let ((var val)) (mvlet* (clause ...) body ...)))))