Perlはオブジェクト指向言語だっけ?
>>952 packageをクラスに見立ててオブジェクト指向は実現できるよ。
>>951 それ、nakeと命令したら、にゃーにゃーと言って、
sineと命令したら、ぎゃーと言って、
namaeと言ったら、タマと言う猫になってるよw
人語を話す猫はちょっと想定外w
>>953 あぁ、Perlだからオブジェクト指向の例だったのね。
>>955 オブジェクト指向版
my $cat = neko->new;
$cat->namae;
$cat->nake;
$cat->sine;
package neko;
sub new {
my $self = shift or die $!;
my $hash = { namae => 'タマ' };
return bless $hash, $self;
}
sub namae {
my $self = shift or die $!;
print $self->{namae}, "\n";
}
sub nake {
my $self = shift or die $!;
print "にゃーにゃー\n";
}
sub sine {
my $self = shift or die $!;
print "ぎゃーーー\n";
}
>>948 get系メソッドで状態が変化するわけではないので
letかwhereで束縛するだけでいいのでは
>>956 理解した!
スレッドつかったら、プロセス指向になるんだ!
さすがperl使いだな
仕事が早いw
961 :
475:2010/10/11(月) 16:20:28
>>950 >IO モナドをどう使えば何が出来るか、何が出来ないか、
>Arrow を使えばどう記述しやすくなるか、ならないか、
あ、スマンが、それを分かり易く、言い換えると「数学用語を使わずに」説明してくれないかな?
>>935で書いたけど、自分はモナド/アローと格闘中。で、一時的に敗北を認め、
今は代数の勉強からやり直しているところ(群と束までは何となくイメージが湧くんだけどね)。
だから、説明してくれるとすごく嬉しいね。
>逆に訊くが、バーコード表示コンポーネントに
>圏論の概念の何が必要か挙げてくれ。
バーコード表示コンポーネントなら不要かもしれない。スマン。
ただ、事務系処理と圏論の概念という話題は、
>>475の関数指向設計技法の話と関連するかもしれない。
まだモヤモヤした状態なので、後からレスするよ。
962 :
475:2010/10/11(月) 16:21:47
>>957 えーと、変数 tama に「何」を束縛するの?
>>959 スレッドでもいいんだけど、ネイティブスレッドは非常に重いので、
今必死で各方面でerlangのような軽量プロセスを実装しようと試みている人がいるよ。
perはメモリ周りが柔軟なので、ネイティブだけど割と軽い。
Cと比べたら激遅なんだけどねw
あと、スレッドを使うだけではなくて、ロック機構を全く使っていないことに注目して欲しい。
メッセージパッシングにスレッドセーフなキューを採用している。
なんだ。結局プロセス指向って
オブジェクト指向言語での
書き方の一つなんじゃねーか。
紛らわしいw
これだけは前提としてくれ
オブジェクト指向のインスタンスのメソッドをたたくことをメッセージというが
これは
プロセス指向のメッセージパシングのメッセージとはぜんぜん別物。
しかたがないから名前つけるか。
前者:オブジェクト指向メッセージ(略してOM)
後者:プロセス指向メッセージ(略してPM)
以上
もう少しだけ分かりやすいプロセス指向のコードをperlで書いてみた。
use threads;
use Thread::Queue;
my $q = Thread::Queue->new;
my $th = neko($q);
my $q2 = Thread::Queue->new;
my $th2 = neko($q2);
$q->enqueue({command=>'namae', namae=>'タマ'});
$q2->enqueue({command=>'namae', namae=>'シロ'});
$q2->enqueue({command=>'nero'});
$q->enqueue({command=>'nake'});
$q->enqueue({command=>'sine'});
$q2->enqueue({command=>'sine'});
$th->join;
$th2->join;
sub neko {
my $q = shift or die $!;
return threads->new(sub {
my $namae = '';
while (1) {
my $message = $q->dequeue();
if ($$message{command} eq 'namae') {
$namae = $$message{namae};
print "命名:$namae\n";
} elsif ($$message{command} eq 'nake') {
print "にゃーにゃー\n";
968 :
475:2010/10/11(月) 16:40:00
では、(
>>844が言うところの)プロセス指向言語でもある GHC(KL1) で参戦w
% オブジェクト TAMA の定義
tama(InqueryStream, ReplyStream) :- tama(InqueryStream, ReplyStream, 'TAMA').
tama([namae | InqueryStream], [Name | ReplyStream], Name) :- tama(InqueryStream, ReplyStream, Name).
tama([nake | InqueryStream], ['NYA NYA' | ReplyStream], Name) :- tama(InqueryStream, ReplyStream, Name).
tama([shine | InqueryStream], ['GYA---' | ReplyStream], Name) :- tama(InqueryStream, ReplyStream, Name).
% オブジェクトTAMA の使い方。ここで、instream はキー入力(標準入力)に、outstream は画面出力(標準出力)に相当する。
?- instream(InqueryStream), tama(InqueryStream, ReplyStream), outstream(ReplyStream).
} elsif ($$message{command} eq 'nero') {
print "$namaeが寝ます。\n";
sleep(3);
print "$namaeが起きました。\n"
} elsif ($$message{command} eq 'sine') {
print "$namaeが死んでしまいました\n";
last;
}
}
});
}
970 :
967:2010/10/11(月) 16:45:13
よく見て欲しいのが$namae変数。
これは一つの関数のローカル変数に過ぎない。
関数型言語なら引数に与えて再帰することで状態を持たずに済むので、
プロセス指向は非常に関数型言語にとって有利な方法なんだ。
>>961 > あ、スマンが、それを分かり易く、言い換えると「数学用語を使わずに」説明してくれないかな?
IO モナドを使えば IO との入出力ができる。
印刷ライブラリも呼べる。
FFI を使って Haskell 用には書かれていないライブラリにも
IO モナドとしてアクセスできる。
バーコードを印刷するアプリの「モナド」に関しては
これくらい知ってるだけで基礎知識としては十分。
あとは自分でライブラリを探して利用することができる。
代数や圏論など出る幕ではない。
>>961 んだよ、じゃあ帳票印刷パッケージでいいよ
代数やら圏論やらの理解がどれほど必要だ?
>>971 > 帳票印刷パッケージ
そんなもんそのへんの乞食にやらしとけよw
100円ぐらいやってくれるんじゃね?
俺らの仕事は数億円の仕事だからさw
一緒にしないでよw
>>971 おっとスマン
FFI を利用して外部ライブラリを呼ぶのなら、
メモリ領域破棄のタイミングについても知っていないと、
商用のアプリやライブラリとしてはちょっとお粗末だった。
でも、やっぱり代数や圏論の知識は要らんな。
>>932 俺じゃなくて、745 に言ってくれ。
彼が
>>941 で自ら例を挙げたんだから。
彼は、君が乞食にやらしとけよと言うモノを作るのに、
代数やら圏論やら難しい概念を正確に理解することが必要なんだと言っている。
fizzbuzzがやっと書けるレベルでも印刷アプリぐらいつくれるだろw
976 :
475:2010/10/11(月) 17:01:57
>俺らの仕事は数億円の仕事だからさw
>一緒にしないでよw
事務系処理であれば、大企業の基幹システム開発とか銀行の勘定系システムだと、
ハード抜きソフト開発費だけで数億の案件なんてザラにあるんだよ。
君が言う100円くらいでやってくれるというCOBOLプログラマが奮闘している。
ところでHaskellで数億円って、どんなお仕事なの?教えて欲しいなーーーーw
100円の仕事やらせるのに難しい知識なんていらないんだよ
>>976 鉄道関係でZ言語使って設計したよ。
実装は他の言語だがな。
979 :
475:2010/10/11(月) 17:17:37
>>978 Zは形式的仕様記述言語だろ。関数の概念も使うけど、それを言い出せば手続き型言語でも関数は使う。
レスとしては、適切ではないな。
で、HaskellでHaskellで数億円って、どんなお仕事なの?
君の仕事が乞食相当100円の仕事だと言われたと思って怒ってるの?
それ以前にHaskellで商売してるって誰が言ってるの?
475 は下らん奴らの相手をしている暇があるなら、
帳票印刷パッケージで代数やら圏論やら
難しい概念を正確に理解する必要性を説いてくれないだろうか。
バカの戯言など無視して集中してくれ
>>970 > よく見て欲しいのが$namae変数。
> これは一つの関数のローカル変数に過ぎない。
> 関数型言語なら引数に与えて再帰することで状態を持たずに済むので、
> プロセス指向は非常に関数型言語にとって有利な方法なんだ。
それは名前を取得しているだけだから
ローカル変数ですむんだろ?
function get_namae() {
return "tama"
}
と同じこと。
現実的には、名前を決めるメソッドも必要。この場合はどうなるのさ。
>>983 オブジェクト指向では状態を持たないとやりたいことは実現できないよ。
>>983 > と同じこと。
ぜんぜん違う。
その方法ではオブジェクト指向的には、
タマバージョンとシロバージョンの2種類のクラスを別々に作る必要が出てくる。
一つのクラスでやろうと思ったら名前をつけるメソッドを用意して、
フィールドにnamae変数を用意しなければならない。
一方でプロセス指向ではフィールドに該当するものを持っても良いし持たなくても良い。
関数型言語を使うなら持たなくても良い。
Queueは副作用あるから関数型じゃないし
オブジェクト指向はObserverパターンを散々推奨しておいて今更dequeue()はないだろ
両方とも詰んでるんだよ
989 :
475:2010/10/11(月) 17:57:52
>>971,973,982
>>475で始めた一連のカキコでは「関数指向設計技法」というものを提案した。
で、入出力データを代数的データ型で定義するところまでは説明したけど、
それら入出力集合間の写像(関数)をどのように定義する方法論については、以下のように
曖昧な表現で終わっており、それを
>>500でツッコまれていた。
>>497 >(2)副関数群への分解手順(アルゴリズム)について、JSP法の考え方に沿って(JSP法を模倣して、あるいは
> JSP法の用語を使って)、指導者が普通のプログラマへ説明する
実は、事務系処理は(100円でもやってもらえるような)比較的単純な機械労働のように
見られがちだけど、世界中のソフトウェア工学の権威が取り組んできていたにもかかわらず、
未だに解決できていない領域の一つだったりする。
上の写像定義であれば、入出力集合間の関係が準同形であれば比較的たやすい。
形式的な関数定義を導出することが可能。(言い換えると、プログラムの自動生成が可能。)
ところがそうでない場合、これをJSP法では「構造不一致」と呼ばれているが、
case-by-caseで、言い換えると設計者の「経験と勘」で対応せざるをえないのが現実。
JSPにおける構造不一致(structure clashs)については、以下の文献を参照してくれ。(英語だよ)
・The Jackson Development Methods (Michael A Jackson 1992)
http://www.jacksonworkbench.co.uk/resources.htm (長いので続く)
>>987 そのコードのどこに、名前を変更する処理が入ってるのさ?
インスタンス生成時に、値設定しているだけじゃないか。
> タマバージョンとシロバージョンの2種類のクラスを別々に作る必要が出てくる。
それから、これ訂正すべきだな。
クラスは1種類(猫クラス)だけで十分。
インスタンスは複数必要だが。
事実プロセス指向とやらでも、インスタンスは複数あるよな。
> $q->enqueue({command=>'namae', namae=>'タマ'});
> $q2->enqueue({command=>'namae', namae=>'シロ'});
つまり、プロセス指向とやらは、
インスタンスを、その言語で定義されたインスタンスというもので表すか、
perlのようにハッシュをインスタンスとして使うかの違いでしかないのか?
手続き型言語では、データ(構造体)とそれを扱う関数が分かれていた。
プロセス指向は、その構造体をハッシュにすることで
構造体の型の定義を作らないですむようにしたもの。
これでいいのか?
C#にはクラスのインスタンス時のみに値を設定できるreadonlyって属性があるんだわ。
http://msdn.microsoft.com/ja-jp/library/acdd6hb7(VS.80).aspx
これを使えば、あと状態を変えることができなくなる。
プロセス指向ってのは、このように
状態を最初に設定することだけできて、
後から設定する変数を持たないようにしたクラスと同じ。
プロセス指向だけで、ソフトウェアが作れることはまずなくて、
状態をあとから変更できないようにしておけば、
バグが少なくなるよって考え方のことだろう。
994 :
475:2010/10/11(月) 18:15:26
>>988 えーと、
>>968では副作用なんてありませんですよ。関数型言語じゃなくて論理型言語だけどねw
Prologだとretract/assertみたいな副作用が必須だったけど、並列論理型言語では副作用無しに状態を保持し、
ストリームを応用してクラス間の継承(インヘリタンス)すら記述できます。
というか、Haskellでの参戦者はいないの? (自分は、このスレじゃHaskellに批判的な立場だから書かないぜ)
ストリーム(無限リスト)を使えば、
>>968相当の処理は、もっとエレガントに記述できるんだけど。
これは関数型的思考プロセス段位であれば「中級」に相当するレベルだよ。
>>909 誰も皆、モナド・モナド・モナド・モナド・モナド・モナド・モナド・モナド.... ばかり考えているから、
昔の純粋関数型言語におけるストリーム指向プログラミング技法なんて忘れ去られてしまったのかな?
>>993 (
>>844が言うところの)プロセス指向を間違って理解しちゃってますヨ
出発点がおかしいんだわ。
ソフトウェアを状態を持たないで作ることは不可能なんだよね。
それが関数型言語で言えばモナドになる。
オブジェクト指向で言えば、インスタンスのこと。
(インスタンスではないクラスはメソッドの集まりなんで状態を持ってないよ。基本的に。)
実体を持たないメソッドを抽象メソッドと呼ぶように、
状態を変更しないメソッドを、関数とかプロセス指向(?)とか
言っているだけではないか?
結局は特殊な性質を持ったメソッドに、さもえらそうな名前をつけているだけ。
> 状態を変更しないメソッド
あぁ、C++でいうconstメソッドのことねw
語尾に指向をつければ、なんでもすごく感じるメソッド指向
俺えんてっど
>>995 メソッドって特殊な性質を持った手続きのことでしょ
1000なら関数型言語は普及しない。
1001 :
1001:
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。