素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: すかいぷ:javascripter_  か javascripter あっと tsukkun.net skypeのほうがいいです

マクロとか

マクロ展開後に変数を漏らす必要がない場合?は、define-syntaxを使う。

#!/usr/bin/env gosh

(define-syntax ++
 (syntax-rules ()
  ((++ var)
   (begin
    (set! var (+ var 1))
    var))))

(let ((i 0))
 (print i) ; 0
 (print (++ i)) ; 1
 (print (++ i))) ; 2

JSみたいなfunctionを書けるようにするマクロ。exprにarguments-calleeを見せる必要があるから、define-syntaxが使えなくて、define-macroを使う。

#!/usr/bin/env gosh

(define-macro (function name args expr)
 `((lambda ()
     (begin
      (define (,name . arguments)
       (let ((arguments-callee ,name))
        (apply (lambda ,args ,expr) arguments)))
      ,name))))

(print
 ((function fib (n)
   (if (< n 2)
    n
    (+ (fib (- n 2)) (fib (- n 1)))))
  10))

リストのn番目を取り出す

#!/usr/bin/env gosh

(define (get-item lis n)
 (if (= n 0)
  (car lis)
  (get-item (cdr lis) (- n 1))))

(print (get-item '(1 2 3 4 5) 4))

リストを(再帰的に)フラットにする

#!/usr/bin/env gosh

(define (flatten lis)
 (if (pair? lis)
  (let ((item (car lis)))
   (append
    (if (list? item)
     (flatten item)
     (list item))
    (flatten (cdr lis))))
  '()))

(print (flatten '(1 2 3 (4 5 6 (7 8 9)))))

マクロとかでcall/ccってのを使ってbreakとかreturnとかをやってみたいのだけど、いまいちよく分からない…。