Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2011-01-18

マクロ 99問 P02

| 21:31 | マクロ 99問 P02 - わだばLisperになる を含むブックマーク はてなブックマーク - マクロ 99問 P02 - わだばLisperになる

P01に引き続いてやってみました。M-99 P02

INC1を作成せよ
テーマ:変数の補足

(let ((x 0))
  (inc1 x)
  x)
≡ (let ((x 0))
     (setq x (+ x 1)))
;=> 1

inc1(x)というのを、x = x + 1という風に展開しろというお題です。

inc1のようなものは、CLでは、関数ではできないことの1つで、マクロにする必要がありますが、他の言語も大体同じかなと思います。

早速チャレンジ。まずは、CL

Common Lisp
(defmacro inc1 (var)
  `(setq ,var (1+ ,var)))

(let ((x 0))
  (inc1 x)
  x)
;=> 1

31秒でした。

次にGauche(Scheme)

Scheme (Gauche)
(define-syntax inc1
  (syntax-rules ()
    ((_ var) (set! var (+ 1 var)))))

(let ((x 0))
  (inc1 x)
  x)

こちらは57秒。

今回のお題ならば、Dylanでも可能なので、Gwydion Dylanで

Dylan
module: p02
synopsis:
author:
copyright:

define macro inc1
 { inc1(?var:expression) }
    => { ?var := ?var + 1 }
end macro inc1;

define function main(name, arguments)
  let var = 1;
  format-out("var => %=\n", var);
  inc1(var);
  format-out("var => %=\n", var);
  exit-application(0);
end function main;

// Invoke our main() function.
main(application-name(), application-arguments());
var => 1
var => 2

4分かかりました。

REPLがないとなかなか辛いです。今後問題は、複雑になりますが、Dylanではマクロ展開とかどうやって確認するのやら…。

GOO
(ds inc1 (,arg)
  `(set ,arg (+ 1 ,arg)))

goo/user 0<=  (let ((x 0))(inc1 x)x)
goo/user 0=> 1

30秒。

Arc
(mac inc1 (arg)
  `(= ,arg (+ 1 ,arg)))

arc> (let x 0 (inc1 x) x)
1

32秒

GOOもArcも似たようなものです。

どうもinc1一番簡単で無難な問題に思えてきました。