#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))))
(provide aif aif-not awhen aprogn aand)