LLにおける関数型プログラミング

■ このスレッドは過去ログ倉庫に格納されています
2012/08/16(木) 22:17:50.32
339 返信:153[sage] 投稿日:2012/08/16(木) 22:16:29.83
>>314
>関数型言語でなければならないという観点は間違ってる気がする

ああ、これについては同感だね
現状のどの関数型言語も文字列、パターン、ハッシュの操作に難があるから、
現行LLであるPerl/Python/Rubyを置き換えるには無理があると思う

ただし、関数型言語にも良い特性がある訳で、実際に(LLを含む)多くの言語に影響を与えている
だから自分は「LLにおける関数型プログラミング」に注目している
2012/08/16(木) 22:20:44.31
そうか
3うゆ
垢版 |
2012/08/16(木) 22:24:22.07
rubyが最強っていってんじゃん
2012/08/16(木) 22:29:24.64
いい加減関数型とかうるさい
2012/08/16(木) 22:42:07.04
>>1
> 現状のどの関数型言語も文字列、パターン、ハッシュの操作に難があるから、

その難というのを、もっと明確に言ってほしい。

たとえば、**というプログラムをする上で必要な
文字列に関する$$という操作が、
どの関数型言語でもできない、あるいはやりにくい。

など

パターンとハッシュに関しても同様に。
2012/08/16(木) 22:46:25.19
【関連サイト: Python編】

・関数型プログラミング HOWTO ― Python 2.7ja1 documentation
 http://www.python.jp/doc/nightly/howto/functional.html

・魅力的なPython: Pythonでの関数プログラミング: 第1回 - IBM dw
 http://www.ibm.com/developerworks/jp/linux/library/l-prog/

・Pythonの技法:関数型言語スタイル「関数の部分適用」 - ZDNet Japan
 http://builder.japan.zdnet.com/script/20364411/

・Pythonの"関数型"の機能の起源 - The History of Python.jp
 http://python-history-jp.blogspot.jp/2009/05/python.html
2012/08/16(木) 22:54:29.59
カリー化なんかもRubyで簡単にできる時代

def add(a, b)
 return a + b
end

def curry(f, a)
 return lambda { |b| method(f).call(a, b) }
end

add1 = curry(:add, 1)
p add1.call(2)

Rubyは関数オブジェクトを扱えるので、
置き換えるも何も、既にRubyは関数型言語
当然純粋関数型言語ではないし、関数型言語らしく書かない事もできるけど、
関数型言語としての特性を備えている事に変わりはない

そもそもどの言語でも最近関数オブジェクトの取り入れが盛んで、
関数型言語かどうかという分類が既に成り立たなくなってる
C++11ですらカリー化できる時代、
可能なのはせいぜい純粋関数型言語か否かという区別程度だな
http://ideone.com/H82Pn
8uy
垢版 |
2012/08/16(木) 22:57:19.48
同意ですよ
2012/08/16(木) 23:08:53.70
>>7
それのどこがカリー化だアホめ
2012/08/16(木) 23:09:47.31
関数名がカリーだろよく見ろ
2012/08/16(木) 23:10:41.08
以降おいしいカレーとチャーハンの作り方のスレ
2012/08/16(木) 23:13:14.87
間を取ってドライカレーで
2012/08/16(木) 23:13:58.81
>>7
それはカリー化ではなく、部分適用です。
14uy
垢版 |
2012/08/16(木) 23:18:13.64
http://www.ruby-doc.org/core-1.9.3/Proc.html#method-i-curry

はいはいわろ
2012/08/16(木) 23:31:18.63
例えば f (a, b, c) という3引数の関数に対して、これをカリー化した関数というのは、
y (b, c) という2引数の関数を戻り値として返す1引数の関数 g (a) のことだ。

関数 f から関数 g を作ることをカリー化という。

では >>7 の中でカリー化された関数とはどれか、明確に示してみよ。
2012/08/16(木) 23:34:41.03
んじゃこれで
1.9では>>14なんてのもあるみたいだが

def add(a, b)
 return a + b
end

def curry(f)
 return lambda { |a| lambda { |b| method(f).call(a, b) } }
end

add1 = curry(:add).call(1)
p add1.call(10)
2012/08/16(木) 23:34:48.19
f :: (a, b, c) -> d から
g :: a -> (b -> (c -> d)) を作るのがカリー化
2012/08/16(木) 23:40:44.49
>>16
2引数の場合しか動かんようなクソコードなら貼らなくて良いよ
19デフォルトの名無しさん
垢版 |
2012/08/16(木) 23:49:07.32
ソースコードに全角スペース入れる奴なんなの?
2012/08/16(木) 23:53:57.05
お前は黙ってろ
2012/08/17(金) 00:02:31.38
>>17
違う

f :: (a, b, c) -> d から
g :: a -> ((b, c) -> d) を作るのがカリー化だ。

-- Wikipedia : カリー化(http://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AA%E3%83%BC%E5%8C%96
> 複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること。

カリー化された関数の戻り値は「もとの関数の残りの引数を取り結果を返す関数」だ。

(b, c) を勝手に b -> c -> と形を変えることまではカリー化には含まれない。
2012/08/17(金) 00:08:24.78
>>21
ごめんねーwikipediaは英語見てたわーww

http://en.wikipedia.org/wiki/Currying

> In mathematics and computer science, currying is the technique of transforming a function
> that takes multiple arguments (or an n-tuple of arguments) in such a way that
> it can be called as a chain of functions each with a single argument (partial application).
2012/08/17(金) 00:12:29.05
>>14がそれを満たしてんじゃないの?
2012/08/17(金) 00:24:16.48
>>14 のレスはあぼーんされて見えないから無視する。

Ruby でカリー化が本当にできるのかどうかは知らない。
少なくとも、確実に >>7 はカリー化ではないと指摘しているだけだ。

>>16 もなんか怪しい気がする。
カリー化された関数とはどれのことか?
2012/08/17(金) 00:29:51.41
>>16はcurry(:add)でカリー化はできてる
ただ、2引数にしか使えない

1.9ではまんまcurryメソッドが用意されてるので変な事する必要ない
http://www.ruby-doc.org/core-1.9.3/Proc.html#method-i-curry
2012/08/17(金) 00:47:30.59
Pythonのfunctionalモジュールにcurryがあるけど
自前で定義するとこんな感じか

def curry(f):
    n = f.__code__.co_argcount
    def _(args=[]):
        return f(*args) if n == len(args) else lambda x: _(args + [x])
    return f if n == 0 else _()

@curry
def foo(a,b,c):
    return a + b + c

print(foo(1)(2)(3))
27デフォルトの名無しさん
垢版 |
2012/08/17(金) 09:01:48.91
そもそもrubyはHLですしおすし
2012/08/17(金) 13:16:16.85
>>5
>その難というのを、もっと明確に言ってほしい。

現行のLLにはこれらデータを「簡潔に表現」できる専用の記法/構文がある
以下はRubyの例(これらはPerl(awk?)から影響を受けた(=パクッた)と思われる)

【文字列】  文字列リテラルには「式展開」や「ヒアドキュメント」がある
      たとえば "my name is #{$ruby}" は、format "my name is %s", $ruby よりも
      簡潔に書ける
【パターン】 「正規表現リテラル」がある。たとえば /^Ruby is OOPL/ は、
      Regexp.new "^Ruby is OOPL" よりも簡潔だ
【ハッシュ】 「ハッシュ式」とハッシュ操作のための構文がある
      たとえば {a: 1, b: 2} は Hash.new [:a, 1, :b, 2] よりも簡潔だし、
      obj[:a] は obj.fetch :a よりも簡潔に書ける

これらの記法/構文はRuby全体からすればほんの一部であり、
LLの主用途(主戦場)である日常的なテキスト処理に特化した様々な工夫が施されている
これらの多くは関数型言語ではライブラリ関数として提供され、
同等な処理は書けてもLLの専用記法/構文と比較すれば冗長である(=めんどくさい)と考える
2012/08/17(金) 13:34:56.55
> {a: 1, b: 2}

この暗号みたいなの何?
2012/08/17(金) 13:45:54.65
>>28
× 現行のLL
○ Ruby
2012/08/17(金) 13:47:00.73
RubyってPerlが糞だと言われたことと同じ轍を踏んでるよな
2012/08/17(金) 14:20:06.15
>>29
Ruby 1.9で導入された新しいハッシュ式の記法
以前の記法 {:a => 1, :b => 2} と同じ
2012/08/17(金) 14:24:36.76
糞分かりにくいな
3428
垢版 |
2012/08/17(金) 14:33:34.42
>>31
UNIXプログラミング環境に住み慣れた人なら、
sh や awk でなじみがあるから好意的に受け止める人は多いのではないかと思う
少なくともWeb開発の世界では、Perlの記法を引き継いだPHP(と一部でRoR)が主流だし...

まあWindowsプログラマからすれば、これらの記法に違和感があるというのは認めるw
2012/08/17(金) 14:43:29.41
PHPが主流なのはCの記法に似てるからだろw 何言ってんだコイツは…
2012/08/17(金) 14:52:20.75
Rubyの関数型プログラミングスレで良かったんじゃねぇ〜?
元のLL云々ってRuby&関数型マニアのコイツがLLスレで暴れたいだけの口実だったんだしぃ〜
なんかLLの話するのかと思って釣られてくる被害者が出そうだわぁ〜
まーた関数型言語用のお題ってのを早速コテみたいなのをつけ出したコイツが出してくるんだろぉ〜
都合の良いルールで縛ってさぁ〜、結論ありきの議論は面白いですかぁ〜
3728
垢版 |
2012/08/17(金) 15:25:41.58
>>36
>Rubyの関数型プログラミングスレで良かったんじゃねぇ〜?

んー自分はそれでも良かったけど、せっかく>>1がスレを立ててくれたんだから、
Rubyに限定せず、あらゆるLLで関数型プログラミングを語る場になれば....と思う
特に(>>6にあるように)Pythonは関数型プログラミングに関する情報が豊富みたいだから、
Python&関数型マニアの参加は大いに歓迎したいな
2012/08/17(金) 15:33:53.84
でも実践的な話は一切出来ないみたいだから隔離して良かった
2012/08/17(金) 15:43:48.64
>>28
camlp4使って構文拡張すれば足りるな
40uY ◆gXFLM6waxs
垢版 |
2012/08/17(金) 17:43:13.21
>Perlの記法を引き継いだPHP
>Perlの記法を引き継いだPHP
>Perlの記法を引き継いだPHP


それ変数につく$だけだろwwwwwww

Perlの汚い部分を引き継いだのがPHP

綺麗な部分だけ選んで引き継いだのがRuby

Rubyでは$変数をあまり使わない
perと同じように $_ 使える部分もあるんだけど、基本的には使えない場所のが多い 使えてもいい気がするんだけどな
2012/08/17(金) 18:41:20.65
>>33
実際にはActiveRecord/Rails系列の「キーワード風」メソッド引数の mes(sym1: val1, sym2: val2) のときに*しか*使用されない
これ以外の場面で使うのはなにもわかってないただのバカで早晩自爆するので放置でOK
42uY ◆gXFLM6waxs
垢版 |
2012/08/17(金) 19:08:08.44
なんていうか
シンボルが
:symbol

こうだから
xx: 4

だといったん、タイプがとまるんだよね

かといって
:xx => 4
だとタイプ数があるし

2.0に期待するしかない
2012/08/17(金) 19:29:55.50
>>28
では、逆に関数型言語にはあって、Ruby などの LL には無い機能や仕組みで、
是非 LL にも取り入れてほしいと思ってるものは何?

こちらも詳細にお願いします。
2012/08/17(金) 19:40:22.07
Rubyは同じことをやるのに手段を大量に提供するコンセプトなのかもしれないけど
それって人のコード読むときに苦労するよな。そういう用途は対象外なのかもしれないが。
45uY ◆gXFLM6waxs
垢版 |
2012/08/17(金) 21:02:31.33
>>44
大量の手段あるけど
それはC++みたいにソース見ただけじゃ何やってるかわからない構文は無いんだよ
手段とはいっても
オブジェクト.メソッド で呼び出す形だから
メソッドの動作さえ覚えれば良いだけ

こういうところの考えからPythonとかのリスト内包表記は入れないんだと思う
2012/08/17(金) 21:17:26.95
>>44
DSLに関しては「読みにくくて書きづらくて覚えにくい」で意見の一致をみている
一時期ライブラリがなんでもかんでもDSLっぽい記述になったりもしたが、これからはそんなことは無いだろう
2012/08/17(金) 22:11:38.46
殆どはリテラルの表記の問題ということだな
48uY ◆gXFLM6waxs
垢版 |
2012/08/17(金) 22:42:52.85
バカには無理
4928
垢版 |
2012/08/18(土) 00:04:09.84
>>43
まず各LLにおける関数型プログラミングの適性度には大きな差異があること、
およびLLプログラミングではRubyしか深い経験/知識が(自分には)無いという理由から、
以降で述べる要望は「Rubyだけを対象」にしていることを断っておきます

最初の要望は、理想論であるけど「型推論を前提とした静的型付け」です
LLの主用途は(>>28で述べたように)日常的なテキスト処理であるけれど、
RailsやmRubyなどの登場によって「Rubyで製品を開発する」ケースが増えつつあります
この場合、生産性(効率的な開発)も大切ですが、長期間に渡って運用/開発が継続するという
性格から、品質(バグ発生率や保守性)が最も重要であると考えます
この高品質コード設計においては、生産性(簡潔さ)と高品質(安全性)を兼ね備えた
「型推論を前提とした静的型付け」がRubyに求められることになるでしょう

ただし、サブセットのRuby言語仕様であれば型推論の実験的実装について
いくつかの報告が存在しますが、完全なRuby言語仕様についてはかなり遠い目標でしょう
そこで、これに代わる現実論(=妥協案)として「省略可能な動的型検査構文」を要望したい
これは単純に def hoge(num : Integer, str : String) : MyClass といった構文でもいいし、
typexpr Integer * String -> MyClass のような明示的型式宣言でもいいし、
あるいはPythonのデコレータ記法を応用した型検査手法をパクってもいいと思います
なお、当たり前ですがこの要望は組み込み/標準添付ライブラリに関しても適用されるべきです

この要望は、ドキュメンテーションの改善にも役立てることができます
現在のRubyコミュニティでは、コメントとして記述された型情報を含む解説を抽出するという
JavaDocスタイルの文書化が主流です(たとえば「引数 num は整数、str は文字列 ......」)
ここで、もしも動的型検査構文が導入され、かつ型情報を外部へ出力できるようになれば、
そこからメソッドの型に関する解説を文書の一部として自動生成できるようになるはずです
また「コードとコメントの乖離」というJavaDocスタイル固有の問題(の一部)も解消されます

(続きは、また明日)
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況