mvlet.scm 1.9 KB

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