昨日のやつをもすこし修正した

  • 相互再帰を導入した。
  • ((式1=>SとかKとか) (式2) ...) のような式に対応した。
(use srfi-11)
 
(define (cutlist size car_l result_size l)
  (if (or (= size 0) (null? l)) (values (reverse car_l) l result_size) (cutlist (- size 1) (cons (car l) car_l) (+ 1 result_size)(cdr l))))
 
(define (construct-S p1 p2 p3 rest)
  (let ((p1dash  (if (pair? p1) p1 (list p1)))
        (p2dash  (if (pair? p2) p2 (list p2))))
  `(,@p1dash ,p3 (,@p2dash ,p3) ,@rest)))
 
(define (construct-K p1 p2 rest)
  (if (not (pair? p1))
    `(,p1 ,@rest)
    `(,@p1 ,@rest)))
 
(define (custum-apply max-args constructor l)
  (let-values (((args rest args_num) (cutlist max-args '() 0 (cdr l))))
  (let ((evaled_args (map beta-red-itr args))
        (prefix (car l)))
    (if (= args_num max-args)
    (beta-red-itr (apply constructor `(,@evaled_args ,rest)))
    (cons prefix evaled_args)))))
 
(define (apply-S l)
  (custum-apply 3 construct-S l))
 
(define (apply-K l)
  (custum-apply 2 construct-K l))
 
(define beta-red-itr
  (lambda (seq)
    (begin (display "---   ") (display seq) (newline)
  (cond
    ((not (pair? seq)) seq)
    ((and (not (pair? (car seq))) (null? (cdr seq))) (car seq))
    ((eq? 'S (car seq)) (apply-S seq))
    ((eq? 'K (car seq)) (apply-K seq))
    ((eq? 'I (car seq)) (beta-red-itr (cdr seq)))
    ((and (null? (cdr seq)) (symbol? (car seq))) (car seq))
    ((symbol? (car seq)) (map beta-red-itr seq))
    (else
    (let ((op (beta-red-itr (car seq))))
      (let ((evaled_op (if (pair? op) op (list op))))
        (beta-red-itr `(,@evaled_op ,@(map beta-red-itr (cdr seq))))))))
    )
))
(define (beta-reduction l)
  (let ((result (beta-red-itr l)))
  (if (and (pair? result) (null? (cdr result))) (car result) result)))
 


なんでか自分は多値が好きなようだ。
最近の言語ではそうめずらしくもないのかな。C#とか。使ったことないけど。

確かPHPでも似たようなことが出来た

list($x, $y) = hoge();

function hoge() {
  return array(1, 2);
}

こんな感じだった。
rubyでも昔使った気がしないでもない。