srfi-39.scm 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Mike Sperber
  3. ; Parameters are like fluids, but support mutation, and have a really
  4. ; awkward API.
  5. ; Note that the parameter cells are shared among threads, which gives
  6. ; us semantics different from, say, MzScheme, but probably the same as
  7. ; Gambit-C.
  8. (define *return-fluid* (list 'return-fluid))
  9. (define *return-converter* (list 'return-converter))
  10. (define make-parameter
  11. (lambda (init . conv)
  12. (let* ((converter
  13. (if (null? conv) (lambda (x) x) (car conv)))
  14. (global-cell
  15. (make-cell (converter init)))
  16. ($fluid (make-fluid global-cell)))
  17. (letrec ((parameter
  18. (lambda new-val
  19. (let ((cell (fluid $fluid)))
  20. (cond ((null? new-val)
  21. (cell-ref cell))
  22. ((not (null? (cdr new-val)))
  23. (apply assertion-violation
  24. 'make-parameter
  25. "parameter object called with more than one argument"
  26. parameter new-val))
  27. ((eq? (car new-val) *return-fluid*)
  28. $fluid)
  29. ((eq? (car new-val) *return-converter*)
  30. converter)
  31. (else
  32. (cell-set! cell (converter (car new-val)))))))))
  33. parameter))))
  34. (define-syntax parameterize
  35. (syntax-rules ()
  36. ((parameterize ((?expr1 ?expr2) ...) ?body ...)
  37. (parameterize-helper ((?expr1 ?expr2) ...) () ?body ...))))
  38. (define-syntax parameterize-helper
  39. (syntax-rules ()
  40. ((parameterize-helper ((?expr1 ?expr2) ?binding ...) (?args ...) ?body ...)
  41. (let ((val1 ?expr1)
  42. (val2 ?expr2))
  43. (parameterize-helper (?binding ...)
  44. (?args ...
  45. (val1 *return-fluid*)
  46. (make-cell ((val1 *return-converter*) val2)))
  47. ?body ...)))
  48. ((parameterize-helper () (?args ...) ?body ...)
  49. (let-fluids ?args ... (lambda () ?body ...)))))