hygienic-syntax-rules.scm 1.8 KB

12345678910111213141516171819202122232425262728293031323334
  1. ;; The following macro was suggested by Mark H. Weaver on the Guile Scheme user mailing list, as a
  2. ;; response to a different formulation of Chris Vine, also on the Guile Scheme user mailing list.
  3. ;; Comments added by me.
  4. (define-syntax pipe-right
  5. ;; We are not defining any literals.
  6. (syntax-rules ()
  7. ;; Base case. If there is only the initial expression, it means, that no operations are applied,
  8. ;; so the expression is already the result of the pipe.
  9. [(-> exp) exp]
  10. ;; If there is an arbitrary number of expressions `exp ...` followed by one final expression
  11. ;; `(op args ...)`, which consists of an operation `op` and an arbitrary number of arguments
  12. ;; `args ...` for that operation, ...
  13. [(-> exp ... (op args ...))
  14. ;; ... we destrcuture the final operation into the operation name `op` and its arguments `args
  15. ;; ...`. With that we are able to make it the outer-most wrapping operation call in the syntax
  16. ;; produced by the macro. Furthermore we output a new macro call, which is the same, except,
  17. ;; that it is wrapped inside the last operation and does not contain the last operation any
  18. ;; longer, reducing the number of expressions in the macro call. When the macro is called
  19. ;; again, it will have another expression as the final operation. This will continue until all
  20. ;; expressions have been wrapped as procedure calls around the initial expression and the macro
  21. ;; will go into the base case.
  22. (op args ... (-> exp ...))]))
  23. ;; From this we can easily derive a version `pipe-left`, which always puts the value of the previous
  24. ;; pipe step on the left, instead of the right of given arguments to the operations as follows:
  25. (define-syntax pipe-left
  26. (syntax-rules ()
  27. [(-> exp) exp]
  28. [(-> exp ... (op args ...))
  29. (op (-> exp ...) args ...)]))