srfi-39.scm 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. ; Copyright (c) 1993-2007 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Parameters are like fluids, but support mutation, and have a really
  3. ; awkward API.
  4. ; Note that the parameter cells are shared among threads, which gives
  5. ; us semantics different from, say, MzScheme, but probably the same as
  6. ; Gambit-C.
  7. (define *return-fluid* (list 'return-fluid))
  8. (define make-parameter
  9. (lambda (init . conv)
  10. (let* ((converter
  11. (if (null? conv) (lambda (x) x) (car conv)))
  12. (global-cell
  13. (make-cell (converter init)))
  14. ($fluid (make-fluid global-cell)))
  15. (letrec ((parameter
  16. (lambda new-val
  17. (let ((cell (fluid $fluid)))
  18. (cond ((null? new-val)
  19. (cell-ref cell))
  20. ((not (null? (cdr new-val)))
  21. (apply call-error "parameter object called with more than one argument"
  22. parameter new-val))
  23. ((eq? (car new-val) *return-fluid*)
  24. $fluid)
  25. (else
  26. (cell-set! cell (converter (car new-val)))))))))
  27. parameter))))
  28. (define-syntax parameterize
  29. (syntax-rules ()
  30. ((parameterize ((?expr1 ?expr2) ...) ?body ...)
  31. ;; massage the argument list for LET-FLUIDS
  32. (parameterize-helper (((?expr1 *return-fluid*) (make-cell ?expr2)) ...)
  33. ?body ...))))
  34. (define-syntax parameterize-helper
  35. (syntax-rules ()
  36. ((parameterize-helper ((?stuff ...) ...) ?body ...)
  37. (let-fluids ?stuff ... ... (lambda () ?body ...)))))