2009/08/02

Parrot でのクロージャ

:outer で環境を指定した sub を .const 'Sub' でつかまえて newclosure する。

他のネームスペースの sub をつかまえるときは find_name を使う。

.sub main
$P0 = make_closure(10)
$P1 = make_closure(100)
$P0() # 11
$P1() # 101
$P0() # 12
$P1() # 102
.end

.sub make_closure
.param pmc n
.lex 'n', n
.const 'Sub' foo_sub = "foo"
$P1 = newclosure foo_sub
.return($P1)
.end

.sub foo :outer(make_closure)
$P0 = find_lex 'n'
$P0 += 1
say $P0
.end

夏休みコンサート

日本フィル夏休みコンサート2009 に行ってきた。昨日。

オーケストラ、バレエ、歌と大人でも楽しかった。なんといっても、あまり長くないところがいい。ずっと座っているのは苦手なので。

来年もまた行きたいな。

2009/07/26

Parrot で eval もできる

http://docs.parrot.org/parrot/latest/html/docs/book/pir/ch06_subroutines.pod.html

Evaluating a Code String

.sub main
.local pmc compiler, generated1, generated2
.local string source1, source2
compiler = compreg "PIR"
source1 = ".sub foo\n$S1 = 'in eval 1'\nsay $S1\n.end"
source2 = ".sub foo\n$S1 = 'in eval 2'\nsay $S1\n.end"
generated1 = compiler(source1)
generated2 = compiler(source2)
generated1() # in eval 1
generated2() # in eval 2
foo() # in eval 2
$P1 = generated1
$P1() # in eval 1
.end

Parrot はとことん言語実装のための VM だな。

Parrot をさわってみた

http://www.parrot.org/

PIR

PIR(Parrot Intermediate Representation)は Parrot の中間レベルのアセンブリ言語。

使える機能としては

  • ガーベッジ・コレクション
  • コンティニュエーション
  • レキシカルバインディング
  • オブジェクト指向
  • 例外
  • テイルコール
  • UTF-8 UTF-16 のサポート

などがある。とんでもなく高機能。もっとずっと低レベルの機能しかないと思っていたから意外だった。さらに、いろいろとライブラリも充実してるみたい。 Hash もあったりする。

hello.pir

.sub hello
.local pmc en, jp
$P0 = newclass "EnHello"
$P1 = newclass "JpHello"
en = new "EnHello"
jp = new "JpHello"
en.'hello'("Parrot")
jp.'hello'(utf8:unicode:"おーむちゃん")
.end

.namespace [ "EnHello" ]

.sub 'hello' :method
.param string name
$S0 = "Hello, "
$S0 .= name
$S0 .= "!"
say $S0
.end

.namespace [ "JpHello" ]

.sub 'hello' :method
.param string name
$S0 = utf8:unicode:"こんにちは、"
$S0 .= name
$S0 .= utf8:unicode:"♪"
say $S0
.end

parrot ./hello.pir として実行できる。

2009/07/12

習字

娘と習字で遊んだ。習字で遊ぶってのはちょっとへんだな。毛筆で遊んだか。

最初は練習らしきものをしたが、あとはひらがなで二文字ほど書いて、その下に絵を描く遊びになった。なにはともあれ、上手にばくが書けました。

2009/07/04

lambda

今日の Shibuya.lisp の Shiro さんの話にもでてきたけど lambda の表記。慣れの問題かもしれないが、lambda と素直に書くのが一番読みやすい気がする。うぅむ。

(deftest test-^ ()
(is (equal '((2) (3) (4)) (mapcar (^ list (1+ _)) '(1 2 3))))
(is (equal '(1 4 9) (mapcar (^ * _ _) '(1 2 3))))
(is (equal '((1 a "A") (2 b "B"))
(mapcar (^ list _z _y _x) '("A" "B") '(a b) '(1 2))))
(is (equal '(1 2 3)
(funcall (^ identity _rest) 1 2 3)))
(is (equal '(2 1 3 4)
(funcall (^ apply #'list _b _a _rest) 1 2 3 4)))
(is (equal "a"
(with-output-to-string (*standard-output*)
(funcall (^ princ _) #\a))))
(is (equal "cba"
(with-output-to-string (*standard-output*)
(funcall (^ (princ _z) (princ _y) (princ _x)) #\a #\b #\c)))))

(deftest |test-{}| ()
(is (equal '((2) (3) (4)) (mapcar {list (1+ _)} '(1 2 3))))
(is (equal '(1 4 9) (mapcar {* _ _} '(1 2 3))))
(is (equal '((1 a "A") (2 b "B"))
(mapcar {list _z _y _x} '("A" "B") '(a b) '(1 2))))
(is (equal '(1 2 3)
(funcall {identity _rest} 1 2 3)))
(is (equal '(2 1 3 4)
(funcall {apply #'list _b _a _rest} 1 2 3 4)))
(is (equal "a"
(with-output-to-string (*standard-output*)
(funcall {princ _} #\a))))
(is (equal "abc"
(with-output-to-string (*standard-output*)
(funcall {(princ _x) (princ _y) (princ _z)} #\a #\b #\c)))))

(deftest test-lambda ()
(is (equal '((2) (3) (4)) (mapcar (lambda (x) (list (1+ x))) '(1 2 3))))
(is (equal '(1 4 9) (mapcar (lambda (x) (* x x)) '(1 2 3))))
(is (equal '((1 a "A") (2 b "B"))
(mapcar (lambda (x y z) (list z y x)) '("A" "B") '(a b) '(1 2))))
(is (equal '(1 2 3)
(funcall (lambda (&rest rest) (identity rest)) 1 2 3)))
(is (equal '(2 1 3 4)
(funcall (lambda (a b &rest rest)
(apply #'list b a rest)) 1 2 3 4)))
(is (equal "a"
(with-output-to-string (*standard-output*)
(funcall (lambda (x) (princ x)) #\a))))
(is (equal "cba"
(with-output-to-string (*standard-output*)
(funcall (lambda (x y z)
(princ z) (princ y) (princ x)) #\a #\b #\c)))))

2009/06/28

Linux 環境での Clozure CL で日本語パス名

Linux 環境での Clozure CL で日本語パス名を扱うには次のコードが必要みたい。 Mac と Win はデフォルトで大丈夫そう。

(ccl::set-pathname-encoding-name :utf-8)