and-or.scm 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. (define-syntax and
  2. (syntax-rules ()
  3. ;; Trivial case of no arguments.
  4. [(and) #t]
  5. ;; If there is only one expression, the expansion is the value produced by that one expression.
  6. [(and exp) exp]
  7. ;; The case of multiple arguments. We destructure into the first expression and the rest of
  8. ;; expressions.
  9. [(and exp0 exps ...)
  10. ;; Check the first expression given to `and`.
  11. (if exp0
  12. ;; Recur: Expand with the remaining expressions.
  13. (and exps ...)
  14. ;; If only one expression is falsy, the whole expansion is false.
  15. #f)]))
  16. (define-syntax or
  17. (syntax-rules ()
  18. [(or) #t]
  19. [(or exp) exp]
  20. [(or exp0 exps ...)
  21. (if exp0
  22. exp0
  23. (or exps ...))]))
  24. ;; However, we could also use a case-lambda to define `and` or `or`. Maybe it would be better to
  25. ;; avoid the macros in this case. (Although case-lambda might actually do the same behind the scenes
  26. ;; as our macros (?), it would still improve readability to use case-lambda.)
  27. (define and
  28. (case-lambda
  29. [() #t]
  30. [(expr) expr]
  31. [(expr . rest-exprs)
  32. (if expr
  33. (apply and rest-exprs)
  34. #f)]))
  35. (define or
  36. (case-lambda
  37. [() #t]
  38. [(expr) expr]
  39. [(expr . rest-exprs)
  40. (if expr
  41. expr
  42. (apply and rest-exprs))]))