2007年 11月 28日

Ruby1.9 のラムダさん

やばいやばい。知らなかった。手元で既に使えるシンタックスっていう! (でも将来使えるかわからない予感) id:secondlife さんに教えてもらった。id:secondlife++ あと parse.y をながめてやりかたを覚えたw

この前の true/false のラムダを書いてみる。

# curry は http://subtech.g.hatena.ne.jp/cho45/20071119/1195420784

# 1.8
t = lambda {|x, y| x }.curry
f = lambda {|x, y| y }.curry

t[lambda {
	puts "hoge"
}][lambda {
	puts "fuga"
}][]

#1.9 head
t = -> (x, y) { x }.curry
f = -> (x, y) { y }.curry

t[-> {
	puts "hoge"
}
][-> {
	puts "fuga"
}][]

# or
t.
(-> {
	puts "hoge"
}).
(-> {
	puts "fuga"
}).()

やばすぎる萌えすぎる。


メモ

t = -> (x, y) { x }
t = -> x, y { x }   # 括弧いらないらしい

(1..3).map {|x| x * x }
(1..3).map(&-> x { x * x }) # このつかいかたはあんましなそう?
(1..3).map &-> x { x * x }  # おなじ

car = -> x,*xs { x }
cdr = -> x,*xs { xs }
p car[10, 20, 30] #=> 10
p cdr[10, 20, 30] #=> [20, 30]

car = -> ((x,*xs)) { x }
cdr = -> ((x,*xs)) { xs }
p car.([10, 20, 30]) #=> 10
p cdr.([10, 20, 30]) #=> [20, 30]

どういうとき一番うれしいかなぁ。ラムダ計算のやつは普通書かないし

hoge = ->&b{ b.yield b }

hoge.() {|x|
	p x.lambda? #=> false
}

hoge.(&->x{
	p x.lambda? #=> true
})

これ記法によって挙動が変えられるってことで夢ひろがりんぐだけど、実際変わるメソッドがあったりするとびびりそう。どういう意図で入ってるんだろう。

Ruby1.9 のラムダさん 2 (SKI とチャーチ数 256)

#!ruby1.9 -v

s = -> x {-> y {-> z { x.(z).(y.(z)) } } }
k = -> x {-> y { x } }
i = -> x { x }

t = k
f = s.(k)

car = -> list { list.(t) }
cdr = -> list { list.(f) }

car = s.(i).(k.(t))
cdr = s.(i).(k.(f))

# ((lambda (n) (n n)) ((lambda (n) (n n)) (lambda (f x) (f (f x)))))
cn256 = -> n { n.(n) }.(-> n { n.(n) }.(-> f {-> x { f.(f.(x))}}))
# SII(SII(S(S(KS)K)I))
cn256 = s.(i).(i).(s.(i).(i).(s.(s.(k.(s)).(k)).(i)))

inputlist = -> list {
	-> f { f.(list.first || cn256).(inputlist.(list.drop(1))) }
}


cn2num = -> cn { cn.(-> x { x + 1 }).(0) }
num2cn = ->  n { -> f {-> x { (1..n).reduce(x) {|r,_| f.(r) } } } }

il = inputlist.([72, 101, 108, 108, 111].map(&num2cn))
p cn2num.(cn256)
p cn2num.(car.(il))
p cn2num.(car.(cdr.(il)))

Ruby のコードに見えないすぎるw

GDHM

黄金の鐘の歌詞があとかたもない。ハレルヤのところより看守は奴隷にパンを売りつけのところがなくなったのがすげー残念だなぁ。

Hash#put がほしい

class Hash
	def put(key, value)
		self[key] = value
		self
	end
end

a = { 1 => "foo", 2 => nil }
b = { 2 => "bar", 3 => "baz" }
p a.inject({}) {|r,(k,v)| r.put(k, b[k] || v) }

a.inject({}) {|r,(k,v)| r[k] = b[k] || v; r } # ← これがダサい

ML に投げるべきなんだろうなぁ……メールこわい……


というか []= が value を返すのはわかるけど、store (さっきしった) まで value かえさなくてもいいのに (Array#{push,unshift} は self をかえす)

jAutoPagerize / microformats hAtom

どういう風に入れようか悩んでて (autopagerize_insert_before は microformats っていうのかなぁ……じゃあ名前なにがいいんかなぁとかいろいろ) いれてなかったけど、コミットされてたのでまいっかー的に……(他人まかせ)

それとは別に hAtom と rel="next" による microformats のルールを入れた。link rel="next" もマッチすべきかも

, { url          : '^https?://.*'
  , nextLink     : '//a[@rel="next"]'
  , insertBefore : '//*[contains(concat(" ",@class," "), " hfeed ")]/following-sibling::node()'
  , pageElement  : '//*[contains(concat(" ",@class," "), " hfeed ")]'
  }

clear cache のメニュー追加をかかないとなぁとおもってたらコミットされてたww CodeRepos++

wiki clone

どうも wiki clone がつくれない。なんか考えることが多くて、しかもちらばってて、まとまらない。だめすぎる……

  1. 履歴管理と diff
  2. データの保存方法
  3. 記法パーサー
  1. データベースを使わない
  2. 全てのリビジョンをそのまま保存する (過去のは全部 gzip)
  3. diff は履歴表示のときだけ
  4. 記法なし

でつくってみればいいんだろうけど、いまいちやる気がわかない。こんなのつくっても、って感じ…… Ruby で blosxom クローンつくらなかったのもこういう理由なんだよなぁ……blosxom クローンを Ruby で書いても Ruby がある程度わかってるならあれじゃ学習にならないし、書くならまともなのが書きたかったから、プラグインシステムをどうするかでずっと悩んでた。

しかし wiki clone だとユーザの書きこみがあったりするから、他の言語で勉強しながらつくるっていうのは結構荷が重い……