yaotti's diary

Software is Eating the World

逆ポーランド記法で計算

(define (re-polish args)
  (let1 operators (list '+ '- '* '/)
    (define (iter rest-args stack)
      (cond [(null? rest-args) (car stack)]
	    [(number? (car rest-args)) (iter (cdr rest-args) (append stack (list (car rest-args))))]
	    [(find (cut eq? (car rest-args) <>) operators) (iter (cdr rest-args) (list (eval (cons (car rest-args) stack) (interaction-environment))))]
	    [else (error "invalid argument:" (car rest-args))]))
(iter args '())))

(re-polish '(1 2 3 + 4 *))
=>24

(car rest-args)がたくさん出てきて美しくない。
束縛したいんだけど、どこですればいいんだろう。


operatorsと同じところで

(let ((next (car rest-args))
      (operator (list '+ '- '* '/)))

のように束縛すると、rest-argsがpairでないときにエラーが出る。



方法としては、
「cond節の前にifでrest-argsがpairでない時の分岐をつくる」
というのがあるけど。

;;該当部分だけ
    (if (null? rest-args)
	(car stack)
	(let ((next (car rest-args))
	       (operators (list '+ '- '* '/)))
;;cond節が続く

きれいじゃないな。
いい方法はないものか。