;;; shift / reset を使った A 正規形変換
;;; 『shift/reset プログラミング入門』
;;; http://p...content-available-to-author-only...c.jp/‾asai/cw2011tutorial/main-j.pdf
;;; pp. 11--12
(use gauche.partcont)

;; Racket の場合
;; (require racket/control)

(define (a-normal term)
  (cond ((and (pair? term)
              (eq? (car term) 'lambda))
         (let ((var (car (cadr term)))
               (body (caddr term)))
           `(lambda (,var) ,(reset (a-normal body)))))
        ((pair? term)
         (let ((abs (car term))
               (arg (cadr term)))
           (shift k
             (let* ((v (gensym))
                    (body (k v)))
               `(let ((,v (,(a-normal abs) ,(a-normal arg))))
                  ,body)))))
        (else term)))

(a-normal '(lambda (x) (lambda (y) (x y))))
;; Gauche:
;; => *** ERROR: attempt to return from a ghost continuation.
;; Racket:
;; => '(lambda (x) (lambda (y) (let ((g1233 (x y))) g1233)))
