#lang racket (provide pp translate_ split) ; pp accepts any expression exp. If exp is a list, it recursively pp's ; every item in the list and then checks to see if it is an _ expression ; to be translated. (define pp (lambda (exp) (if (not (list? exp)) exp (let ((base (map pp exp))) (if (not (member '_ exp)) base (translate_ base)))))) ; translate an _ expression into a legal function (define translate_ (lambda (_exp) (let ((newvar (gensym)) (parts (split _exp '_))) (list 'lambda (list newvar) (append (car parts) (cons newvar (cdr parts))))))) ; split a list ( ...1 pivot ...2 ) ; returns pair (( ...1 ) . ( ...2 )) (define split (lambda (_exp pivot) (letrec ((go (lambda (_exp front) (if (eq? pivot (first _exp)) (cons (reverse front) (rest _exp)) (go (rest _exp) (cons (first _exp) front)))))) (go _exp '())))) ;