n-ary-comparison.scm 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Mike Sperber, Robert Ransom
  3. ; Tricky business, as we want to typecheck all arguments, and avoid
  4. ; redundant normalizations.
  5. ; x is already wrapped
  6. (define (compare-n-ary name =? wrap pred x . rest)
  7. (let loop ((x x)
  8. (rest rest))
  9. (or (null? rest)
  10. (let ((next (wrap (car rest))))
  11. (if (=? x next)
  12. (loop next (cdr rest))
  13. (check-pred name pred (cdr rest)))))))
  14. (define (check-pred name pred lis)
  15. (cond
  16. ((memp (lambda (x)
  17. (not (pred x)))
  18. lis)
  19. => (lambda (wrong)
  20. (assertion-violation name
  21. "invalid argument"
  22. (car wrong))))
  23. (else #f)))
  24. (define-syntax define-n-ary-comparison
  25. (syntax-rules ()
  26. ((define-n-ary-comparison ?name ?pred ?wrap ?binary-name)
  27. (define (?name a b . rest)
  28. (let ((bw (?wrap b)))
  29. (cond
  30. ((?binary-name (?wrap a) bw)
  31. (or (null? rest)
  32. (apply compare-n-ary '?name ?binary-name ?wrap ?pred bw rest)))
  33. ((null? rest) #f)
  34. (else (check-pred '?name ?pred rest))))))))