fork(1) download
; square triple

(define range
  (case-lambda
    ((stop) (range 0 stop (if (negative? stop) -1 1)))
    ((start stop) (range start stop (if (< start stop) 1 -1)))
    ((start stop step)
      (let ((le? (if (negative? step) >= <=)))
        (let loop ((x start) (xs (list)))
          (if (le? stop x) (reverse xs)
            (loop (+ x step) (cons x xs))))))
    (else (error 'range "too many arguments"))))

(define-syntax fold-of
  (syntax-rules (range in is)
    ((_ "z" f b e) (set! b (f b e)))
    ((_ "z" f b e (v range fst pst stp) c ...)
      (let* ((x fst) (p pst) (s stp)
             (le? (if (positive? s) <= >=)))
        (do ((v x (+ v s))) ((le? p v) b)
          (fold-of "z" f b e c ...))))
    ((_ "z" f b e (v range fst pst) c ...)
      (let* ((x fst) (p pst) (s (if (< x p) 1 -1)))
        (fold-of "z" f b e (v range x p s) c ...)))
    ((_ "z" f b e (v range pst) c ...)
      (fold-of "z" f b e (v range 0 pst) c ...))
    ((_ "z" f b e (x in xs) c ...)
      (do ((t xs (cdr t))) ((null? t) b)
        (let ((x (car t)))
          (fold-of "z" f b e c ...))))
    ((_ "z" f b e (x is y) c ...)
      (let ((x y)) (fold-of "z" f b e c ...)))
    ((_ "z" f b e p? c ...)
      (if p? (fold-of "z" f b e c ...)))
    ((_ f i e c ...)
      (let ((b i)) (fold-of "z" f b e c ...)))))

(define-syntax list-of (syntax-rules ()
  ((_ arg ...) (reverse (fold-of
    (lambda (d a) (cons a d)) '() arg ...)))))

(define (isqrt n)
  (if (not (and (positive? n) (integer? n)))
      (error 'isqrt "must be positive integer")
      (let loop ((x n))
        (let ((y (quotient (+ x (quotient n x)) 2)))
          (if (< y x) (loop y) x)))))

(define (f xs)
  (list-of (list x y z)
    (x in xs)
    (y in xs)
    (< x y)
    (z2 is (* x y))
    (z is (isqrt z2))
    (= (* z z) z2)
    (member z xs)))

(display (f (range 1 20))) (newline)
Success #stdin #stdout 0.01s 8656KB
stdin
Standard input is empty
stdout
((1 4 2) (1 9 3) (1 16 4) (2 8 4) (2 18 6) (3 12 6) (4 9 6) (4 16 8) (8 18 12) (9 16 12))