(define-macro (def-choice name proc ls) (let ((varname (gensym)) (valname (gensym))) (let1 varname (string->symbol #`",|name|s") `(begin (define-values (,name ,(string->symbol #`"push-,|varname|!")) (let1 ,varname ,ls (values (lambda () (,proc ,varname)) (lambda (,valname) (push! ,varname ,valname))))))))) (def-choice adj one-of '(big)) (def-choice prep one-of '(to)) (sentence) ;; (the big man to the ball to a big big big big big woman to a big woman to the table to a big big man to a big big big table to a big big man to the table to the big man to a ball to a table to a man saw a big big big big woman) (sentence) ;; (the big big ball to a man took a big man) (push-adjs! 'little) ;; (little big) (push-adjs! 'blue) ;; (blue little big) (push-adjs! 'red) ;; (red blue little big) (sentence) ;; (the blue man to the big table liked the little little table to the big little big big blue little table) (sentence) ;; (a red little woman hit the red table to a table to the ball to the blue ball) (push-preps! 'by) ;; (by to) (push-preps! 'in) ;; (in by to) (push-preps! 'with) ;; (with in by to) (push-preps! 'on) ;; (on with in by to) (sentence) ;; (the table saw a little ball) (sentence) ;; (the big table to the little man saw a little ball on the big table in the ball) (sentence) ;; (a little table hit the woman with a table with the red little woman by the red big ball to a ball by the red big big ball with the red table on the big blue red red ball)