main.rkt
#lang racket
(require (for-syntax racket/syntax))
(define-syntax bind-it
  (lambda (stx)
    (syntax-case stx ()
      ((_  exp) #'exp)
      ((_  exp0 exps ...) 
       (with-syntax ((it (datum->syntax #'exp0 'it #'exp0)))
         #'(let ((it exp0))
             (bind-it exps ...)))))))
(define-syntax-rule (aprogn e es ...)
  (bind-it e es ...))
(define-for-syntax ((aif-x not?) stx)
  (syntax-case stx ()
    ((_ e e1 e2)
     (with-syntax* ((it (datum->syntax #'e 'it #'e))
                    (cond-exp (if not? #'(not it) #'it)))
       #'(bind-it e (if cond-exp e1 e2))))))
(define-syntax aif (aif-x #f))
(define-syntax aif-not (aif-x #t))
(define-syntax-rule (awhen e es ...)
  (aif e (aprogn es ...) #f))
(define-syntax aand
  (syntax-rules ()
    ((_) #t)
    ((_ e) e)
    ((_ e es ...) (aif e (aand es ...) #f))))
;; (define-syntax aor
;;   (syntax-rules ()
;;     ((_) #f)
;;     ((_ e) e)
;;     ((_ e es ...) (aif-not e (aor es ...) it))))
(provide aif aif-not awhen aprogn aand)