【PHP,Python】スクリプト,バトルロワイヤル37【Perl,Ruby,JS】

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
前スレ

【PHP,Python】スクリプト,バトルロワイヤル36【Perl,Ruby】
http://toro.2ch.net/test/read.cgi/tech/1374371254/
2デフォルトの名無しさん:2013/08/19(月) 10:38:55.96
< `∀´>ニダー
3デフォルトの名無しさん:2013/08/22(木) 09:41:17.81
Python万歳!バカruby死ねw
4デフォルトの名無しさん:2013/08/22(木) 21:35:07.58
python -V
5デフォルトの名無しさん:2013/08/22(木) 21:36:55.05
前スレの続き
http://dictionary.goo.ne.jp/leaf/ej3/11830/m0u/

[名][U]
1 体積, 容積, 大きさ, かさ, 大きい[かさばっている]こと, 巨大;[C]巨大な人[動物, 物];巨体;((形容詞的))大量の, 大規模な
bulk buying 大量購入
bulk production 大量生産
bulk sale (不良債権の)【【【【一括】】】】売却.

2 ((the ?))(…の)大部分, 大半((of ...))
The bulk of the work was finished. 仕事の大半は終わった.

3 [U](船の)積荷;(船荷の)ばら荷.

4 繊維質の食べ物. break bulk
積荷を降ろし始める.
in bulk
(1) 大口で, 大量に.
(2) ばら荷で, 梱包しないで.

━━[動](自)
1 大きくなる;(数量が)増大する, かさばる, かさむ((up));(集合して)大きくなる, (…の)かたまりになる((into, to ...)).

2 ((文))[bulk large]大きく見える;重そうである;重大そうである
The subject bulks large in his mind. その問題は彼の心に大きくのしかかっている.

3 〈紙・ボール紙などが〉かさがある.
━━(他)
1 …をかさばらせる, 重く[大きく, 分厚く]する[見せる]((out, up)).
2 …をいっしょにする, 混ぜる.
3 (太るために)たらふく食う((up)).
[スカンジナビア語. 原義は「船の荷」]
6デフォルトの名無しさん:2013/08/22(木) 21:37:33.21
http://ejje.weblio.jp/content/bulk

名詞としての「bulk」のイディオムやフレーズ
break bulk in bulk
【動詞】 【自動詞】
1〔動詞(+up)〕
aかさばる.
bかたまりになる.

2〔+補語〕[通例 bulk large で] 〈大きく〉見える; 〈重要に〉思われる.
用例
The trade imbalance bulks large in our minds. 貿易不均衡が大きな問題であるように思える.
【他動詞】
1〈…を〉かさばらせる.
2〈ものを〉ひとまとめにする; 一括する.
7デフォルトの名無しさん:2013/08/22(木) 21:42:31.04
997 名前:デフォルトの名無しさん[sage] 投稿日:2013/08/22(木) 21:28:54.83
> >>995
> その変数が格納しているものと名前の関係を教えてくださいな
> 特に別の型の変数を代入して使いまわしている事について
>
> 俺はそういう事するのは汚いコードだと思うんだけど
> いくら言っても汚くない綺麗だって言うからさ

どこのコードが知りたいの?
8デフォルトの名無しさん:2013/08/22(木) 21:43:09.09
https://github.com/jquery/jquery/blob/1eb1ad616069ab103ceecf48c48514f51dd5d5ac/src/core.js#L802

// Mutifunctional method to get and set values to a collection
// The value/s can optionally be executed if it's a function
access: function( elems, key, value, exec, fn, pass ) {
var length = elems.length;

// Setting many attributes
if ( typeof key === "object" ) {
for ( var k in key ) {
jQuery.access( elems, k, key[k], exec, fn, value );
}
return elems;
}

// Setting one attribute
if ( value !== undefined ) {
// Optionally, function values get executed if exec is true
exec = !pass && exec && jQuery.isFunction(value);

for ( var i = 0; i < length; i++ ) {
fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
}

return elems;
}

// Getting an attribute
return length ? fn( elems[0], key ) : undefined;
},
9デフォルトの名無しさん:2013/08/22(木) 21:44:27.14
>>7

> 特に別の型の変数を代入して使いまわしている事について

他の言語の言うところの
オーバーロードの話ですか?

引数の型によって処理を変えること。
10デフォルトの名無しさん:2013/08/22(木) 21:46:20.94
別に面白くもない話だけどいま何人で回してるんだろ
11デフォルトの名無しさん:2013/08/22(木) 21:47:55.28
なんでオーバーロード?
12デフォルトの名無しさん:2013/08/22(木) 21:47:55.77
>>8は古いコードだったので修正

https://github.com/jquery/jquery/blob/master/src/core.js#L658

// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
var i = 0,
length = elems.length,
bulk = key == null;

// Sets many values
if ( jQuery.type( key ) === "object" ) {
chainable = true;
for ( i in key ) {
jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
}

// Sets one value
} else if ( value !== undefined ) {
chainable = true;

if ( !jQuery.isFunction( value ) ) {
raw = true;
}
13デフォルトの名無しさん:2013/08/22(木) 21:48:30.96
if ( bulk ) {
// Bulk operations run against the entire set
if ( raw ) {
fn.call( elems, value );
fn = null;

// ...except when executing function values
} else {
bulk = fn;
fn = function( elem, key, value ) {
return bulk.call( jQuery( elem ), value );
};
}
}

if ( fn ) {
for ( ; i < length; i++ ) {
fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
}
}
}

return chainable ?
elems :

// Gets
bulk ?
fn.call( elems ) :
length ? fn( elems[0], key ) : emptyGet;
},
14デフォルトの名無しさん:2013/08/22(木) 22:00:57.06
>>11
引数の数が違う場合に、引数の値の位置をずらすのは
型がない言語でオーバーロードを実現するテクニック。

このコードはkeyがあるかないかで、
引数の位置が変わっている。
15デフォルトの名無しさん:2013/08/22(木) 22:08:58.65
汚いっていうのなら、綺麗に書き直せばいいだけの話なのに。

俺が三項演算子苦手だからとかいうアホらしい理由じゃ無しに。
そこだけかよ指摘点。
16デフォルトの名無しさん:2013/08/22(木) 22:09:19.14
>>14
引数ずれてないじゃん。
そもそも使いまわしてるのは局所変数だから全然関係ない。
17デフォルトの名無しさん:2013/08/22(木) 22:16:39.23
>>15
直してもコード可読性じゃなくて圧縮率の話をし始めて
その上の話で圧縮プログラム名出せって言っても無視
そんな奴にまともに取り合うわけ無いだろ
18990:2013/08/22(木) 22:47:58.21
すまん帰宅が遅れた

bulkは引数の関数fnが「要素全体(elems)」を引数に取る場合はtrue,
関数fnが「単独の要素(elem[i])」を引数に取る場合はfalseになる。

以下のURL時点でのコードで解説するよ。
https://github.com/jquery/jquery/blob/6318ae6ab90d4b450dfadf32ab95fe52ed6331cb/src/core.js#L658

たとえば683行を見てみよう。fn.callの引数にはelemsを渡しているね。
これは680行の条件分岐を見ればわかるように、bulk==trueの場合に実行される行だ。

次に706行〜708行を見てみよう。
やはりbulk==trueの場合にはfn.callの引数にはelemsを渡しているね。
そしてbulk==falseの場合にはfn.callの引数にはelems[0]を渡している。

つまりbulkはfnがelemsを受け取るタイプなのか、elems[i]を受け取るタイプなのか、ただそれだけの簡単な変数なんだ。

そしてこれはbulkとは関係ないことだけど、683行と707行を見比べてほしい。
何か気づかないかな?ヒントは673行だ。

そう、これはセッターとゲッターなんだ。
valuesが存在するときはセッターとして683行を実行し、それから707行のゲッターを実行してセット後の全要素を返す。
valuesが存在しないときはゲッターとして707行を実行だけして返す。

チェックするポイントを絞るととっても簡単なコードであることが理解していただけただろうか?
19デフォルトの名無しさん:2013/08/22(木) 23:04:03.73
>>18
そのbulkになんでかfnが代入されてるけどfnとbulkという用語の関係は?
その上で型を区別せずに一つの変数を使いまわす事について
コードが綺麗だと言える理由は?

>そしてこれはbulkとは関係ないことだけど、683行と707行を見比べてほしい。
本当に関係ないな
それにfnがgetterかどうかなんてこのコードだけじゃわからないよ
fnの動作を見なきゃ
20デフォルトの名無しさん:2013/08/22(木) 23:07:57.99
帰宅が遅れた()
21990:2013/08/22(木) 23:26:09.82
>>19
fnは引数の数でゲッターとセッターを区別する仕様になっていなければならない。
bulk処理の時は引数0個と1個で区別、bulk処理でない時は引数1個と2個で区別。

bulkにfnを代入しているのは引数valueが関数である時は関数の実行結果をセッターの値として渡すため。
697行を見ればわかるよ。raw==true、つまり引数valueが関数ではないときは単純な値をセッターに渡しているけど、
raw==falseのときは関数の実行結果をセッターに渡している。

それと>>18に少しだけ間違いがあったな。
些細な間違いだからコードを理解してる人にしか間違いは指摘できないだろう。
四捨五入して20文字の誤った記述があるからコードを理解した人は指摘してみてね。
22デフォルトの名無しさん:2013/08/22(木) 23:46:01.43
>>21
使いまわした後の話でなく、使いまわすことそのものの是非を聞いてる
もちろん変数宣言とコードをケチってるだけだというのはわかるが

明らかに別々の場所で異なる役割を1変数に与えてるから(俺は)汚いと言ってる
記述量が少なくなるという話でなく
そのコードが綺麗であると主張する理由だぞ

>raw==true、つまり引数valueが関数ではないときは
そのrawも指摘しようとしてた部分なんだが
rawの意味やその型がbooleanしか取らない事は
valueとの関連だと気づくまでわからない
だから可読性を考えればせめてisRawかisRawValue

そしてこうやって解説することはそれだけ理解を早めるために
別の情報がいるという事を証明している事になるがそれについてはいいのか?
23デフォルトの名無しさん:2013/08/22(木) 23:57:39.82
> 使いまわした後の話でなく、使いまわすことそのものの是非を聞いてる

だから、それは引数がずれているだけ。

オーバーロード的な使い方をする場合に、
関数呼び出しの際に引数の数が違うことによって、fnに関数が入っておらず
fnにオブジェクトが入っているから、bulkにfn(オブジェクト)を移動し、
fnに関数を入れることで、正しい引数に入れ替えている。

使い回しではなく、正しい引数に調整している。
24990:2013/08/22(木) 23:58:55.91
>>22
もともと俺が来たのは前スレで「bulkの意味答えてみ」と言われたから。
その意味については>>18で完全に説明できたと思うから、
コードの可読性とか汚さとかにはあんまり興味がないんだ。

俺は前スレからコードの可読性については何も言ってないよ。
可読性について何か言ってたのは別の人。
25デフォルトの名無しさん:2013/08/23(金) 00:00:44.31
>>23
fnには常に関数が来るっつーの

> bulkにfn(オブジェクト)を移動し、

fnがオブジェクトだったら直後のbulk.callできねーだろうが
26デフォルトの名無しさん:2013/08/23(金) 00:09:14.75
>>23
これの本質はthisのバインディング
ただし旧ブラウザのためにbindの代わりにクロージャを使ってる
そのクロージャとしてbulkを使いまわしてる
27デフォルトの名無しさん:2013/08/23(金) 00:14:35.57
>>25
ああよく見りゃ本当だw

じゃあ話は早い。

fnもbulkも関数だ。
bulkにfnを入れているのは、
関数を別の関数でラップしているだけ。

つまり、

bulk = wrap(bulk)

これを実行しているだけじゃないか。
使い回しではなくて関数を加工しているだけだ。
28デフォルトの名無しさん:2013/08/23(金) 00:16:58.51
>>24
なるほど理解できた
ちなみに間違いってのはbulkのtruthy/falsy?
それともfnの引数ってところ?
いずれにしろ丁寧に答えてくれて感謝する
29デフォルトの名無しさん:2013/08/23(金) 00:18:56.52
コード読めない奴は大変だなw
30デフォルトの名無しさん:2013/08/23(金) 00:22:48.21
間違えた
thisバインドしてるんじゃなくてwrapしてるだけだな
ついつい勝手にthisのクロージャのイディオムとして読んでしまった
31デフォルトの名無しさん:2013/08/23(金) 00:22:58.97
コードの動きがわかった所で、
このaccess関数を全く同じ動きのまま、
綺麗に書きなおして欲しいんだが
まあ汚いって書いた奴はもうでてこれないかな。
32デフォルトの名無しさん:2013/08/23(金) 00:24:01.19
三項演算子について指摘して認めた時点で
汚かったって話で終わりなはずなんだけどなあ
33デフォルトの名無しさん:2013/08/23(金) 00:25:05.83
>>31
>このaccess関数を全く同じ動きのまま、
>綺麗に書きなおして欲しいんだが
でも変数宣言変えただけで別の動きだと騒ぐんでしょう?
34デフォルトの名無しさん:2013/08/23(金) 00:26:51.14
なんか、C言語のstrcpyの実装を思い出した。

技巧的なコードであり、説明が必要だが、
シンプルで無駄がないコード。

char *strcpy(char *s1, const char *s2)
{
char *p = s1;
while (*s1++ = *s2++)
;
return (p);
}
35デフォルトの名無しさん:2013/08/23(金) 00:30:33.63
三項演算子ってそんなに見難いの?
36デフォルトの名無しさん:2013/08/23(金) 00:38:17.25
やっぱりわかんないや。日本語にすると、

chainable なら elems、
bulk なら fn.call( elems )、
length なら fn( elems[0], key )
それ以外なら emptyGet;

って自然に読めると思うんだけど?
37デフォルトの名無しさん:2013/08/23(金) 00:42:26.86
>>35
ネストが問題なだけ
ネストするとtruthyとfalsyの境界がわかりにくくなる
38デフォルトの名無しさん:2013/08/23(金) 00:43:43.19
if (条件) {
  return
}

:処理が続く


っていうのは、関数の始めのほうで見なくて良いコードを
見なくて済むように、処理を打ち切るとか
インデントを深くさせないために使うけど、
関数の最後でやっても意味ないよなぁ。
39990:2013/08/23(金) 00:46:51.58
>>28
> セッターとして683行を実行し、【それから707行のゲッターを実行して】セット後の全要素を返す。
↓正しくは
> セッターとして683行を実行し、セット後の全要素を返す。

セッターの時は必ずchainable = trueになるので707行に行くことはない。
40デフォルトの名無しさん:2013/08/23(金) 00:48:52.16
ネストするとわかりにくくなるのは横に並べてみればわかる。

chainable ? elems : bulk ? fn.call( elems ) : length ? fn( elems[0], key ) : emptyGet;
41デフォルトの名無しさん:2013/08/23(金) 01:00:03.64
どうでもいいところにこだわって前へ進めない奴らだ
42デフォルトの名無しさん:2013/08/23(金) 01:49:47.06
>>40
いや、とても分かりやすい
?のところで戦いが起こって、脱落して行き、右側に行くほど
生き残ってる様子がよく分かる
43デフォルトの名無しさん:2013/08/23(金) 01:53:34.75
なんか、jqueryの作者をdisるのって、サッカーとか野球とかで世界的な
スーパースターのプレーを「この下手くそ」ってテレビの前でdisってる
バカおやじに似てる
44デフォルトの名無しさん:2013/08/23(金) 03:34:17.01
作者を馬鹿にしてる訳じゃないって何度言えばいいのか
disるとか言ってるのお前だけだからな?
それと自分と作者を重ねてるみたいだけど
お前はその作者じゃないっての
45デフォルトの名無しさん:2013/08/23(金) 07:25:58.49
問題の部分がどうなのかは知らないが、作者といってもそこらへんの趣味グラマもいれば
バリバリのMSの社員もいるわけで、玉石混淆なのは想像に難くないな
46デフォルトの名無しさん:2013/08/23(金) 10:26:21.82
>>44
この話の元となったblogではdisってますが何か。
47デフォルトの名無しさん:2013/08/23(金) 22:29:46.55
>>45
少なくともjQueryのソースにコミットされたコードは
スーパープログラマのレビューに通ったコードだわな
48デフォルトの名無しさん:2013/08/23(金) 22:41:00.93
まあ少なくともMSの社員が書いたんではないだろうなw
適当なのがある程度許されるのはwebワールドだからこそで
MS社内で例のコード書いたらさすがに怒られるよ
49デフォルトの名無しさん:2013/08/23(金) 22:43:50.09
は?JS文化では、あれでもキレイな方なんですがねぇ……
50デフォルトの名無しさん:2013/08/24(土) 00:25:53.79
確か、Paul IrishはGoogle社員だったよな
Google社員はMS社員より格上ですか?
51デフォルトの名無しさん:2013/08/24(土) 00:27:20.97
>>49
少なくともそういう次元をはるかに越える人たちであるのは
間違いない
52デフォルトの名無しさん:2013/08/24(土) 01:18:40.75
>>50
プログラミング能力的にはMSに遠く及ばない
プロダクトを継続して開発続けられないレベル、ウンコ
53デフォルトの名無しさん:2013/08/24(土) 01:40:31.72
 
( ´_ゝ`)フーン
54デフォルトの名無しさん:2013/08/24(土) 01:41:18.87
そりゃまあ、MSはGoogleに比べて古いからなw
長い間開発してるものは必然的に沢山あるだろうよ

まあしかし、Googleもここにいる奴らがおいそれと軽々しく叩ける
しろもんじゃないな
一般人が「レアルマドリードに比べてバルサは糞」とか、
「巨人に比べて楽天は糞」とか、
そういうこと言ってるのとだいたい同じw
55デフォルトの名無しさん:2013/08/24(土) 01:45:08.41
Googleにはプログラミングコンテストの世界大会優勝者とかレーティング一位に
なった奴が次から次へと入社していくじゃん
東大のプログラミング一番できる人たちも軒並みmsじゃなくてGoogleらしいし
56デフォルトの名無しさん:2013/08/24(土) 02:00:38.09
少なくともMS社員であらせられる、Scottさんが
jqueryを絶賛しているのだが
http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx
つか、MSは積極的にjQueryを採用してるだろw
MS教の信者がjQuery叩いてるみたいだけど、教祖様は逆に絶賛してるぞ
どうするんだ?w
57デフォルトの名無しさん:2013/08/24(土) 06:37:55.15
Python万歳!バカルビー死ねw
58デフォルトの名無しさん:2013/08/24(土) 07:23:25.41
中のコードの一部出して汚いって言ったのに
jQuery全否定してることになってるらしい
なんかどこかで見たことある光景
59デフォルトの名無しさん:2013/08/24(土) 07:48:41.10
どこかで見たことあると思ったらゲハじゃねえか
権威主義で所属してるわけでもない団体の権威を振りかざして中身を語る
60デフォルトの名無しさん:2013/08/24(土) 08:14:53.16
厳しいねえ
元のブログはどう見ても、「一部例として抜き出しますけど、これがjQueryですか?
助けてー」なんて
全体を否定する論調なんだが
61デフォルトの名無しさん:2013/08/24(土) 08:22:17.61
Getsのsが複数形のsだって分からなかったのは、
単に英語力が無いだけだよねw
62デフォルトの名無しさん:2013/08/24(土) 08:41:06.73
>>60
なんでそいつに同調してることになってるんだよ
もしかして元のブログの奴だと思ってたの?
63デフォルトの名無しさん:2013/08/24(土) 08:47:49.78
MSは公式に開発に参加してるはずだし、
「作者といっても色々いる。ポリシーもそれぞれ」て言ってるだけだろw
64デフォルトの名無しさん:2013/08/24(土) 09:03:47.85
一応統一スタイルガイドラインとか
その辺のポリシーはある程度統一されてるよ
開発チームになるには、承認が必要だし
65デフォルトの名無しさん:2013/08/24(土) 11:23:38.73
>>61
うわぁ...
66デフォルトの名無しさん:2013/08/24(土) 12:22:53.04
>>65
どうした?ネイティブなら簡単に想像がつくコメントを
英語の苦手な日本人が勘違いして叩いたというイタイ事例だよ
67デフォルトの名無しさん:2013/08/24(土) 12:54:36.32
ここのgetsは動詞だろ...
68デフォルトの名無しさん:2013/08/24(土) 16:17:00.66
>>66
自覚ねえのかよ
それとも盛り上げようとしてくれてるのか?
69デフォルトの名無しさん:2013/08/24(土) 16:24:45.60
>>64
見てきたけどかなり自由度高いよ
GoogleやMSと比べられるような内容じゃないな
70デフォルトの名無しさん:2013/08/25(日) 18:44:39.31
jQueryなんてRailsの凄さに比べたら
マジ比較にならんけどなー
あんなんで凄いと崇めてる奴マジうけるわー
71デフォルトの名無しさん:2013/08/25(日) 18:58:17.19
Railsしゅごいねーちゅよいねー
72前スレ367:2013/08/25(日) 19:20:23.86
前スレの終盤で行われたクイックソートのコード合戦について、
整理、加筆してマトメた記事を公開しました

・関数型プログラミングにおけるクイックソート・アルゴリズムの実装
  http://www.h6.dion.ne.jp/~machan/misc/qsort-in-fp.html
  http://www.h6.dion.ne.jp/~machan/misc/qsort-in-fp.epub

記事の結論としては、Ruby/JavaScript/Pythonともに、それら言語の特徴を生かしたスタイルを貫けば、
(「式指向」を含む)「関数型プログラミングの適性度」に明らかな差異は見られず、
あとは開発者の(主観的な)「好み」で選べばいいという、平凡なものとなっています
73デフォルトの名無しさん:2013/08/25(日) 19:22:08.86
>>72
これはよくまとめたな
74デフォルトの名無しさん:2013/08/26(月) 01:44:48.46
>>72
無断転載だろこれ。
75デフォルトの名無しさん:2013/08/26(月) 01:47:48.17
>>74
2chまとめブログなんて腐るほどあるわい
76デフォルトの名無しさん:2013/08/26(月) 02:07:32.78
>>74
開いたが問題ないだろ。
コードは2chと同じ物があるのかもしれないが、まとめサイトでない。
77デフォルトの名無しさん:2013/08/27(火) 04:41:13.34
英語のドキュメントや書籍・フォーラムなどを読めるようになりたいのですが、TOEICと大学入試英語、どちらを勉強した方が良いですか?
78デフォルトの名無しさん:2013/08/27(火) 06:33:43.65
バカスレw
死ねやお前らw
79デフォルトの名無しさん:2013/08/27(火) 07:35:30.46
>>77
TOEICはゲーム
英語の勉強にはならん
80デフォルトの名無しさん:2013/08/27(火) 11:41:32.72
>>79
そういうことは、950点超えてから言え
81デフォルトの名無しさん:2013/08/28(水) 14:36:22.57
558 名前:login:Penguin [sage]: 2012/09/19(水) 22:10:14.38 ID:9wlOWrob
node.jsはイベント型で同期ではない非同期のプログラミング言語。
しかもシングルスレッド。
制限が大きく用途によっては全く使い物にはならんよ。
C言語のようなことができないのだからな。
82デフォルトの名無しさん:2013/08/28(水) 17:36:23.35
いっぱつやりてぇ。ほげほげーっと。

>>77
Chromeのエクステンション入れて、一文字ずつマウスカーソルあてながら
よめば、栄研準2級のおれっちでも、技術文書よめるお( ´ω`)
83デフォルトの名無しさん:2013/08/28(水) 17:37:39.24
Weblio英和辞典っていうアドオンね。
84デフォルトの名無しさん:2013/08/28(水) 17:39:55.28
英語の本の場合は、ヤフオクでやっすい中古の電子辞書を買うか
gooの英和辞典のサイトとかで調べながらやってるな。

Excelの升目に単語と意味をタブで猛烈にタイプして
重要そうな単語はおぼえていります。
85デフォルトの名無しさん:2013/08/28(水) 20:35:08.53
日本人プログラマーって全然英語出来ないよね
86前スレ367:2013/08/28(水) 21:13:36.86
前スレ#707について、同>>981の方針を「暫定的」に反映させました
具体的には、Python/JavaScriptを「壁5. 式指向の壁」の上へ移動しました

FP
 ---- 壁0. 変数の壁 ----
Haskell
 ---- 壁1. 純粋性(副作用)の壁 ----
F#/OCaml/SML/Scala
 ---- 壁2. 型推論の壁 ----
=====<< 越えられない壁 >>=====
Erlang
 ---- 壁3. パターンマッチの壁 ----
Common Lisp/Scheme/Ruby1.9
 ---- 壁4. 末尾再帰最適化の壁 ----
Emacs-lisp/Closure/Smalltalk/Python/JavaScript/Ruby1.8
 ---- 壁5. 式指向(条件判定式)の壁 ----
(**** C++/Java/C#/Perl...etc ****[暫定]**** )
 ---- 壁6. ラムダ式の壁 ----
C

「暫定的」という言葉ですが、壁5. と 壁6. の間の言語グループについて、
式指向の壁を越えているか否かの判断が未確定であることを意味します
これらの言語についても、式指向の条件(前スレ#887)を満たしていれば
PythonやJavaScriptと同様に上げたいと考えています
個人的にはコードを期待しますが、特に無ければこの議論も終息するでしょう
87デフォルトの名無しさん:2013/08/28(水) 22:09:43.57
ますます式指向()が意味不明になったな
C#はほぼJavaScriptのスーパーセットだ
JavaScriptが式指向()でC#がそうでないというのは意味不明
88デフォルトの名無しさん:2013/08/28(水) 23:37:53.79
型推論の位置も良く分からんな
MLならともかくScalaの型推論は別にC#あたりに比べて威張れるレベルじゃなかった
気がするが
89デフォルトの名無しさん:2013/08/29(木) 00:34:50.80
C#
わかると思うがorderbyはグループのソートに使ってるだけだぞ

static IEnumerable<T> QSort<T>(IEnumerable<T> xs)
 where T : IComparable<T> {
 var part =
  from e in xs
  let c = e.CompareTo(xs.First())
  group e by c < 0 ? -1 : c == 0 ? 0 : 1 into p
  orderby p.Key
  select p.Key != 0 ? QSort(p) : p;
 return xs.Count() <= 1 ? xs : from p in part from e in p select e;
}
90デフォルトの名無しさん:2013/08/29(木) 00:37:55.01
長いし分かりにくいし糞だな
91デフォルトの名無しさん:2013/08/29(木) 10:50:57.86
C#の場合linqクエリはインテリセンスで補完効いて型安全だから
動的型のスクリプト言語をテキストエディタで書くのとは比較にならない
92デフォルトの名無しさん:2013/08/29(木) 12:21:00.18
C#のvarって静的型宣言だったんだな。初めて知った。
93デフォルトの名無しさん:2013/08/29(木) 14:10:00.50
>>86
Common LispはANSI規格で末尾再帰最適化は規定されてないので、一段下にしないと。
末尾再帰最適化をするかどうかは処理系依存で、実際にstack overflow出す処理系もある。
94デフォルトの名無しさん:2013/08/29(木) 14:42:32.14
linqクエリは
95デフォルトの名無しさん:2013/08/29(木) 17:04:26.14
>>93
【PHP,Python】スクリプト,バトルロワイヤル36【Perl,Ruby】
http://toro.2ch.net/test/read.cgi/tech/1374371254/444
> あと、Common Lispは末尾再帰最適化する処理系が多いのに、
> デフォルトで末尾再帰最適化がオフのCRubyより下に居るのも変だと思うよ
96デフォルトの名無しさん:2013/08/29(木) 20:29:49.04
>>89のやり方だと引数の要素数が1のときの場合分けは不要だな
return from p in part from e in p select e;
でいいはず
97前スレ367:2013/08/29(木) 21:51:06.12
>>87
Scalaの型推論がML未満なのはオブジェクト指向(部分型)との混在を
許す設計方針なのだと推測していますが、やや甘い判断なのかもしれません
あえて壁を設けるなら「パラメタ多相を完全に実現」のような感じなると思いますが、
Scalaだけを下げるだけのために壁を設けるのは、大人げないような気がします.....


>>89
他の言語のコード(>>72)では、条件分岐はソート終了判定と大小判定の2ヶ所だけです
それに対して>>89では4ヶ所ありますが、他の言語と同じように書き直せませんか?
このクイックソートというお題は、C#であれば素直に書き下せる程度のレベルですが、
LINQに無理にこだわることで、かえってコードの可読性を悪化させているように見えます
C#にとってLINQが大きな個性(特徴)であるのは理解しますが、TPOを考えませう

>>93
すでに>>95がレスされていますが、
前スレでメジャーなCL処理系では実装されてると反論があり、この位置にしています
あえて壁を設けるなら「TCOが言語仕様規定(=実装非依存)」ですが、細かすぎるかと思います
98デフォルトの名無しさん:2013/08/29(木) 22:11:34.37
static IEnumerable<T> QSort<T>(IEnumerable<T> xs)
 where T : IComparable<T> {
 var part = xs.Skip(1).ToLookup(e => e.CompareTo(xs.First()) < 0);
 return xs.Count() <= 1 ? xs
  : QSort(part[true]).Concat(xs.Take(1)).Concat(QSort(part[false]));
}
ほらよ
99デフォルトの名無しさん:2013/08/29(木) 22:17:15.45
小飼弾          1969年生まれ Jcode.pm(笑)の開発者
リーナス・トーバルズ  1969年生まれ Linuxの開発者
100デフォルトの名無しさん:2013/08/29(木) 22:19:21.54
Encode.pmは重宝しています
んで、>>99は何の開発者な訳?
101デフォルトの名無しさん:2013/08/29(木) 22:20:15.59
OrderByを許すならこれがベストかな
static IEnumerable<T> QSort<T>(IEnumerable<T> xs)
where T : IComparable<T> {
return xs
 .GroupBy(e => Math.Sign(e.CompareTo(xs.First())))
 .OrderBy(p => p.Key)
 .Select(p => p.Key != 0 ? QSort(p) : p)
 .SelectMany(p => p);
}
102デフォルトの名無しさん:2013/08/29(木) 22:35:02.90
他の言語で>>101スタイルの実装をしたらどうなるのか興味ある
Rubyで関数型っぽく書く場合には好まれるスタイルだと思うけど
103デフォルトの名無しさん:2013/08/29(木) 22:53:26.29
つうか、sqlがそもそもこの世界をダメにした張本人であり、
その流れを組むlinqも当然ながら糞
書いてる本人が本当は気づいてると思いたい
普通に書いた方が早いということに
104デフォルトの名無しさん:2013/08/29(木) 23:02:00.88
>>102
> Rubyで関数型っぽく書く場合には好まれるスタイルだと思うけど

は?なんでRuby?
こういうスタイルを知ったときの言語がたまたまRubyだったから知ったかぶりしてみただけ?
105前スレ367:2013/08/29(木) 23:03:10.30
>>102

def quicksort(xs)
  xs.group_by { |x|
    x <=> xs[0]
  }.sort { |(key1, _), (key2, _)|
    key1 <=> key2
  }.map { |key, val|
    if key == 0 then val else quicksort(val) end
  }.flatten
end

[ご参考]
・Matzにっき(2006-01-28)
  http://www.rubyist.net/~matz/20060128.html
106デフォルトの名無しさん:2013/08/29(木) 23:03:17.68
>>103
その批判はまさにActiveRecordのことだろ。

LINQって別にSQL書くためだけに使う言語じゃないぞ。
C#にはLINQオブジェクトとして使えるインターフェイスを実装したクラスが腐るほどあるんで、
これによって静的言語なのに、VSのインテリセンスと合わさってものすごく楽に書けるというのがLINQの本質。
ただ文字列に対してもインテリセンスでLINQのメソッドが大量に出てきてたまにうぜーと思うけど。

RubyにActiveRecordがついても対して革命は起きなかったつーかむしろActiveRecord専用の記法覚える手間が増えただけだが、
C#にLINQがついたことはまさに革命。
107前スレ367:2013/08/29(木) 23:21:53.21
>>98
了解です、C#が「式指向の壁」を越えたと判断し、
>>86の次回更新時に反映させることを約束します

なお、引き続き他の言語のコードも期待します
108デフォルトの名無しさん:2013/08/29(木) 23:24:59.72
>>107
スレタイ読める?
109デフォルトの名無しさん:2013/08/30(金) 05:05:51.77
集合操作はSQLで記述するのが手続き型の言語より断然簡潔
110デフォルトの名無しさん:2013/08/30(金) 08:41:14.72
>>109
少なくとも、Quicksortはそうじゃなかったみたいだね
111デフォルトの名無しさん:2013/08/30(金) 09:14:53.23
>>110
SQL版のQuicksortってどれですか?
112デフォルトの名無しさん:2013/08/30(金) 10:31:15.08
>>111
は?なんでSQLで手続きの記述って発想が出てくるの?
113デフォルトの名無しさん:2013/08/30(金) 11:08:45.64
>>97
> あえて壁を設けるなら「TCOが言語仕様規定(=実装非依存)」ですが、
それでいい。

> 細かすぎるかと
違うだろ。Rubyを壁の下に落としたくないからだろ?
114デフォルトの名無しさん:2013/08/30(金) 11:20:12.77
>>109
そんなことないだろ
例えばPythonでは和集合は単に A | B と書くし差集合は A - B と書く

select a from A union select b from B
のように書かないといけないSQLのどこが簡潔なのか
115デフォルトの名無しさん:2013/08/30(金) 13:33:30.78
>>114
直積は?外部結合は?
116デフォルトの名無しさん:2013/08/30(金) 13:48:55.02
>了解です、C#が「式指向の壁」を越えたと判断し、
こいつ何様なんだよw
ボクちゃんの判断はスゴイんだぞぉーってかw
117デフォルトの名無しさん:2013/08/30(金) 14:15:49.00
>>115
直積は単に [(a,b)|a<-A, b<-B] とか A.product(B) とかだろ

外部結合は一般的な集合演算ってよりは関係代数、しかも関係代数から見ても
異端の存在じゃん
118デフォルトの名無しさん:2013/08/30(金) 14:25:11.38
SQLは、selectionやprojectionが不要なとき(集合全体を扱っているとき)も常に
selectを書く必要があるのが冗長
119デフォルトの名無しさん:2013/08/30(金) 15:27:32.68
ごく単純な処理なら手続き型で書いてもいいんじゃない
SQLでも正規表現でも
120デフォルトの名無しさん:2013/08/30(金) 17:10:21.09
SQLより数式(から輸入した演算子や表記)の方がシンプルで好きだ
121デフォルトの名無しさん:2013/08/30(金) 19:09:26.34
>>105
def qsort(xs)
xs.group_by{|e| e <=> xs.first}
.sort_by{|k,v| k}
.flat_map{|k,v| k.zero? ? v : qsort(v)}
end
122デフォルトの名無しさん:2013/08/30(金) 19:36:26.20
どうせならsort_byのところも
qsortに置き換えたら良いのに
123デフォルトの名無しさん:2013/08/30(金) 21:09:23.46
qsortの実装にsortを使う茶番
124前スレ367:2013/08/30(金) 21:30:07.87
>>113
既にTCOの壁があるのにあえて壁を細分化したいのなら、
型推論の壁も細分化しないと不平等でしょうね
結果的にはScalaを下げるために壁を設けることになりますが....
125デフォルトの名無しさん:2013/08/30(金) 21:42:31.83
>>123
もともと簡潔な記述のためにとんでもなく無駄な処理をしているのだから
今更3要素のソートくらいでガタガタ抜かすな
126前スレ367:2013/08/30(金) 21:55:07.00
>>72の記事にあるPythonコードで気になった点がある
関数内関数宣言の代わりに「ラムダ式を入れ子にした」以下のコード:
  lambda pivot = xs[0]:
    (
      lambda (littles, bigs) = partition(xs[1:], lambda x: x < pivot):
        quicksort(littles) + [pivot] + quicksort(bigs)
    )()
  )()

この箇所、できるのなら以下のように書きたかったが、
(構文としては正しいけれど)実行時に変数 pivot が未定義エラーとなってしまう
これは局所変数宣言をラムダ式の仮引数のオプション式で代用している為
  lambda
    pivot = xs[0],
    (littles, bigs) = partition(xs[1:], lambda x: x < pivot): # この行で実行時エラー
        quicksort(littles) + [pivot] + quicksort(bigs)
  )()

ところが>>72の記事を見ればわかるように、Python以外の言語は(ラムダ式を入れ子にせずとも)
すべて1つのラムダ式内で変数 piviot/littles/bigs を「何の苦もなく」宣言できる

>>113
もし壁の細分化にこだわるなら、「ラムダ式の壁」の細分化も賛同してくれますよね?
127前スレ367:2013/08/30(金) 22:01:28.01
>>126について、細部を訂正

・各コードの最終行 ")()" は不要なので削除

・中盤にある「オプション式」を「デフォルト値の評価式」に変更
128デフォルトの名無しさん:2013/08/30(金) 22:06:44.06
http://www.h6.dion.ne.jp/~machan/misc/FPwithRuby.html
こんなの翻訳しちゃう人が公正な判断なんてできるわけ無いでしょ
129デフォルトの名無しさん:2013/08/30(金) 22:09:39.74
部分コピーが大量に作られるゴミ実装が多いので
シーケンスの遅延評価の壁も必要ですよね
130前スレ367:2013/08/30(金) 22:52:47.47
>>106
Ruby使いの一人から見たLINQ:

・RubyならEnumuerable(列挙可能)をメソッドチェーンで繋げば、
 LINQと同じことができるよね(>>105で実証)

・LINQを初めて知った人であれば>>89,101が魔法の呪文に見えて感動するかも
 しれないけど、LINQってそれほど最先端の技術という訳じゃないんだよなあ
 たとえば>>105のMatzにっきは2006年だし、そこでは効率の問題が指摘されている
 そして、その課題は(Ruby1.9のEnunuratorを経て)Ruby2.0のEnumuerable#lazyで解決を見た
 RubyはLINQを否定する気は無く、逆に強く意識して進化しているような気がする

  Ruby 2.0 メモ: Lazy と LINQ とループ融合
    http://www.oki-osk.jp/esc/ruby/20-lazy.html#5

・同様に、ActiveRecordもLINQの影響を受け、LINQ風の問い合わせ式を
 メソッドチェーンで記述する Arel へと進化をとげた

  第43回 Rails 3を支える名脇役たち その1 - Arel -
    http://gihyo.jp/dev/serial/01/ruby/0043

・どちらにしても、Rubyでは「LINQ式」のような大きい言語仕様追加は必要とされていなかった
 これは、Rubyという言語の強い柔軟性(ただしLisp族には負けるが...w)を実証していると思う

>>102は何か勘違いしているようだけど、RubyのメソッドチェーンでLINQ風の
 クイックソートは「書ける」が(>>72と比較すると)「読みづらい」から好まれない
 何とかとハサミは使いようという言葉があるように、
 メソッドチェーンもそれが効果的な場合には積極的に使うけど、
 そうでなければ無理して使うべきではないと考える
 >>105は好ましくないRubyコードで、同様に>>89,101は好ましくないC#コードだろう
131デフォルトの名無しさん:2013/08/30(金) 22:56:15.14
遅延評価にする場合、
・Ruby2.0, Scala, C#あたりは問題なし
・2.0未満のRubyは絶望的
・JavaScriptはリストの連結などをyieldで実装し直す必要があり
 多くの実装で動作せず式指向()の条件も満たさなくなる
・Pythonはitertoolsで連結とreduceを置き換えればいけそう
こんな感じかな?
誰かコード書いてくれ
132前スレ367:2013/08/30(金) 23:01:51.58
>>130の先頭部を訂正

X: RubyならEnumuerable(列挙可能)をメソッドチェーンで繋げば、
O: RubyならEnumuerable(列挙可能)なオブジェクトをメソッドチェーンで繋げば、
133前スレ367:2013/08/30(金) 23:10:32.64
>>131
では、まず簡単なお題で>>128(w の「自然数の2の倍数から構成されるシーケンス」から:
以下はRub2.0のコード

(1..Float::INFINITY).lazy.map { |x| x * 2 }.take(10).to_a
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
134デフォルトの名無しさん:2013/08/30(金) 23:15:05.08
>>130
そんなに読みづらいか?
そう不自然なことはやってるわけでもないと思うけどな
まあkey==0のときの場合分けだけはちょっとアレだが、
見た目が異質だから理解に時間が掛かるだけだろ
135デフォルトの名無しさん:2013/08/30(金) 23:15:18.35
>>126
式志向の話をしてるんだろ
それなら、lambdaが問題なんじゃなくてlet式が無いのが問題
let式が無いからlambdaで代用するしかない

同様にletの無いRubyのコードもJavaScriptのコードも
Lispで言ったらprogn/begin相当の、ずらずら文を並べていて
つまりそれらの文が逐次的に実行される、その順序性に依存した
手続き的なコードになってるだろ
「式志向的」とは言えないな
136デフォルトの名無しさん:2013/08/30(金) 23:16:14.22
LINQにはletがあるのは偉い
137デフォルトの名無しさん:2013/08/30(金) 23:30:49.14
関数型言語から見たらマジうんこなのに
必死になって頑張ってる姿は哀れ
138前スレ367:2013/08/30(金) 23:33:35.13
>>135
式指向の壁とは無関係な、別の話題だよ
式指向については、JavaScriptの三項演算子やPythonのif式であっても
クイックソートは「実装できる」という客観的な結論になって終わった、と思っている

今回は「ラムダ式(内部で局所変数宣言ができる)」という、ラムダ式の壁を細分化する些細な話
実現方法は、言語の個性に応じて最適なものを選択すればいい
たとえばHaskellならwhen節、SMLならlet式、Rubyならブロック、JSなら関数宣言がある

ところが、ナゼかPythonのラムダ式にはそれが欠けているから
「ラムダ式を入れ子にする(>>126上段)」というテクニック(魔術?)が必要になる
もし同じインデントベースなHaskell風の構文を導入すれば、以下みたくなってステキなのに....
  lambda:
      quicksort(littles) + [pivot] + quicksort(bigs)
    where:
      pivot = xs[0]
      (littles, bigs) = partition(xs[1:], lambda x: x < pivot)
139デフォルトの名無しさん:2013/08/30(金) 23:42:42.92
where節は副作用のある言語じゃ無理
140前スレ367:2013/08/30(金) 23:52:28.07
>>134
C#のLINQにしてもRubyのメソッドチェーンにしても、
最初の分類操作(C#のGroupBy, Rubyのgroup_by)の返す値が、
より小さい(<)/等しい(==)/より大きい(>)を要素とする
列挙可能(enumerable)な列(sequence)であることを前提にしている

しかし、これは数学的直感では列ではなく「三つ組(triple)」を意味しているはずだ
そして組をその要素の大小関係でソートするというのは、数学的直感では有り得ない

だから、読みづらいと思う
もちろんこれは(自分の)主観であって、慣れで解決できる話かもしれないけどね....
141デフォルトの名無しさん:2013/08/30(金) 23:55:45.41
数学に失礼
論理的に喋れよ
142前スレ367:2013/08/30(金) 23:58:05.86
>>139
では、副作用のある、言い換えると破壊的代入やI/Oも受け付けるSMLに習って、
let式を導入するとか:
  lambda:
    let:
      pivot = xs[0]
      (littles, bigs) = partition(xs[1:], lambda x: x < pivot)      
    in:
      quicksort(littles) + [pivot] + quicksort(bigs)

それともRubyに習って、ブロッ.............(以下略)
143デフォルトの名無しさん:2013/08/31(土) 00:01:15.43
Pythonのlambdaがウンコなのは、まあその通りだと思うのだけど、


それはそれとして、そんなダラダラと長い無名関数は
関数型言語使ってても書かないけどな
読みにくいじゃん
なんか関数型言語がdisられてる印象を受けるわ
144デフォルトの名無しさん:2013/08/31(土) 00:10:41.89
それに、whereやletは名前を束縛するのに使う訳だけど、
しょーもない変数は名前束縛するのに関数は名前束縛しないとか、
誰得のプログラミングスタイルなんだよって感じ
Rubyってそうなの?
145デフォルトの名無しさん:2013/08/31(土) 00:12:46.35
>>140
タプルの特定位置の要素でソートするのがあり得ないと?
自分で何言ってるか分かってるの?
146デフォルトの名無しさん:2013/08/31(土) 00:39:46.24
>>140
group byの結果は ( (<), (=), (>) ) ではなく
( (-1, (<)), (0, (=)), (1, (>)) ) だ
(<)/(=)/(>)の要素数はそれぞれ異なるが、このような構造を単に
( (key, val), (key, val), (key, val) )の形のシーケンスと見做して
keyでソートするというようなことはプログラミングでは決して珍しくないと思うし
君のコード見てもこんな構造あるんじゃないの?
147デフォルトの名無しさん:2013/08/31(土) 00:39:53.65
>>138
いやだから、JavaScriptやRubyのように
無名関数の中でダラダラ「手続き的な」逐次実行文を記述できることが
なぜ「関数プログラミング」の適正につながるの?
相変わらずlambdaが問題なんじゃなくてletが欲しいだけにしか聞こえないんだが
148デフォルトの名無しさん:2013/08/31(土) 01:04:59.32
>>142
letの後ろとinの後ろの:は冗長だろ
lambdaの:は引数リストとbodyを区切るのに必要だけど

lambda x: let fx, gx = f(x), g(x) in ...
でいいし、Schemeのlet*みたいな順序性が欲しいときは
lambda x: let fx = f(x) and gx = g(x) in ...
とかでいい
149デフォルトの名無しさん:2013/08/31(土) 01:08:10.22
っていうか、inはもともとPythonの予約語で別の機能があるからダメだな
150デフォルトの名無しさん:2013/08/31(土) 10:23:16.34
lambdaは名前が不要だから良い
同じ理由でwhile,for,break,continueも良い
この良さは関数型で説明できないから関数型はどうでもいい

式指向だろうがなんだろうがletをダラダラ並べて無駄な名前を定義したらダメ
151デフォルトの名無しさん:2013/08/31(土) 10:54:14.01
そもそも、quicksortの実装をしようとしているのに、sortを使うのは
やはり反則感が否めないな
しかも本当に並び替えのところで使うわけだし
152デフォルトの名無しさん:2013/08/31(土) 11:46:25.94
lambdaで再帰するとスコープが難しいんだよな
無名関数じゃなくて無名オブジェクトがあればselfを使えるけど
153デフォルトの名無しさん:2013/08/31(土) 12:14:20.63
>>150
名前を定義しないスタイルならHaskellのポイントフリー最強
154デフォルトの名無しさん:2013/08/31(土) 12:58:05.42
名前は要らんけど時間や場所のイメージは必要だぞ
さっきのあれをここで使うとか
ポイントフリーでは時間や場所を想像できない
155デフォルトの名無しさん:2013/08/31(土) 13:03:32.77
などと意味不明な供述をしており
156デフォルトの名無しさん:2013/08/31(土) 17:24:59.34
じゃあexcelは名前を使わないが場所を使うってのは分かるよね
名前を使わないだけで最強と思うのは甘い
157デフォルトの名無しさん:2013/08/31(土) 17:28:23.93
excelはセルに全部名前ついてて
その名前で参照できるじゃん
名前を使わないどころか、名前束縛しまくりですわ
158前スレ367:2013/08/31(土) 17:51:02.81
>>146
group byの結果が ( (-1, (<)), (0, (=)), (1, (>)) ) という対リストであるのは分かるし、
分かったからLINQのコード(>>101)をRubyへ書き換える(>>105)ことができた
そして、こういったシーケンス操作はありふれたものだ(=珍しくない)し、自分もよく使う

ただし、何度も述べている(>>97中段, >>130最下段)ように、
  「クイックソートというお題に限れば」
>>98のC#コードや>>72の記事内のRubyコードのほうが、
そのアルゴリズムを素直かつ簡潔に表現しているエレガントなコードだと考える
わざわざLINQ(C#)やメソッドチェーン(Ruby)を使うまでもない

LINQやメソッドチェーンには、それを用いることでエレガントに解けるお題が数多くあると思う
しかしながら、今回の「クイックソートというお題に限れば」そうではなかった、だけのこと


また対(key, val)について、そのキーは「より小さい/等しい/より大きい」という
排他的関係を意味しているが、C#やRubyでは「たまたま」-1/0/1 という
大小関係のある(=comparableな)整数値を割り当てている
ただし、そもそもの意味としては排他的関係でしかないのだから、
データ型について厳密な言語、たとえばSMLでは以下のような直和型として定義される
  datatype order = LESS | EQUAL | GREATER
当然、これら型構成子 LESS/EQUAL/GREATER に大小関係は存在しないからソート不可であり、
結果としてLINQコード(>>101)の考え方(=アルゴリズム)はSMLには適用できないことになる

つまり特定の言語(ここではC#とRuby)に依存するアルゴリズムよりも、
依存しないもののほうが、優れていると思う
159デフォルトの名無しさん:2013/08/31(土) 18:20:27.38
ソート関数がkeyやcmpのような比較用関数を引数に取ることにすれば
SMLにも適用できますがな
160前スレ367:2013/08/31(土) 18:33:53.48
>>147
まず、タイポを修正しておこう
 X: なぜ「関数プログラミング」の適正につながるの?
 O: なぜ「関数型プログラミング」の適性につながるの?

では、本題だ
Python/JavaScript/Rubyは非関数型言語(=命令型言語, 手続き型言語)であり、
それらの代入の意味が「メモリの書き換え」であり、
これが関数型言語の代入の意味「値を名前に束縛する」とは異なることも事実

これらを理解した上で、非関数型言語でも代入操作として
「初期化は許すが、再代入(=破壊的な書き換え)は禁止」というスタイルで
関数型言語の代入を模倣しようというのが、「非関数型言語による関数型プログラミング」の発想
詳しくは、>>128の記事を参照のこと

そして、この関数型プログラミングの発想は、すでに前スレで示されていて、
その発想そのものへの批判は一切無かったと記憶しているし、
実際に様々な非関数型言語によるクイックソートのコードのどれも、そのスタイルで書かれていた
だから、たとえ

  > 無名関数の中でダラダラ「手続き的な」逐次実行文を記述

していたとしても、前記の代入意味論の解釈に従っていれば、
その「関数型プログラミングへの適性」を損なうものではないと考える
161デフォルトの名無しさん:2013/08/31(土) 18:42:59.82
関数型言語の適正の話を続けるの?
流石に同じ続きすぎて飽きたんだけど...

まだクイックソートの話を続けるなら、
in-placeでソートを行うコードを書いてほしいな
そっちの方が効率良いんだから
162前スレ367:2013/08/31(土) 18:48:05.58
>>159
SMLの標準関数sortは、比較関数を引数に取ることになっていますよ

 val sort : ('a * 'a -> order) -> 'a list -> 'a list

問題は、比較関数 order * order -> order を書くのが面倒だってこと
たとえば、こんなコードになる

fun comp LESS LESS = EQUAL
|  comp LESS EQUAL = LESS
|  comp LESS GREATER = GREATER
|  comp EQUAL LESS = LESS
|  comp EQUAL EQUAL = LESS
|  comp EQUAL GREATER = GREATER
|  comp GREATER LESS = GRATER
|  comp GREATER EQUAL = GREATER
|  comp GREATER GREATER = EQUAL

こんなコードの積み重ねであっても、>>72の記事内にあるSMLコードより美しいと思う?
163デフォルトの名無しさん:2013/08/31(土) 18:53:30.55
fun key LESS -> -1
| key EQUAL -> 0
| key GREATER -> 1

があれば良いがな

ていうか、datatype order って型名なのに順序が定義されてないことが驚きだわ
ウンコすぎる
164デフォルトの名無しさん:2013/08/31(土) 19:46:21.81
>>160
言ってることがよくわからんなぁ

束縛ってのは値を名前に対応付けるという意味しかないから
単一代入かどうかは問わないし、再束縛とミューテーションも違う
参照型ベースの言語ではCのような言語とは値の持ち方が違って、
再束縛では紐づけが変わるだけで実体の値が書き換わる(ミューテーション)
わけじゃないし、そもそもPythonの言語仕様とかで思いっきりname bindingsという
用語を使ってるだろ
http://docs.python.org/3/reference/executionmodel.html

それに、Lisp/Schemeとか普通にsetf/set!とか使って破壊的代入できるけど
letあるじゃん
まあletがない言語でpoor man's functional programmingをしようみたいな
涙ぐましい話なのはなんとなくわかったけど
165デフォルトの名無しさん:2013/08/31(土) 20:47:45.04
>>163
intで実装すればこの問題が解決するのは事実
しかしその事実を>>158は「たまたま」だという
偶然の事実には依存しないほうが優れているという

ここで気になるのは、「優れている」という意見それ自体は偶然ではないのか
事実を偶然といい、人間の意見は偶然ではないというのか
人間はそんなにえらいのか
166デフォルトの名無しさん:2013/08/31(土) 21:36:29.34
>>158
> つまり特定の言語(ここではC#とRuby)に依存するアルゴリズムよりも、
> 依存しないもののほうが、優れていると思う

これまで散々、○○言語では(367の望む書き方で)書けないってケチつけてたくせに、
自分の贔屓する言語で書けない場合は書き方にケチつけんのかよ
本当に367はダブスタの糞野郎だな
167前スレ367:2013/08/31(土) 22:13:43.25
>>164
関数型言語において、束縛ってのは「値を名前に対応付ける」という意味しかないから、
再束縛では「(新たな環境内で)別の値を同じ名前に対応付ける」だけで、
実体の値が書き換わるわけではない.... ここまではOKだと思う

そして(Pythonを含む)手続き型言語における束縛とは、(値を名前に対応付けるのではなく)
「実体(=値)への参照を名前に対応づける」ことになる
結果として、手続き型言語の再代入では(関数型言語における再束縛ではなく)参照先の実体を
書き換えることになり、それを一般には「破壊的代入」と呼ぶ
以下はPython言語リファレンスからの引用:
  名前 (name) とは、オブジェクトを参照するものを指します。

同じ「束縛(binding)」という単語が関数型言語と手続き型言語とでは
別の意味(「値」と「値への参照」)を指すというだけで、何も難しい話は無いと思うがね
168デフォルトの名無しさん:2013/08/31(土) 22:20:49.48
>>167
>手続き型言語の再代入では(関数型言語における再束縛ではなく)参照先の実体を
>書き換えることになり

は?
参照先の実体を書き換えるってのは一体何のことを言ってるんだ?
PythonやRubyやJavaScriptで、
x = X
y = x
x = Y <- 再代入
とかやったとして、xが指してたX(実体)はなんも書き換えられないだろ
一体何が言いたいんだ?
シンボルテーブル上のxで紐づいているものがYに変わっただけで
破壊的更新がされたのは実体ではなくシンボルテーブル、つまり環境だ
169前スレ367:2013/08/31(土) 22:46:45.82
>>168
>破壊的更新がされたのは実体ではなくシンボルテーブル、つまり環境だ

そのとおりだね
そして、その(シンボルテーブル上の)シンボルを、変数と呼ぶ
関数型言語では新たな環境上で新しい束縛が生まれるのに対して、
手続き型言語では同じ環境(シンボルテーブル)上の(名前と束縛された)参照を書き換える
170デフォルトの名無しさん:2013/08/31(土) 23:22:32.33
「実体を書き換える」とか言ってるから何のこっちゃと思ったが
言いたいことは分かった

環境を書き換えずに新たな環境を作り外の環境の重複した名前を隠すのと
現在の環境を書き換える差を言いたかったんなら、そう言ってくれ
letはlambdaの構文糖で、新たな環境を作るから、当然そういう動きになる

上の話に戻るが、「lambda式の壁」よりも「let式の壁」のほうが実情に
沿ってるんじゃないのか?
RubyがLispやSchemeの下になるのが気に入らないかもしれんがなw
171前スレ367:2013/08/31(土) 23:39:19.97
>>170
>上の話に戻るが、「lambda式の壁」よりも「let式の壁」のほうが実情に
>沿ってるんじゃないのか?

では、let式だと特定しすぎるから(Haskellのwhen節でも意味論としてはlet式と同じ....)、
「局所宣言式の壁」も新たに候補として追加することを考えてみよう

>RubyがLispやSchemeの下になるのが気に入らないかもしれんがなw

もともとLisp族は関数型言語でRubyは手続き型言語なのだから、
その間に何らかの壁が存在する事実に関して、何ら不満はありませんよ.....


で、こちらも前の話に戻るけど、
(たとえ代入の意味が手続き型であったとしても)「ラムダ式の本体で局所変数を宣言できる壁」は
相変わらず存在し続けているのだけれど、それは了解してもらえますかね?
Pythonが同じスクリプト系言語であるRubyやJavaScriptの下になるのが、
気に入らないかもしれませんけどねw
172デフォルトの名無しさん:2013/09/01(日) 00:21:00.97
>>171
その壁はletが無い言語では
「lambdaのbodyにおいて手続き的な逐次実行文を許容するかどうか」の差だろ
C#あたりだと、式形式と文形式のlambdaという形で構文が分かれている

あくまで「自分は」手続き的な逐次実行のために使うんじゃなくて
letの代用に局所変数を使いたいがためにその機能が欲しいんだ、と
言いたいかもしれないが、「実際には」上のような違いだぞ

局所変数が使えない実用的な言語は存在しないが
なぜ「lambdaの中の局所変数」にそこまでこだわるのかも意味不明だな
Pythonは関数内関数を普通に提供していて、もちろんそこでは局所変数が
使える訳だが
173デフォルトの名無しさん:2013/09/01(日) 00:26:36.07
>>171
>では、let式だと特定しすぎるから(Haskellのwhen節でも意味論としてはlet式と同じ....)、
>「局所宣言式の壁」も新たに候補として追加することを考えてみよう
Haskellにletあるのにwhereもあるから他の言語でも似た文があればいいってか?
散々式傾向だの抜かしてたくせに何抜かしてるんだ?
お前の今までのクソみたいな屁理屈撤回してから言えよ
174前スレ367:2013/09/01(日) 00:59:36.56
>>174
いくら「主観的」なPython擁護の理屈を並べても、
「ラムダ式の本体で局所変数を宣言できる壁」が存在する事実は変えられないよ
他の言語では存在するのが当たり前すぎるほど当然な機能なのに、Pythonには欠けているから、
クイックソートをラムダ式で書き直そうとすれば「ラムダ式を入れ子にする」しかなかった
これは>>72の記事で示したコードで実証された(>>126,127)

もしPythonがこの壁を越えていると主張したいのなら、
(式指向の壁を越えた時と同様に)それをクイックソートのコードで示せばいい
もしもPythonで「1つのラムダ式内で変数 piviot/littles/bigs を宣言(>>126)」したコードを
示せたのなら、壁が存在しないことは「客観的」に実証されたことになる
175デフォルトの名無しさん:2013/09/01(日) 01:14:33.40
>>174
いやだから、できないのは分かってるが、そもそも
なんでそこまで「lambda内のローカル変数定義」にこだわるのか分からんというか……
そこまで重要性高いか?
そもそも>>72に関数型言語のHaskellやSMLの例でもPartitionの下請け関数に
whereやletでgとか名前つけてるじゃねーか

lambdaじゃ一般には再帰したければYコンビネータでも使うしかないし
実際問題として、関数型言語だってそんなにダラダラlambda式使わないだろ
カリー化があれば不要なこと多いしな
176デフォルトの名無しさん:2013/09/01(日) 01:27:00.91
要は、壁なんてのはいくらでも恣意的に作れるのであって、
代数データ型の壁とか、入れ子関数の壁だとか、ファーストクラス関数の壁とか
演算子=関数の壁とか、色々ありえるわな

lambda内ローカル変数が重要だといいたいのなら、それがないことが
どれだけ重大なことであって、具体的に何ができなくて困るのか示せよって話だ
177デフォルトの名無しさん:2013/09/01(日) 03:35:56.32
前スレ367は
束縛の意味(なぜ「束縛」なのか)わかってないな
178デフォルトの名無しさん:2013/09/01(日) 09:46:59.80
>>166
結局、クイックソートの実装に適した道具がライブラリに"たまたま"あるかどうかの勝負になってたもんな
今更ライブラリのたまたまな仕様に依存するなとか頭おかしい
179前スレ367:2013/09/01(日) 10:51:48.71
>>175
>そこまで重要性高いか?

いや、重要性は低いと(個人的には)考えているよ

「lambda内のローカル変数定義」という壁が存在することは事実であり、
それは>>86へ追加する壁(=評価基準)の候補となることを意味する
ただし、(個人的には)他の壁候補と同様に、些細な事柄のように思う

>>176
>要は、壁なんてのはいくらでも恣意的に作れるのであって、

まったく、そのとおりだね
そして、そんな数ある壁候補から「関数型プログラミングへの適性」という観点で
(恣意的に)取捨選択したものを>>86に反映させている

で、上でも書いたように、(個人的には)他の壁候補と同様、
「lambda内ローカル変数」は採用に値しない(=捨てられる)些細な事柄だと思っている
180デフォルトの名無しさん:2013/09/01(日) 12:00:05.31
自分が大好きなRubyちゃんのTCOが否定されちゃったから
発狂して色んな言語の重箱の隅を突き出したのか
まじでカスだな
181デフォルトの名無しさん:2013/09/01(日) 12:02:41.57
自分で恣意的と言ってるんだからそんなもんでしょ
「俺の都合のいいように基準を選んでます」って最初っから公言してるじゃん
気に入らなければ構うな
182デフォルトの名無しさん:2013/09/01(日) 12:10:46.29
いやいや、最初のころは「僕ちゃん客観的ですー」ってノリだったよ367は
183デフォルトの名無しさん:2013/09/01(日) 13:08:18.98
「ラムダ式を入れ子にする」のと
「lambda内のローカル変数定義」とで
本質的に何が違うと367が勘違いしてるのかがよく分からない。
184デフォルトの名無しさん:2013/09/01(日) 13:25:49.27
とにかく367の話はつまらんよ
相手にするべきじゃない

なんだかんだ言って、結局のところ
自分好みの記述が可能かどうかを基準に
優劣を云々してRuby厨として優越に浸りたいだけだから

ついでに、けなした言語のファン心理を煽って、
自分が使えそうな情報を引き出そうと
画策しているのがさらにむかつく
185デフォルトの名無しさん:2013/09/01(日) 19:07:14.70
ライブラリ暗記力の壁を感じる
その話題を必死に避けようとしてるのが逆に生々しい
186デフォルトの名無しさん:2013/09/01(日) 19:52:58.89
>>183
lambdaの引数でほぼそのまま代用できるよな
その上ローカルスコープに拘る意味もわからない
lambdaなんて書くときは外部のをキャプチャする事のが多いのに
187デフォルトの名無しさん:2013/09/01(日) 21:44:41.38
let x = 1 in 〜

(lambda x: 〜 )(1)
で代用できるけど、そもそもPythonでは関数内で関数が出来るのだから
後者のような読みにくい書き方をしてまでlambdaを使う意味は全くない
188デフォルトの名無しさん:2013/09/01(日) 22:41:47.53
PythonもRubyもゴミなのに、何を競っちゃってるんですかねーって感じ
189デフォルトの名無しさん:2013/09/01(日) 22:44:28.01
>>188
ゴミじゃない言語を挙げない時点でw
話についていけないからって負け惜しみ言ってんじゃねえよダッセー
190デフォルトの名無しさん:2013/09/01(日) 22:44:57.30
callfun = lambda a, b: b(a)

callfun(1, lambda x:
callfun(2, lambda y:

))

変数名は適当だが並べ方を変えるだけで読みやすいという例
191デフォルトの名無しさん:2013/09/01(日) 22:50:17.64
>>190
なにそれキモイ
192前スレ367:2013/09/01(日) 23:00:01.53
>>187
>let x = 1 in 〜
>は
>(lambda x: 〜 )(1)
>で代用できるけど、

代用できるから何の問題も無いと主張したいのなら、
>>72の記事にあるラムダ式版のPythonコードについて、
「ラムダ式を入れ子にせず」書き直したコードを示せばいいのではないかな?
そのコードを示すことが「ラムダ式の本体で局所変数を宣言できる壁」を越えたことの
実証であると、>>174でも書いているんだけどね.....

論よりコードだよ
193デフォルトの名無しさん:2013/09/01(日) 23:01:28.44
>>190
F#のパイプライン演算子とかは、まさに順序ひっくりかえすだけだよな
定義も
let (|>) x f = f x
とかだけ
194デフォルトの名無しさん:2013/09/01(日) 23:16:01.33
>>192
> 代用できるから何の問題も無いと主張したいのなら、
いや、そんなこと言ってないけど……
lambdaで無理やり代用しても「読みにくい」って書いたじゃん

日本語に不自由してるのか、藁人形論法か
195デフォルトの名無しさん:2013/09/01(日) 23:36:03.23
どーでもいいけど、lambdaの入れ子が邪道だったり変数宣言が必要というなら
>>86の階層の一番上のFPはどうなるの?
196前スレ367:2013/09/01(日) 23:44:33.08
>>194
本当に「読みにくい」だけなの?
もしも「読みにくても書ける」のなら壁越えに問題無いと考えているけど、本当のところは

 Pyhtonではラムダ式を入れ子にしなければ、クイックソートは「書けない」

というのが、真実なのでは?

もし書けるのなら、書いて示せばそれが客観性のある実証であると何度も言ってるのに....
他の言語では(少なくとも>>72の記事で挙げた言語すべてでは)何の苦もなく「書ける」んだけどなぁ

繰り返すけど、「論よりコード」だよ
197デフォルトの名無しさん:2013/09/01(日) 23:49:21.70
>>196
ねーねー、>>195にも答えてよー
198前スレ367:2013/09/02(月) 00:07:43.44
>>197(>>195)
そもそもFPには変数が存在しないから、壁自体が存在しない
だからFPは究極の関数型言語だと言われている

ただし、普通のプログラマがFPで実際にプログラミングができるのか?という点には
疑問があって、少なくとも自分にはFPでクイックソートを書ける自信が無い(=書けない)

究極という言葉で示されるように、FPが>>86の最上位に位置しているのは
「関数型言語の象徴」としての意味合いがある
だから、もしFPが>>86にとってふさわしくないという意見があれば、
FPを>>86から外すことを検討したいと考えている
199デフォルトの名無しさん:2013/09/02(月) 00:29:02.89
外さなくていいよ
壁を追加して矛盾が出てくるたびに弄ってたらキリが無いよ
200デフォルトの名無しさん:2013/09/02(月) 00:31:36.96
論よりコードってセリフ、ださいから二度と使わないで
201デフォルトの名無しさん:2013/09/02(月) 00:45:51.13
>>196
意味が分からんな
読みにくくても書ければ問題ないなら、なぜラムダの入れ子はダメなんだ?
ラムダを入れ子にしてはいけない、とでもいう謎の自分ルールがあるのか?

def partition(xs, p):
  return reduce(lambda ys, y: p(y) and (ys[0]+[y],ys[1]) or (ys[0],ys[1]+[y]), xs, ([],[]))

def quicksort(xs):
  return xs if len(xs) <= 1 else (lambda x, ls, bs: quicksort(ls) + [x] + quicksort(bs))(xs[0], *partition(xs[1:], lambda x: x < xs[0]))
202デフォルトの名無しさん:2013/09/02(月) 00:50:48.52
>>201
367にとってラムダの入れ子は関数型プログラミングに相応しくないんだろ
書いてて意味わからんが
203デフォルトの名無しさん:2013/09/02(月) 00:54:39.05
Rubyでブロック使ったらアウトだね
204デフォルトの名無しさん:2013/09/02(月) 01:01:58.69
>>198
> そもそもFPには変数が存在しないから、壁自体が存在しない

この論法に従うなら、
Cにはラムダ式が存在しないから、ラムダ式の壁自体が存在しない
ってことになるんじゃないですかねぇ...?
205デフォルトの名無しさん:2013/09/02(月) 08:20:24.72
変数が存在すると簡約が面倒臭い
簡約モデルより環境モデルが便利でしかも手続き型と異常に相性が良い
ふざけた壁をぶちこわすくらいの異常さ
206デフォルトの名無しさん:2013/09/02(月) 14:44:29.15
ES7では今のコミュニティの流れだと
いろんな数値型、型固定(guards)、演算子オーバーロード、真の非同期関数
などなどもろもろがバッサバッサ導入されていく方向だけど、それらについてどう思う?
www.slideshare.net/BrendanEich/value-objects
207デフォルトの名無しさん:2013/09/02(月) 16:20:21.74
>>206
jsはシンプルで柔軟なままにしておいて、大規模開発用に別言語を用意すればいいのにって思う
まあDartのコケっぷりを見るにそれは大変なことなんだろうけど
208デフォルトの名無しさん:2013/09/02(月) 16:57:26.46
使われる世界(Web)がみるみる広がっていくんだから、多少無理があろうと言語も拡張されなきゃならんだろうな。
ES6のスクリプト言語的進化はPythonとRuby、大規模開発向けはJAVAやC#が参考にされてるね。
ES7のそういうメタ的拡張はCやC++の名前がよく挙がってる。
ほかにもライブラリやフレームワーク的仕組みを標準に組み込んだり、必死に温故知新を勤めてるようだ。
互換性を残したまま言語をリフォームしたいみたいだね。
209デフォルトの名無しさん:2013/09/02(月) 19:27:34.89
JSが語るに耐えない言語になってないのは過去のバージョンへの互換性があるから。
平気で互換性切り捨てた言語で、これすごいよねって言われても、言語の長所としてパッとしないんだよね。
未だに論争抱えてる言語もあるし、他の言語と比較する前に、自分自身をどうにかしろよと思う。
210デフォルトの名無しさん:2013/09/02(月) 19:30:46.86
あれ?dat落ち多いな
211デフォルトの名無しさん:2013/09/02(月) 19:36:19.03
さっき30分くらい2ch落ちてた
212デフォルトの名無しさん:2013/09/02(月) 19:39:03.87
スレ情報がぶっ壊れてやがる……
生き残った言語スレに乾杯!!
213デフォルトの名無しさん:2013/09/02(月) 20:00:58.77
>>211
鯖の移転してるんだよ
DAT落ちした過去ログは消して、aliveなスレだけ残して移転だとさ
214デフォルトの名無しさん:2013/09/02(月) 20:07:52.33
てぇことは、alive なスレが 8 個しかなかった、と…。
どんだけ過疎ってんですか…。
215デフォルトの名無しさん:2013/09/02(月) 20:11:04.48
スレ一覧の更新が後回しになってるだけ。
現状はスレ一覧に、書き込みがあったスレだけ反映されてるから。

そのうち(運営が仕事すれば)、存在してたスレは全部戻るはず。
216デフォルトの名無しさん:2013/09/02(月) 20:16:21.81
僕の肛門も閉鎖されそうです><
217デフォルトの名無しさん:2013/09/02(月) 20:27:47.24
JavaScriptはゴミすぎるけど、CoffeeScriptは結構良いな
218デフォルトの名無しさん:2013/09/02(月) 20:32:22.16
JSとCSって括弧が省略可かどうかくらいしか違いないじゃん
219デフォルトの名無しさん:2013/09/02(月) 20:54:36.40
天才達が作ってるHaskellに比べたら
どの言語もヘボいんだけど…
220デフォルトの名無しさん:2013/09/02(月) 20:58:49.17
beforeunloadとやら、生まれて一度もちゃんと使われてるのを見たこと無い……
221デフォルトの名無しさん:2013/09/02(月) 21:00:59.93
Haskellって実在してるの?
222デフォルトの名無しさん:2013/09/02(月) 21:04:42.35
最初は天才が作ることが重要だけど、その後はコミュニティの活発さが大事だと思う
223デフォルトの名無しさん:2013/09/02(月) 21:18:29.53
>>214
意味が違うぞよ
過去ログは一旦全部消すんだそうだ
そして今残ってたスレはそのまま移転
しばらく●ビューアの機能はスレ立て専用みたいになっちゃう
224デフォルトの名無しさん:2013/09/02(月) 21:54:36.80
>>218
括弧の省略?
それを言うならせめてキーワードの省略や自動returnだろ
使ったこと無いのがバレバレだぞ
225デフォルトの名無しさん:2013/09/02(月) 22:04:06.95
>>224
キーワードの省略や自動return?
それを言うならアロー関数だろ
使ったこと無いのがバレバレだぞ

それにそれはES6にあるから言語としてのアドバンテージにならないし
それならCSじゃなくてTranspiler使ったほうが保守性も高くていいよねってことになる
226デフォルトの名無しさん:2013/09/02(月) 22:08:08.87
>>225
なんで急にES6の話をしだしたんだ?
普及もしてないのに
227デフォルトの名無しさん:2013/09/02(月) 22:08:18.60
>>206
劣化Schemeから劣化C++へダウングレードしてると思う
228デフォルトの名無しさん:2013/09/02(月) 22:09:05.32
>>226
ネットで聞き齧ったんだろ
2chがソースかもしれんな
229デフォルトの名無しさん:2013/09/02(月) 22:25:31.42
>>226
普及してないって、CSだってそのままでは動かないではないか。
急にというがこっちはそういうコンパイルの面とか無視して、最初から言語仕様のアドバンテージの話をしてるんだぞ。
それに多くの環境が対応しないと言語機能として認めないなんて言う方が急に変な話だと思うが。
実際現状FFの拡張なんかですごく便利に使えてるし、CSのアドバンテージにはならないよ。
230デフォルトの名無しさん:2013/09/02(月) 22:34:53.16
>>229
JavaScriptとCoffeeの比較の話をしてるのに
ES6の話をしだしてるからおかしいぞと

ES6がJavaScriptであるという話なら形は合うけど
JavaScriptとして普及はしてないから通じないぞと
わかった?
231デフォルトの名無しさん:2013/09/02(月) 22:38:48.61
ブラウザ用言語はWebは言語の質よりも
知識やコードが共有できるかどうかのが遥かに重要
じゃなきゃElmやってるわ
232デフォルトの名無しさん:2013/09/02(月) 22:43:32.14
>>230
わかったわかった。
『ECMAScript』と書かなかったコチラが大変悪うございました。
233デフォルトの名無しさん:2013/09/02(月) 22:46:55.96
駄目だなこりゃ。自覚がない。
お前は自分の主張を聞いてもらいたくて、他人に食いついてるだけだぞ。
234デフォルトの名無しさん:2013/09/02(月) 22:49:17.81
聞いてもらいたかったから食いついたし。
聞いてもらえないとわかったから引いた。
もういいだろw?
235デフォルトの名無しさん:2013/09/02(月) 22:49:34.30
>>232
そうだな
最初からES6と書かなかったお前が悪い
236デフォルトの名無しさん:2013/09/02(月) 22:57:57.99
JSだけじゃJS1.0かもしれないしね
最低を考えて発現するのは大人の常識だよ
237デフォルトの名無しさん:2013/09/02(月) 23:00:59.70
何この流れ
やっぱり規制解除は良くないね
238デフォルトの名無しさん:2013/09/03(火) 07:51:08.33
PythonのselfがJavaScriptのthisの2.5倍くらい気持ち悪い。
239デフォルトの名無しさん:2013/09/03(火) 08:02:53.97
慣れればself無しでは生きられない体になるよ
240デフォルトの名無しさん:2013/09/03(火) 08:04:41.42
日本で底辺ドカタやってる分には
Pythonなんて触りもしないので
気持ち悪くても問題無い
241デフォルトの名無しさん:2013/09/03(火) 08:13:00.07
気持ち悪くても使わなければ問題ないとか言い始めたらなんにも話にならんな
気持ち悪いのが問題なんだろ、実際廃止するか揉めたんだし
242デフォルトの名無しさん:2013/09/03(火) 08:16:20.84
正数を0で割ると無限大を返す糞処理系があるらしい
そんな電卓使えるわけ無いだろ
243デフォルトの名無しさん:2013/09/03(火) 08:20:43.62
>>241
まあ、デコレータとかあるし、廃止するの無理そうではある
244デフォルトの名無しさん:2013/09/03(火) 08:24:26.46
>>238
selfのおかげで常にオブジェクトの振る舞いを意識せざるをえなくなるので
手続きドカタが学習するのには向いてる
245デフォルトの名無しさん:2013/09/03(火) 08:31:03.52
>>244
ドカタにはオブジェクトなど意識させないのが正しい
どうせ理解できないのだから
246デフォルトの名無しさん:2013/09/03(火) 08:41:01.18
浮動小数点型の0は厳密に0ではないので除算で∞を返したほうが正しい
ここで言う∞も浮動小数点型では厳密に無限大ではないから問題ない
247デフォルトの名無しさん:2013/09/03(火) 08:43:36.60
じゃあ0/0は?厳密に0じゃないとか意味不明すぎる理屈なんだが頭大丈夫かよ
248デフォルトの名無しさん:2013/09/03(火) 08:44:28.82
無理矢理に擁護するために馬鹿の振りをするのやめて
糞なところは糞だと認めたほうが成長できると思うよ
249デフォルトの名無しさん:2013/09/03(火) 08:56:43.39
浮動小数点について、ちょっと勉強した程度の奴がよく罹る、
「浮動小数点表現は厳密じゃない病」だなw

まぁ0.0の他に-0.0もある、というあたりで普通じゃないことは確かだが。
250デフォルトの名無しさん:2013/09/03(火) 09:09:48.64
Infinityなんて返さず全部NaNでも良いけど、
Infinity返してくれた方がデバッグするときのヒントにはなる
ただし例外の無いC限定
251デフォルトの名無しさん:2013/09/03(火) 09:14:14.81
なんのための例外処理だって話だからな。本当にこれ作った奴は頭おかしい
252デフォルトの名無しさん:2013/09/03(火) 09:21:52.94
Infinityを返す仕様でも別にいい
問題は例外を送出させるという選択がないこと
やるにしても全て手動で実装する羽目になる
253デフォルトの名無しさん:2013/09/03(火) 09:21:58.12
数値型をブール型にキャストする時、0は偽、それ以外は正になるわけだが
0は厳密に0ではないのですべてBoolean(0)もtureを返す!
254デフォルトの名無しさん:2013/09/03(火) 09:38:17.23
一体何の話?
255デフォルトの名無しさん:2013/09/03(火) 10:00:46.24
頭おかしい、Infinityになった方が明らかに有用だろう。
嫌なら整数型を使えばいいだけだし。
256デフォルトの名無しさん:2013/09/03(火) 10:16:17.09
扱いが楽になるのは確かだが有用かは用途によるだろ
257デフォルトの名無しさん:2013/09/03(火) 10:22:18.32
>>252
feenableexcept使え
258デフォルトの名無しさん:2013/09/03(火) 10:26:08.94
>>257
スクリプトだとレイヤが違うから結局自分でハンドリングすることになる
259デフォルトの名無しさん:2013/09/03(火) 10:40:28.63
整数の0除算命令はCPUハードで例外フラグ出してくれるけど、
浮動少数だとソフトウェアで実装しなきゃならんからあまりにもオーバーヘッドが大きい。
これに文句をいうのは1言語の枠を超えてる。
260デフォルトの名無しさん:2013/09/03(火) 10:43:46.15
あくまで1言語仕様が糞だって問題だろ
261デフォルトの名無しさん:2013/09/03(火) 10:57:43.66
浮動小数点型の0除算例外は、ハードが確実にサポートしている保証がないので、
パフォーマンスの都合上、一言語にはどうしようもないということだろう。
それを議論するのは愚の骨頂……
262デフォルトの名無しさん:2013/09/03(火) 11:01:12.89
どうしようもあるだろ。クソ仕様だって認めてるだけじゃねーか
263デフォルトの名無しさん:2013/09/03(火) 11:13:54.13
ハードが確実にサポートしている保証がない→クソ仕様だって認めてるだけ

論理がおかしい
264デフォルトの名無しさん:2013/09/03(火) 11:16:44.97
クソ仕様なのは整数型が付けないって点で浮動小数点型に罪はないな。
問題あるなら何十年も変えられないはずがないし。
ひょっとすると>>206みたいな感じでそう遠くないうちに解決するんじゃね。
265デフォルトの名無しさん:2013/09/03(火) 11:26:29.47
そもそも途中の何処かで例外が起きるかもしれないようなロジック書いて
まとめて例外を拾って対処するという考え方がLLっぽくないと思う

動的型付け言語では入出力時に値をできる限り正規化するのが合ってて、
すぐすぐ例外という事にはしない方がいいんじゃないかな

それがクソだと思うのは文化の違いだと思うよ
そういう人の好きな言語とその好きな点を聞いてみたいね
266デフォルトの名無しさん:2013/09/03(火) 11:32:47.92
オブジェクトの等値評価が参照比較なのは不便だ!ってのと同じ香りがする
267デフォルトの名無しさん:2013/09/03(火) 11:33:59.94
例えば除算と余りは別の記号を使うだろ
実数の除算と整数の除算を別の記号にするのも珍しくない
型を増やさなくても記号を増やすだけで解決するよ
268デフォルトの名無しさん:2013/09/03(火) 11:36:04.66
>>265
引数のチェックは静的型でもするよ。
それともまさか暗黙の変換するほうが良いって発言?
269デフォルトの名無しさん:2013/09/03(火) 11:43:17.81
どうも流れが変だなと思ったら
どの場合でも0除算でInfinityになる方がいいと思ってる頭おかしいのがいるのか
270デフォルトの名無しさん:2013/09/03(火) 11:47:00.88
そんな奴いないと思うが、、、
271デフォルトの名無しさん:2013/09/03(火) 11:50:20.71
例外が出るべきか出るべきでないか
また例外が出る手段は要るのか
要るのならフラグがいいのか、ちゃんと型を整備するのがいいのか、演算子を増やすのがいいのか
っていう議論だよね?
272デフォルトの名無しさん:2013/09/03(火) 12:00:25.57
ぜんぜん違う。
スクリプト言語は糞か否か、それだけだ。
細かいことはどうでもいい。
273デフォルトの名無しさん:2013/09/03(火) 12:06:20.61
スレタイの言語よりもアセンブリの方がよっぽどスクリプト言語
274デフォルトの名無しさん:2013/09/03(火) 12:08:45.07
信号機の色の順番並みに不毛な議論だとは思わんか
275デフォルトの名無しさん:2013/09/03(火) 12:15:52.63
議論がいくら不毛でも弁証法的に考えれば有益な事もある
何かが得られるならそれで十分
276デフォルトの名無しさん:2013/09/03(火) 13:07:24.38
0除算で例外がでるのは整数型にそれを表現することが出来ないからしかたなくで
浮動小数点型ではNaNやInfinityとして表現出来るんだからわざわざエラーにする必要がない
277デフォルトの名無しさん:2013/09/03(火) 13:18:01.83
やっぱりおかしいのがいるじゃないか
278デフォルトの名無しさん:2013/09/03(火) 13:22:31.91
Nullable<T> とかで選択できればよい。
279デフォルトの名無しさん:2013/09/03(火) 13:22:56.07
そもそも「例外」という考え方自体が古いというか固い言語の考え方だと思う
現にLLでは例外処理構文は発達してないし、合ってない
280デフォルトの名無しさん:2013/09/03(火) 13:25:15.53
LLのが古い考えだろ。
281デフォルトの名無しさん:2013/09/03(火) 13:27:45.08
LLのが古い考えだからなんだというのだろう。
282デフォルトの名無しさん:2013/09/03(火) 13:31:42.97
例外を吐くべきかという視点はおかしくないか?
どんな言語でもIEEEの浮動小数点型採用してるのは吐かないというか、仕様的に吐いちゃいけないだろ。
スクリプト言語にまともな整数型を導入すべきかという議論にしよう。
283デフォルトの名無しさん:2013/09/03(火) 13:33:44.03
インタプリタ型言語の限界だろ
284デフォルトの名無しさん:2013/09/03(火) 13:34:04.91
まともな奴は最初からその議論をしてる
285デフォルトの名無しさん:2013/09/03(火) 13:43:13.95
>>276
>現にLLでは例外処理構文は発達してないし、合ってない
何を血迷ったことを言ってるんだ・・・
286デフォルトの名無しさん:2013/09/03(火) 13:45:16.24
してるのもあるが一般的にはJAVAと比べてチンケなもんだろ
287デフォルトの名無しさん:2013/09/03(火) 13:45:17.32
例外を「吐く」とか表現してるし
食わず嫌いなのかな
288デフォルトの名無しさん:2013/09/03(火) 13:47:54.80
例え食わず嫌いと感じたとしても、そこに突っ込む必要はないな
内容に突っ込むべきだろう
289デフォルトの名無しさん:2013/09/03(火) 13:50:06.97
>>288
内容も例外投げちゃいけないわけじゃないよね
投げない場合はそう表現するってだけで
290デフォルトの名無しさん:2013/09/03(火) 13:52:21.96
検査例外を導入してるのはJavaぐらいだし、
Javaの検査例外は失敗、というのがほぼ定評だろ。

それはそれとして、例外は最近の言語ならたいていある。
291デフォルトの名無しさん:2013/09/03(火) 13:53:01.60
「例外をはく」ってそんな変な表現だったのか…
292デフォルトの名無しさん:2013/09/03(火) 13:54:31.65
Python万歳!るびい死ねw
293デフォルトの名無しさん:2013/09/03(火) 13:55:25.00
きっと「例外処理構文が発達してない」を「例外処理構文がない」とミスリードしちゃったんだろうね……
294デフォルトの名無しさん:2013/09/03(火) 13:57:39.82
例外の動詞としてはやっぱ投げる、だろ
295デフォルトの名無しさん:2013/09/03(火) 13:58:48.62
JAVAのが失敗だっていうのは>>265のように
そもそもそんな頻繁に例外投げるのが時代遅れって言うことで
話の根底が矛盾してるな
296デフォルトの名無しさん:2013/09/03(火) 13:59:12.17
>>291
Webページにスタックトレース画面を垂れ流して平気でいる奴のセンスだ
297デフォルトの名無しさん:2013/09/03(火) 14:01:06.70
合ってないって部分に突っ込んでるんだよ
これで普段使ってないんだろうなと思った
298デフォルトの名無しさん:2013/09/03(火) 14:02:12.08
例外を吐くっていうのはログを吐くと同じようなものじゃない?
catchするとこまで考える投げる、受け取るの方が良くて、
そうじゃないのなら吐くで良いと思う。
299デフォルトの名無しさん:2013/09/03(火) 14:05:04.41
普段使ってないだろ!と非難してもなんにも意味が無いと思うよ
むしろそういうとこから喧嘩になるから荒らしと同じ
300デフォルトの名無しさん:2013/09/03(火) 14:07:22.04
LLでも少なくともPythonだと頻繁に使ってる
JavaScriptも最低でもparse系やJSONは使うし特に最新のAPIは投げまくる
PerlやRubyは知らない

>>299
すまない気をつける
301デフォルトの名無しさん:2013/09/03(火) 14:07:59.90
例外は「投げる」じゃね?
302デフォルトの名無しさん:2013/09/03(火) 14:13:35.04
吐くのはcore dump
303デフォルトの名無しさん:2013/09/03(火) 14:18:53.83
>>300
JSはそうは思わないな
例えばindexOfなんかで-1の代わりに例外投げられちゃたまらんでしょ?
最近で大きい仕様だと、イテレーターが値を返して、
例外が投げられて終了だと判断する方式から
終了状態を含むオブジェクトを返す方式になったし
その他にも、多くのAPIで例外よりも失敗コールバックを採用してる
非同期と例外が合わないってのも大きい
Node.jsではそれに対応できるAPIがあって、
標準の例外キャッチはもうかなり限定的にしか使わない
304デフォルトの名無しさん:2013/09/03(火) 14:23:31.20
JSで例外が起きる時は例えばnullのメンバにアクセスしようとしたとか
取り返しの付かなくてキャッチしても仕方ない時だと思う

逆にAPIでそうでもないエラーを出したい時は、コールバックの仕組みが良いと思う。
もしくは近いけどPromiseみたいなのとか、最近はそういう流れ
305デフォルトの名無しさん:2013/09/03(火) 14:28:31.52
確かにコールバックと例外の相性が悪いっていうのは、スクリプト言語あるあるだな。
306デフォルトの名無しさん:2013/09/03(火) 14:32:13.24
>>303
indexOfはちょっと意味がわからないからスルーしよう
Javaですらそういう仕様だ

最近のは少なくともブラウザのストレージ関係のAPIは平気で例外投げる
ただ確かに非同期コールバックと例外に関しては相性は悪いと思う
でもそれで例外を全てを否定する理由にはならない
domainだって必要だから対応してるんだし
307デフォルトの名無しさん:2013/09/03(火) 14:36:03.17
>>303
> 例えばindexOfなんかで-1の代わりに例外投げられちゃたまらんでしょ?

それは例えのレベルが低すぎる。
「検索結果が0だったこと」は業務フローで想定されている機能の一つなんだから、
そんなものを例外で投げるのは言語に限らず設計上の禁止事項だとあらゆる文献に書いてある。
例外設計の初歩的なレベルで口を酸っぱくなるほど注意されることだ。

> 最近で大きい仕様だと、イテレーターが値を返して、
> 例外が投げられて終了だと判断する方式から

これも例外設計の分野では有名すぎる「間違った例外の使い方」の一つ。
イテレータの終了判断に例外を使ってはいけません、というのは色々な文献が避けるべき例として取り上げてる。

つまり君が挙げた二例はいずれも例外設計の分野では既に「禁止事項」として有名すぎる話であり、
ゆえに「例外は使いにくいから例外は可能な限り使うな」という主張の根拠足りえない事例ということだ。
308デフォルトの名無しさん:2013/09/03(火) 14:42:52.13
>>265
例えばリスト構造を扱うクラスを作った時に、
インデックスで渡された数がリストの要素数をオーバーしてたらどうすんの?
例外吐かないで何を返すんだ?nullでも返すのか?
309デフォルトの名無しさん:2013/09/03(火) 14:44:10.35
ここで言う例外ってtry-catchとそれに対してのthrowのことだよ
そういう例外は扱いづらいし、スクリプト言語に合わないんじゃないかと言いたい
それにストレージ関係APIも普通にコールバックだよ
310デフォルトの名無しさん:2013/09/03(火) 14:47:00.24
>>309
>ストレージ関係APIも普通にコールバックだよ
いやいやいやいや
容量オーバーとかクオータ拡張とかdbアクセスとかの例外全部無視してるのか?
localStorageですら例外飛ばしてくるのに
311デフォルトの名無しさん:2013/09/03(火) 14:50:18.24
例外を使わないことは難しくないからねえ。
返り値をチェックして自分の想定外の値だったら「事実上の例外報告」として処理することはできる。
そうすれば例外を全て無視することもできなくはない。

そういう人からすると「例外なんて邪魔。いらない」って考えになるんだろう。哀れなり
312デフォルトの名無しさん:2013/09/03(火) 14:56:53.51
>>310
全部無視なんかしてないって
もしかして例外を撲滅しようみたいに聞こえた?
それで気分を悪くしたのなら謝るけど、つっかかりすぎじゃない?

localStorageの容量オーバーは例外投げられるけど他は無いはずだよ
IndexedDBとFileSystemでは無いはず
313デフォルトの名無しさん:2013/09/03(火) 15:00:56.46
自分が言いたかったのは両方、よく使うもので頻繁に例外が投げられちゃ敵わん
だから、デフォルトで0除算例外なんて起きなくていいんだってこと

例外で終了を判定するのは内部の例えばfor-ofとかの実装がそうなっていたから挙げただけで
実際にどうのとは言ってないよ
314デフォルトの名無しさん:2013/09/03(火) 15:02:09.08
>>312
http://www.w3.org/TR/file-system-api/#errors-and-exceptions
http://www.w3.org/TR/IndexedDB/#exceptions
これ以上はコード書く羽目になるのでこれで許して
315デフォルトの名無しさん:2013/09/03(火) 15:05:45.26
>>313
> だから、デフォルトで0除算例外なんて起きなくていいんだってこと

0除算は「不可能」。続行不能な計算なんだぜ?
それで例外吐かなくていいってのは、数値と文字列を足し算しても例外吐かなくていいってのと同義
どちらも続行不可能で数学的には未定義な処理なんだからさ
316デフォルトの名無しさん:2013/09/03(火) 15:06:35.40
>>313>>307へのレスね

>>314それはコールバックにエラーオブジェクトが渡される
さっきも言ったけど、throwがあってそれをtry-catch構文で受け取ることに否定的なんだよ
否定的ってだけで撲滅しようとは言ってない
念のためもう一度ね
317デフォルトの名無しさん:2013/09/03(火) 15:09:30.93
>>315
0除算が例外なのは、定義されてないから
もっと言えば、整数データのビット配列にはいい結果の状態を定義できないからだよ
浮動小数なら定義されてるからそれでいい
数学的にとは別の話だと思う
318デフォルトの名無しさん:2013/09/03(火) 15:17:16.78
数学的にできないことが、計算機の演算でできてしまうのは駄目でしょう。
その意味で、数学的な文脈と関連はあるよ。
319デフォルトの名無しさん:2013/09/03(火) 15:18:54.16
>>317
ゼロ除算を「定義」することはできるけど?
整数を表現するクラスにゼロ除算を表現する値を突っ込めばいいだけで
それをしないのは、数学にゼロ除算を持ち込むメリットがないからそうしないだけ
320デフォルトの名無しさん:2013/09/03(火) 15:22:55.50
じゃあ関連があるとして、そうすることでデメリットがメリットを上回ると思う理由は何?
321デフォルトの名無しさん:2013/09/03(火) 15:24:15.34
>>316それはコールバックにエラーオブジェクトが渡される
確かにlocalStorage以外は規格上全部ありそう
これはこちらの不勉強だったようなので謝ります
322デフォルトの名無しさん:2013/09/03(火) 15:27:06.82
どこで問題が発生したか特定できる。
323デフォルトの名無しさん:2013/09/03(火) 15:33:28.48
>>319
そんな屁理屈言ってないよ
現実的な話をしてる

宇宙はこうであるのが一番正しいと言っているのではなく
今の宇宙ではこうであった方が都合がいいのではと言いたい

>>321
まだ出たてのものだから仕方がない

>>322
それはメリットとして当然分かる
でもそういうのは数値型の種類とか、動的型付け言語の話まで関係してきて
結局「スクリプト言語」であるならば、言語の出来方や文化的に合わないんじゃないかと思う
324デフォルトの名無しさん:2013/09/03(火) 15:33:32.30
Javascriptでtry-catchなんか使ったことない
325デフォルトの名無しさん:2013/09/03(火) 15:37:05.56
>>324
parseInt
eval
326デフォルトの名無しさん:2013/09/03(火) 15:42:14.36
>>325
なにそれ使ったことないんだけど
327デフォルトの名無しさん:2013/09/03(火) 16:15:47.89
JSで何をtryしても一生例外なんて投げないで意味不明な実行結果になるだからcatchの意味がないな
328デフォルトの名無しさん:2013/09/03(火) 17:19:08.91
さすがにJSON.parseはtry囲んで使うだろ
329デフォルトの名無しさん:2013/09/03(火) 18:15:20.77
jQuery使ってるから、JSON.parseってやったことない
330デフォルトの名無しさん:2013/09/03(火) 18:26:26.13
関数型が副作用を避けるのと同じで
いわゆるフレームワークはreturnでデータを受け渡しするスタイルを避けるよね
returnが駄目ならthrowも駄目じゃないか
331デフォルトの名無しさん:2013/09/03(火) 18:44:24.75
避けてるんじゃなくて、単に待ちが使えないからコールバックを使うだけじゃね?
332前スレ367:2013/09/03(火) 20:52:39.99
>>201
>読みにくくても書ければ問題ないなら、なぜラムダの入れ子はダメなんだ?
>ラムダを入れ子にしてはいけない、とでもいう謎の自分ルールがあるのか?

ラムダ式の入れ子が好ましくない理由:

・おおざっぱな「関数宣言とはラムダ式を変数に代入したもの」という定義の元で、
 書き換え元(>>72)にある1つの関数宣言に対して2つのラムダ式を必要とし、複雑さが増す
 (厳密には関数再帰があるので上記は正しくないが、ここでは枝葉な事柄)

・一般にインデントは分岐や反復といったプログラムの制御構造を読みやすくするものだが、
 書き換え元にある変数 pivot と (littles, bigs) への代入文のインデントが揃わない

どちらの問題点も、Python以外の言語、少なくとも>>72で挙げた言語すべてでは、
「関数宣言とラムダ式を1対1に対応させ」、「代入文のインデントを揃える」ことは
何の苦もなく実践できる(JavaScriptについては、すでに>>72でコードを示している)

ただし、>>179で書いたように、これは主観的な意見であり、
>>86に追加する壁候補として採用するには、些細な根拠だと考えている
 
333デフォルトの名無しさん:2013/09/03(火) 21:09:02.19
ラムダ式はまだいいが配列内包の気持ち悪さが取れないのは何故?
334前スレ367:2013/09/03(火) 21:15:41.10
>>201
「ラムダ式を1つにする」という要望にコードで応えてくれてありがとう
まず、可読性を考慮して>>72のインデントスタイルと変数への命名を書き換えたものを以下に示す

def partition(xs, f):
return reduce(
lambda pair, x:
f(x) and (pair[0] + [x], pair[1]) or (pair[0], pair[1] + [x]),
xs, ([], [])
)


def quicksort(xs):
return xs if len(xs) <= 1 else (
lambda pivot, littles, bigs:
quicksort(littles) + [pivot] + quicksort(bigs)
)(xs[0], *partition(xs[1:], lambda x: x < xs[0]))


次に、要望を示す

・関数 partition について、条件分岐が(and と or の)2度使われている
 他の言語と同様に、1回の条件分岐で書き換えできないだろうか?(これは容易なはず)

・関数 partition について、>>72のアルゴリズム定義では部分リストを変数 Ys と Zs で表現している
 他の言語と同様に、変数 ys, zs を残したコードに書き換えできないだろうか?

・関数 quicksort について、入力リストの先頭要素 xs[0] へのアクセスが2度行われている
 他の言語と同様に、変数 ys, zs を残したコードに書き換えできないだろうか?
335前スレ367:2013/09/03(火) 21:18:42.65
>>334の最後の1行を訂正

X: 他の言語と同様に、変数 ys, zs を残したコードに書き換えできないだろうか?
O: 他の言語と同様に、先頭要素へのアクセスを1度だけとするコードへ書き換えできないだろうか?
336デフォルトの名無しさん:2013/09/03(火) 21:57:22.45
JavaScriptを最近よく書くようになったけど、そこまで悪い言語じゃなくね?
サクサク書けるし、開発環境もブラウザだけで下手なIDEより機能充実してるからお手軽。
undefinedとnullと0以外はtrueというのも好きだ。
ただ強いて言えば、一つのHTMLに多数の.jsを埋め込んで全て同じ階層で実行されるというのが嫌。
せめて名前空間みたいなものがあって、グローバルオブジェクトは基本的に名前空間.オブジェクトという書式でしか呼び出せないとかあれば。
あとはいまだにfor (var i=0; ....)のループを使うしかなかったりとかも難。

個人的には、Perl、Java、Objective-Cよりは全然好きだわ。
337デフォルトの名無しさん:2013/09/03(火) 21:59:09.86
>>336
いまさら
338デフォルトの名無しさん:2013/09/03(火) 22:01:07.18
Ruby使いの一人から見たゼロ除算論争について:

・Rubyでは、整数(Integerクラス)でゼロ除算があると例外 ZeroDivisionError を投げるが、
 浮動小数点(Float)でゼロ除算があると定数 Float::INFINITY を返す

・浮動小数点の振る舞いは、標準規格である IEEE 754 に従った実装によるもの

  Ruby 2.0.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Floatクラス
   http://doc.ruby-lang.org/ja/2.0.0/class/Float.html

・IEEE 754 実装は、もしIEEE 754に従う厳密な数式処理/数値計算システムを開発するのなら好ましい
 また、Ruby2.0では>>133のコードで示したように無限(無限数/無限シーケンス)を扱う方向で
 開発が進められており、この流れに沿った適切な判断だと思う(真実はRubyの中の人しか知らない....)

・もし整数と同じ振る舞いを望むのであれば、以下のようにメソッド Float#(y) をオーバライドするだけ

  class Float
    def /(y)
      if y == 0.0 then raise ZeroDivisionError else self / y end
    end
  end


結論:ことRubyに限れば、熱く論争するほどのトピックではない
339デフォルトの名無しさん:2013/09/03(火) 22:03:10.97
>>338を訂正
X: メソッド Float#(y) をオーバライドするだけ
O: メソッド Float#/(y) をオーバライドするだけ
340デフォルトの名無しさん:2013/09/03(火) 22:09:34.94
>>336
>あとはいまだにfor (var i=0; ....)のループを使うしかなかったりとかも難。

Array.forEach や Array.map ではダメなの?

あと、グローバルオブジェクトによる汚染問題については同感で、
(Java風の?)階層的な名前空間を構文として導入し、今のまちまちな記述が統一化されると嬉しい
341前スレ367:2013/09/03(火) 22:14:40.76
>>334のインデントがボロボロだったので、再カキコ

def partition(xs, f):
  return reduce(
    lambda pair, x:
      f(x) and (pair[0] + [x], pair[1]) or (pair[0], pair[1] + [x]),
    xs, ([], [])
  )


def quicksort(xs):
  return xs if len(xs) <= 1 else (
    lambda pivot, littles, bigs:
      quicksort(littles) + [pivot] + quicksort(bigs)
  )(xs[0], *partition(xs[1:], lambda x: x < xs[0]))
342デフォルトの名無しさん:2013/09/03(火) 22:54:03.63
>>333
配列内包の気持ち悪さって、具体的には何?
343デフォルトの名無しさん:2013/09/03(火) 23:34:36.19
JavaScriptは今で言うWebアプリが大したこと出来ないでしょ舐められてただけで
言語としては別に普通レベルに良い
344デフォルトの名無しさん:2013/09/03(火) 23:36:12.89
リスト内包が気持ち悪いとは俺は思わないが
日本人には語順が意味不明だし表現力もあまり高くないから嫌われるのはわかる
345デフォルトの名無しさん:2013/09/03(火) 23:44:49.50
すべてが式の言語なら自然だけど
本来文のforやifをまるで式のように使えるのは変だな
346デフォルトの名無しさん:2013/09/04(水) 00:16:16.07
キーワード使い回してるだけじゃん
347デフォルトの名無しさん:2013/09/04(水) 00:29:04.79
>>338
ちゃんと前スレ367って付けろよ。非表示にならないじゃないか!
348デフォルトの名無しさん:2013/09/04(水) 00:52:02.71
PythonはまだBooがあるが、RubyやPHPの重さはどうにかならんのかね。
こういうのってどこで決まるんだろう。
既発スタッフの技術力?
349デフォルトの名無しさん:2013/09/04(水) 00:57:46.40
>>334
注文の多いやっちゃな、それぐらい自分で書け

def partition(xs, f):
return reduce(lambda (ys,zs), x: (ys + [x], zs) if f(x) else (ys, zs + [x]), xs, ([], []))

def quicksort(xs):
return xs if len(xs)<=1 else (lambda pivot: (lambda littles, bigs: quicksort(littles) + [pivot] + quicksort(bigs))(*partition(xs[1:], lambda x: x < pivot)))(xs[0])
350デフォルトの名無しさん:2013/09/04(水) 02:30:30.57
あんなめちゃくちゃ仕様のJSより早く出来ないっておかしいよな
351デフォルトの名無しさん:2013/09/04(水) 11:07:40.39
言語を標準化するとライブラリは不安定化するが最適化が捗る法則
352デフォルトの名無しさん:2013/09/04(水) 12:29:42.10
JavaScriptがJAVAを参考にして「全部が式」としなかったことは吉か凶か。
353デフォルトの名無しさん:2013/09/04(水) 15:38:01.65
末吉くらい
354デフォルトの名無しさん:2013/09/04(水) 17:28:20.00
そろそろどの言語が最強か決めようぜ
355デフォルトの名無しさん:2013/09/04(水) 17:54:55.72
どの言語もほぼチューリング完全とかいうクラスに属して可能な事は変わらないはずだ。
356デフォルトの名無しさん:2013/09/04(水) 18:07:24.47
>>355
JavaScriptでメモリ内容を直接書き換える方法を教えてくれや
357デフォルトの名無しさん:2013/09/04(水) 18:37:03.14
チューリング完全なので、CでJSのインタプリタを作れる
インタプリタの中からJSが命令して外でCが実行する
Cが実行できることなら何でも命令できる
358デフォルトの名無しさん:2013/09/04(水) 18:40:58.15
>>357
「外」の処理系をJavaScriptで作りたいんやが
どうすればええんや?
359デフォルトの名無しさん:2013/09/04(水) 19:45:42.81
360デフォルトの名無しさん:2013/09/04(水) 19:49:12.70
>>350
最凶仕様のCより早くできないのはおかしいとでも?馬鹿すぎる
全知全能のプログラマにバグの管理を任せることで高速化してるだけ
361デフォルトの名無しさん:2013/09/04(水) 20:21:42.19
JSでCPUエミュしてその上で動くLinuxでCのコンパイル/実行できたし、そういうことでしょう
362デフォルトの名無しさん:2013/09/04(水) 20:23:53.42
型も曖昧でコンパイラに優しくないってことだよ
より最適化のためのヒントを付加できる言語がずっと遅いって、甘えだろ
363前スレ367:2013/09/04(水) 21:17:33.68
>>349
コードありがとう
>>334と同様、可読性を考慮してインデントを書き直した:

def partition(xs, f):
  return reduce(
    lambda (ys,zs), x: (ys + [x], zs) if f(x) else (ys, zs + [x]),
    xs, ([], [])
  )

def quicksort(xs):
  return xs if len(xs)<=1 else (
    lambda pivot: (
      lambda littles, bigs: quicksort(littles) + [pivot] + quicksort(bigs)
    )(*partition(xs[1:], lambda x: x < pivot))
  )(xs[0])


次に要望:

・関数 quicksort について、「ラムダ式が入れ子」になっている
 他の言語と同様に、1つのラムダ式で書き換えできないだろうか?

・なお、他の言語と同様、>>334(>>335)の要望も満たすコードを考えてもらいたく
364デフォルトの名無しさん:2013/09/04(水) 22:32:28.12
「lambdaを入れ子にしないと変数定義が書けないPythonは関数型プログラミングに適さない」
って結論で良くね?
ここまで粘着してるの見るとキモ過ぎて怖いわ
365デフォルトの名無しさん:2013/09/04(水) 22:37:13.72
>>364
でもそれを言ってる奴は変数定義できると
関数型プログラミングに適さないとも言ってるぜ?
相手がPythonかどうかなんて関係ないんだよ
366デフォルトの名無しさん:2013/09/04(水) 22:47:21.55
ラムダの入れ子は関数型プログラミングとして何の問題も無いどころか
(変数を宣言しない)純粋な関数型プログラミングに近いと言えるが、
そもそも関数型プログラミングの可読性が低いので、ラムダの入れ子も可読性が低い
367デフォルトの名無しさん:2013/09/04(水) 22:50:39.60
クロージャ化されたラムダを返すラムダの読みにくさは異常
あれは関数型に慣れてる頭じゃないと読めないと思う
368デフォルトの名無しさん:2013/09/04(水) 23:08:13.27
partitionひとつとっても、Rubyでarray.inject使ったコードや
Pythonでreduce使ったコードより
手続き型でループ回したコードの方が読みやすいよね?
369前スレ367:2013/09/04(水) 23:24:11.82
>>364
>「lambdaを入れ子にしないと変数定義が書けないPythonは関数型プログラミングに適さない」
>って結論で良くね?

その結論には反対する
とりえあえずは、
 「式指向であるPythonは関数型プログラミングに適している(>>72で実証済み)。
  ただし、ラムダ式の本体部で局所宣言できないので、RubyやJavaScriptに劣る一面がある」
くらいだろな
もし「劣る」という言葉が厳しすぎるなら、「表現の制約が強い」と言い換えてもいい

それよりも、>>349(または別のPythonプログラマ)がコードを書いてくるのを待つことにしようぜ

>>365
え、えっ!!
まったく正反対に解釈してるみたいだね
困ったものだ.....
370デフォルトの名無しさん:2013/09/04(水) 23:32:49.85
関数型言語に近ければ近いほど、表現の制約は強いんだけどね
表現の制約が強いことを劣ってるというなら、関数型言語は劣ってるってことだな
371デフォルトの名無しさん:2013/09/04(水) 23:34:56.09
関数型で書かなくちゃいけないってのがもう次元が違うよな
制約というか縛りプレイだよ
372デフォルトの名無しさん:2013/09/04(水) 23:39:41.69
静的型関数型言語は型推論と型検査が強力だし、
Lisp系はマクロが強力なので、
これらは縛りプレイしてまで使う価値があるのかもしれんが、

LLで関数型縛りしても何の意味もないよね
373デフォルトの名無しさん:2013/09/04(水) 23:45:57.72
関数型の最大の利点は、マルチスレッド用に最適化されたコンパイラが出てきた時だろう。
それがなければ大した意味は無いとおもう。
374デフォルトの名無しさん:2013/09/04(水) 23:47:13.03
フィボナッチとか書くのにはいいが、アプリケーションには根本的に向かないだろうし、
スレタイの言語で関数型を誇ってもしかたない気もする……
375デフォルトの名無しさん:2013/09/04(水) 23:52:20.78
Common Lispで

(defun partition (f xs)
 (reduce (lambda (cons x)
      (destructuring-bind (ys . zs) cons
       (if (funcall f x)
         (cons (cons x ys) zs)
         (cons ys (cons x zs)))))
     xs
     :initial-value (cons nil nil)))

(defun quicksort (list)
 (when list
  (destructuring-bind (pivot . xs) list
   (destructuring-bind (littles . bigs)
     (partition (lambda (x) (< x pivot)) xs)
    (append (quicksort littles) (list pivot) (quicksort bigs))))))

ちなみに自分はreduceはあまり使わず、loopをよく使う。
376デフォルトの名無しさん:2013/09/04(水) 23:53:29.79
1つの処理をマルチスレッド化する方向は現状かなり限界があるんだよなあ
メモリバスと競合のオーバーヘッドの関係で全コア使って2倍になったらかなりいい方
それだけのことする価値はないと思う

マルチスレッドはマルチスレッドとしてプログラム組まないと現状仕方ない
377前スレ367:2013/09/04(水) 23:54:14.57
>>371
>関数型で書かなくちゃいけないってのがもう次元が違うよな

そういう「お題」なんだから、しかたないのではないかと....

>制約というか縛りプレイだよ

Pythonの一人縛りプレイ状態?


>>372

X: LLで関数型縛りしても何の意味もないよね
O: Pythonで関数型縛りしても何の意味もないよね
378デフォルトの名無しさん:2013/09/04(水) 23:55:42.16
御題はゴミだし、その御題に執着してる奴はアホ
379デフォルトの名無しさん:2013/09/04(水) 23:56:29.65
ぶっちゃけブロックの中で逐次実行してるだけのRubyの
どこが関数型よ、と言いたいw
380デフォルトの名無しさん:2013/09/04(水) 23:56:52.82
百歩譲ってお題はいいとしても
判定してる奴が恣意的だからまともな収束なんてしない
381デフォルトの名無しさん:2013/09/04(水) 23:57:07.45
お題って、えらい長くやってるな
そろそろ飽きないか?
382デフォルトの名無しさん:2013/09/04(水) 23:58:18.69
同じ話繰り返してるだけじゃん……
383デフォルトの名無しさん:2013/09/04(水) 23:59:42.88
Rubyサイキョを言いたいのは分かったから、
それが言えるようなお題にしてくれ
恣意的に判定するんじゃなくてさ
384デフォルトの名無しさん:2013/09/05(木) 00:01:32.05
低レベルな、抽象的な処理を書くのには有効なこともあるんだろうけど、仕事で普段書くようなプログラムには関数型の必要性は全然感じないわ
385デフォルトの名無しさん:2013/09/05(木) 00:05:57.06
>>372
Lispならletがなければlambdaからつくればいいじゃないって世界だわな
>>384
低レベルってどういう意味で使ってる?
386デフォルトの名無しさん:2013/09/05(木) 00:14:42.86
>>373
関数型なら条件分岐とかのマルチスレッド化投機が容易なんだよね。
でもそれって絶対に副作用のない真の関数型言語じゃないと厳しいと思う。
387デフォルトの名無しさん:2013/09/05(木) 00:16:52.70
RubyとかPythonって次世代Perlのコンセプトじゃないの?
なんで関数型っぽさをかなり取り入れたんだろう
不思議
388デフォルトの名無しさん:2013/09/05(木) 00:17:40.72
超並列処理時代に備え、ゲーム開発はどう変わっていくべきか?
現状でさえマルチスレッドプログラミングは開発の困難さが指摘されている分野である。
同時並列的に動作するプログラムがモデルデータやゲーム内状態などの共有情報にアクセスしようとするとき、
そこには必ずデータ競合によるバグの発生や、デッドロックによるプログラムの停止というリスクがつきものである。
しかも、それを効率的にデバッグすることは非常に難しく、開発規模の拡大や期間の長大化を招いているのだ。
Sweeney氏は、この問題を解決するためには、ゲーム開発言語として純粋関数型の言語が必要になるだろうと言う。
各関数のアトミック性が構造的に保証されており、安全に並列実行できるのだ。
しかも、コンパイラが対応さえすれば、関数を自動的に多数のコアに分散処理させることができるというスケーラブルな実行バイナリを作り出せる。
Sweeney氏は純粋関数型言語のもつ並列処理安全性に着目しており、将来的にゲームプログラミングはそういった処理系に移行していくべきだとした。
その抜本的解決になりそうな言語は純粋関数型の言語特性を持たなければならないが、現在のところゲーム開発に使えるレベルの処理系は存在しない。
Sweeney氏は将来、ゲーム開発に使える純粋関数型言語が開発されることを期待している。
http://game.watch.impress.co.jp/docs/20080911/epic.htm



コンピュータサイエンス史上最大の課題「並列処理による性能向上」
現在のソフトウェアは、ここで必要とされるような並列化を提供していません。性能を向上するにはソフトウェアの並列化に向かわなければなりませんが、それは提供できていない。これが現在のジレンマです。
ハードウェアレベルでは、今後10年から12年後にはチップに15ビリオン(150億)のトランジスタが乗ることが現実となります。
こうした新しい並列化のためのコードをユーザーは書くことができるのでしょうか? どうすれば15ビリオンのトランジスタが乗っているチップを、私たちは使いこなすことができるのでしょうか?
とりわけ言語に課題があると考えています。現在プログラミングによく使われているCやC++、Javaといった言語はハードウェアに近いものであり、言語としてローレベルです。
http://www.publickey1.jp/blog/10/50.html
389デフォルトの名無しさん:2013/09/05(木) 00:30:35.71
関数型使えば、並列処理の安全性は得られるけど
メインメモリとの転送能力がCPUの処理能力に対して100倍レベルで不足しているのは変わらないわけで
結局そこがボトルネックになってる処理はどうしようもなくないか

コア数が2桁になってくると安全性が強く活きてくるかもしれんが
390デフォルトの名無しさん:2013/09/05(木) 00:37:53.34
>>389
ハードウェアとソフトウェアは別。
1コアでも1万コアでも同一ソースで動いて
人間が手動でマルチコアに最適化させたものに匹敵するものはない。
391デフォルトの名無しさん:2013/09/05(木) 00:52:12.20
1万コアだとコア数意識しない設計になるだろうから
コアを使わせやすい関数型が活きるかもしれないね
そこまでくると人の手(非関数型言語)で最適化は限界があるって話

問題は数コアとかで勝手に振り分けて貰うべきかってこと
沢山のサブプロセッサに処理を分担するのは向いてるけど、
現状全部メインだよねって感じ
392デフォルトの名無しさん:2013/09/05(木) 00:58:49.28
手動で最適化って…アセンブラでも書くつもりでしょうかねえ
ファミコンじゃないんだから……
393デフォルトの名無しさん:2013/09/05(木) 01:04:14.18
可能不可能以前に今の技術者の頭じゃ無理
394デフォルトの名無しさん:2013/09/05(木) 01:04:56.84
自動でマルチコアに最適化してくるコンパイラは現存してないだろ。
プログラマの指示なしには1スレッド動作。
OSが空きリソースに割り振るかもしれないが、自動で最大限の性能を出せるようになってない。
395デフォルトの名無しさん:2013/09/05(木) 01:15:05.95
並列処理でも100%関数型でプログラミングする必要はないだろうし、
手続き型でいいところは手続き型で書けばいいと思う。
396デフォルトの名無しさん:2013/09/05(木) 01:15:38.85
今のコンパイラは自動並列化の機能を持ってるぞ
まあ使い物になるレベルのものは確かに現存してないが
397デフォルトの名無しさん:2013/09/05(木) 01:16:55.97
数年前で止まってるのかここは
398デフォルトの名無しさん:2013/09/05(木) 01:19:28.36
まずOS上で1つのアプリケーションしか動かないわけじゃないし、
そういうのは100コアとかになってこないと流行らないと思う。
そもそも現状のアーキテクチャじゃバス幅がボトルネックで特殊な場合じゃないとパフォーマンス上がらないし。
399デフォルトの名無しさん:2013/09/05(木) 01:21:19.16
SIMDですら上手くいって部分的に2倍がやっとなのに、何でもかんでもマルチスレッドにしてうまくいくはずがない。
400デフォルトの名無しさん:2013/09/05(木) 01:25:45.87
そもそもスレタイの言語はみな副作用だらけで適応外だろうが
Parallels.jsみたいに配列の各要素に比較的重い処理をかける時明示的にパラレルにしてもらうくらいが関の山
401デフォルトの名無しさん:2013/09/05(木) 01:30:47.73
>>387
クロージャはオブジェクトと同じだから
ラムダの外側にインスタンス変数のようなものがあるのがクロージャ
読みにくいのはデザインパターンと同じ

でもデザパタじゃなくて数学やりたいと思ったら
ラムダの外側の変数とか考えたくないだろ?
402デフォルトの名無しさん:2013/09/05(木) 01:31:52.09
LLは重たい処理はなんでもネイティブで別スレッドでやってもらって
お得意のコールバックで頑張ればいいのにと思うんだけど
そうもいかないのかな
403デフォルトの名無しさん:2013/09/05(木) 01:39:18.24
LLで大事なのはJavaScriptのWorkerみたいな面倒くさい仕組みじゃなくて
気軽に関数単位でマルチスレッド化できる事じゃないかな
それで十分な気もするけどどう思う?
404デフォルトの名無しさん:2013/09/05(木) 01:45:34.17
>>402
ネイティブと複雑なデータやりとりすんの面倒くさくね
辞書だの木だの受け渡しとか吐き気がする

>>403
C++だとg++のparallel mode、MSVCのPPLみたいなの昔から考えるとすげー楽だわな
std::foreach -> __gnu_parallel::foreachとか書き換えるだけ、みたいな
.NETもそんな感じだし、Javaも8でそういうの来るみたいだな
405デフォルトの名無しさん:2013/09/05(木) 01:46:27.15
でもそれでメモリ食いまくるのも問題なんだよな
406デフォルトの名無しさん:2013/09/05(木) 01:50:10.50
配列のfillメソッドとかはうってつけなんじゃないかな
407デフォルトの名無しさん:2013/09/05(木) 02:05:36.45
408デフォルトの名無しさん:2013/09/05(木) 02:13:49.20
Rubyの次はJSか
409デフォルトの名無しさん:2013/09/05(木) 02:33:46.70
JavaScriptの場合互換を切るわけにいかないから
ヘタすると言語崩壊するな
410デフォルトの名無しさん:2013/09/05(木) 02:41:21.91
新しいJavaScriptから、古いJavaScriptへの
コンバーターがあればどうとでもなると思う。
411デフォルトの名無しさん:2013/09/05(木) 02:41:56.91
"use strict"
で問題解決だ!
412デフォルトの名無しさん:2013/09/05(木) 03:24:57.25
>>410
逆でしょ
古いコンテンツへの互換を切れないから大変ってこと
413デフォルトの名無しさん:2013/09/05(木) 15:02:00.51
JSでは最近コールバックブームからPromise、イテレーターブームに変わりつつあるけど
他の言語もAPIスタイルの流行ってあるの?
414デフォルトの名無しさん:2013/09/05(木) 16:46:16.59
あるよ
415デフォルトの名無しさん:2013/09/05(木) 18:32:50.06
イテレーターって昔からあんの?
なんで昔も言語によっちゃ流行ってたの?
416デフォルトの名無しさん:2013/09/05(木) 19:12:00.67
この手のは流行して定着するのが多いな。
417前スレ367:2013/09/05(木) 19:52:12.90
Erlang で

partition(F, Xs) ->
  lists:foldr(
    fun(X, {Ys, Zs}) ->
      case F(X) of
      true -> {Ys ++ [X], Zs};
      false -> {Ys, Zs ++ [X]}
    end
  end,
  {[], []}, Xs
 ).

quicksort2([]) -> [];
quicksort2([Pivot|Xs]) ->
  {Littles, Bigs} = partition(fun(X) -> X < Pivot end, Xs),
  lists:append([quicksort2(Littles), [Pivot], quicksort2(Bigs)]).
418前スレ367:2013/09/05(木) 20:11:18.37
>>415
反復処理をコルーチンで記述する手法は昔から存在したが、
「反復の抽象化としてのイテレータ(反復子)」を言語の要素に取り込んだのは、
おそらく手続き型言語 CLU が最初
図書館でbitの連載記事を見た記憶を辿ると、1970年代になる

で、ほぼ同じ時期、最初のオブジェクト指向言語Smalltalkでも
イテレータに相当する仕掛けが導入された
ただし、これら言語のイテレータという概念は
専門家(研究者)の間では知られていたのかもしれないが、
一般のプログラマにとっては雲の上の話でしかなかった

とはいえ、たとえばC言語でコレクションを扱う時に
xxx_get_first(&iterator, &collection) と xxx_get_next(&iterator) という関数を
介してアクセスする技法(テクニック)は、一部では実践されていた

これがブームになったのは、GoF本でIteratorパターンが登場してからだろう
1980年代の中盤になる

さらに、イテレータを言語の基本設計レベルで取り込んだスクリプト言語、
Rubyが1990年代に登場して現在に到る、という流れかな
419デフォルトの名無しさん:2013/09/05(木) 20:38:40.15
>>418
Rubyにいわゆる普通のイテレータ(外部イテレータ)が導入されたのは結構最近だぞ
メジャーな言語に組み込まれたのはPythonやC#が先だ
Rubyワールドでは、コードブロックを使った旧来の列挙方式を内部イテレータ、
カーソル的なオブジェクトを使った新しい方式を外部イテレータと呼んで区別するが、
前者は実体がないからイテレータと呼ぶのは苦しいし実装が単純なだけで非常に制限の多い方法
420デフォルトの名無しさん:2013/09/05(木) 20:43:21.51
とはいえ、C#とかJavaでforeachを取り入れたのは2005年前後
それまではイテレーターとか自分でインターフェイス定義するしかなかった
421デフォルトの名無しさん:2013/09/05(木) 20:52:34.36
イテレータの真価は遅延評価だけど、
Rubyの内部イテレータって>>105みたいなのは原理的に遅延評価では実現できないからね
クソみたいな方法
422デフォルトの名無しさん:2013/09/05(木) 20:54:24.86
つまり総合して21世紀に流行り出したってことでOK?
423前スレ367:2013/09/05(木) 21:16:14.06
>>419
CLUのイテレータは、いわゆる内部イテレータだよ
Rubyは、CLUのアイデアをほぼそのままパクって導入した

内部イテレータが外部イテレータと比較して表現力に劣るのは事実だけど、
その代わり反復(イテレーション)を簡潔に記述できる利点があるし、
有限コレクションを扱う多くのケースでは内部イテレータで十分
おまけに外部イテレータもRuby1.9から、無限イテレーションもRuby2.0でサポートされた
これで、イテレータに関しては、全方位で対応ができるから問題ナシじゃね?

>>421
クイックソートをC#のLINQでは>>101で、Rubyのメソッドチェーンを介した
内部イテレータでは>>105でコードが示された
さて、Pythonの外部イテレータでは、どんなコードになるの?
>>105の内部イテレータを「クソ」と言うからには、外部イテレータでも書けるんだよね?

あと、>>133は無限コレクションに対応したRuby2.0のコードだけど、
これはPythonの外部イテレータではどうなるんだろなあ....?


ところで、>>363の要望へのレス(Pythonコード)を待っているんだけど、まだかなあ.....
424デフォルトの名無しさん:2013/09/05(木) 21:27:38.22
プッシュ型の設計って魅力的に目に映りがちだけど、融通が利かないから
rubyの内部イテレータのようにあんまり基礎的なところに据えると失敗するんだよね
SAXとプルパーサの関係に通じる

>>423
lazyは外部イテレータだよw
結局不便だから外部イテレータに乗り換えたの
425デフォルトの名無しさん:2013/09/05(木) 21:28:20.37
Rubyで初めて内部イテレータ使ったとき、

[1,2,3,4].each {|x| puts x; break} #=> 1

って感じでブロック内でbreakすると何故かeachの実行が途中で止まったり、

def f()
puts 'begin'
[1,2,3,4].each {|x| puts x; return}
puts 'end'
end

って感じでブロック内でreturnすると何故かfの実行が途中で止まったりするのでビックリした
ブロックはクロージャじゃなく、もっとおぞましい何かだよね
426デフォルトの名無しさん:2013/09/05(木) 21:39:01.80
イテレータにも種類があるんだな
勉強になる
427デフォルトの名無しさん:2013/09/05(木) 21:47:50.95
>>423
C#のLINQも外部イテレータ
list.Where(x => x < 3).Select(x => x * 2) はリストを操作しているのではなくて
要素をフィルタリングして射影する外部イテレータを定義している
そのイテレータを使って要素を取得しようとするときになって、はじめて実際に評価が行われる
それに対し、>>105のコードはメソッドを呼ぶたびにリストができる
それを改善するためにまんまC#と同じ仕組を導入したのがRubyのlazyだ
428デフォルトの名無しさん:2013/09/05(木) 21:50:40.13
Ruby厨にとっては、意味論や処理的にAとBが等価かどうか
なんてどうでも良くて、コードの見た目が全てなんだよ
429デフォルトの名無しさん:2013/09/05(木) 21:53:27.06
>>423
本物の関数型言語から見ると>>133はウンコすぎるので
Rubyでドヤ顔やめてね恥ずかしいから

take 10 [x * 2 | x <- [1..]]
430前スレ367:2013/09/05(木) 21:56:08.53
>>418,423に出たCLUに関する参考資料をば:

・Rubyist Magazine - Rubyist のための他言語探訪 【第 2 回】 CLU
  http://magazine.rubyist.net/?0009-Legwork

・Rubyチュートリアル:6. イテレータ … ブロック付きメソッド
  http://www.oki-osk.jp/esc/ruby/tut-06.html

・岩波講座 情報科学〈12〉算法表現論 (1982年): 木村 泉, 米澤 明憲
  http://www.amazon.co.jp/dp/B000J7P0KY/

最後の「算法表現論」という古書だけど、「制御構造の抽象化」という節の中で、
CLU風の言語を使ってイテレータや例外(exception)を簡潔に解説している
他にも、この板でたびたび出てくる(手続き型言語と関数型言語の統合計算モデルとしての)
アクター理論、(型推論が登場する以前の)関数型言語、証明論の基礎など、
プログラミング言語設計技術に関する幅広い分野を扱っているのでオススメする
431前スレ367:2013/09/05(木) 21:57:14.51
>>429
Haskellではなくて、Pythonは?
432デフォルトの名無しさん:2013/09/05(木) 21:58:16.04
は?書きたい奴が勝手に書けよw
433デフォルトの名無しさん:2013/09/05(木) 21:59:38.29
Ruby厨はRubyのことすらロクに理解してないんだな
さすがに>>423は酷すぎる
434デフォルトの名無しさん:2013/09/05(木) 21:59:50.81
粘着ruby厨のせいでいつまでたっても別の話ができない
435前スレ367:2013/09/05(木) 22:01:25.88
>>424
>lazyは外部イテレータだよw

いや、正確に言えばファイバー(Fiberクラス)だよ
そして、lazyが従来の内部イテレータと組み合わせてチェーンを構成できること、
それがプログラマにとっては大切だと思う
436前スレ367:2013/09/05(木) 22:02:05.97
>>432
なんだ、書けないんだ
437デフォルトの名無しさん:2013/09/05(木) 22:02:43.53
http://doc.ruby-lang.org/ja/1.9.3/class/Enumerator.html

> 外部イテレータとしての機能は Fiber を用いて実装されているため Fiber と同じ制限があります。
438デフォルトの名無しさん:2013/09/05(木) 22:03:04.59
頼むからもう自サイトに引きこもってろよ
いつまでquicksortやってんだよこのアスペは
439デフォルトの名無しさん:2013/09/05(木) 22:06:45.81
list(islice((x * 2 for x in count(1)), 10))
440デフォルトの名無しさん:2013/09/05(木) 22:06:55.54
>>429
Pythonだと
from itertools import *
islice((x * 2 for x in count()), 10)
かな

なんだRubyって2.0になるまで>>133程度の機能もなかったのか?
441デフォルトの名無しさん:2013/09/05(木) 22:07:14.34
C#においてyieldで外部イテレータを生成するのと本当に全く同じだな
C#がコルーチンでyieldを実装した時にはヘルスバーグの頭がおかしくなったのかと思ったが
難しい説明をしないだけでなんだかんだ言って妥当で理論的背景のある設計だったんだね
442前スレ367:2013/09/05(木) 22:10:57.79
細かいけどインデント等が変だったので、>>417を訂正

Erlang で

partition(F, Xs) ->
  lists:foldr(
    fun(X, {Ys, Zs}) ->
      case F(X) of
      true -> {Ys ++ [X], Zs};
      false -> {Ys, Zs ++ [X]}
      end
    end,
    {[], []}, Xs
  ).

quicksort([]) -> [];
quicksort([Pivot|Xs]) ->
  {Littles, Bigs} = partition(fun(X) -> X < Pivot end, Xs),
  lists:append([quicksort(Littles), [Pivot], quicksort2(Bigs)]).
443デフォルトの名無しさん:2013/09/05(木) 22:11:40.72
ぶっちゃけ構文だけならHaskellが最強なんだよね

実際はライブラリや開発環境の充実度、エコシステムの活発さの方が大事だけど
444前スレ367:2013/09/05(木) 22:28:28.91
>>440
>なんだRubyって2.0になるまで>>133程度の機能もなかったのか?

必要性が無かった、あるいは優先度が低かったのではないかと思う

実際、数学的なモデリングを日常的に行う人達を除けば、
日常的なプログラミング活動で無限を扱うことってほとんど無いよね
たとえばfizzbuzzやエラトステネスの篩といった「お題」は、
プログラミングとしては興味深いけど、その実用性を問われれば返答に困る

あと、>>429のHaskellみたいに内包表記では書けないの?

islice([x * 2 for x in count(1)], 10)

こんな感じで
445デフォルトの名無しさん:2013/09/05(木) 22:32:38.39
ちゃぶ台返しを始めたようです
446デフォルトの名無しさん:2013/09/05(木) 22:39:47.58
お前ら普段コード書く時こんなキモい関数型っぽく書かないだろ

関数型っぽくかけるのは一部の処理を「簡潔に書く」ためであって
多重ネストのラムダ式とか関数型の精神や設計を模倣しようとするのは無茶だよ

そこまで考えて言語も作られてない
もっと普通のコードで戦おうぜ
447デフォルトの名無しさん:2013/09/05(木) 22:44:36.61
>>444
ばっかじゃねーの
ジェネレータ式も内包表記だろうが
448デフォルトの名無しさん:2013/09/05(木) 22:46:46.86
折角関数型言語の良いとこが取り入れられてるのに、悪いとこまで再現する必要なんて無いよね。
関数型スタイルの真の恩恵はスタイルを貫き通さないと得られないんだから、
そこまで張り合うのなら最初から関数型言語使えばいいじゃん?ってことにならない?
449デフォルトの名無しさん:2013/09/05(木) 22:47:23.73
>>448
同意
450デフォルトの名無しさん:2013/09/05(木) 22:50:45.35
どうせRubyのどうしようもない激遅クソエンジンは関数型で書いたからってまともに再帰周りの最適化もしないんでしょ
知ってるよ
451デフォルトの名無しさん:2013/09/05(木) 22:51:33.24
>>444
> 日常的なプログラミング活動で無限を扱うことってほとんど無いよね
え?全然そんなことないぞ
ストリームの一番典型的な例はファイルやネットワーク等の入出力だし

import sys
from itertools import *
stream = iter(lambda: sys.stdin.readline().rstrip(), '')
doubled = imap(lambda x: x + x, stream)
for x in doubled:
  print x
452デフォルトの名無しさん:2013/09/05(木) 22:54:46.58
>>451
その辺ってもっと抽象化されるべきじゃないの?
逆に扱いづらいわ
453デフォルトの名無しさん:2013/09/05(木) 22:59:33.62
>>448
別にソートはどうとでも書けるしね
なんとしてでも1、2行で書かないといけないわけでもないし
454デフォルトの名無しさん:2013/09/05(木) 23:01:48.79
>>451
こうじゃね?

stream = (x.rstrip() for x in sys.stdin)
455デフォルトの名無しさん:2013/09/05(木) 23:05:36.33
JavaScript(Node.js)なら一行かバッファがいくらか貯まる度に関数が呼ばれる設計になるとこだね
456デフォルトの名無しさん:2013/09/05(木) 23:07:27.55
ビジーループ思い出してなんか抵抗あるわ>無限イテレーション
457デフォルトの名無しさん:2013/09/05(木) 23:09:43.81
>>454
端末から実際に入力してみると違いがわかるよ
そう書きたいが、そう書くと期待した動作にならない
458前スレ367:2013/09/05(木) 23:10:15.04
>>451
そうかなあ?
自分は関数型プログラミングには不慣れだから、
I/O処理は普通に手続き型プログラミングのスタイルで書くよ

import sys

def get_line():
  return sys.stdin.readline().rstrip()

def compute(string):
  return string + string

line = get_line()
while line != '':
  print compute(line)

  line = get_line()

もしも、このコードの関数 compute の定義が複雑になった時には、
はじめて(副作用の無い)式を関数型プログラミングのスタイルで書くことを考えるなあ....

それとも、Pythonコミュニティでは、>>451のほうが「ふつう」のコードなの?
459457:2013/09/05(木) 23:11:03.62
まあimap()はジェネレータ式にしてもよいというか、そっちが普通だけど
Python知らない人にはimapのほうが分かりやすいかと思って
460デフォルトの名無しさん:2013/09/05(木) 23:12:23.05
ストリーム系って昔ながらも短いメソッド名とか多いけど現代的じゃないと思うんだよな
キャメルケースにならんかな
461デフォルトの名無しさん:2013/09/05(木) 23:13:19.02
本当に手のひら返し来たなw
手続き型言語の分際で関数型ゴッコやってんじゃなかったのか?
不得意分野は逃げるだけっすか
462デフォルトの名無しさん:2013/09/05(木) 23:15:31.82
そんなことする必要ないだろ
石頭か?
463デフォルトの名無しさん:2013/09/05(木) 23:16:31.83
reactive programmingあたりだと、GUIのイベントをストリームとして見る
勿論関数型方面から来てる話だけど、MicrosoftもReactive Extension(Rx)とか
出してたりする(イベントのストリームにLINQ適用したりとかそういうの)
464デフォルトの名無しさん:2013/09/05(木) 23:17:55.51
>>457
あ、imap使ってるしPython2か
間違えたよスマン
465デフォルトの名無しさん:2013/09/05(木) 23:18:41.02
>>464
imapもそうだけどprint文なので……
こっちこそすみませんすみません
466デフォルトの名無しさん:2013/09/05(木) 23:21:20.80
MSはとんがった技術を土方向けにアレンジして広めるの上手いよな
467デフォルトの名無しさん:2013/09/05(木) 23:25:26.84
>>458
関数型と手続き型で優劣の差がなかったクイックソートに比べると

> line = get_line()
> while line != '':
>   print compute(line)
>
>   line = get_line()

これは明らかに関数型スタイルに比べて劣ってないか?まあ主観だけど
468デフォルトの名無しさん:2013/09/05(木) 23:29:35.40
どう形にしようと、半無限に回す、という考え方がそもそも良くない。
469デフォルトの名無しさん:2013/09/05(木) 23:31:29.35
まるで低級言語みたいな書き方だな
470デフォルトの名無しさん:2013/09/05(木) 23:32:45.26
せっかくイテレータあるんだから、外界からの入力に対しては
毎回手動でEOF判定するより、無限ストリームとして扱えた方が
良いに決まってる
471デフォルトの名無しさん:2013/09/05(木) 23:37:44.20
これ、別の関数に処理回るの?
非同期や遅延評価じゃないと駄目だし、そうだとしたら処理の流れが分かりにくい気がする
472前スレ367:2013/09/05(木) 23:38:42.29
>>461
そこは臨機応変にw
というか、Haskellに代表される純粋関数型パラダイムは、
学術的な価値や貢献はあっても、現状では実用性に問題があると考えている
だから、もし静的型付けな関数型言語であればML族(F#/OCaml/SML)を推す
Rubyも動的型付けであるけれど、ML族と同じ非純粋関数型パラダイムで
関数型プログラミングを楽しめばいいと思っている

たとえば、ここの過去スレであった「RPN計算機」というお題では、
多くのコードは関数型プログラミングで書いているけど、メインループの
I/O処理部分(コードの一番最後)だけは、手続き型の until ... end 構文で書いていた

  http://play.island.ac/codepaste/code?id=27

ただし、最近はRuby1.9で導入されたEnumeratorクラス(外部イテレータというかジェネレータ)を
使い始めているけどね

  http://play.island.ac/codepaste/code?id=1553 -- 内部イテレータ版
  http://play.island.ac/codepaste/code?id=1554 -- 外部イテレータ版
473デフォルトの名無しさん:2013/09/05(木) 23:38:46.77
2行づつつなげる例

stream = (x.strip() for x in sys.stdin)
joined = (x + y for x, y in zip(stream, stream))

for x in joined: print(x)
474デフォルトの名無しさん:2013/09/05(木) 23:41:13.43
マルチコアを最大限効率よく動かす関数型コンパイラ開発しろよ
475デフォルトの名無しさん:2013/09/05(木) 23:41:23.89
Haskell
do記法も使ってるので、手続き型風味


import Control.Applicative

main = do
  stream <- lines <$> getContents
  mapM_ (putStrLn . doubled) stream
    where
      doubled x = x ++ x
476デフォルトの名無しさん:2013/09/05(木) 23:42:29.39
>>471
気になる
IO処理でブロッキングは実アプリケーションじゃご法度だと思うし
477デフォルトの名無しさん:2013/09/05(木) 23:46:10.37
>>471
勿論eagerにしか処理できない言語だと、全部リストに読み込んでからじゃないと
mapとかできないので非実用的
今の例は遅延で動いてる
478前スレ367:2013/09/05(木) 23:47:23.10
>>467
確かに>>456の手続き型コードよりも、
>>451(Python)や以下(Ruby)のコードのほうがエレガントに見えるねえ....

STDIN.each_line.lazy.map { |input_line|
  line = input_line.chop

  line + line
}.each do |line|
  puts line
end
479前スレ367:2013/09/05(木) 23:49:03.81
>>478のアンカーを訂正

X: 確かに>>456の手続き型コードよりも、
O: 確かに>>458の手続き型コードよりも、
480前スレ367:2013/09/05(木) 23:57:01.13
>>477
そのとおりだね

実際、>>478のコードは改行するたびに結果が返されるけど、
メソッド lazy を外してしまうと
EOF(コントロール+D)が入力されるまで計算結果が出力されなくなる
481デフォルトの名無しさん:2013/09/05(木) 23:59:16.01
Python3


import sys

stream = (x.rstrip() for x in sys.stdin)
for x in map(lambda x: x + x, stream):
    print(x)
482デフォルトの名無しさん:2013/09/06(金) 00:03:00.14
Haskellとは違い、printもreadlineも関数だから
print(double(readline())って感じに関数合成するだけでいいよ
483デフォルトの名無しさん:2013/09/06(金) 00:07:23.41
>>482
それで遅延ストリームが動くの?すげえぇ!
で、どの言語の話?
484デフォルトの名無しさん:2013/09/06(金) 00:11:05.00
カオス
485デフォルトの名無しさん:2013/09/06(金) 00:17:32.34
>>482
今の例はたまたまそれでいいけど、mapじゃなくてfilterだとそれじゃだめだし
486デフォルトの名無しさん:2013/09/06(金) 00:54:41.50
>>424
RubyのEnemerator::Lazyは外部イテレーターそのものというわけではない
結果を配列で返すのではなく
手続きをラッピングしたオブジェクト(Enemerator::Lazy)で返すことにしただけのもの
外部イテレーターとしての機能もあるけど
(EnumeratorもLazyも)外部イテレーターとして使われることは少なく
内部イテレーターをラッピングして、遅延させたものとしてしか使われない

Fiberつかってるのは実装しやすいからで
(EnumeratorのためにFiberが実装されたのだが)
1.8では継続を使ってたし
1.9開発初期にはThreadを使ってたことがある
487デフォルトの名無しさん:2013/09/06(金) 01:15:11.69
main = mapM_ (putStrLn . \x -> x ++ x) . lines =<< getContents
488デフォルトの名無しさん:2013/09/06(金) 01:17:23.73
↑何をやってるのか全然伝わってこない
やり直し
489デフォルトの名無しさん:2013/09/06(金) 01:29:14.42
そりゃ馬鹿には伝わらんだろ
490デフォルトの名無しさん:2013/09/06(金) 01:41:14.61
驕るプログラマにはできる奴はいない。
491デフォルトの名無しさん:2013/09/06(金) 05:46:16.56
諸行無常

       r' ̄ヽ 打    祗園精舎の鐘の声、(ぎおんしょうじゃのかねのこえ)
      '心゛ゎj |    諸行無常の響きあり。(しょぎょうむじょうのひびきあり)
    /にソノそ`ヽ、   娑羅双樹の花の色、(しゃらそうじゅのはなのいろ)
   / ソ V / |||`ヽノlヽ 盛者必衰の理をあらはす。(じょうしゃひっすいのことわりをあらわす)
    {. \∨ |||  |V 丿おごれる人も久しからず、(おごれるひともひさしからず)
    jヽ(巛<!巾  ,! く  唯春の夜の夢のごとし。(ただはるのよのゆめのごとし)
   (´ ̄ ̄ ヽ== へ  \ たけき者も遂にはほろびぬ、(たけきものもついにはほろびぬ)
  ムニ二{ミス二二人_ノ   偏に風の前の塵に同じ。(ひとえにかぜのまえのちりにおなじ)
492デフォルトの名無しさん:2013/09/06(金) 06:41:53.44
読めば読むほどRubyが嫌いになるスレ
493デフォルトの名無しさん:2013/09/06(金) 07:28:35.06
>>486
状態を持つ列挙子の実体があって外部に返すんだから外部イテレータの方が近いだろ
しかもその実装方法、列挙子の構造やマイクロスレッド使ってるところまでC#とまんま同じなんだけど
494デフォルトの名無しさん:2013/09/06(金) 07:40:07.01
stdin,stdoutがないSmalltalk,JavaScriptが、ビッグウェーブに乗り遅れるスレ
495デフォルトの名無しさん:2013/09/06(金) 07:46:26.74
>>492
スクリプト言語が嫌いになるスレ
496デフォルトの名無しさん:2013/09/06(金) 11:11:48.55
JSのイテレータはどういうタイプになるの?
497デフォルトの名無しさん:2013/09/06(金) 12:04:07.18
JSにyieldなんてあったっけ
498デフォルトの名無しさん:2013/09/06(金) 12:33:11.25
Mozilla JavaScriptだと1.7でgenerator,iterator,array comprehension,let expressions
1.8でgenerator expression(Pythonと同じ奴)が導入されてるみたい
EcmaScriptだと策定中の6で入る予定じゃね
499デフォルトの名無しさん:2013/09/06(金) 12:34:38.12
GNU Smalltalk

| double |
double := [:x | x, x].
1 to: FloatD infinity do: [:each |
  Transcript cr; show: (double value: stdin nextLine)]
500デフォルトの名無しさん:2013/09/06(金) 13:05:03.54
JavaScript1.7仕様とES6仕様とFirefox実装とChrome実装
それぞれのイテレータはかなり違う
http://d.hatena.ne.jp/teramako/20130831/p1#c
501デフォルトの名無しさん:2013/09/06(金) 13:12:28.58
>>500
ES6が実際的にも標準と認められるまでは駄目だなこりゃ。
502デフォルトの名無しさん:2013/09/06(金) 13:45:50.66
ES6の技術はお互いに絡み合っててメソッドならまだしも
構文を1つずつ準備出来たのから実装できるほど容易くない
だから当分はどうしてもでっち上げになってしまう
forofなんかはまだ良いほうで実装側は大変だと思う
503デフォルトの名無しさん:2013/09/06(金) 14:07:41.83
副作用の代表格のstdin, stdoutですら
Haskellの圧勝じゃん
504デフォルトの名無しさん:2013/09/06(金) 14:11:13.49
あんなキモいコードで圧勝とか言われても……
短く書いた方が勝ちなの?
505デフォルトの名無しさん:2013/09/06(金) 15:21:39.16
ハスケルはコードの見た目が愛せない
ダサい
506デフォルトの名無しさん:2013/09/06(金) 15:26:06.68
モナドはすばらしいアイデアだが
そんなモナドつかわなあかん以前でHaskellつーか関数型は負けてる
507デフォルトの名無しさん:2013/09/06(金) 15:31:20.11
いや、関数型はあえて制約を課すことでメリットを得ているからそれはそれでいいんだよ
LLとコーディングスタイルで競う事自体がおかしな事なんだよ
508デフォルトの名無しさん:2013/09/06(金) 15:33:00.14
パイプライン的な


import Control.Arrow
main = getContents >>= (lines >>> map (\x -> x ++ x) >>> unlines >>> putStrLn)
509デフォルトの名無しさん:2013/09/06(金) 16:14:31.56
行単位じゃなく単語単位のlazyなuniq @ Python3

import sys
from itertools import chain
from functools import reduce

flatten = chain.from_iterable
each = lambda f, xs: reduce(lambda acc, x: f(x), xs, 0)
def uniq(xs):
  seen = set()
  return (seen.add(x) or x for x in xs if x not in seen)

each(print, uniq(flatten(x.split() for x in sys.stdin)))
510デフォルトの名無しさん:2013/09/06(金) 16:23:52.69
何やっているかいっそ分からん。
1トークンずつ解説してくれ。
511デフォルトの名無しさん:2013/09/06(金) 16:32:52.84
>>510
flatten: シークエンスのネストを一段はぎとる
[1,2,3],[4,5],[6,7,8],... -> 1,2,3,4,5,6,7,8....

each: 単にforeach的な関数。これはlazyではなく、ここでストリームが消費される
uniq: 重複を取り除いたシークエンスを返す

最後:
sys.stdinから各行を読み込んで、各行を単語に割って、
結果が単語のリストの列になるので単語の列にして、
重複を取り除く、ここまでlazyなストリーム
最後にeachがドライバとなって、ストリームから要素を一つずつ呼んで印字
512デフォルトの名無しさん:2013/09/06(金) 16:44:29.66
stdinからまとめて読み込んで正規表現でパースはお嫌いですか?
513デフォルトの名無しさん:2013/09/06(金) 16:54:43.75
なんで一単語ずつ印字する必要があるのかがわからん。
514デフォルトの名無しさん:2013/09/06(金) 18:04:35.13
>>493
外部イテレーターとして使わないのであれば
内部でFiberが生成されることもなく
列挙途中の内部状態が外部に露出したりすることはない
基本、コールバック関数(ブロック)を記憶しておいて
列挙ごとにネストしたコールバック関数を呼んでるだけ

複数コレクションを平行イテレートするためにEnumerator(旧Generator)ができて
イテレーターを遅延させるためにそのEnumeratorを利用して
って流れで実装されたんで、外部イテレータ機能をも含んではいるが
イテレートを遅延させるだけなら外部イレテータとは無関係
515デフォルトの名無しさん:2013/09/06(金) 18:10:15.46
GNU Smalltalk

| uniq words |

uniq := [:xs | Generator on: [:g |
  | seen |
  seen := OrderedCollection new.
  xs do: [:x | (seen includes: x) ifFalse: [g yield: (seen add: x)]]]].

words := [:xs | Generator on: [:g |
  [xs nextLine subStrings do: [:x | g yield: x]] repeat]].

(uniq value: (words value: stdin)) do: [:x | Transcript showCr: x]
516デフォルトの名無しさん:2013/09/06(金) 19:42:21.06
ここのスレ見てるとJavaScriptがまともな言語でよかったと思えてくる
RubyやPythonだったら大変なことになってた
517デフォルトの名無しさん:2013/09/06(金) 19:48:51.27
>>515
[:x | g yield: x]
[:x | Transcript showCr: x]
この [:x | ... x] と value: の件さえなければSmalltalk最強だったと思う
518前スレ367:2013/09/06(金) 19:51:17.19
>>509をRubyで:

  http://play.island.ac/codepaste/code?id=1556

現状のRuby2.0には、ストリーム(=遅延シーケンス)に対応したメソッドが
(かなり)不足しているので、組込みクラス Enumerable::Lazy へいくつか追加せざるをえなかった

・Enumerator::Lazy#transduce(init) { |acc, x| ... }
 ・Enumerable#reduce の遅延バージョンであり、入力ストリームから出力ストリームを再構成する
 ・引数 init は累積値 acc の初期値
 ・ブロック(=ラムダ式)のSML風型式は 'acc * 'x -> 'acc * 'y list であり、これは
  事前累積値 'acc と入力ストリームの要素 x から 事後累積値 'acc と 出力ストリームの要素 y への
  写像を意味し、1つの入力要素が0 個以上の出力要素に対応できる
  言い換えると、累積値を状態とするFSM(finite state machine, 有限状態機械)の関数型表現である

・Enumerator::Lazy#scan
 ・1文字(Stringクラス)を要素とする入力ストリームから、空白文字(/&yen;s/)を区切りとした
  単語((Stringクラス)を要素とする出力ストリームを再構成する
 ・内部状態 state は、:init - 初期状態、:between_word - 単語間、:in_word - 単語内を意味し、
  この状態と(入力)文字に応じて次の状態と(出力)単語が決定する

・Enumerator::Lazy#uniq
 ・入力ストリームの各要素について、重複を排除した出力ストリームを再構成する

あとは、>>478と同様に、
・生産者 STDIN.each_char.lazy を始点、
・上記のストリーム演算子 scan および uniq、そして
・消費者 each do ... end を終点
とするストリーム計算式を組立てている
519デフォルトの名無しさん:2013/09/06(金) 20:03:22.15
言語がいくら機能豊富でも結局プログラマが未熟だから
適切な使い方ができずに機能に溺れるだけになってしまうという良い見本
520デフォルトの名無しさん:2013/09/06(金) 20:10:35.39
Smalltalk版もRuby版もあえて>>509のPython版に似せて書いてくれてるんじゃないかと
思うけど、そうする必要はないっすよ
uniq()は手続き型としてはこれでいい気がするけど
lazyなcar, cons, filterと再帰で実現したほうがpureだと思う
Pythonでいいやりかたは思いつかなかったのでこうなったけど
書ける人は書いてください
521デフォルトの名無しさん:2013/09/06(金) 20:18:05.11
オープンソースで公開されているさまざまなソフトウェアの品質を調査したところ、Pythonが最も高かったという調査結果が発表された
http://developers.slashdot.org/story/13/09/03/2032248/open-source-python-code-shows-lowest-defect-density
522デフォルトの名無しさん:2013/09/06(金) 20:36:26.32
Pythonは確かに本来良いコードが書きやすい言語だと思う。
でもこのスレではしつこいクソPythonerのせいで泥が付いてきてる。
523デフォルトの名無しさん:2013/09/06(金) 20:37:45.22
せやろか?
524デフォルトの名無しさん:2013/09/06(金) 20:41:21.02
せやろな
525デフォルトの名無しさん:2013/09/06(金) 20:43:28.22
まあPythonも頑張ってるんじゃない?
Haskellには及ばないけど
526デフォルトの名無しさん:2013/09/06(金) 20:49:15.00
Haskellはスレチ
本部に戻れ
527デフォルトの名無しさん:2013/09/06(金) 20:50:43.10
まるでHaskellを使えば大層なことができるかのようなえらい自信だな
528デフォルトの名無しさん:2013/09/06(金) 20:55:03.86
Haskellerって日夜いかにフィボナッチを理想的に書くかの研究ばかりしてるって本当??
529デフォルトの名無しさん:2013/09/06(金) 20:59:21.44
うん
あとはアッカーマン関数で時間つぶしてる
530デフォルトの名無しさん:2013/09/06(金) 21:03:08.33
たらい回し関数が爆速で動くのを見て
悦に入ってるよ
531デフォルトの名無しさん:2013/09/06(金) 21:07:05.68
>>522
Pythonの場合、Pythonistaじゃなかったっけ?と思ってぐぐったら
Pythonerも意外と多いのな
532デフォルトの名無しさん:2013/09/06(金) 21:21:29.14
アッカーマン関数試してみてすぐスタックオーバーフロー起きるなと思ってたけど
これ原理的にループ最適化はできないのか。
533デフォルトの名無しさん:2013/09/06(金) 21:24:29.51
スタックが足りなければ頼らずに自分で実装してしまえばいい
534デフォルトの名無しさん:2013/09/06(金) 21:27:00.05
せ、せやな
535デフォルトの名無しさん:2013/09/06(金) 21:30:33.15
限界を作るのは言語じゃねえ
己自身だっ……
536前スレ367:2013/09/06(金) 21:44:34.75
>>423
>おまけに外部イテレータもRuby1.9から、無限イテレーションもRuby2.0でサポートされた

Ruby1.8の外部イテレータ対応について、間違いがあったので自己レスで訂正

実はRuby1.8にも(Rubyで書かれた)添付ライブラリ generator.rb で外部イテレータが提供されていた
ただし、遅延評価には対応していないので、
>>133,478,518のようなストリーム(=遅延シーケンス)処理は実現できない

それでも、もしRuby1.8でもRuby2.0と同様なストリーム機能を利用したいのなら、
(反則技になるが)サードパーティ製のgemsライブラリ backports と enumerable-lazy を
利用することで実現できる
具体的には、これらgemライブラリをインストール後、コードの先頭に以下の行を追加するだけ:

require 'rubygems'
require 'backports'
require 'enumerable/lazy'

backports は、Ruby1.8にRuby1.9の機能追加を移植(バックポート)したもの
enumerable/lazy がRuby1.9向けにストリーム機能を提供するライブラリで、
Rubyで書かれたシンプルなコードなので、>>518のプログラミングでは参考にさせてもらった
537デフォルトの名無しさん:2013/09/06(金) 21:49:20.32
-- Haskell

import Control.Arrow

uniq [] = []
uniq (x:xs) = x : uniq (filter (/=x) xs)

main = getContents >>= (lines >>> uniqWords >>> unlines >>> putStrLn)
  where
    uniqWords = map (words >>> uniq >>> unwords)
538デフォルトの名無しさん:2013/09/06(金) 21:55:39.25
関数型ブームが終わったからといってステマ必死だな
539デフォルトの名無しさん:2013/09/06(金) 22:09:48.44
>>509
Always use a def statement instead of an assignment statement that binds
a lambda expression directly to a name.
540デフォルトの名無しさん:2013/09/06(金) 22:19:34.57
・入力を変換して出力する関数を定義する
・遅延評価する

これは純粋関数型言語のストライクゾーンど真ん中
Haskellで書きやすいのは当たり前
541デフォルトの名無しさん:2013/09/06(金) 22:27:13.56
まあ、関数型プログラミング適正とやらを測る御題としては
クイックソートよりはマシだな

どうやらRubyは不得意のようだけど
542デフォルトの名無しさん:2013/09/06(金) 22:31:43.47
>>539
そんな頻繁に更新されてる規約追いかけ続けてるなんてPython使いは大変だな
真面目に守ってるやついるのか?

今年6月時点ではなかった条項なのに
http://hg.python.org/peps/file/c6a5738d5eb3/pep-0008.txt
今年8月に追加されてるのな
http://hg.python.org/peps/file/fb24c80e9afb/pep-0008.txt
543デフォルトの名無しさん:2013/09/06(金) 22:50:33.85
Ruby 2.0 で単語ごとにuniq 遅延ストリーム版
uq = Hash.new
$stdin.each_line.lazy
.flat_map{|e| e.split(/\s+/)}
.select{|e| uq[e] ? nil : uq[e]=true }
.each{|e| puts e}

全列挙せずに、最初の数個だけを得て残りを打ち切るような場合等は
遅延ストリームのほうがスマートに記述できるが
通常は無理に遅延ストリームなど使わずとも
普通に配列を生成すればいいし、そのほうが速い
メモリを多く消費するけれども
$stdin.each_line
.flat_map(&:split)
.uniq
.each{|e| puts e}

そもそもメモリに収まらないようなデータを扱うのはスクリプト言語には荷が重い
C#やHaskellやScala等だと、巨大なデータを扱うこともあるかもしれないが
544デフォルトの名無しさん:2013/09/06(金) 22:59:21.51
昔のPerlみたいだな
545デフォルトの名無しさん:2013/09/06(金) 23:03:35.61
それ誉めてないよね
546前スレ367:2013/09/06(金) 23:11:52.85
>>543
イイネ!!

flat_map を使えば、単語への切り出しは簡単だったんだ....
るりまでLazyのメソッドを読み直してきます

ただし、遅延ストリームの目的は大量データ処理もあるけど、
>>451が言うように入出力処理があって、それが今回の「お題」なんだ
後半の有限シーケンスでは「お題」に対する「答え」になっていないと思う
547デフォルトの名無しさん:2013/09/06(金) 23:28:09.81
前の処理が終わるまで待たずに次の処理を始めたい
データの量ではなくタイミングの問題
548デフォルトの名無しさん:2013/09/06(金) 23:29:30.07
>>543
配列一括処理の欠点は、メモリを多く消費するだけじゃない
入力が完了してして処理が終わるまで出力が始まらないし
その間完全にブロックしてしまい逐次的に処理できない

ttyから入力を打ち込んでみれば違いは明らかで
その方法は少なくとも対話的なプログラムでは全く使えないことが分かるし
パイプラインで使うようなソフトとしても使い勝手が悪い
パイプラインの下流やユーザが「必要な分だけ出力を見て残りを打ち切る」ことは
よくあるが、それを考慮してないわけだしな
549デフォルトの名無しさん:2013/09/06(金) 23:43:15.77
もとが揺るぎない配列であるならまだ分かる
でもわざわざ配列として扱ってまでイテレータ使うのは割にあわない
550デフォルトの名無しさん:2013/09/06(金) 23:45:51.49
イテレータの使い方がダサいというか貧相
イテレータが泣いてるよ
551デフォルトの名無しさん:2013/09/07(土) 05:57:10.22
ようわからんけどPowerShellで書いてみた

cmd /c type con | % { $_ + $_ }

$a=@{}
cmd /c type con | ? { !$a.Contains($_) } | % { ($a[$_]=$_) }
552デフォルトの名無しさん:2013/09/07(土) 08:13:05.59
あ、>>551は今回に限れば別にContainsメソッド要らなかった
$a=@{}
cmd /c type con | ? { !$a.$_ } | % { ($a.$_=$_) }

ハッシュの代わりに配列使って無理矢理一行にするとこんな感じ
cmd /c type con | ? { $_ -notin $a } | % { ($a+=,$_)[-1] }
553デフォルトの名無しさん:2013/09/07(土) 09:28:36.43
GNU Smalltalk 。主処理をメソッドチェーンで書くバージョン。

Stream extend [
 words [
  ^Generator on: [:g | self linesDo: [:line | line subStrings do: [:str | g yield: str]]]
 ]
 uniq [
  ^Generator on: [:g |
   | seen |
   seen := OrderedCollection new.
   self do: [:each | (seen includes: each) ifFalse: [g yield: (seen add: each)]]]
 ]
]

Symbol extend [value: obj [^obj perform: self]]

stdin words uniq do: #displayNl
554デフォルトの名無しさん:2013/09/07(土) 10:03:25.86
お題を勘違いしてたので>>537を訂正

import Control.Arrow

uniq [] = []
uniq (x:xs) = x : uniq (filter (/=x) xs)

main = getContents >>= (words >>> uniq >>> mapM_ putStrLn)
555デフォルトの名無しさん:2013/09/07(土) 10:16:31.76
PowerShellが最強すぎてヤバい
何やってるか全然分からない
556デフォルトの名無しさん:2013/09/07(土) 10:18:48.52
>>552
お題を勘違いしているような気がする
557デフォルトの名無しさん:2013/09/07(土) 10:57:32.70
Haskellは[a]とIO aを区別する意味がほとんどなくなってるだろ
yieldがないから仕方なくリスト使ってるだけ
558デフォルトの名無しさん:2013/09/07(土) 10:58:37.39
>>555
perl -ane 'for (@F) {print $_, "\n" unless $a{$_}++}'

>>555
ただ短けりゃいいんならこんなのでもいいけど
uniqという汎用的な処理を関数として切り出せていないのが
抽象化が十分でない証拠
このお題の例では単純すぎてどうでもいいけどな
559デフォルトの名無しさん:2013/09/07(土) 10:59:22.19
レスアンカーが無駄に2箇所についてしまった、ごめん
560デフォルトの名無しさん:2013/09/07(土) 11:01:47.14
>>556
ありゃ、勘違いしてるかな
1つ目は標準入力が改行される度に最新行を2つ繋げてエコー
2つ目は標準入力が改行される度に最新行が履歴になければエコー
って意味かと思ってた
561デフォルトの名無しさん:2013/09/07(土) 11:03:42.80
>>560
2つめはそれだとUnixのuniqコマンドと同じだけど
単語に割って、履歴に単語がなければそれぞれの単語を一行ずつ出力のがお題
562デフォルトの名無しさん:2013/09/07(土) 11:05:07.54
ごめんちょっと説明曖昧だった
履歴にない単語をそれぞれ一行ずつ出力
563デフォルトの名無しさん:2013/09/07(土) 11:12:11.41
>>561
d
こういうことね

$a=@{}
cmd /c type con | % { $_ -split "\s" } | ? { !$a.$_ } | % { ($a.$_=$_) }

フィルタは関数かした方がよかったかー
564デフォルトの名無しさん:2013/09/07(土) 11:54:28.65
結局、短さと読みやすさでバランス取れて優れてるのはどれよ?
565デフォルトの名無しさん:2013/09/07(土) 12:21:04.07
このお題ではHaskell
566デフォルトの名無しさん:2013/09/07(土) 12:45:47.52
JavaScriptだな次点でPython
Haskellは論外
567デフォルトの名無しさん:2013/09/07(土) 12:46:20.25
>>565
スクリプト言語じゃないから無効票
568デフォルトの名無しさん:2013/09/07(土) 12:47:22.70
Javascriptはコードすら出てねぇ
569デフォルトの名無しさん:2013/09/07(土) 12:48:54.98
Haskellはコードの見た目が美しい
570デフォルトの名無しさん:2013/09/07(土) 12:49:23.66
数十行のコードならJSも悪くないかなと思うけど、1万行のJSとPythonなら圧倒的にPython
571デフォルトの名無しさん:2013/09/07(土) 12:50:29.20
コードすら出てないからいいのでは。
ここまで出たコードの大半がマイナス点、平均してもマイナス点だと思う。
572デフォルトの名無しさん:2013/09/07(土) 12:53:03.74
>>570
1万行の現実のアプリケーションを書くとなるとまた随分話が変わってくるのでは?
住む世界が違うからまたいろいろと比較は難しいだろうし。
573デフォルトの名無しさん:2013/09/07(土) 12:53:11.32
JS厨はコード書けない奴が大半だからな
でもJS厨がうんこだとしても、言語の評価とは別だから
574デフォルトの名無しさん:2013/09/07(土) 12:54:06.96
Haskellは汎用言語装ってんじゃねえよ
他所でフィボってろ
575デフォルトの名無しさん:2013/09/07(土) 12:54:10.14
>>571がプラス点のコードを書いてくれるってさ
576デフォルトの名無しさん:2013/09/07(土) 12:55:58.37
>>575
すまんがお題に興味が無いから書かない。
いいお台なら当然書いてる。
正直この流れ乗れないわ。
577デフォルトの名無しさん:2013/09/07(土) 12:57:14.38
書けない奴の定番の言い訳キタよー
たかが数行のコードすら一瞬で書けないって言語も書き手もゴミすぎ
そんな奴が批評とか失笑
578デフォルトの名無しさん:2013/09/07(土) 12:57:23.97
まとめると while (<>) 最強ということでよろしいですね
579デフォルトの名無しさん:2013/09/07(土) 12:57:50.19
>>446,448
580デフォルトの名無しさん:2013/09/07(土) 13:01:59.62
>>577
お前さんはプログラミングの前に道徳の勉強した方がいいよ。
その性格反省した方がいい。自分も他人も不幸にする。
581デフォルトの名無しさん:2013/09/07(土) 13:03:28.79
>>580
その行数打ち込む時間があったら
コード書けたねw
582デフォルトの名無しさん:2013/09/07(土) 13:04:55.83
とりあえず、Haskellはスレチ
583デフォルトの名無しさん:2013/09/07(土) 13:06:10.90
Haskeller大暴れ

見苦しいぞ
584デフォルトの名無しさん:2013/09/07(土) 13:07:18.89
早く平穏なバトルロワイヤルスレに戻ってくれ!
585デフォルトの名無しさん:2013/09/07(土) 13:08:30.19
Haskell称賛してる人に
で、お前はHaskellでどんなアプリケーション作ったの?って訊ねると黙る
586デフォルトの名無しさん:2013/09/07(土) 13:10:38.53
ソートと標準入力で各1スレ使えるとか平和だなあ
587デフォルトの名無しさん:2013/09/07(土) 13:11:40.60
>>585
じゃあ、お前はどんなアプリケーション作ったの?
言語はなんでもいいよ。

お前が黙るかそれ以外の何をするかを
見たいだけw
588デフォルトの名無しさん:2013/09/07(土) 13:12:13.21
コード書けない奴の劣等感に触れると
スレが伸びるよ!
589デフォルトの名無しさん:2013/09/07(土) 13:12:34.66
結局Haskellって関数型プログラミングを学ぶための学習用言語だから、
汎用言語と同じ土俵で語るのはよくない
590デフォルトの名無しさん:2013/09/07(土) 13:15:03.95
Haskell関係なく、
どんなアプリケーション作ったの?って
尋ねると黙るなwww
591デフォルトの名無しさん:2013/09/07(土) 13:15:14.47
同じ土俵で語ってみたら完敗したでゴザルw
592デフォルトの名無しさん:2013/09/07(土) 13:17:06.02
Haskell信者が草を生やしだした模様
593デフォルトの名無しさん:2013/09/07(土) 13:18:38.84
>>590
訊く方も、実名バレできねーだろって読んだ上で
訊いてるからな
594デフォルトの名無しさん:2013/09/07(土) 13:19:02.06
Haskellは悪くない。
各言語のラムダ式導入の参考にもなってるし、その部分を語るのも悪く無い。
でもあまりに他の言語を意識することは自分の長所を捨てて、
結局相手の長所もそんなには得られないし、良くはないと思う。

関数型スタイルは関数型言語に敵うはずがないし、
その代わりもっと豊かなスタイルで書けるんだから、住み分けたらいい。
ストリームを関数型スタイルでバリバリ書けますよーとは言うけど、
実際バリバリ関数型よりのスタイルでアプリ書かないでしょと言いたい。

使えるものは有効活用すべきだけど、溺れちゃってるだけになってるね今。
595デフォルトの名無しさん:2013/09/07(土) 13:19:35.67
Haskellは玩具だけど、それ以上にコード書けないJS信者に草不可避
596デフォルトの名無しさん:2013/09/07(土) 13:25:14.08
「どんなアプリケーション作ったの?」
じゃあ答えにくいよね

所謂ウィンドウ型、もしくはスマホ用みたいいな「アプリ」という話なら
自分はJS+HTMLで、作りにくくは無かったけど

Haskellとかは作りにくそうなイメージ持ってるけど
各言語使いの方、実際はどうなの?
597デフォルトの名無しさん:2013/09/07(土) 13:25:50.67
最高の言語を追い求めることに一生懸命で、結局アプリケーション書けないまま一生を終える人たちのスレ
598デフォルトの名無しさん:2013/09/07(土) 13:28:44.09
JSには標準入力がないし、Nodeのreadlineとかはもっと抽象化されてもあるインターフェースだから、
あの書き方はする必要がないというか、全然あわないんじゃない?
書いても他と全く違うものになるから、関数型、イテレータで盛り上がってる所には入りずらいかと
599デフォルトの名無しさん:2013/09/07(土) 13:36:46.99
みんな違ってみんな良い
600デフォルトの名無しさん:2013/09/07(土) 13:38:02.68
最近になってJSで関数型を!って声も大きくなってきたけど
現状Haskellっぽく書く文化が全くないと思う
こういうのがES6に間に合えばまた変わってくるかもしれないけど
http://wiki.ecmascript.org/doku.php?id=harmony:generator_expressions
同時にDOM側からは抽象度の高いフレームワーク的機能が沢山提供されるし
JSerは中々Haskellっぽく書きたくならないだろうな
601デフォルトの名無しさん:2013/09/07(土) 13:38:20.69
普通の標準入力とやらを教えてくれよ。
JSでそれと同じ書き方ができれば問題無いだろ?
602デフォルトの名無しさん:2013/09/07(土) 13:39:38.12
Haskellっぽいってのは何なんだ?

Haskellっぽいのが最高なものという訳じゃないし、
クソコード=Haskellっぽいって可能性もあるんだが。

つまりHaskellっぽく書くのは
悪いコーディングスタイル。
603デフォルトの名無しさん:2013/09/07(土) 13:39:57.74
>>597
スクリプトは静的型を捨てた
静的型の夢を諦め切れない奴が多すぎるのも異常だよ
604デフォルトの名無しさん:2013/09/07(土) 13:41:03.12
どちらかと言うと全体的にはclassが入ったことでJAVA的思想になりそう。
605デフォルトの名無しさん:2013/09/07(土) 13:42:26.36
Haskellっぽい == 全部が式
ってことだろ
606デフォルトの名無しさん:2013/09/07(土) 13:42:34.13
>>602
「つまり」より前の文章が後の文章の帰結になってない
論理的に思考できないお前はプログラマに向いてないよ
607デフォルトの名無しさん:2013/09/07(土) 13:45:12.49
Haskellっぽくなくて良いので、
パターンマッチ導入してくれ
608デフォルトの名無しさん:2013/09/07(土) 13:45:41.29
スクリプトは静的型を捨てたというと具体的ではないが
要するに、コンパイラや処理系などによる
静的解析を諦めたということ。

静的解析ができれば、コードの問題点を素早く見つけ出すことが出来る。
またプログラムに必要な作業にたいしてコンピュータからサポートが出来る。

スクリプト言語はこれらを捨てたということ。
これは欠点ではない。

問題点が見渡せる程度、サポートがなくても人間が頑張れる程度
その程度の小さいコードを作ることを前提にして、
宣言的なコードをなくしているのだ。

だから大規模ソフトを作らなくて、CLIの延長でプログラム言語を使う
インフラ技術者において、スクリプト言語は人気がある。
609デフォルトの名無しさん:2013/09/07(土) 13:47:25.79
大規模ソフト = GUIかよ、視野せめーな
610デフォルトの名無しさん:2013/09/07(土) 13:48:25.05
>>608
そんなことは全員の共通認識
なにその今さらな長文
611デフォルトの名無しさん:2013/09/07(土) 13:49:06.55
△静的解析を諦めたということ
○静的解析を一部諦めたということ
612デフォルトの名無しさん:2013/09/07(土) 13:50:35.59
プログラミング言語が使えなくても
コマンドなら叩けるという意味でインフラ技術者は、
プログラミング技術的にはアプリプログラマよりも技術力は下である。

そのインフラ技術者が、コンピュータ使ってるんだから仕事なんて一緒だろ?
みたいな感覚で、アプリの開発をさせられると火を噴く。

言語が開発に適しているかどうかなんて考えずに
自分の使える言語(=スクリプト言語)を使って大規模なアプリを作り出す。

そしてスクリプト言語を使う感覚で、その場しのぎのコードを
積み重ねてアプリを作るのだ。
全体の整合性なんて考えちゃいない。
動けばいい。そういう考えで作る。
613デフォルトの名無しさん:2013/09/07(土) 13:51:17.67
>>609
> 大規模ソフト = GUIかよ、

あれ? どこにGUIって書いてあんの?

ヤクでもやってる?
614デフォルトの名無しさん:2013/09/07(土) 13:51:22.57
そうとも言えないと思うけどな
最近になってスクリプト言語で書かれる種と量はうなぎのぼりだし
常に言語開発の問題として挙がってる
615デフォルトの名無しさん:2013/09/07(土) 13:52:23.75
最近のスクリプト言語の多くは実際にはもはやスクリプト言語ではない
616デフォルトの名無しさん:2013/09/07(土) 13:54:13.23
>>608
捨てたり諦めたわけでない。スクリプト言語のほうが複雑。
かりにアセンブラ言語が静的解析を諦めたら、スクリプト言語になるか?
617デフォルトの名無しさん:2013/09/07(土) 13:55:32.57
クラスベースでない≒スクリプト言語
618デフォルトの名無しさん:2013/09/07(土) 13:55:35.48
>>616
静的解析を諦めたらスクリプト言語になるのではない
スクリプト言語になるには、静的解析を諦めないといけないのだ。
一部は出来るというが、それ以外は諦めるということだからな。
619デフォルトの名無しさん:2013/09/07(土) 13:56:08.33
Javaから遠い = スクリプト言語
620デフォルトの名無しさん:2013/09/07(土) 13:57:28.90
意味わかんね
C系だって一部諦める代わりに利便性を取ってるぞ
621デフォルトの名無しさん:2013/09/07(土) 13:59:55.07
>>620
程度のもんだだよ。

スクリプト言語は実行時にならないとわからないことが多すぎる。
実行時にならないとわからないことがデフォルトになってる。
622デフォルトの名無しさん:2013/09/07(土) 14:02:57.23
いや、結局何が関数型言語かの時の結論のように
作ってるとこがそう言えばそうってことでしかないんじゃね
623デフォルトの名無しさん:2013/09/07(土) 14:05:36.93
a < b < c

a < b && b < c
が等価である

スクリプト言語
624デフォルトの名無しさん:2013/09/07(土) 14:11:56.48
CPUが実行可能なマシン語に変換できるかどうかでわけると
C#やJavaもスクリプトか?
625デフォルトの名無しさん:2013/09/07(土) 14:14:50.99
>>621
ソフトの目的は、ハード設計時にわからないことを先送りすること
むやみに予想したり賭けたりしないことだ
626デフォルトの名無しさん:2013/09/07(土) 14:16:42.74
実行可能なマシン語・・・の一段階前を
テキストエディタで修正可能なものが
スクリプト言語
627デフォルトの名無しさん:2013/09/07(土) 14:17:56.25
>>625
誰もソフトウェア外部のハードの話なんかしていません。
外部が予測不可能なのはあたりまえじゃないですか。
ソフトウェア内部の話です。
馬鹿なんですか?
628デフォルトの名無しさん:2013/09/07(土) 14:29:34.54
まあ、ソフトウェアもライブラリやフレームワークは
設計時に全てを決めるのは難しい
Javaなどで標準GUIライブラリが何度も作り直されて
それでもウンコなのをみても明らか
629デフォルトの名無しさん:2013/09/07(土) 14:29:35.59
>>605>>623はJavaScriptがJavaを真似た最大級の失敗
http://esdiscuss.org/topic/everything-is-an-expression
http://esdiscuss.org/topic/chained-comparisons-from-python-and-coffeescript

前者はまだどうにかできるが後者は難しい
将来的にスイッチを導入してまで変えるかもしれない

一応ES7で演算子オーバーロードやValueProxiesが入ると無理やりエミュレートはできるかもしれない
http://wiki.ecmascript.org/doku.php?id=strawman:operator_overloading_with_double_dispatch
http://wiki.ecmascript.org/doku.php?id=strawman:value_proxies
630デフォルトの名無しさん:2013/09/07(土) 14:35:51.45
>>628
本当に馬鹿なのかな?

外部が予測不可能なのは当たり前てて書いたよね?
ライブラリやフレームワークの外部だって
予測不可能なのは当たり前。

内部の話だよ。ばーかw
631デフォルトの名無しさん:2013/09/07(土) 14:36:44.11
メジャーなエンジンでES6の実装が完了するのは2015年
ES7は早くてあと5年はかかりそうだな
632デフォルトの名無しさん:2013/09/07(土) 14:39:16.61
eval関数がある ≒ スクリプト言語
633デフォルトの名無しさん:2013/09/07(土) 14:39:26.15
フレームワークの穴埋めだけやる場合は
全て決まってるのかもな
634デフォルトの名無しさん:2013/09/07(土) 14:40:49.98
>>598
他と全然ノリが違うPowerShellやPerlの例すら挙がってるのに
そんなこと気にする意味ないような
ブラウザにはstdinなんてないかもしれないけれども
別にnodeでもRhinoでもSpiderMonkeyでもWSHでもいいのよ?
635デフォルトの名無しさん:2013/09/07(土) 14:46:30.28
つーかNodeなら似たようなもんになるだろ
636デフォルトの名無しさん:2013/09/07(土) 14:46:54.58
なら書いて
637デフォルトの名無しさん:2013/09/07(土) 14:48:37.01
じゃあ俺が書いてみるからお題ちょうだい
638デフォルトの名無しさん:2013/09/07(土) 14:52:44.90
既に出てるお題を解いてから言え
639デフォルトの名無しさん:2013/09/07(土) 14:56:34.59
どれか指定してよ
絶対ちゃんと書くことは書くから
640デフォルトの名無しさん:2013/09/07(土) 14:58:34.96
>>612 mediawikiとwordpressの悪口はそこまでだ
641デフォルトの名無しさん:2013/09/07(土) 15:01:07.35
>>639
その程度も自分で考えられない奴が書くコードなんてたかが知れてる
642デフォルトの名無しさん:2013/09/07(土) 15:06:03.05
標準入力なんてあんまり扱ったことないから
イメージがしにくいのよ
すまんな
643デフォルトの名無しさん:2013/09/07(土) 15:10:12.14
>>642
それ結構衝撃的発言なんだが、俺もおっさんになったということだなぁ
644デフォルトの名無しさん:2013/09/07(土) 15:15:27.05
>>643
(数値なんかの)入力機能としてならよく使うけど
入力されたものを整形して出力しようなんて考えたこともない
645デフォルトの名無しさん:2013/09/07(土) 15:22:29.55
>>639
標準入力からの入力を待って
単語ごとに分割し
既出の単語を除いて単語ごと改行して出力
というのをループではなく遅延ストリームで行う
って直近のお題をよろしく
646デフォルトの名無しさん:2013/09/07(土) 15:32:38.39
別にループでやってもいいしストリームじゃなくていいけどレイテンシは守って欲しい
いままで出てる遅延実装=レイテンシゼロ
最後まで読んでから処理=レイテンシが無限大

上の仕様を守りつつuniqを独立した関数として実装可能かどうかという点に
言語の抽象化能力が問われる
uniqを関数にできずにループに埋め込まれてしまうなら、抽象度が低いという
ことになる
647デフォルトの名無しさん:2013/09/07(土) 15:42:45.52
どこに落ち着けばいいのか分かんないけどとりあえず苦戦してみる
648デフォルトの名無しさん:2013/09/07(土) 15:58:03.94
レイテンシなんて言葉を知らなくてもできるのに
無駄な言葉を使うと問題が難しくなる見本
649デフォルトの名無しさん:2013/09/07(土) 16:00:20.08
わかんね
「最後まで読んでから処理」ってなんのことだ
650デフォルトの名無しさん:2013/09/07(土) 16:01:29.34
ストリームが届き始めた次点からパースを開始しなさいってこと?
651デフォルトの名無しさん:2013/09/07(土) 16:03:45.37
レイテンシ=遅延
>>649
入力を1行読む度にすぐ出力される→レイテンシゼロ
入力を最後の行まで読まないと出力が始まらない→「最後」はいつになるか分からないなのでレイテンシが無限大

ファイルにリダイレクトせずに標準入力から手で入力すれば違いはすぐ分かる
652デフォルトの名無しさん:2013/09/07(土) 16:05:40.15
あー了解
653デフォルトの名無しさん:2013/09/07(土) 16:21:48.82
これって一度に複数行の入力を許容して
かつ順序を保って非同期に出力すればいいの?
それと重複の判断は行単位だよね?
654デフォルトの名無しさん:2013/09/07(土) 16:47:48.30
nextTickは使いたくなかったけどこれに落ち着いた


process.stdin.on('data', function(buf) {

var arrItr = (buf.toString().match(/\S+/g)||[]).values()
var set = new Set

function itrFunc() {
var nextObj = arrItr.next()
var done = nextObj.done
if (done) return
var value = nextObj.value
if (!set.has(value)){
console.log(value)
set.add(value)
}
process.nextTick(itrFunc)
}

itrFunc()
})
655デフォルトの名無しさん:2013/09/07(土) 16:50:11.51
>>634
え、いやあの、>>563のPowerShellスクリプトは
ほとんど>>543を直訳しただけよ・・・?
たまたま遅延評価っぽくなってるだけで、実際は遅延評価してるわけじゃないけど
656デフォルトの名無しさん:2013/09/07(土) 16:58:09.91
itrFuncがちょっとごちゃごちゃしてるけど短く書いたらこんな感じ?

function itrFunc() {
var {done, value} = arrItr.next()
if (done) return
set.has(value) && set.add(value) || console.log(value)
process.nextTick(itrFunc)
}
657デフォルトの名無しさん:2013/09/07(土) 17:13:03.41
ループ&ES6でいいのなら"ソレ"っぽく書けるんだけど
V8のES6対応が中途半端だからキツイ

process.stdin.on('data', function(buf) {
for (let v of new Set(buf.toString().match(/\S+/g) || [])) console.log(v)
})
658デフォルトの名無しさん:2013/09/07(土) 17:16:14.51
>>654
values()のところでエラーになるのはうちのV8が古いから?
659デフォルトの名無しさん:2013/09/07(土) 17:31:28.05
想像を絶するダサさだった

uniqの抽象化も出来てないしループもC言語を彷彿とさせる
いままで出た中でブッチギリのワースト
660デフォルトの名無しさん:2013/09/07(土) 17:32:15.65
>>658
V8 3.20.5辺り以降かNode 0.11系でharmonyフラグを付けて起動する
661デフォルトの名無しさん:2013/09/07(土) 17:38:33.85
>>660
ありがとう
うちのDebianで入るやつはv0.10.15だから古いんだな
662デフォルトの名無しさん:2013/09/07(土) 17:39:42.25
>>659
もっとSetに頼れればuniqとやらも随分良くなるんだけど
まだ実装不足だからなぁ
663デフォルトの名無しさん:2013/09/07(土) 17:41:39.83
とはいえこのコードを書いてて遅延処理の良さが分かったかもしれない
それが本当に一番良かった
お題を教えてくれた人ありがとね

JSでも提案はあるみたいだから実装されるといいね
664デフォルトの名無しさん:2013/09/07(土) 18:46:24.74
uniqをストリーム対応で定義できてるのは
Python、Smalltalk、Haskellだけかー
665デフォルトの名無しさん:2013/09/07(土) 18:57:39.98
逆に差、Pythonとかのほうが
ダサくなる例って無いの?

例えば、ウェブサーバーを書いてみるとかさ。
ちょっとお題が一方に都合が良すぎる感じがする。
666デフォルトの名無しさん:2013/09/07(土) 19:02:11.01
いや、別に気にする必要なんてないと思うよ。
これがああ書けたからなんだって話だし。
元々意味のないお題なんだからWebサーバーを引き合いに出すのはちょっと違うよ
667デフォルトの名無しさん:2013/09/07(土) 19:03:50.65
uniqをストリーム対応で定義できるの意味が分からん
uniqをストリーム対応で定義できると何があんの?
668デフォルトの名無しさん:2013/09/07(土) 19:04:12.37
>>654
過去にさかのぼって履歴に単語があれば、その単語は出力してはいけない
そのコードだと現在行の重複を取り除いているだけでは?
669デフォルトの名無しさん:2013/09/07(土) 19:04:43.46
>>667
元々意味のないお題って二度も言わせるなw
670デフォルトの名無しさん:2013/09/07(土) 19:05:11.40
言語の抽象化能力を比較するのに
どういうお題が相応しいか考えるのにも
知識とセンスが要るんだなー

Webサーバだってw
671デフォルトの名無しさん:2013/09/07(土) 19:07:36.45
>>667
uniqはただの例で、GUI、対話的アプリケーション、ネットワークプログラム、
デジタルフィルタ等、応答性が重要なケースでの抽象化能力をはかる一つの目安になる

こんな単純な例でプロセスを切り出せずにループに紛れ込んでしまうのでは
スパゲッティになってしまうか複雑なステートマシンを管理することになるのが
目に見えてる
672デフォルトの名無しさん:2013/09/07(土) 19:08:03.46

こういうのは取り合わなくていいよ
673デフォルトの名無しさん:2013/09/07(土) 19:08:41.69
>>666
> 元々意味のないお題なんだからWebサーバーを引き合いに出すのはちょっと違うよ

いや、その理屈がわからん。

意味が無いお題じゃないといかんのか?
別にウェブサーバーを引き合いに出してもいいじゃないか。

そもそもストリーム対応のuniqは意味のないお題なのか?
どういう点が意味があって、uniqには何がないから
意味が無いお題なんだ?
674デフォルトの名無しさん:2013/09/07(土) 19:10:12.23
>>671
単純な例だからこそ切り分ける必要なんてないのでは?
675デフォルトの名無しさん:2013/09/07(土) 19:10:18.80
>>670
だから、言語の抽象化能力を比較するのに
uniqが適切とは限らないってことでしょ。

そこまで必死になってるのはなぜなんだ?
676デフォルトの名無しさん:2013/09/07(土) 19:11:15.68
>>671
uniqは元々意味のないお題って言ったよね?
無理やり意味を見出そうとするなアホ
677デフォルトの名無しさん:2013/09/07(土) 19:11:32.49
>>673
言語の良さじゃなくて変態度を競ってる
といえば分かる?
678デフォルトの名無しさん:2013/09/07(土) 19:12:54.10
訂正、

俺は俺の基準による変態度を競っている。
誰がお前のフィールドに上がるか(笑)
679デフォルトの名無しさん:2013/09/07(土) 19:13:05.18
>>674
つまり、単純だからやらなかっただけで、
その気になれば切り分けれたの?
680デフォルトの名無しさん:2013/09/07(土) 19:14:12.45
やれば出来る。

だがやらないけどなw
681デフォルトの名無しさん:2013/09/07(土) 19:14:40.91
>>678
なりすまし錯乱荒らしが来たぞーー
682前スレ367:2013/09/07(土) 19:15:19.64
>>664
Rubyでも定義できているよ
>>518 を見れば分かる
683デフォルトの名無しさん:2013/09/07(土) 19:15:28.18
>>672
>>671は割と納得がいく理由を書いてると思うよ?
684677:2013/09/07(土) 19:15:50.59
>>678=>>681

一人で何やってんの?
685デフォルトの名無しさん:2013/09/07(土) 19:16:23.89
>>683
なりすまし錯乱荒らしが来たぞーー
686デフォルトの名無しさん:2013/09/07(土) 19:17:55.94
>>682
できてないよ。
687デフォルトの名無しさん:2013/09/07(土) 19:18:29.93
>>683
>>670へのレスだよ
688デフォルトの名無しさん:2013/09/07(土) 19:20:10.51
定義って何?重複を省く標準関数もないの?
ソッチの方が重病だと思うけど
689デフォルトの名無しさん:2013/09/07(土) 19:24:41.16
>>688
自作すればいいだろばーかw
690デフォルトの名無しさん:2013/09/07(土) 19:26:12.16
ストリーム対応で重複を省く標準関数を持つ言語って例えば?
691デフォルトの名無しさん:2013/09/07(土) 19:27:02.24
簡単にかけるからという理由で
3行ぐらいあるコードを
何十回も書くのやめてください。
スクリプト言語使っている人に多いです。
692デフォルトの名無しさん:2013/09/07(土) 19:28:07.61
>>690
bash。

uniqという関数で出来る。
693デフォルトの名無しさん:2013/09/07(土) 19:32:33.58
>>691
コマンド履歴に残しておけばいいんじゃないすかー
694デフォルトの名無しさん:2013/09/07(土) 19:33:09.99
まあ本来のuniqコマンドは動き違うんだけどね
あれは入力がソートされてることが前提で、「連続した」重複しか取り除けない

勿論そうじゃないと、重複を記憶するためにメモリをバカ食いするか
dbmみたいなものを使うはめになるから
695デフォルトの名無しさん:2013/09/07(土) 19:34:35.15
bash、アウトー
696デフォルトの名無しさん:2013/09/07(土) 19:35:34.28
もうそろそろ次のお題。
ウェブサーバーに移ろうぜ。
697デフォルトの名無しさん:2013/09/07(土) 19:39:09.81
ダサい→入力ストリームの重複を省く汎用的な関数を作る
ステキ→重複を省く汎用的な関数に通せるよう入力ストリームを変形する
698デフォルトの名無しさん:2013/09/07(土) 19:40:11.83
webサーバってあれだろ
python3 -m http.sever 8888
とかで立ち上がるやつだよな?
699デフォルトの名無しさん:2013/09/07(土) 19:40:35.96
WebサーバーはWebサーバーでもアプリケーションサーバーかどうかでだいぶ変わるし、
言語の上のフレームワークの問題でもある
700デフォルトの名無しさん:2013/09/07(土) 19:41:08.40
じゃあ、どっちでも好きな方を書けばいいのでは?
701デフォルトの名無しさん:2013/09/07(土) 19:43:15.12
>>697
確かに後者の方がステキだ
702デフォルトの名無しさん:2013/09/07(土) 19:43:24.88
WebSocketって「JSの」オブジェクトなんでも投げられる仕様になってるけど
他の言語で使う時どうなるの?
703デフォルトの名無しさん:2013/09/07(土) 19:45:34.93
>>697
どちらが良いかっていうのは置いといて
前者がいいって思う人は何かに毒されてると思う
704デフォルトの名無しさん:2013/09/07(土) 19:50:07.12
>>697
後者で実現できるんなら後者でいいよな
ただ後者の「汎用的な関数」が仮にeagerに全入力を読んでしまうものなら
今回の要求仕様を達成できないのだから、使えない

こうしたケースでは使用できない「汎用的な関数」は使用条件が限られるわけで
実は汎用的ではなかったわけだ
705デフォルトの名無しさん:2013/09/07(土) 19:53:51.06
>>563からuniqを切り出すのは楽なんだけど(まんま切り取るだけ)
そこだけ抽象化してもそもそも履歴がグローバル変数だしなー

複数回ストリーム流しても保持できるようにしてるんだけど、
これをローカルスコープで、前回の履歴を引数にしたりせずにってなるとちょっとしんどい
そういうとこHaskellは楽そうでいいね
706デフォルトの名無しさん:2013/09/07(土) 19:53:52.96
>>702
Pythonでは無理。
707デフォルトの名無しさん:2013/09/07(土) 19:55:07.94
>>509のuniqとかは普通に汎用だけどね
別にストリーム専用とかじゃなく、ただのリストも食えるし形式も問わない

>>> for x in uniq([1,3,2,4,5,2,6,1]): print(x)
1
3
2
4
5
6
708デフォルトの名無しさん:2013/09/07(土) 20:00:17.88
いや>>707は入力文字列を空白で区切って配列にしたものをuniqに渡してるんだから
後者の分類でしょう

前者は文字列とすら見ないで、データが届いた端からバイナリ列で走査していく感じが適当だと思うけど
標準入力だと一気にデータが来るから仕方ないけど、ストリーム汎用と見たらそういう実装でしょう
709デフォルトの名無しさん:2013/09/07(土) 20:01:55.35
>>708
なるほど、言わんとしてることが分かったわ
ありがとう
710デフォルトの名無しさん:2013/09/07(土) 20:08:59.25
ダサいっていう人は >>657 の改造版だけどこういうのはどうなの?

process.stdin.on('data', buf => for (let v of new Set(buf.toString().split(' ')) console.log(v) )
711デフォルトの名無しさん:2013/09/07(土) 20:10:56.00
>>710
言語名で決める(笑)
712デフォルトの名無しさん:2013/09/07(土) 20:14:41.15
713デフォルトの名無しさん:2013/09/07(土) 20:24:45.85
やけくそ
let set = new Set
process.stdin.on('data', buf => for (let v of [v for (v of buf.toString().split(' ')) if (set.add(v) || !set.has(v))] ) console.log())
714デフォルトの名無しさん:2013/09/07(土) 20:27:11.25
反省
let set = new Set
process.stdin.on('data', buf => {
let data = [v for (v of buf.toString().split(' ')) if (set.add(v) || !set.has(v))]
for (let v of data) console.log(v)
})
715デフォルトの名無しさん:2013/09/07(土) 20:42:52.08
>>654 はノンブロッキングで「レイテンシ」は0で順序も保証してるけど他にそういうのあるの?
716デフォルトの名無しさん:2013/09/07(土) 20:48:50.93
順序ってなに?
717デフォルトの名無しさん:2013/09/07(土) 20:53:51.37
動くコード書くだけで四苦八苦してるようじゃ
>>697の後者は遠いな
718デフォルトの名無しさん:2013/09/07(土) 20:53:51.24
例えば
a b c
d e f
と入力が合った時に
a
b
d
c
e
f
のようになる可能性が無いってこと
719デフォルトの名無しさん:2013/09/07(土) 20:58:15.59
パッと見そんな変な動作しそうなコードなさそうだが
720デフォルトの名無しさん:2013/09/07(土) 20:58:28.07
フィルタのロジックに変な細工しない限りそうはならないんでは・・・
721デフォルトの名無しさん:2013/09/07(土) 20:58:29.19
nextTickは単純そうに見えてそこら辺の挙動が奇々怪々なんだよな
バージョンによっても違うし、あまり深く使いたくない
722デフォルトの名無しさん:2013/09/07(土) 20:59:28.14
nextTickの魔術でそう動いてるようにみえる
723デフォルトの名無しさん:2013/09/07(土) 21:01:14.72
何も考えない単なる非同期なら>>718こうなるでしょ
724デフォルトの名無しさん:2013/09/07(土) 21:03:05.83
入力受付もノンブロッキング
書き込みもそれぞれノンブロッキングだから
ロジックによっては絡む可能性もある
725デフォルトの名無しさん:2013/09/07(土) 21:19:43.09
デフォルト遅延評価のHaskellがめんどくさいのと同様
デフォルトがノンブロッキングIOなのもめんどくせーな
726デフォルトの名無しさん:2013/09/07(土) 21:24:15.63
ブロックしないのはnextTickと通常IOなんかのイベントで呼ばれる関数だけだけどな
727デフォルトの名無しさん:2013/09/07(土) 21:28:40.26
>>724の補足
書き込みがノンブロッキングというのはロジックの話で
標準入力は特別にブロッキングタイプのIO
だから2重非同期なわけではない
728デフォルトの名無しさん:2013/09/07(土) 21:46:17.46
皆Vert.xとか使わないの?
729デフォルトの名無しさん:2013/09/07(土) 21:49:10.22
流行りのチャラいものに手を出すのはHaskellerの恥。
730デフォルトの名無しさん:2013/09/07(土) 21:50:46.58
お前に聞いてねえよw
そもそも対応してないだろ
731デフォルトの名無しさん:2013/09/07(土) 21:54:30.61
皆がWeb屋なわけじゃなし、C10Kに直面してるヤツらばかりじゃないでしょ
732デフォルトの名無しさん:2013/09/07(土) 21:56:07.98
C10K問題とかどうでもいいけど
アプリケーションサーバは書かないの?
書きたいケース増えてきたでしょ?
733デフォルトの名無しさん:2013/09/07(土) 21:58:03.48
どうでも良く無いからマルチプロセスやマルチスレッドじゃないんでしょ
734デフォルトの名無しさん:2013/09/07(土) 22:02:01.66
JS知らんなりに頑張って書いてみたけど、コールバックスタイルが嫌すぎる
http://ideone.com/j8ScZa

非同期コールバックだからprocess.stdin.on()に行単位でわたってくるとは
限らんし(入力がttyのときは普通そうなるみたいだけど)
735デフォルトの名無しさん:2013/09/07(土) 22:04:20.97
>>733
考え方の順序が違うよ
アプリケーションサーバーが建てたい、近頃必要な機会が増えてきた
でも現状のやり方じゃ問題が多い
その問題の原因の代表が1ソケット1プロセス方式ってだけでしょ
別にC10K問題がいつも付きまとうわけじゃないよ
736デフォルトの名無しさん:2013/09/07(土) 22:07:02.19
>>734
ttyだから行単位で渡ってくると思って問題ない。
737デフォルトの名無しさん:2013/09/07(土) 22:13:05.80
性能問題が出ない限りノンブロッキングIOを書くのは避けたい
うざいから
738デフォルトの名無しさん:2013/09/07(土) 22:15:48.02
>>736
仕様では明記されてないけど、それってリダイレクトされたりパイプとつなぐと
ちゃんと動かないってことだよね
他の言語の例だと動くけど
739デフォルトの名無しさん:2013/09/07(土) 22:19:33.66
どう動かないと思うんだ?
740デフォルトの名無しさん:2013/09/07(土) 22:20:39.95
>>739
つまりchunkが単語の境界に沿ってないときがあるので、単語やマルチバイト文字の
途中で分割されるわけでしょ
手当てをしないと
741デフォルトの名無しさん:2013/09/07(土) 22:29:16.55
>>740
ああ意味分かった
昔は内部バッファがいっぱいになるほど送られてきた時や時間が合いた場合にそういうこと起きてたけど
Stream3のFlowingModeのときはどうなってるのかね
できる限り\nまで待ってくれるはずだけど、ストリームに内部実装変わってきてるから
実験してみないとどんなものかわからん
742デフォルトの名無しさん:2013/09/07(土) 22:32:22.05
ES6にジェネレータ内包間に合いそうだな、良かった
http://domenic.me/2013/09/06/es6-iterators-generators-and-iterables/
743デフォルトの名無しさん:2013/09/07(土) 22:34:02.05
実は>>734はマルチバイト文字泣き別れまでは考慮してない

どのみちnodeでコード書くの初めてなので、Bufferをデリミタで分割する方法が
よくわからなかったのだけれど、↓の恐ろしいコードを見たらいやになった
http://stackoverflow.com/questions/8920293/split-binary-data-into-array-or-classes-in-node-js
744デフォルトの名無しさん:2013/09/07(土) 23:01:41.36
そこまで汎用的なストリームに適用しようと思ったら
それこそ>>708的実装を考えないといけなくなるんじゃないか?
745デフォルトの名無しさん:2013/09/07(土) 23:01:59.71
>>742
JavaScriptにはLINQのメソッドチェイン方式のほうが馴染むと思う
内包表記よりはyieldやイテレータがまともに使える環境が整うほうがだいぶ早いだろうから、
内包表記が使えるようになる前に既にLINQ的なスタイルが普及してて結局なかったことになる予感
746デフォルトの名無しさん:2013/09/07(土) 23:03:59.02
マルチバイトというけれどサロゲペアとか考えたらバグる実装もあるんじゃない?
サロゲートペアの一部が\nの文字コードと等しくなるケースはあるんだろうか?
747デフォルトの名無しさん:2013/09/07(土) 23:10:16.86
そもそもどんな文字コードで来てるか分からんしな
お遊びのコードのあら探ししてもしかたないだろ
748デフォルトの名無しさん:2013/09/07(土) 23:12:26.90
>>745
まあ配列内包があるのならこれも合っていいんじゃない?
自分もそんなに使われないとは思うけど、
遅延for-ofとかできたら化けるかもよ
749前スレ367:2013/09/07(土) 23:16:49.92
Rubyの場合、>>518>>543 を組み合わせた以下が(個人的には)ベスト
・単語の切り出しは、複雑なステートマシン(>>671)を使う>>543よりも、
 組込みメソッドを組み合わせた >>543 が好ましい
・重複の排除は、ストリーム計算式内で共通変数 uq を更新する >>543 よりも、
 同じことをメソッド uniq として抽象化(>>659)した >>518 が好ましい

class Enumerator::Lazy
  def uniq
    hash = {}
    self.class.new(self) do |yielder, x|
      yielder << x unless hash[x]
      hash[x] = true
    end
  end
end

STDIN.each_line.lazy.flat_map { |line| line.split(/&yen;s+/) }.uniq.each { |token| puts token }

>>688が言うように、uniq は汎用的なストリーム操作だと思うから、Rubyでも
本来は Enumerator::Lazy の組み込みメソッドとして定義されるのが望ましいだろう
750デフォルトの名無しさん:2013/09/07(土) 23:17:10.48
やっぱり途中で切れるみたいだな
http://www.aozora.gr.jp/cards/000148/files/794_14946.html
この辺のわりと大きめなテキストを
iconv -f cp932 -t utf8 | node foo.js
とかやって、↓みたいなコードに流しこんでみるとわかるよ
process.stdin.on('data', function(chunk) {
console.log('[[[' + chunk.toString() + ']]]')
})
こういう手当をしなければいけないのが非同期コールバックの面倒なところ
751デフォルトの名無しさん:2013/09/07(土) 23:17:29.11
jQueryがあるからJSの次のステップとしてはメソッドチェインは正しいな
Promiseとかもその手のものだし
752デフォルトの名無しさん:2013/09/07(土) 23:18:17.10
>>746
そこはさすがにUTF-8を仮定する、とかはしてもいいでしょ
そうじゃないと標準ではテキスト処理できない処理系もあるだろう
753前スレ367:2013/09/07(土) 23:18:27.51
>>749を訂正
X: ・単語の切り出しは、複雑なステートマシン(>>671)を使う>>543よりも、
O: ・単語の切り出しは、複雑なステートマシン(>>671)を使う>>518よりも、
754デフォルトの名無しさん:2013/09/07(土) 23:21:55.82
Rubyも最強の仲間入りか……
755デフォルトの名無しさん:2013/09/07(土) 23:27:58.86
>>750
そういう場合はreadline使ってみたら?
756デフォルトの名無しさん:2013/09/07(土) 23:32:06.66
>>755
え、普通にstreamをブロッキングモード、pull modelでも読めるの?
ならどう考えてもそっちのが楽だな
GUIやネットワークアプリでもないのに非同期コードを書くのは馬鹿らしい
757デフォルトの名無しさん:2013/09/07(土) 23:45:27.07
>>756
よく分からんけど
netソケットでも試してみたけど特に問題なかったよ
758デフォルトの名無しさん:2013/09/07(土) 23:47:55.46
readlineも非同期だぞ
ただ「\n」が来たらハンドラを呼ぶだけ
759デフォルトの名無しさん:2013/09/07(土) 23:48:50.30
ああなるほど、そういうことか
教えてくれてありがとう
760デフォルトの名無しさん:2013/09/08(日) 00:09:38.16
良かった良かった
761デフォルトの名無しさん:2013/09/08(日) 00:13:22.24
スクリプト言語のコマンドライン環境における優位性が浮き彫りになっちゃってるなあ
762デフォルトの名無しさん:2013/09/08(日) 00:14:31.65
>>654
でreadline使わなかったのはコマンドプロンプトでペーストが効かなくなったから
763デフォルトの名無しさん:2013/09/08(日) 00:16:52.59
>>761
それ、コマンドライン実行の話じゃなくて?
764デフォルトの名無しさん:2013/09/08(日) 00:20:10.33
readline使うだけで関数2つ消えて、>>734よりはだいぶ単純になったよ
http://ideone.com/XsSW6r
765デフォルトの名無しさん:2013/09/08(日) 00:33:11.76
早くSetが実装されてくれないと重複取りが面倒くさいな。
766デフォルトの名無しさん:2013/09/08(日) 00:34:33.23
早くSetが実装されてくれないと重複取りが面倒くさいな。
767デフォルトの名無しさん:2013/09/08(日) 00:35:49.96
2回も言わなくていいよ
768デフォルトの名無しさん:2013/09/08(日) 00:40:47.42
TwitterのStreamingAPIとか使う時って各言語どうやるの?
769デフォルトの名無しさん:2013/09/08(日) 00:44:03.22
正直、元々が終わりの分からない入力の例として挙げてるだけだから
それをどう処理するかの部分が書けてれば、
標準入力の表現自体はどうでもいいように思う
770デフォルトの名無しさん:2013/09/08(日) 00:51:51.70
ここまで>>520で言うところの純粋なuniq()が書かれてるの、Haskellだけ?
771デフォルトの名無しさん:2013/09/08(日) 00:58:43.30
振る舞いの結果が同じならどれが純粋もクソもなくね?
772デフォルトの名無しさん:2013/09/08(日) 02:05:44.29
JSでもRubyでも再帰を使ったUniqってあんまりスクリプト言語では存在意義ないっしょ。
なんか、JSだとJITでその辺は最適化されるし、RubyのDarwinではLLVMの最適化が得られる。
Pythonの実行系はPyPyでよくわかってないけどやっぱり再帰処理を内部で高速に暗黙処理してる。
スクリプト言語でHaskellの実装系に似せようとしてるだけ無駄な議論。
773デフォルトの名無しさん:2013/09/08(日) 02:11:03.65
>>743
> 実は>>734はマルチバイト文字泣き別れまでは考慮してない

UTF8でマルチバイト泣き別れって何いってんの?
ASCIIと互換性がある(ASCIIとして処理してもほとんど問題がない)
のがUTF8なのに
774デフォルトの名無しさん:2013/09/08(日) 02:14:26.96
>>773
えーと、たとえば4096バイト毎にチャンクで入力が切られて送られてくるとすると、
文字「あ」を構成する3バイト(0xe3, 0x81, 0x82)の途中で切られることが
普通にあり得る
切られた前半と後半をそれぞれ文字列として別途デコードしようとすると、
切られてしまった「あ」は当然復元できない

ステートフルなストリーミングデコーダを用いて続けて入力を与えるなら
大丈夫だけど
775デフォルトの名無しさん:2013/09/08(日) 02:15:05.24
大抵の標準入力はUTF8とかだろうけど
そうじゃない場合ももっと汎用的に考えてるんでしょ
776デフォルトの名無しさん:2013/09/08(日) 02:15:57.57
>>775
いや、>>774を見てもらえれば分かると思うのだけれどUTF8だろうがダメ
777デフォルトの名無しさん:2013/09/08(日) 02:18:26.49
>>773
普通に泣き別れするだろ。Python2.Xでは処理系がASCIIだからUTF8の文字が
2〜3文字のASCIIに分割される。この時点で何らかの破壊的処理加えれれば
もう戻せなくなる。
逆はないのでPython3,Xからは処理系がUTF8になったから大丈夫だったはず。

JSなんざ詳しくしらんがそういうことはある。
778デフォルトの名無しさん:2013/09/08(日) 02:18:52.88
>>776
今回の例題の場合はASCII文字を暗黙のうちに想定してるでしょ
というか英単語の話でしょ
今まで誰も日本語を分割しようとしてないし、屁理屈乙
779デフォルトの名無しさん:2013/09/08(日) 02:21:00.47
納品するんじゃないんだからw
ちょっと神経質すぎるんじゃありません?
780デフォルトの名無しさん:2013/09/08(日) 02:21:05.52
>>778
ASCIIしか考えていないといいたいのならそれでもいいけど、
>>773が何も分かっていないのは変わらない
781デフォルトの名無しさん:2013/09/08(日) 02:22:16.48
内部の処理系がUTF8であれば何ら問題ないと思うがな。
バイトレベルで切るというかそういう処理をしてるのは文字列処理として不適切。
782デフォルトの名無しさん:2013/09/08(日) 02:22:43.32
>>774
あぁ、そういう話か。

センスねぇな。

そういう場合はな、バイト単位で扱うんじゃなくて
行単位に整形して呼び出す形に先に整形するんだよ。

で、そういう関数が普通にあるんじゃねぇの?って発想する。
783デフォルトの名無しさん:2013/09/08(日) 02:25:05.50
>>781
node.jsのような処理系が低水準のIOでバイト単位で切るのはむしろ当たり前
ストリームの中身は文字とは限らず、バイナリの可能性がある
バイトストリームでしかないのだから
そして低水準のIOを使う限りはユーザに渡ってくる時点で「切られてしまっている」
784デフォルトの名無しさん:2013/09/08(日) 02:25:40.77
一行丸っと取り出して成形するのがベター。
ストリームはさすがにUTF8が破壊されない形で入力を受けることはリスキーすぎる。
785デフォルトの名無しさん:2013/09/08(日) 02:29:00.98
>>783
文字列処理をやるんじゃないんですか?ワンライン(\n or \r or \n\r)までをバイナリとして取り出してUTF8の処理系に
持ち込むのが普通だと思います。Haskellのように副作用がない状態では実現できないことですが。

バイト処理で画像でも加工するのですか?だったらそれでいいですけど。
786デフォルトの名無しさん:2013/09/08(日) 02:32:44.78
必ずしもデータがラインでギリで送られてるとも限らんし
バイナリかもしれないし、本当のエンコーディングなんてのも分からんから
汎用的なストリームAPIでそうなってるのは当たり前
787デフォルトの名無しさん:2013/09/08(日) 02:34:19.95
そもそもどこからどこまでがデータの1ブロックかもわからないよね
788デフォルトの名無しさん:2013/09/08(日) 02:35:33.26
>>782 >>785
何か誤解してない?
>>734って別に好き好んでバイトレベルで処理したかったわけじゃないんだよ
node.js使うの今日が初めてだし上の方の例でみな勝手にバイト単位で切ってくる
低水準のIOを使ってたので、それに従って行単位に切るように
ある程度頑張ったけれども、泣き別れ対策までは完全でないって言ったのが>>743
もっと高水準なreadlineを使って楽になったのが>>764
789デフォルトの名無しさん:2013/09/08(日) 02:37:29.91
Nodeのreadline実装を見ればスッキリするよ
https://github.com/joyent/node/blob/master/lib/readline.js
790デフォルトの名無しさん:2013/09/08(日) 02:39:29.19
>>788
d
流れ把握できました。
文字列処理はFAはreadlineでとりましょうですかね。
791デフォルトの名無しさん:2013/09/08(日) 02:42:02.68
>>790
そんなの常識だろ…
文字列を扱う際にバイト単位の低レベルな操作を行うのはただのバカ
792デフォルトの名無しさん:2013/09/08(日) 02:48:19.31
最近javascriptがカッコいいと思えるようになってきた
普通と違う感じがいい
何だこの感覚
793デフォルトの名無しさん:2013/09/08(日) 02:56:22.44
低水準というけど実は下にJSのインターフェイス実装層があって、
その下に更にクラス実装層があって……ってなってる、アレでも抽象化されてる方

http://www.slideshare.net/shigeki_ohtsu/stream2-kihon
今はStream3でこれは2の話だけど基本は同じ
794デフォルトの名無しさん:2013/09/08(日) 03:02:41.10
github.com/joyent/node/blob/master/lib/readline.js
こいつの290行目にバイト処理をregexでどうにかしようとしてる正規表現が見受けられますね。

ワンラインまでまとめてとりましょう感が伝わってきます。

>>791
バカはひどいっすね。C++でapache module作ってるとそこんとこガチになるんですよ。
795デフォルトの名無しさん:2013/09/08(日) 03:05:19.09
>>764

ほら、書きなおしてやったよ。
http://ideone.com/bQJ04f
796デフォルトの名無しさん:2013/09/08(日) 03:06:16.79
>>794
apache moduleはC言語で書けよ
797デフォルトの名無しさん:2013/09/08(日) 03:07:29.98
>>795
えらい変なことしてますね
798デフォルトの名無しさん:2013/09/08(日) 03:08:25.24
>>794
いやそこよりも、
http://nodejs.org/api/string_decoder.html
これを使ってる点が重要かな
まさに>>774が最後に言ってる「ステートフルなストリーミングデコーダ」
バイトベースの低水準IOをラップして高水準なテキストストリームを構築するには
必ずこの手のものが必要になる
799デフォルトの名無しさん:2013/09/08(日) 03:11:36.07
そこ重要か?
確かにバイトベースが基本でStringDecoderが強く分離して表に現れてるのは
Node設計上の特徴かも知れないが、
800デフォルトの名無しさん:2013/09/08(日) 03:12:57.43
>>795
そのuniqWord()関数は、よけいなことをしすぎているせいで
>>764が書いたuniqFilter()関数に比べて用途が限定されてて、
「その用途」にしか使えない関数になってるようだが
一体何がしたかったんだい?
801デフォルトの名無しさん:2013/09/08(日) 03:14:05.38
>>799
バイトから「文字列」を構築できてしまえば以後は泣き別れの心配もないし
行に割るのも簡単でしょ
802795:2013/09/08(日) 03:14:27.86
再利用性よりも行数を短くしたいのなら。

http://ideone.com/yFKY88

createInterfaceの引数部分は合わせた。
俺のコーディングスタイルじゃないんけどな。
803デフォルトの名無しさん:2013/09/08(日) 03:14:36.62
なんかロジックスタイルの可能性を示したかったんだと思うよ。
804デフォルトの名無しさん:2013/09/08(日) 03:16:23.26
>>800
単に全ての入力を受け取って
初めてでる単語であればコールバックを返す
クラス(のようなもの)ですが?
805デフォルトの名無しさん:2013/09/08(日) 03:16:51.68
「書きなおしてやった」とドヤ顔できるレベルでないのは確かだな
806デフォルトの名無しさん:2013/09/08(日) 03:17:41.26
>>798
うーん
リンク先の使い方をみるにバイトでとってUTF8に変換してるけど、
これをラップして使ってるんだよね?この仕組みがあるってことが重要なのね。

UTF8は2 or 3byteだからこれを直に叩こうとすると死ぬわ。
UTF8の企画書とにらめっこしながら、PerlでUTF8を検知するためのくそみたいな
正規表現を書いたのはいい思い出。あれは透過的に使うべきで、エンジニアに
強いていいものじゃない。
807デフォルトの名無しさん:2013/09/08(日) 03:17:42.96
>>801
は?
バイトから文字列を構築する手段で泣き別れが起こるんだが
別にStringDecoderは半端な部分を教えてくれたり、バッファとして返してくれるわけじゃないぞ
見捨てるかデコード不能になるだけ
それを回避するのは結局自力でやらんといかん
808795:2013/09/08(日) 03:20:39.75
>>800

なんなら、もっと汎用的に単語に区切るだけ版もありますが?

http://ideone.com/1iiCwi

これだとuniqという単語の関数すら必要なくて
寂しかったんだよw
809デフォルトの名無しさん:2013/09/08(日) 03:20:59.64
readline.createInterface(process.stdin, process.stdout)
でいいのに
810デフォルトの名無しさん:2013/09/08(日) 03:23:07.97
uniq関数なんて作る必要ない
俺はSetちゃんを待つ

仕様には超絶楽な方法が書かれているのに
自分で書く気なんて起るか!!
811795:2013/09/08(日) 03:23:19.06
ここで出てる仕様のuniqは以前出た単語を
出さないってだけなので文字にさえ分割してしまえば
すごく単純なコードになっておもしろみがないんだよな。
一番簡単なキャッシュに仕組みと同じ。
812795:2013/09/08(日) 03:23:48.85
>>809
nodeしらねぇもんw
813デフォルトの名無しさん:2013/09/08(日) 03:25:10.73
>>807
うわホントだ。ウソいってごめん
これじゃ単にtoString()するのと違いなくね?
814デフォルトの名無しさん:2013/09/08(日) 03:25:29.57
Nodeも紆余曲折してきたから、書き方はいくつかある。
815デフォルトの名無しさん:2013/09/08(日) 03:25:37.16
>>802

ダメ出しされてますけど、意味の無い再帰を使うより何倍もましになりましたね。
今は英語しか使えないスタイルですけど、形態素解析エンジン入れれば日本語も
充分なんじゃないですか。
816デフォルトの名無しさん:2013/09/08(日) 03:28:04.97
UTF8なら日本語使えるでしょ?
readline使ってるんだから改行区切りでコールバックでしょ?
(改行含めたASCII文字が文字の2バイト目以降に現れることがないのがUTF8)
817デフォルトの名無しさん:2013/09/08(日) 03:28:14.47
>>815
入れ子関数の間違い、か?
元々再帰は使っていないように見える
818795:2013/09/08(日) 03:32:36.45
createInterfaceは修正した。

で、まとめ

単語単位のuniq関数版
http://ideone.com/bQJ04f

関数使わない版(その分行数は一番短い)
http://ideone.com/yFKY88

汎用的に単語区切りでコールバックする関数だけを作った版
http://ideone.com/1iiCwi


あとは実際の使用目的で決めるもんだが、
ここでやってるのはただのサンプル作りなので
どれがいいかは決められん。
819デフォルトの名無しさん:2013/09/08(日) 03:32:52.97
>>817
ただの副作用もった関数の間違いだww
まぁ、副作用もたせないで書くことを前求めててくそコードになってたんでいいんじゃないですか。
JSでatomicな関数オブジェクト作れればもういいですよ。
atomic無理ならC++でエクステ書くか、再帰かければいいです。
820デフォルトの名無しさん:2013/09/08(日) 03:36:01.97
あー、callbackに副作用を集中させればいいのですか。
821デフォルトの名無しさん:2013/09/08(日) 03:39:40.40
>>764
> uniq(words).forEach(function(x, _, _) { console.log(x) })

この部分ってnodeの思想とあわない気がするんだよね。

このコードではwordsの中から重複しない単語リストを求めてからforEachで処理してる。

つまり重複しないとわかった時点で出力するよりも、
レスポンスは悪いわけ。

wordsの数はたかが知れてるから問題無いだろうけど、
nodeはレスポンスを重視した実行環境だから。
822デフォルトの名無しさん:2013/09/08(日) 03:42:34.24
>>821
なるほど、そう説明されると意図が分かった
823デフォルトの名無しさん:2013/09/08(日) 03:46:10.82
その辺はジェネレータだともっと綺麗なんだろうけど
ジェネレータなしでやるとコールバックになりますよってことかね
824デフォルトの名無しさん:2013/09/08(日) 03:49:33.84
ジェネレータはコールバックの外の部分を
まとめる(モジュール化というか・・・)もんでしょ?
825デフォルトの名無しさん:2013/09/08(日) 03:58:22.73
>>821
なんにせよどっかに様態を持たせないと前に現れたものなのかどうなのか
わからくないですかね。
もっと低レイヤーで処理しようとしても、関数型言語をfeatureしても無理、なきがします。
826デフォルトの名無しさん:2013/09/08(日) 04:02:55.25
>>813
いや君の考え方で合ってるよ
余ったバッファend()で返してくれる機能がある
でもそもそもそれを使わなくてもいいし、readlineはこれに頼ってない

何故なら泣き別れが起こるバイト列が渡された時は
正常にパースできるとこまでが返されて
半端に残ったバイト列は保持され、次writeした時に結合されるから

これがないとかなり大変だね
827デフォルトの名無しさん:2013/09/08(日) 04:07:59.61
string_decoder
思ったより随分簡潔
https://github.com/joyent/node/blob/master/lib/string_decoder.js
828デフォルトの名無しさん:2013/09/08(日) 04:08:32.87
>>825
すいませんが、何に対して意見しているのかわかりません。
関数型言語でも状態は持っています。
状態が変数に再代入が出来ないだけです。
829デフォルトの名無しさん:2013/09/08(日) 04:13:55.11
致命的だな
830デフォルトの名無しさん:2013/09/08(日) 04:18:56.85
>>828
すみません。関数型云々は忘れましょう。

言いたいのは、応答速度あげようとしてもどっかに様態を持たないと
前に現れた単語を判別するすべがなくないですか。

nodeやjsは詳しくないですがリアルタイムに単語をユニークにしようとしている
と見受けられたのでそう言いました。
831デフォルトの名無しさん:2013/09/08(日) 04:23:27.97
リアルタイムに単語をユニークにするのがダメなら
リアルタイムに文字列を単語に切り分けるのもダメだな
そこはバイトバッファを少しずつ走査してもらわないと
832デフォルトの名無しさん:2013/09/08(日) 04:28:27.38
ダメってほどでもないと思いますけどね。
自分はC++,Python, Cを使いますけど、いずれでも実現できない芸当だと思います。
833デフォルトの名無しさん:2013/09/08(日) 04:31:36.78
エンコーディング分かってたら可能でしょ
splitとかのネイティブ実装もそれと近いことやってんだろうし
834デフォルトの名無しさん:2013/09/08(日) 04:39:58.32
本気でやれって言われたら、CのファイルポインタとCPUのレジスタを使用して読み込みながら、CPUに一度検知したものをスタックしていって、読み終わったらフラッシュが、一番早いですが、、、そのまでやろうとは思えませんね、、、

あと、なんでエンコーディングがわかったらできるんです?
835デフォルトの名無しさん:2013/09/08(日) 04:41:34.99
ある程度大きくなったらプロセス分離が一番いいと思う
そこで気になるのは受け渡しのオーバーヘッドだけど
JSのWorkerはオブジェクトの委譲ができるけど
他の言語ってそういうのできるの?
836デフォルトの名無しさん:2013/09/08(日) 04:46:12.26
>>834
速い遅いの問題じゃないよ
速さ重視ならそもそも分割する必要なんて無い
重い処理をする時にある程度分割してノンブロッキングにした方がいいねってことでしょ

エンコーディングがわかったらそのコーディングのルールの中で
目的の文字に当たるバイト列見つけられるでしょ
837デフォルトの名無しさん:2013/09/08(日) 04:46:37.33
下手な方法だとプロセス間通信とかあります。

nodeだとC++でエクステンション書くのが早いそうですよ。
スクリプト言語の限界をここでは感じますね。
838デフォルトの名無しさん:2013/09/08(日) 04:48:24.78
現実的には1MBずつくらい例のStringDecoderに渡していくのがいい?
839デフォルトの名無しさん:2013/09/08(日) 04:49:09.99
スレタイ読んでー
CやC++の話はしてないよ
840デフォルトの名無しさん:2013/09/08(日) 04:57:34.28
>>836
ノンブロッキングですかーnginxのコードをいじってますけど、nodeできるのかな。
そこはわかんないので、詳しい方に投げたいです。

分割送信をしてノンブロッキングで適当に送信しても内容が保障されるには、確かに
文字コードをIFレベルで知ってる必要がありますね。nodeのファイルストリームはasciiで
受け取ってるみたいなので、そこかえないと難しいのではないでしょうか。
841デフォルトの名無しさん:2013/09/08(日) 05:02:06.20
エクステの話はしません、ごめんなさい。
842デフォルトの名無しさん:2013/09/08(日) 05:03:31.74
何が難しいのか分からんな
それに>>838でいいじゃん
843デフォルトの名無しさん:2013/09/08(日) 05:03:33.98
>>839
じゃあこの下り全体がスレ違いだな
バトルしてないし
844デフォルトの名無しさん:2013/09/08(日) 05:12:30.39
なんだかすごい脱線しましたが、>>838のやつで実装できると思います。
845デフォルトの名無しさん:2013/09/08(日) 05:36:29.36
>>837
プロセス間通信とメモリ空間の安全な委譲じゃ次元が違うと思う
あと必ずしもネイティブで書いたのがスクリプトを上回るとは言えないよ

こういう例もあるし
tech.a-listers.jp/2012/10/10/faster-than-c/

これは動的に最適化された関数を作ってevalするみたいな
スクリプト言語のポテンシャルを上手く引き出してる
将来的にはもっとJITのサンプリングに期待できるしね
846デフォルトの名無しさん:2013/09/08(日) 07:19:37.54
>>845
それって、コードこれだろ?
https://github.com/felixge/node-mysql

evalなんて一つも使ってないんだが?

evalはevilっていってな、
どうしても使わなければ出来ない時以外
使うべきではないんだよ。
遅いし使うことなんてめったにないし。
847デフォルトの名無しさん:2013/09/08(日) 07:28:41.79
>>845
スクリプト言語のポテンシャルを引き出したというよりも、

動的言語は静的に比べてパフォーマンスは悪い。
しかしV8エンジンは頑張っていて、特定の書き方に限って
最適化がうまく出来る場合がいくつかある。

そのV8エンジン特有の最適な書き方を見つけ出し、
スクリプト言語で自由に書くという発想ではなく、
V8エンジンに依存した制限された書き方をすることで
パフォーマンスを上げているようにしか思えない。
848デフォルトの名無しさん:2013/09/08(日) 07:34:50.01
JSのコードを高速化するのに使った労力を
Cのエクステンション書くのに使ったら
もっと楽に高速な実装が出来てた気がする
849デフォルトの名無しさん:2013/09/08(日) 08:04:55.05
一晩でスレがすごく伸びたけど、結局のところJavascriptは
>>697については前者止まりって結論でOK?
850デフォルトの名無しさん:2013/09/08(日) 08:29:37.43
仮にnodeがダメでもJSがダメということにならないから
言語仕様は反証不可能
851デフォルトの名無しさん:2013/09/08(日) 09:03:11.74
ネイティブと速度比較なんて勝ち目のない戦いはよせ
速いと言われてるJavaScriptですらJavaより遅いのが現実なんだから
852デフォルトの名無しさん:2013/09/08(日) 09:06:57.32
速いJavaScript=node=ネイティブ
853デフォルトの名無しさん:2013/09/08(日) 09:48:42.58
Objective Cもネイティブにコンパイルされるがオブジェクト使うと遅い
動的型だからね
854デフォルトの名無しさん:2013/09/08(日) 10:30:03.70
標準入出力に力を入れてない点では
SmalltalkとJavascriptで同じなのに、
あっさりと完璧に解いてみせたSmalltalkに対して、
グダグダと議論した上にしょぼい解答のJavascript……

どこで差がついたのか
855デフォルトの名無しさん:2013/09/08(日) 11:19:39.39
仕様の詳細がわからないので何とも言えないが
nodeならsync系の関数もあるからジェネレータ作ればできるんじゃないのか?
なんでわざわざコールバックで実装してるのか知らんが
856デフォルトの名無しさん:2013/09/08(日) 11:53:01.06
SmalltalkにはRubyみたいなLazyとか無いはずなのに
どうしてちゃんと仕様どおり動くの?
もしLazy使わなくていいなら、
RubyでもLazy使わずに後者で書けるのか?
それともRubyはLazyが入るつい最近まで
Smalltalkなんかに負けてたの?
教えてエロい人!
857デフォルトの名無しさん:2013/09/08(日) 11:55:02.44
>>855
その通り。
ほんと、JSの事わかってないよな
アホどもは。
858デフォルトの名無しさん:2013/09/08(日) 11:55:47.21
>>854
完璧に解いたってどれ?
大差ないだろ。
ほんの少しライブラリが有るかどうかの差。
859デフォルトの名無しさん:2013/09/08(日) 12:02:37.78
JSとSmalltalkの比較

process.stdin.resume();
process.stdin.setEncoding('utf8');
var readline = require("readline");
var rl = readline.createInterface(process.stdin, process.stdout);
var seen = {};
rl.on('line', function (line) {
 var words = line.match(/\S+/g) || [];
 words.forEach(function(word) {
  if (word in seen) {;
   seen[word] = true;
   console.log(word);
  }
 });
});
860デフォルトの名無しさん:2013/09/08(日) 12:02:42.75
ところが、このお題は>>697的な観点から言って
イケてるライブラリを作れるかどうかの差なんだなぁ
861デフォルトの名無しさん:2013/09/08(日) 12:03:12.26
Stream extend [
 words [
  ^Generator on: [:g | self linesDo: [:line | line subStrings do: [:str | g yield: str]]]
 ]
 uniq [
  ^Generator on: [:g |
   | seen |
   seen := OrderedCollection new.
   self do: [:each | (seen includes: each) ifFalse: [g yield: (seen add: each)]]]
 ]
]
862デフォルトの名無しさん:2013/09/08(日) 12:03:43.67
>>860
違うぞ?
863デフォルトの名無しさん:2013/09/08(日) 12:04:42.47
Smalltalkのuniq完璧や!
864デフォルトの名無しさん:2013/09/08(日) 12:06:51.54
標準入出力初期化部分の重要ではない部分を削除してみる。

var seen = {};
rl.on('line', function (line) {
 var words = line.match(/\S+/g) || [];
 words.forEach(function(word) {
  if (word in seen) {;
   seen[word] = true;
   console.log(word);
  }
 });
});
865デフォルトの名無しさん:2013/09/08(日) 12:07:33.46
>>862
違わないぞ?JSがうんこすぎてイケてないからって目を背けるな
866デフォルトの名無しさん:2013/09/08(日) 12:08:43.21
とりあえず深呼吸して>>671を読もう
その後でコードを読んで判断しよう
867デフォルトの名無しさん:2013/09/08(日) 12:09:19.99
wordsの部分が標準ライブラリにあると仮定する。

var seen = {};
rl.on('line', function (line) {
 line.words.forEach(function(word) {
  if (word in seen) {;
   seen[word] = true;
   console.log(word);
  }
 });
});
868デフォルトの名無しさん:2013/09/08(日) 12:15:08.33
単語を短くして一行につないでみる。

var seen = {};
rl.on('line', function (line) {
 line.words.forEach(function(w) { if (w in seen) { seen[w] = true; console.log(w); }});
});

そして関数部分を分離して、更に一行につないでみる。

var seen = {};

function words(w) { if (w in seen) { seen[w] = true; console.log(w) }}

rl.on('line', function (line) { line.words.forEach(); });
869デフォルトの名無しさん:2013/09/08(日) 12:15:29.71
あとはuniq関数を定義して、seenをuniq内部に閉じ込めれば完成
Smalltalkまであと一歩!
870デフォルトの名無しさん:2013/09/08(日) 12:17:00.88
さらに関数を分離してみる。

var seen = {};

function words(w) { if (w in seen) { seen[w] = true; console.log(w) }}
function lines(line) { line.words.forEach(word) }

rl.on('line', lines);


結論としては、ただの書き方の違いなのである。
871デフォルトの名無しさん:2013/09/08(日) 12:18:28.45
>>868
おい、どうせ動かないコードだからって検証もしてないテキトーなコード載せんな
872デフォルトの名無しさん:2013/09/08(日) 12:19:20.84
結局uniqのアルゴリズムとハンドラを分離できてない件
873デフォルトの名無しさん:2013/09/08(日) 12:20:37.29
>>869
seenを閉じ込めればいいの? くくるだけだけど。

var words = (function() {
 var seen = {};
 return function (w) { if (w in seen) { seen[w] = true; console.log(w) }}
})());
874デフォルトの名無しさん:2013/09/08(日) 12:23:34.83
>>873
その関数をwords.forEach内で使うと
各行毎の重複しか判定できなくない?
875デフォルトの名無しさん:2013/09/08(日) 12:29:31.85
再利用するコードなら少々冗長だろうが関係ないだろう
その点では利用者側から見て>>872が綺麗に実現できる方がずっと重要だ
まさかuniqが必要になるたびにコピペするつもりか?
876デフォルトの名無しさん:2013/09/08(日) 12:57:48.31
コピペするんじゃない?
長々と書いたけど結局出来てないみたいだし
877デフォルトの名無しさん:2013/09/08(日) 13:11:14.78
>>871
まあまあ、慌てなさんなw 書き方次第だよっていう考え方を示したまでだよ。

http://ideone.com/tgfO5H

・11行(7行 ・・・ 標準入出力の初期化と、改行だけの行を除いた場合)
process.stdin.resume()
process.stdin.setEncoding('utf8')
var rl = require("readline").createInterface(process.stdin, process.stdout)

String.prototype.words = function() { return this.match(/\S+/g) || [] }
function words(f) { return function (l) { l.words().forEach(f) } }
function uniq(f) {
  var seen = {}
  return function (w) { if (!(w in seen)) { seen[w] = true; f(w) } }
}
rl.on('line', words(uniq(function(w) { console.log(w) })))

-----------------------------------------------------------------------------------------------
・11行
Stream extend [
 words [
  ^Generator on: [:g | self linesDo: [:line | line subStrings do: [:str | g yield: str]]]
 ]
 uniq [
  ^Generator on: [:g |
   | seen |
   seen := OrderedCollection new.
   self do: [:each | (seen includes: each) ifFalse: [g yield: (seen add: each)]]]
 ]
]
878デフォルトの名無しさん:2013/09/08(日) 13:41:50.14
>>846
お前の目は節穴か、new Function使ってんだろ
それにevalが遅い?何言ってんだか
evalで作った関数はJITも効くし、最適化の1手法なんだよ
github.com/felixge/faster-than-c
eval is awesomeと言ってるじゃねえか

>>847,848
現実を認めようね
負け惜しみの希望論はいらない
879デフォルトの名無しさん:2013/09/08(日) 13:45:32.33
grep -r 'Function' .

反応がない。new Functionも使われてないようだw
880デフォルトの名無しさん:2013/09/08(日) 13:49:22.84
process.stdin.resume()
process.stdin.setEncoding('utf8')
は要らない。
881デフォルトの名無しさん:2013/09/08(日) 13:55:25.08
>>877
一見Pythonのコードと同じで、フローが逆になってるのが面白いな
継続渡しスタイルっぽい感じ

>>880
その2行はそのサイト(ideone.com)が最初にデフォルトで挿入するみたい
882デフォルトの名無しさん:2013/09/08(日) 13:56:11.31
>>879
本当に節穴だったか
github.com/felixge/faster-than-c/blob/master/figures/mysql2-vs-new-parser/benchmark/new-parser/Protocol.js
883デフォルトの名無しさん:2013/09/08(日) 13:56:34.29
>>880
うん。ideoneが勝手に入れるから、
ideone特有の何かが有るんじゃないの?って
思ってそのままにしただけ。
884デフォルトの名無しさん:2013/09/08(日) 13:57:43.01
>>882
実際のライブラリの方でお願いしますwww

なんで使ってないんですか?w
885デフォルトの名無しさん:2013/09/08(日) 14:10:11.81
JavaScriptはPython/C#方式のyieldを入れるんなら
カウンターパートのasyncも入れればいいのに
プッシュ地獄のJavaScriptにこそ必要だろ
886デフォルトの名無しさん:2013/09/08(日) 14:13:04.19
>>877
このスタイルで、例えば途中で読み込みやめたい場合ってどうするの?
>>509の例だと、
stream = uniq(flatten(x.split() for x in sys.stdin)
としたとき、
for i, x in stream:
 if i > 2:
  break
とか書いたり、streamをtakewhileに渡したりできる
 
887886:2013/09/08(日) 14:13:49.00
- for i, x in stream:
+ for i, x in enumerate(stream):
888デフォルトの名無しさん:2013/09/08(日) 14:16:09.30
>>886
例外投げる
889デフォルトの名無しさん:2013/09/08(日) 14:16:24.92
>>856
まあRubyでLazy使わんでも>>553を書けんことはない。

require "set"

class IO
 def words
  Enumerator.new do |e|
   each_line{ |line| line.split(/\s+/).each{ |str| e.yield(str) } }
  end
 end
end

class Enumerator
 def uniq
  Enumerator.new do |e|
   seen = Set.new
   each{ |x| e.yield(x) if seen.add?(x) }
  end
 end
end

$stdin.words.uniq.each{ |x| puts x }
890デフォルトの名無しさん:2013/09/08(日) 14:17:44.87
>>888
なるほど、ありがとう
891デフォルトの名無しさん:2013/09/08(日) 14:19:38.64
>>885
なにそれどんなの?
892デフォルトの名無しさん:2013/09/08(日) 14:38:05.09
>>563からseenとuniq切り出した、以下比較

#ロジックはちゃんと切り分けたいよ派(整理整頓主義)
filter uniq { begin { $seen = @{} } process { if (!$seen.Contains($_)) { ($seen.($_)=$_) } } }
cmd /c type con | % { -split $_ } | uniq

#いや面倒だからワンライナーがいいよ派、変数名も適当フィルタも文字列前提でいいよ派(やっつけ仕事主義)
cmd /c type con | % { -split $_ } | % { $a=@{} } { if (!$a.$_) { ($a.$_=$_) } }

#ワンライナーはいいけどseenはちゃんと閉じ込めたいよ派(コマンド長すぎ本末転倒主義)
cmd /c type con | % { -split $_ } | & { begin { $seen=@{} } process { if (!$seen.Contains($_)) { ($seen.($_)=$_) } } }
893デフォルトの名無しさん:2013/09/08(日) 14:41:10.71
ロジック切り分けるんならちゃんとインデントと改行してよみやすくしろよ
894デフォルトの名無しさん:2013/09/08(日) 14:41:53.46
>>891
// C#5.0
button.Click += async (object sender, EventArgs e) => {
 button.IsEnabled = false;
 using (var reader = File.OpenRead("file.txt")) {
  string line;
  while ((line = await reader.ReadLine()) != null) { // 一行非同期に読み込む
   dialog.Content = line;
   await dialog.ShowAsync(); // 非同期にユーザーの応答を待つ
  }
 }
 button.IsEnabled = true;
};
継続渡しパターンを言語に組み込んだものだよ
awaitするたびにいったん処理が戻り、非同期操作が終わったらその後から再開する
yieldと似てるけど動作が真逆でしょ?
895デフォルトの名無しさん:2013/09/08(日) 14:44:37.25
>>894
訂正
ReadLine -> ReadLineAsync
896デフォルトの名無しさん:2013/09/08(日) 14:47:31.58
>>888
JSはエラーは握りつぶす一方で、フロー制御には例外を使うんだね
897デフォルトの名無しさん:2013/09/08(日) 14:52:55.31
>>894
うーんと、非同期処理が終わったら帰ってくるんだよね?
終わったっていうのはどういうところで判断してるの?
returnされたら?
それだったら非同期処理から非同期処理呼びたい時は全部await使うことになって
コールバックの仕組みと共存できないってことになるのかな?
898デフォルトの名無しさん:2013/09/08(日) 14:55:26.79
>>JSはエラーを握りつぶす
???
899デフォルトの名無しさん:2013/09/08(日) 15:02:12.13
>>893
この辺はやっぱよく使う言語の習性と個人の性格が出るねぇ
自分だとこのくらいの関数定義なら一行の方が読みやすい、くらいの勢いだから

filter uniq {
 begin { $seen = @{} }
 process {
  if (!$seen.Contains($_)) { ($seen.($_)=$_) }
 }
}
cmd /c type con | % { -split $_ } | uniq
900デフォルトの名無しさん:2013/09/08(日) 15:04:10.89
>>897
そう。returnされたら完了。
いわゆるFutureオブジェクト(C#ではTask)を使うので、コールバックを受け取るメソッドはそのままawaitできない。
その場合は専用のクラス(Promise相当ね)を使ってラップすることで簡単にawaitableにできる。
901デフォルトの名無しさん:2013/09/08(日) 15:05:11.40
>>899
なら他のスタイルにいらんイチャモンつけんでよかろ
全ては機械のためじゃなくて人が理解しやすいようにスタイルというもんはあるんだからさ
902デフォルトの名無しさん:2013/09/08(日) 15:06:36.29
数と文字列との加算どころか、リストや関数と加算しても
エラーにならないのは、握りつぶしてるんじゃなくて
それがJavascriptでは正しい動作という文化だから
903デフォルトの名無しさん:2013/09/08(日) 15:10:49.13
エラーになってるわけではなく、
単にそういう解釈をするって
定義されているだけの話だね。
904デフォルトの名無しさん:2013/09/08(日) 15:11:08.22
>>901
あ、ごめんあんまりいちゃんもん付けてる自覚はなかった
ネタ風味にはしてたけど
905デフォルトの名無しさん:2013/09/08(日) 15:11:36.09
>>882
これどういう基準で速いって言ってるんだ?
parseRowだけ速いってオチじゃないよな?
906デフォルトの名無しさん:2013/09/08(日) 15:14:48.56
>>900
JSでは逆にyieldベースで似たことやろうとしてると思う
ここのCOの例みたいなのがいくつかある
tech.nitoyon.com/ja/blog/2013/06/27/node-yield/
要はyieldで呼びたい関数を返して、返された側(CO)で適切なコールバックにフックを登録して
それが呼ばれたら適切な値を渡してイテレーターを1つ進めるというようなことをやってると思う
907906:2013/09/08(日) 15:17:44.50
これなら結局はコールバック式を用いてるにすぎないから、
呼び出された先が更にコールバック式でも、擬似await式でも気にする必要ないと思う
908デフォルトの名無しさん:2013/09/08(日) 15:21:55.36
ま、重要なのは目的を達成することであって
手段じゃないからな。
909デフォルトの名無しさん:2013/09/08(日) 15:24:34.41
設計とか手段が目的の一つになる場合も
910デフォルトの名無しさん:2013/09/08(日) 15:27:17.20
>>909
仕事じゃない場合はそうかもねw
911デフォルトの名無しさん:2013/09/08(日) 15:36:39.49
言語の差って言うほど無いんだよね。
ライブラリのほうが圧倒的に差が出る。
912デフォルトの名無しさん:2013/09/08(日) 15:41:03.23
そりゃそうだ
というかそのうちすべての言語は近づいていって
3種類くらいに落ち着くんじゃないか?
913デフォルトの名無しさん:2013/09/08(日) 15:41:57.23
お前それコボラーにも同じ事言えんの?
914デフォルトの名無しさん:2013/09/08(日) 15:43:31.66
今のブラウザシェアの様な感じにはなると思う
915デフォルトの名無しさん:2013/09/08(日) 15:44:24.63
関数型と手続き型はだいぶ近付いて来たけど
論理型は孤高のまま
916デフォルトの名無しさん:2013/09/08(日) 16:13:16.95
しょぼい言語使ってるヤツほど
言語に差は無いと言いたがる
917デフォルトの名無しさん:2013/09/08(日) 16:17:56.77
>>916
必死だね
918デフォルトの名無しさん:2013/09/08(日) 16:19:56.01
いい加減使い分けを覚えろって話だよな
これだけやって得手不得手が見えてる状況でまだ言うんだから笑えるw
919デフォルトの名無しさん:2013/09/08(日) 16:23:47.48
これみても差がないなんて言えるの?

・11行(7行 ・・・ 標準入出力の初期化と、改行だけの行を除いた場合)
process.stdin.resume()
process.stdin.setEncoding('utf8')
var rl = require("readline").createInterface(process.stdin, process.stdout)

String.prototype.words = function() { return this.match(/\S+/g) || [] }
function words(f) { return function (l) { l.words().forEach(f) } }
function uniq(f) {
  var seen = {}
  return function (w) { if (!(w in seen)) { seen[w] = true; f(w) } }
}
rl.on('line', words(uniq(function(w) { console.log(w) })))

-----------------------------------------------------------------------------------------------
・11行
Stream extend [
 words [
  ^Generator on: [:g | self linesDo: [:line | line subStrings do: [:str | g yield: str]]]
 ]
 uniq [
  ^Generator on: [:g |
   | seen |
   seen := OrderedCollection new.
   self do: [:each | (seen includes: each) ifFalse: [g yield: (seen add: each)]]]
 ]
]
920デフォルトの名無しさん:2013/09/08(日) 16:25:30.99
>>919
無理やりギュウギュウに詰め込んでるだけやん。普通に書けばこうなる。


process.stdin.resume()
process.stdin.setEncoding('utf8')
var rl = require("readline").createInterface(process.stdin, process.stdout)

String.prototype.words = function() {
 return this.match(/\S+/g) || [];
}

function words(f) {
 return function (l) { l.words().forEach(f) }
}

function uniq(f) {
  var seen = {}
  return function (w) { if (!(w in seen)) { seen[w] = true; f(w) } }
}

rl.on('line', words(uniq(function(w) { console.log(w) })))
921デフォルトの名無しさん:2013/09/08(日) 16:35:36.53
俺も大差ないと思う。
言語仕様の差じゃねぇもん。

言語の部分だけで、10行が1行ぐらいになったら
大差あると思うけどさ。
922デフォルトの名無しさん:2013/09/08(日) 16:47:19.01
そのnodeの例はそれ自体としては面白いんだけどさ
普段から全部CPS(継続渡しスタイル)で書きたいか?と考えると
使い勝手に如実に差がある感じはする

まあnodeのスタイルがCPSだというのなら仕方がないけれども
上で誰かが話してた内部イタレータと外部イタレータの違いみたいな話じゃないか?
923デフォルトの名無しさん:2013/09/08(日) 16:59:55.99
>922
V8がES6サポートしたら
>713,714
みたいなんで書けばいいと思いますよ
924デフォルトの名無しさん:2013/09/08(日) 17:03:22.84
>>566>>571あたりで大口叩いてたから期待してたのに
出てきたコードがこれなのでガッカリだ
925デフォルトの名無しさん:2013/09/08(日) 17:04:25.65
>>924
言い返せないお前にがっかりだw
926デフォルトの名無しさん:2013/09/08(日) 17:05:57.34
Nodeでもイテレーター等使いたいけど、まだ見せかけ実装だからアレ
いま丁度JSは言語が10年ぶりに大きく変わる微妙な時期に差し掛かってる

今年の11月がラストコールの予定だから
来年実装が一気に進むとは思うが
927デフォルトの名無しさん:2013/09/08(日) 17:06:08.80
>>923
その例だとIOは相変わらずコールバック(プッシュ型)だけど、
そこが上で出てたasync/awaitみたいな方法で普通のプル型にできるんなら
文句はなさそうかな……
その辺、今はまだ発展途上って感じがするね
928デフォルトの名無しさん:2013/09/08(日) 17:08:32.80
forEach等だって導入されてからそんなに立ってないし
どうとでも書けることにはどうとでも書けるから
正直言っていかに簡潔なコードを書くかみたいな探究心がJSerには足りんのかもしれん

すくなくとも自分は見合ってないと思う
言語が悪いんじゃないから言語に申し訳がない
929デフォルトの名無しさん:2013/09/08(日) 17:09:26.36
>>925
RubyやPythonやSmalltalkに比べて
どこが優れてるの?
いいとこイーブンじゃない?
930デフォルトの名無しさん:2013/09/08(日) 17:10:17.90
>>928
だから十分簡潔だろ。
頭大丈夫か?
931デフォルトの名無しさん:2013/09/08(日) 17:11:14.71
簡潔なコードを書けるかどうかは
ライブラリによる所が大きい。
932デフォルトの名無しさん:2013/09/08(日) 17:11:50.20
プッシュ型とかプル型ってどこのこと言ってるの?
何が嫌なのか分からんな
IOの話しならreadline使えば差異は無いんじゃないか?
933デフォルトの名無しさん:2013/09/08(日) 17:14:06.20
>>930
ここでいう十分とは、ここにいる人を満足させられるということだと思ってる
そっちの面での戦いは厳しいわ
実アプリがどうのとかじゃなくて
934デフォルトの名無しさん:2013/09/08(日) 17:16:08.45
>>932
プル型はconsumerが主体になってproducerからデータをひっぱる(pull)
プッシュ型はproducerが主体になってconsumerにデータを渡す(push)
主体の違い
普通のGUIプログラミングのコールバックとか
SAXのようなコールバック式のストリームパーサみたいなのがpush型
while ((c = getchar()) != EOF)
みたいなのがpull型
935デフォルトの名無しさん:2013/09/08(日) 17:19:01.69
で、consumer側が主体になってドライブするpull型を俺が好むのは、
データを必要としてる側が「必要に応じて」ドライブするほうが
明らかに楽かつ制御しやすいから

普通はみんなそうだと思うのだけれど
936デフォルトの名無しさん:2013/09/08(日) 17:23:26.67
>>935
必要に応じてって、どこが終わりかわからないソケットで今回のケースは
定期的に調べてバッファを貯めて1行分溜まったと判断出来たら切り出して処理をするよりも、
内部的にそれをやってもらって、行単位でプッシュしてくれることにこしたことないんじゃない?
例の「レイテンシ」の話もあるしさ
間違ってる?
937デフォルトの名無しさん:2013/09/08(日) 17:36:11.12
内部的に色々やってもらって、行単位になったデータをpullしたいってことでしょ
938デフォルトの名無しさん:2013/09/08(日) 17:38:28.62
>>936
何か勘違いしてるみたいだけど、プル型だからといって
別にポーリングになる訳じゃないよ
939デフォルトの名無しさん:2013/09/08(日) 17:44:01.80
ポーリングじゃないなら粒度が違うだけで実質プッシュ型だと思うが……
940デフォルトの名無しさん:2013/09/08(日) 17:46:12.72
よくわからん。それで何のメリットが?
Nodeも.read(size)で好きな時に好きなだけプルできるけど
それやるとめんどくさくなるだけだと思うんだけど。
941デフォルトの名無しさん:2013/09/08(日) 17:51:02.06
.words.next() で単語を1個ずつ引っ張ってくるのがpull?
942デフォルトの名無しさん:2013/09/08(日) 17:55:24.17
ポーリング:
producerにデータがあるか尋ねる→あるかないかが即座に回答が返ってくる
これを定期的に繰り返して、データがあったら受け取る

割り込み:
producerからデータがある場合にconsumerにイベントで通知するので無駄がない

一般的なブロッキングIO:
consumerはデータが欲しいと要求する。データが来るまでconsumerの制御は
そこでブロックする。データが来た時点で即座にconsumerに制御が戻り、
consumerの処理が中断していたところから再開される。
内部的にはトランポリンと呼ばれる仕組みが使われる。producerからの
イベントをトリガとしているので、やはり無駄がない。

非同期のプル型:
consumerにはブロッキングIOと同じように見える。ただし実際には
「consumerは」そこで止まっているけれどもプロセスはブロックしていない。
プロセス内で自前でコンテキストを管理しているコントローラに制御が戻るだけで
そっちは動いている。データが来た時点で、コントローラがconsumerの仕事を
再開させる。
943デフォルトの名無しさん:2013/09/08(日) 18:02:50.60
http://e-words.jp/w/E3838EE383B3E38396E383ADE38383E382ADE383B3E382B0I2FO.html


ノンブロッキングI/O 【 non-blocking I/O 】 非同期I/O / asynchronous I/O


コンピュータ内部のCPUと周辺装置のデータ入出力(I/O)において、
データの送受信の完了を待たずに他の処理を開始する方式。並列処理の一種。

ノンブロッキングI/Oでは、I/O処理と並列に、データの送受信が完了していなくても
可能な処理を進め、送受信が済まないと進められない処理にたどりついた場合に、
そこで送受信の完了を待つ。これに対し、正常に送受信が完了したかどうかの結果を待ち、
送受信処理に完了してから残りの処理を行う方式を同期I/O(ブロッキングI/O)という。
944デフォルトの名無しさん:2013/09/08(日) 18:06:28.84
なんか>>942の書き方だと
ブロッキングI/Oが優れているように見えるけど、
他にやれることがあったとしても、ブロックして止まるから
効率は悪いんだよな。
945デフォルトの名無しさん:2013/09/08(日) 18:07:53.82
>>943
そうそう、なので非同期のプル型では同期のブロッキングI/Oと同様に
consumerが止まっていても、プロセス自身は他の仕事ができる(並列処理)
kernelがやっている仕事(コンテキストスイッチ)を処理系がプロセス内でやるイメージ
946デフォルトの名無しさん:2013/09/08(日) 18:10:48.77
ひとつのプロセスの効率だけを追求するならね
947デフォルトの名無しさん:2013/09/08(日) 18:11:06.17
ブロッキングI/Oの場合、CPUは他の作業ができるといっても
プロセス自体はそこで停止してしまう。
それを避けるためにforkしたりスレッドを作ったりするが、
そうするとメモリ使用効率が悪くなる。

そこでブロックするような処理を全部非同期で行えば、
メモリ使用量も控えられパフォーマンスをあげられるという考えがでてきた。
948デフォルトの名無しさん:2013/09/08(日) 18:17:28.07
readlineもどき書いてみたけど
こういうのがpullってことでいいんだよね?
http://ideone.com/G9aqFo
949デフォルトの名無しさん:2013/09/08(日) 18:22:56.23
>>948
nodeは知らんからよくわからん
イメージだけで言えば

while ((line = stdin.readline()) != null)
 console.log(line)
とか
for (line <- stdin)
 console.log(line)
みたいな形で書けるのがpull
950デフォルトの名無しさん:2013/09/08(日) 18:25:13.67
ビジーループだと標準入力が入力を受け付けないし
Nodeの思想的にもアウトでしょう
951デフォルトの名無しさん:2013/09/08(日) 18:29:58.92
>>950
ビジーループじゃないよ

stdin.readline()
を呼ぶと、readline()を呼んだタスクなりコルーチンなりはそこで止まって
待ちに入る
止まっているのだからビジーではない
かといって、非同期モデルであれば、プロセス自体が停止してしまうのでもなく
他の仕事はできる
一方readline()を呼んだタスクは貰える入力に「依存」しているから、
入力が届くまでここで待たされるのが正しい
952デフォルトの名無しさん:2013/09/08(日) 18:30:53.02
自分の感覚だと
http://ideone.com/G9aqFo pull
http://ideone.com/6NDxyd push+pull
http://ideone.com/q9wenL push
だと思ったんだけど
953デフォルトの名無しさん:2013/09/08(日) 18:36:45.81
> for (line <- stdin)
>  console.log(line)

これをビジーループと思う人が
どういうプログラミング言語を使って来たのか興味ある
煽り成分0で
954デフォルトの名無しさん:2013/09/08(日) 18:37:39.72
>>951
いや、Nodeだとビジーループになるって話
それにそのタイプだと登録したいくつもの同じ関数が処理途中のまま存在する状況が容易く起きるから
副作用を使う場合だと、マルチスレッドのときの競合を
1関数の中でも考えなくちゃいけなくなって大変じゃない?
それは副作用のない関数型の考え方だと思う
955デフォルトの名無しさん:2013/09/08(日) 18:46:16.59
上で例として上がってた.NETにしても、元は非同期I/Oがコールバックを使う
プッシュ型だったのを、async/awaitの導入でプル型の非同期処理を可能にした
経緯があるわけで、その心配は的外れと言わざるを得ない
「現状の」nodeの処理系では、それを適切な形でサポートしていないというだけの話
956デフォルトの名無しさん:2013/09/08(日) 18:52:00.12
line = stdin.readline()
puts "Hello"
puts line
puts "World"


これを実行したときに、「"Hello"出力 => 標準入力待ち => line出力 => "World"出力」
って順番で実行される非同期処理ってあるっけ?
入力はputs lineまで使わないから、それまでに進められる処理は進めとく、みたいな。
これってスゲー効率良くない?
957デフォルトの名無しさん:2013/09/08(日) 18:54:17.12
適切な形っていうけど例えば

func アクセスがあったら{
配列の長さ=ログイン者ID一覧の配列の長さ
「配列の長さ+"人がログイン中"」と返答する (ここで待機)
配列の長さのインデックスに新しいIDを登録
}

みたいな関数は厳禁になるでしょ
>>951の話通りのもので適切にってのはありえないと思うよ
だからNodeではそういう文化のないJSとコールバック式が積極的に選ばれたんでしょ
958デフォルトの名無しさん:2013/09/08(日) 19:01:25.07
>>957
ここで待機って、何を待ってるの?
959デフォルトの名無しさん:2013/09/08(日) 19:09:29.11
>>958
例だよ例
データを読むのでもいいし、ファイルに書き込むのでもいいし、何でもいい
関数が中断して他の関数が始まるような設計だと副作用がおいそれとはできないでしょ
960デフォルトの名無しさん:2013/09/08(日) 19:13:08.46
どうしてもやりたけりゃ>>906みたい感じでやればいいと思うが
それがデフォルトだとコールバック地獄以上に頭が痛くなると思うわ
961デフォルトの名無しさん:2013/09/08(日) 19:17:44.49
何事も使い分けが肝心
962デフォルトの名無しさん:2013/09/08(日) 19:26:50.66
まあでも今回は使い分けと言っても
言語システムから上のフレームワークまでどちらかに絞った設計じゃないと破綻しそう
963デフォルトの名無しさん:2013/09/08(日) 19:26:55.94
>>959
要は、待機時に他に制御が移るなら、プログラムのグローバルな状態が
待機の前後で変わる可能性があると言いたいわけな
一方nodeの単純なコールバック式では関数が終了するまで他に制御が
渡らない(よってその間状態は書き換わらない)と確信が持てると

それはその通りで、もしグローバルな状態を扱っている場合は、
制御が戻った後で、再度取り出すように書かないとダメ
そこは要注意だけど、nodeでは上の例だと待機の後の仕事をコールバックとして
書くだろうから、コールバックがつらなるよりは書きやすいことが一般には多い
グローバルな状態でなければ、上のような心配もないしね
964デフォルトの名無しさん:2013/09/08(日) 19:37:31.17
思想の問題といった方がいいかな
でもJSとは水と油なんじゃないか?
Node.haskellとかなら有りだと思う
965デフォルトの名無しさん:2013/09/08(日) 19:38:30.17
>>956
無理
966デフォルトの名無しさん:2013/09/08(日) 19:39:58.13
グローバルじゃなくても1つ上のスコープ、要はクロージャとは相性最悪
結局関数型スタイルで書く事になるんじゃないか?
967デフォルトの名無しさん:2013/09/08(日) 19:58:39.86
>>966
どっちも一緒じゃないか?

関数A:
 グローバル状態Aでの仕事
 何かを待つ
 グローバル状態A'での仕事
と、
関数A:
 グローバル状態Aでの仕事
 待機後の仕事をする関数A'を登録
関数A':
 グローバル状態A'での仕事

の違い
どっちも待機後にグローバルな状態が変わっている可能性は変わらなくて、
できることも変わらない
前者のプログラミングスタイルではそれを失念しやすいというだけ
968デフォルトの名無しさん:2013/09/08(日) 20:03:30.25
ああそうか、関数Aにおいてグローバル状態Aをキャプチャしたクロージャを
グローバル状態A'で使うと困るんじゃないの?という話かな
それは困るだろうな
969デフォルトの名無しさん:2013/09/08(日) 20:13:52.48
グローバルって、トップレベルスコープってことだろ?
グローバル変数を触るのは元々あんまり良いことじゃないとされてるけど
1つ上のスコープの変数扱うことは日常茶飯事で
特に扱いも注意しないし大胆に使う事が一般的だから
そういうスタイルとは水と油ってことでは?
970デフォルトの名無しさん:2013/09/08(日) 20:19:50.69
>>969
困るケースはとりあえず2つ思いつくんだが、どっちもグローバル絡みだな
・グローバルな状態をキャプチャしているので、書き換わってしまう
・クロージャインスタンスをグローバルな場所に置いてあるので、
 クロージャが他のコンテキストから呼ばれて、キャプチャ変数が書き換わってしまう

普通のクロージャの用途では、外のスコープのローカル変数をキャプチャすることが
多く、クロージャインスタンスを他のコンテキストから可視な場所に置かなければ
困ることはないはず
971デフォルトの名無しさん:2013/09/08(日) 20:41:16.28
972デフォルトの名無しさん:2013/09/08(日) 20:49:49.65
多分「グローバル」と「クロージャ」という単語の感覚に各言語差異があるんだろうね。
973デフォルトの名無しさん:2013/09/08(日) 21:00:06.55
>>949
>
> stdin.readline()
> を呼ぶと、readline()を呼んだタスクなりコルーチンなりはそこで止まって
> 待ちに入る

そういうこと。止まってしまうね。何もできなくなってしまうね。

> 止まっているのだからビジーではない
> かといって、非同期モデルであれば、プロセス自体が停止してしまうのでもなく
> 他の仕事はできる

うん、その場合、forkしたりスレッドを使う必要がある。
でもそうすると、メモリを食うわけよ。

nodeができたのは、その問題点を解決するには
どうするかってのが出発点なわけ。

俺からすればドヤ顔で欠点を言ってるようにしか見えないんだよ。
974デフォルトの名無しさん:2013/09/08(日) 21:00:47.23
>>971

1つの参照型のオブジェクトを多くの関数から参照している干渉問題と
いくつかのクロージャ(スコープ)が外の同じ変数を参照している干渉問題は
同時に起こることも多いけど違う問題だと思う
975デフォルトの名無しさん:2013/09/08(日) 21:03:20.78
世の中には軽量スレッドってものがあってだな
976デフォルトの名無しさん:2013/09/08(日) 21:07:09.88
>>973
> うん、その場合、forkしたりスレッドを使う必要がある。
> でもそうすると、メモリを食うわけよ。
fork()したりスレッドを使う必要があるのは、あくまで同期(ブロッキング)I/Oの場合
それが嫌なので、非同期I/Oとコルーチンやファイバ、自前のスケジューラを使って
同期と同じようなプルモデルを実現したのが上で言っているやり方
977デフォルトの名無しさん:2013/09/08(日) 21:09:11.26
何事もトレードオフ
銀の弾丸は存在しない
978デフォルトの名無しさん:2013/09/08(日) 21:12:10.41
要はawaitみたいなものだろ?
979デフォルトの名無しさん:2013/09/08(日) 21:15:49.19
次スレからJSという文字が消えたけど
JSerとしては泣けばいいんですかねぇ
980デフォルトの名無しさん:2013/09/08(日) 21:17:33.25
>>975
そんなこと知ってるよ。

nodeの作者のRyan DahlはJavaScriptが好きだったからnodeを作ったのではない。
C10K問題を解決するのにどうするか?って問題に取り組んでいた。
コルーチンやスレッドを使った方法ではC10K問題が起きていたのだ。

そしてあるとき非同期が有効であると気づいた。
C10K問題を解決するために、非同期メインで全てのライブラリを構築しなければならない。
だが既存の言語、ライブラリは、同期メインで作られていた。
標準入出力といった基本的な部分が、同期ライブラリとして既に言語に組み込まれていた。

JavaScriptはブラウザで動かすがゆえに標準入出力を含めた機能が言語になかった。
そしてブラウザではsetTimeoutなどの非同期を使ったプログラミングが主流だった。
それがC10K問題を解決するため、非同期ライブラリで世界を構築するという目的に見事に当てはまった。

JavaScriptを使ったサーバーサイド実行環境はnode以外にも存在する。
それらは既存の言語と同じように同期ライブラリも多数ある。

だがnodeといった時、それはコルーチンやスレッドは害であり
非同期で作ったほうがパフォーマンスが高いというのが根底にある。
そこにブロッキングI/Oとか持ちだしても、そもそもそのやり方がダメだから
避けようという話だったよね。ということにしかならないのである。
981デフォルトの名無しさん:2013/09/08(日) 21:20:09.20
>>979
なあに、次スレの次スレではJSが復活するさ
982デフォルトの名無しさん:2013/09/08(日) 21:22:07.82
Nodeは徹底したイベントループがやりたかったんでしょ
983デフォルトの名無しさん:2013/09/08(日) 21:23:48.92
NodeのファンボーイはErlangとかGoとか知らんのかいな
984デフォルトの名無しさん:2013/09/08(日) 21:23:52.52
> コルーチンやスレッドを使った方法ではC10K問題が起きていたのだ。

なんでコルーチンでC10K問題が起きるの?
よく知りもしない事を適当に書いてない?
985デフォルトの名無しさん:2013/09/08(日) 21:23:59.56
nodeではブロッキングI/Oなどは
意図的に排除してるんだよね。
986デフォルトの名無しさん:2013/09/08(日) 21:30:36.19
JSが選ばれたのはコールバック、つまりシングルスレッドで非同期処理をする文化が合ったからだね
987デフォルトの名無しさん:2013/09/08(日) 21:31:45.17
それとあとはV8エンジンが当時から素晴らしかったってこと
988デフォルトの名無しさん:2013/09/08(日) 21:33:24.25
>>985
いや普通に同期IOも使えるよ
nodeが開発用のツールを作るのにも使われてるのは同期IOがあるおかげ
989デフォルトの名無しさん:2013/09/08(日) 21:36:09.03
どうしてnodeを作るのにJavascriptを選んだか
http://bostinno.streetwise.co/2011/01/31/node-js-interview-4-questions-with-creator-ryan-dahl/


> BostInno: Why did you originally choose javascript for node?

> Dahl: Originally I didn't. I had several failed private projects doing the same on C, Lua, and Haskell.
> Haskell is pretty ideal but I'm not smart enough to hack the GHC.
> Lua is less ideal but a lovely language - I did not like that it already had a lot of libraries written with blocking code.
> No matter what I did, someone was going to load an existing blocking Lua library in and ruin it.
> C has similar problems as Lua and is not as widely accessible.
> There is room for a Node.js-like libc at some point - I would like to work on that some day.

> V8 came out around the same time I was working on these things and I had a rather sudden epiphany that
> JavaScript was actually the perfect language for what I wanted: single threaded,
> without preconceived notions of "server-side" I/O, without existing libraries.
990デフォルトの名無しさん:2013/09/08(日) 21:36:34.27
ノンブロッキングI/Oは、PHPだとCURL(ネットワーク通信)のみで使える。この程度でいいだろ。
至る所、終了待たず実行されてしまうと、プログラマの手間が増える。
991デフォルトの名無しさん:2013/09/08(日) 21:36:35.52
それは主にツール用で、あえて使うことはあっても、
同期APIを「使ってしまう」ことはない
そこがポイントだと思う

httpなんかも標準では同期ないし、使ってしまわないように徹底的に排除されてる
992デフォルトの名無しさん:2013/09/08(日) 21:38:14.42
Haskellはとても理想的だけど、GHCをハック出来る程には自分は賢くない、か

なるほどNode.jsにJSが選ばれるのにも色んな経緯があったんだねぇ
993デフォルトの名無しさん:2013/09/08(日) 21:41:51.19
V8はネイティブモジュールとの相性が抜群にいいからね。
言語とネイティブを繋ぐ部分も非常にうまく出来てる。
994デフォルトの名無しさん:2013/09/08(日) 21:44:43.63
まあGHCがクソだとは言えんだろうしな
995デフォルトの名無しさん:2013/09/08(日) 21:52:43.28
>>988
> いや普通に同期IOも使えるよ
数はものすごく少ない。

> nodeが開発用のツールを作るのにも使われてるのは同期IOがあるおかげ
非同期I/Oでできないことなんてないよ。
だから同期I/Oのお陰ではない。
996デフォルトの名無しさん:2013/09/08(日) 21:52:45.14
もしかしたらNode用Haskell→JavaScriptコンバータ書いたほうが簡単なんじゃない?
997デフォルトの名無しさん:2013/09/08(日) 21:54:03.06
>>996
はいはい。それがハックです。
スマートなあなたがハックしてください。
998デフォルトの名無しさん:2013/09/08(日) 21:55:14.85
nodeも次の0.12からES6標準のyieldが使えるようになるし。
そうなったら鬼に金棒だろう。
999デフォルトの名無しさん:2013/09/08(日) 21:55:19.13
Nodeで非同期が重要なのはサーバーとして振る舞うときだから
ツールとかでは普通に同期使う
起動時の設定ファイル読み込みとかも非同期でやる価値ないし
1000デフォルトの名無しさん:2013/09/08(日) 21:56:19.43
続きは次スレで
>>971
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。