Hatena::ブログ(Diary)

しんちゃんの日記

2016-06-19

自分なりの宣言的プログラミングの定義

関数型言語や論理型言語(Prolog)は宣言的にプログラミングが出来ると入門書には書いてることがあります。
一方で、Javaの本でも宣言的なコードと書かれたものがあります。
どうもメソッド呼び出しのみが並ぶようなコードっぽい。

となると、ifやfor等の制御構造が無ければ宣言的と言う事なのかな?
まあ、手続き型言語関数オブジェクト指向も、もとは抽象的に扱うための物ですしね。
宣言的であるのと、参照透明な事は関係ないと考えればしっくりきます。
昔、2chで型がある言語で書く人はクラスをよく書くけど、型のない言語で書く人はクラスをあまり書かないとか見かけましたが、ある意味ではクラスを書かなくて済むくらいになるのが手続き型言語抽象化の理想ではないかと。
手続き的な処理は一切書かなくて良くて、全てメソッド関数の呼び出しだけで完結できるようになったら、関数型言語と同じくらいの抽象度になっているのかもしれません。

そう言えば、次期JavaScriptが末尾再帰最適化出来るようになるそうですね。
理屈の上では手続き型言語だって出来ると思ってましたので、他の手続き型言語にも採用されていくと思います。
しかし、Haskellはいつの間にか普通の(単純な)再帰も(恐らく内部で末尾再帰に変換して)ループになるようになってました。
これは地味にうれしい。
これも、いずれは手続き型言語に採用されていくように思いますが、もう少し先でしょう。

C#型推論もまだまだですね。
そして、あれ以上の推論は手続き型では無理な気はしますね。
手続き型で関数型言語並みの抽象度になるのは結局LLやsmalltalkの様な型の無い言語だけのように思います。

だったら、型があって抽象度の高いHaskellが(ry

2013-01-05

関数型言語のパターンマッチはifやswitch/case文の代わりではあるが、仕組み的にはオーバーロードに近い気がする

変な事を書いてすみません。

タイトルからして訳が分からないと思うのですが、私が最近思っている、パターンマッチに関する考察です。

単純に、よくパターンマッチはifやswitch/case文を書かなくて済む。と言う話があるのですが、使っていくうちに、パターンマッチは単純なifやswitch/case文の置き換えでは無いと思う時があるのです。

例えば、mergesortを自作すると、以下のようになるのですが、ifやswitch/caseで同じように再帰で書こうとすると、結構ごちゃごちゃすると思います。
(まあ、その辺はオブジェクト指向的な別のやり方があると思いますが)

mergesort [] = []
mergesort [z] = [z]
mergesort zs = merge (mergesort xs) (mergesort ys)
	where
		(xs,ys) = mysplitAt (mylength zs `div` 2) zs


merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) | x < y = x:merge xs (y:ys)
merge (x:xs) (y:ys) = y:merge (x:xs) ys

mytake 0 _ = []
mytake _ [] = []
mytake n (x:xs) = x:mytake (n - 1) xs

mydrop 0 xs = xs
mydrop _ [] = []
mydrop n (_:xs) = mydrop (n - 1) xs

mysplitAt n xs = (mytake n xs, mydrop n xs)

mylength = mylength' 0
	where
		mylength' v [] = v
		mylength' v (_:xs) = mylength' (v + 1) xs

オブジェクト指向オーバーロードと全く使い道が違うのは承知なのですが、こう、同じ関数名がズラズラ並ぶと、オーバーロード引数の数だけじゃなく、値でも同名の違う関数メソッド)を呼べるようにしたのがパターンマッチなんじゃないか?と、思ってしまう時があります。

まあ、パターンマッチは、あくまで「同じ型の違う値」で機能するので(そして、引数の数は同じじゃないといけないので)、本当に、概念的には全く違うんですけど・・・

仕組み的には、ifやswitch/case文よりも、近いものを何故かオーバーロードに感じてしまう私です。

そう言えば、LLだと型が無いからなのか、オーバーロード使った事ないですね・・・。
そもそも、コンパイラばかり使ってたので、LLの経験自体が少ないですが。