■掲示板に戻る■ ■過去ログ倉庫めにゅーに戻る■
関数型言語
1 名前: デフォルトの名無しさん 投稿日: 2001/04/23(月) 00:46
Lisp Scheme ML Haskell FP Mirranda など
関数型言語について話し合いましょう


2 名前: デフォルトの名無しさん 投稿日: 2001/04/23(月) 00:48
関数型言語の定義って何ですか?


3 名前: デフォルトの名無しさん 投稿日: 2001/04/23(月) 00:56
>2
関数の組合せによって形成していく言語
変数への代入が無い。
でもLISPやSchemeなどでは見かけ上、ローカル変数が使えます。


4 名前: デフォルトの名無しさん 投稿日: 2001/04/23(月) 01:39
ここに関数型言語の説明がある
ttp://www.icsd2.tj.chiba-u.ac.jp/oldmember/shimoda/node1.html


5 名前: デフォルトの名無しさん 投稿日: 2001/04/23(月) 18:24
Haskellに期待age



6 名前: デフォルトの名無しさん 投稿日: 2001/04/23(月) 21:05
状態を持つ Schemeや Lispなんて関数型じゃねえ、っていいたいんだね?
Ocamlも論外。



7 名前: デフォルトの名無しさん 投稿日: 2001/04/23(月) 21:48
>6 俺はschemeやML系の副作用のあるものも、関数型言語として認めるよ。
基本的にプログラムって状態を変化させるものでしょ。Haskellみたいに
purityを保ちながら、今っぽいGUIとかネットワークのプログラムを書く
のは少しこじつけが必要になってくる。

でも、Haskell大好きよ。GHC-5.0リリース万歳!



8 名前: デフォルトの名無しさん 投稿日: 2001/04/23(月) 22:41
関数型言語だと並列化が容易って聞きますが本当ですか?


9 名前: デフォルトの名無しさん 投稿日: 2001/04/23(月) 23:05
HaskellはSchemeのような美しさに欠けますが、現実的な機能
を盛り込んでいて、大規模な開発にも使えそうだと思っている
のですが、実際にはどうなんでしょうか。Haskellで大きなプロ
グラムを組んだことがある人、意外な欠点などがあったら教えて
ください。


10 名前: デフォルトの名無しさん 投稿日: 2001/04/24(火) 00:41
関数型言語でRDB読み書きってできるの?
まあ、やりゃぁできんだろけど、向いてる?


11 名前: デフォルトの名無しさん 投稿日: 2001/04/24(火) 00:47
RDB読み書きに向き不向きなんてあるんですか?>10


12 名前: デフォルトの名無しさん 投稿日: 2001/04/24(火) 02:38
代入がないってのは、もしかして状態がないんでしょうか?
状態のかたまりであるOOPばっかりやってきたもんで、
ものすごくカルチャーショックです。
どういう風になってるんだろう???



13 名前: デフォルトの名無しさん 投稿日: 2001/04/24(火) 03:57
set!


14 名前: >12 投稿日: 2001/04/24(火) 04:11
いや、関数の引数に対しての代入はある。
なので状態は作れる。


15 名前: >12 投稿日: 2001/04/24(火) 04:33
ループも再帰で作る。


16 名前: デフォルトの名無しさん 投稿日: 2001/04/24(火) 09:04
手続き型であるC言語でglobal, static使わないと
関数型プログラミングになるってこと?
単に手続き型を制限しただけ?

いまいち利点がわからないな


17 名前: デフォルトの名無しさん 投稿日: 2001/04/24(火) 13:03
>>16
俺もよくわかってないけど
君の言ってる事はなんか違うと思う。

つか、いっぺん触ってみれ。
したら利点がわかるよ。


18 名前: デフォルトの名無しさん 投稿日: 2001/04/24(火) 15:11
>>16

純粋に関数型な部分については、引数と関数が定まると、出力(戻り値)が
定まるので、たとえば遅延評価(webで牽いてね)なんかができる。
そうして遅延評価をベースにして、ほかの言語ではコルーチンを使う
ような処理が、ごく自然なアルゴリズムとして記述できるようになったりする。



19 名前: デフォルトの名無しさん 投稿日: 2001/04/24(火) 16:15
あそこらへんってアルゴリズムなのか? って気もするけどな。
無限リストをかえす関数なんてのは、それだけじゃ停止性も
ないわけだし。
まあ、制御構造を書かなくていいので、自然に記述できる(こともある)
ってのがうりだね。
&& の shortcutが言語のすべてに行き渡ったような。



20 名前: デフォルトの名無しさん 投稿日: 2001/04/25(水) 00:35
スレ伸びないね。とりあえずage


21 名前: デフォルトの名無しさん 投稿日: 2001/04/25(水) 01:44
型推論萌えage


22 名前: デフォルトの名無しさん 投稿日: 2001/04/25(水) 01:57
やっぱりlambdaは基本でしょうか。
インターナルイテレーターが自然に書けるのも利点?


23 名前: 12 投稿日: 2001/04/25(水) 02:32
>>14
うう。そういや「リスト遊び」も読んだんだっけか。
でも表面的なことはさとえき
やっぱり関数型言語のキモって奴は全然判れなかった(T_T)

>関数の引数に対しての代入

うーむ。わからぬー(T_T)

状態の純粋な器としての変数、が無いということでしょうか?
#だとすると、状態の安息地を求めてOOPに至った俺としては、ちょっと…


24 名前: デフォルトの名無しさん 投稿日: 2001/04/25(水) 04:47
関数型言語は順次処理とかをするためのものじゃないから
状態とかはあまり関係ない話なんでは?


25 名前: デフォルトの名無しさん 投稿日: 2001/04/25(水) 12:21
>12 純粋な関数型言語(Haskell等)には代入がない。つまり状態はありません。
ではどうしているかというと、mainルーチンを現在の計算機の状態をうけとり
新しい計算機の状態を返す関数だと考えることで回避しています。

>23 正解です。

>24 でも、現実のプログラムでは状態を扱うと考えた方が自然な問題もあると思う。



26 名前: デフォルトの名無しさん 投稿日: 2001/04/25(水) 15:56
関数型の肝がわかる入門書ねえ...
R.バード、P.ワドラー共著、武市正人訳「関数プログラミング」
か?
http://www.sampou.org/haskell/ にある易しい Haskell入門はどうかな。




27 名前: デフォルトの名無しさん 投稿日: 2001/04/25(水) 22:39
>26
日本語でおねがいします


28 名前: 12 投稿日: 2001/04/25(水) 23:00
>>25
ココでいうのもなんなんですが、
ガッコで習った算数/数学でピンとこなくて
一方プログラミング(といっても手続き系言語ばかり)で
ピンと来たのが、「状態」の有無なんですよね…。

ところでさらに。自分も使ったことがあるわけじゃない
んですが(笑)、もしかして関数型言語って
アナログコンピュータに似ていますか?
アナログだとデジタルと違って状態の記憶はプリミティブにやれないし、
たしか微分とか発振とかの演算をする部品を
FunctionGeneratorとか呼ぶんでしたよね。
で、あるFunctionの出力を別のFunctionに(配線で)突っ込むことで
計算を行うわけで。似てませんか?

Haskellの日本語な頁はどっかで見たような記憶が。
全然判らなかったのは相変わらずですが(T_T)。
検索したら出てくるんじゃないかなあ。
#最近はGoogleかな…


29 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 03:03
そろそろ具体的な例でも出してみようや。
誰かなんか関数型言語で解く問題きぼんぬ。


30 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 04:10
>>29
関数型言語ならでは、ってやつですか?
自分はちょっと思いつかないです。
とりあえず違う切り口で。

・平均値を求める関数
(average 1 2 3 4 5)
=> 3

(define (average . l)
 [define list-plus
  (lambda (y l)
   (if (null? l) y
    (list-plus (+ y (car l)) (cdr l)]
 ([lambda (x) (if (zero? x) 0 (/ x (length l)]
  (list-plus 0 l)))
Schemeですが、ローカル変数は使ってないです。
このコードは関数型言語に乗っ取った記述と言えるでしょうか?


31 名前: 30 投稿日: 2001/04/26(木) 04:32
こういう書き方もあります。(本質的に同じですが)
(define (average2 . l)
 (let loop ;named let
  ((y 0) (c 0) (z l)) ;仮引数
  (if (null? z)
   [if (zero? y) 0 (/ y c)]
    (loop (+ y (car z)) (+ c 1) (cdr z))]



32 名前: 30 投稿日: 2001/04/26(木) 04:49
>>30のaverageをlengthを使わないで記述するとこうなります。
(define (average3 . l)
 [define list-plus
  (lambda (y c l)
   (if (null? l) (list y c) ;リストを返す(合計 個数)
    (list-plus (+ y (car l)) (+ c 1) (cdr l)]
 ([lambda (x) (if (zero? (car x)) 0 (/ (car x) (cadr x)]
  (list-plus 0 0 l)))
無理矢理っぽいかな
Cでも書けるし。しかも短くなるじゃん(鬱
int average_rec(int var, int len, int *list) {
  if (!len)
    return var;
  return average_rec(var + *list, len - 1, list + 1);
}
int average(int *list int len) {
  return average_rec(0, len, list) / len;
}


33 名前: 30 投稿日: 2001/04/26(木) 04:54
こっちでした
int average(int *list int len) {
  if (!len) return 0;
  return average_rec(0, len, list) / len;
}


34 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 05:00
(define (average . l)
 (/ (apply + l) (length l)))
反則?


35 名前: 30 投稿日: 2001/04/26(木) 05:05
Cならreturn文だけでも書けますね。
int average_rec(int var, int len, int *list) {
  return (!len) ? var : average_rec(var + *list, len - 1, list + 1);
}
int average(int *list int len) {
  return (!len) ? 0 : average_rec(0, len, list) / len;
}
・・何が言いたかったのか判らなくなってきた。もう寝ます。


36 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 05:12
関数型言語って無理矢理副作用が無い理由を作ってるけど、
あまり意味無いよね。
副作用の例外を認めてもいいんじゃないかな。


37 名前: 30 投稿日: 2001/04/26(木) 05:13
>>34
あああそういう方法があったんですか。
applyあんまり使った事ないんで。(汗
(+ 1 2 3 ...)って風に書けるのはlisp/scheme独特の利点ですね


38 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 10:50
(defun average (l)
  (/ (apply '+ l) (length l)))

(average '(1 2 3 4))
=>5/2


39 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 19:14
>>12
逆にOOPはすべてが「振る舞う」ものとして考えることも出来るようだよ。
Behaviorismというらしい。



40 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 21:59
>>36 副作用をなくす利点って、遅延評価ができるようになること以外
のメリットはなんなのかなぁ−。わかるひと教えて。

あと、OcamlやSML,Schemeとかは副作用を認めてるよね。
ホントに副作用がないようにしてるのはHaskellとCleanだけ。

全てを関数としてみるのも不自然だし、全てを手続きとしてみるのも
不自然だと思う。

でも, Haskellまんせ−



41 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 22:05
>>39
つーか、振舞うだけなら他の言語形態でもたいてい
(語弊?)出来るんで、それはまたちょっと傍論かと。

OOPの味噌は細胞膜を作ったことでしょう。
ソレの内部と外部を規定するという。

どうなんでしょう?
関数って、それ自体には内も外もないんじゃないでしょうか?

ところでLispってListProcessorでしたよね。
List自体は変数と大差無いものであるように
思えたんですが、それでも関数型というのでしょうか?




42 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 22:30
>41 関数の外と内という表現はよく分からんが、スコープはある。
あと、Haskellなんかはグローバルな(手続き型言語のような)変数
はない。

Listは変数とも見れるが、Lisperは基本的には破壊的代入をあまり
しないでプログラムを書くので関数型とも見れる。



43 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 23:12
話はずれますが、
MLでは型推論という方法でgc起動回数を抑えてるらしいんですが、
LISP/Schemeで、その型推論は可能でしょうか。
appendやreverseなんかで大量にセル消費するけど、
gcに(あまり)頼らずにセルを還元する様なアルゴリズムにならないかな。


44 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 23:43
>43 型推論でGCを回避?なんじゃそりは?初耳です。

Lisp, Schemeには型がないので型推論はできません。



45 名前: デフォルトの名無しさん 投稿日: 2001/04/26(木) 23:44
>>43
よくわからんが(君の言ってることのせいじゃなく俺が馬鹿だからね)
MLの型推論は処理系がコンパイル時にって話で
LISP/Schemeじゃ無理なんじゃないでしょか。


46 名前: 43>44-45 投稿日: 2001/04/27(金) 00:17
やっぱり型無いと無理ですか。
地道に関数の呼出し時にプロファイリングして不要になるセルを
チェックしていけば還元は結構できるかもしれないですね。


47 名前: デフォルトの名無しさん 投稿日: 2001/04/27(金) 00:36
>Lisp, Schemeには型がない
初耳だな。


48 名前: デフォルトの名無しさん 投稿日: 2001/04/27(金) 00:57
それは例の「形なし言語逝ってよし」のスレでの
変数の型と値の型の話かい?

ここでは変数の型についていっているよん。



49 名前: デフォルトの名無しさん 投稿日: 2001/04/27(金) 00:57
引数の型チェックが無い

という言いかたが正しいかな?


50 名前: 本論とは外れるが 投稿日: 2001/04/27(金) 01:16
「LISP Scheme」と「関数型言語」のスレの住人は同じに違いないのにスレだけが別れていてキモイなあ。


51 名前: デフォルトの名無しさん 投稿日: 2001/04/27(金) 01:28
俺はこっちしかかきこんでないぞ!
でも、しょぼ関数型プログラマよりグレートなlisper
の方が多そうなのでいろいろ聞きたいです。



52 名前: デフォルトの名無しさん 投稿日: 2001/04/27(金) 02:07
>>43 Region Based Memory Managementのことかしらん?
http://www.itu.dk/research/mlkit/kit2/readme.html
型推論じゃなくて effect inferenceとかいったような...
萌える理論である事はたしか。




53 名前: デフォルトの名無しさん 投稿日: 2001/04/27(金) 15:10
>>51
厨房Lisp信者発見。


54 名前: デフォルトの名無しさん 投稿日: 2001/04/27(金) 23:35
別にいいじゃないかage>50


55 名前: デフォルトの名無しさん 投稿日: 2001/04/28(土) 20:40
>Lisp, Schemeには型がない
これは曖昧な表現だと思います。
「変数にはどんな型のデータも入る」の方が良いかと。
つまりデータについての型は存在します。
(a . b) =>pair型(dot対)
(a) =>list型 (=> (a . '()))
a=>symbol型
#\a=>character型
"a"=>string型
#(〜)=>vector型
#t #f =>boolean型
(lambda ()〜)=>closure型
(call/cc 〜)=>継続型
など
変数として使えるのはsymbol型とpair,list型だけですが。


56 名前: デフォルトの名無しさん 投稿日: 2001/04/29(日) 16:08
そういうのも昔は型がないといったもんだが...まあ弱い型って
いうのが最近の呼び方かな。



57 名前: デフォルトの名無しさん 投稿日: 2001/04/29(日) 19:56
>>56
もしかして昔は、データ(今風にいえばObject)に
(実行時)型情報も持たせるのは、コスト的に重いんで
メジャーな戦略ではなかった、のでしょうか?

つーても、卑近な意味でのジツヨー言語のことだけ考えても
この場合ショウガナイだろうしなあ。


58 名前: デフォルトの名無しさん 投稿日: 2001/04/29(日) 19:59
>>55
>変数として使えるのはsymbol型とpair,list型だけですが。
vector型も追加だ(゚Д゚)


59 名前: デフォルトの名無しさん 投稿日: 2001/04/30(月) 02:52
いやー、Lisp1.5のころ (Fortranと同じぐらい) からだから、
そうともいえないだろうが >>57
そのころの Lispは、汎用言語とは考えられてなかったかも知れぬが。
型なし言語(BCPLとか?) はそもそも「型なし」と形容する必要さえ
認識されてなかった、というのが俺の邪推。



60 名前: デフォルトの名無しさん 投稿日: 2001/04/30(月) 02:54
>>58 変数として使える、って意味はなんだ??
55にあがってるのはみんな一級の値(First class value)だから
代入とかはできるはずだが。
後 number型がないな >>55



61 名前: 55 投稿日: 2001/04/30(月) 04:58
defineとか〜set!ができるって意味です>>60
number型だったら
(define 1 'a)
とかできないでしょ?


62 名前: デフォルトの名無しさん 投稿日: 2001/04/30(月) 16:51
>>40
OCamlとかSMLは副作用を認めてると言うより(多少は認めてるけど)
型推論を可能にしつつreferenceを表せるような
強力な型理論を頑張って作ったんだよね。
だからwhileループなんかが関数型の枠組みのなかで表現できる。


63 名前: 60 投稿日: 2001/05/01(火) 03:42
>>61 vector型を変数として使えるのか?
(define #(a) 1) なんてできないよな?
(define (a b) ...) だって
(define a (lambda (b) ...)) のsyntactic sugarに過ぎないし。
∴変数として使えるのは symbolにきまっとる。



64 名前: >63 投稿日: 2001/05/01(火) 04:27
あの〜、
vector-set!とか忘れてません?
(define vec (vector 'a 'b)) ;=> vec
(vector-set! vec 0 'c) ;=> #(c b)
vec
=> #(c b)


65 名前: >63 投稿日: 2001/05/01(火) 04:32
listも
(define lis (list 'a 'b)) ;=> lis
(set-car! lis 'c) ;=> (c b)
lis
=>(c b)


66 名前: >63 投稿日: 2001/05/01(火) 04:34
あ、defineができないって意味ですか。
失礼しました。


67 名前: デフォルトの名無しさん 投稿日: 2001/05/01(火) 04:47
defineは「何かを」人間が判りやすいように、
「名前で参照」可能にするための物で、
変数としても見れるけど、意味が少し異なる。


68 名前: 67 投稿日: 2001/05/01(火) 04:52
あ、>67
変数→入れ物のまちがい。
変数って用語は「名前」を前提にしないと意味不明なので。
よってsymbolは変数、
list/vector/pairなどは入れ物。
って解釈で良い?


69 名前: 67 投稿日: 2001/05/01(火) 04:53
または無名変数とか。>入れ物


70 名前: 67 投稿日: 2001/05/01(火) 05:00
てことは、
(lambda〜
(let〜
なんかも入れ物の内に入るのか。
(lambda〜) ;=>closueの入れ物
(let〜) ;=>環境の入れ物



71 名前: 67 投稿日: 2001/05/01(火) 05:30
ということは、
(define s
 (let ((x 300))
  (lambda (param)
   (list-ref (current-environment) param))))
とした時、
(s 0)
=> ((param . 0))
(s 1)
=> ((x . 300))
が返るわけだ。


72 名前: 67 投稿日: 2001/05/01(火) 05:35
(set-cdr! (car (s 1)) 100)
(s 1)
=> ((x . 100))
だんだんわかってきました。


73 名前: 67 投稿日: 2001/05/01(火) 05:57
>>71-72 を応用すればローカルスコープの変数を増やしたりもできる。

結論:Schemeは自由度がかなり高い。
なんであんまり普及しないんだろう?
・・括弧だらけだからか。


74 名前: デフォルトの名無しさん 投稿日: 2001/05/01(火) 08:42
頭のなかをリカーシブにしなくちゃいけないから。
リスト構造の物を扱うときは、Cでもリカーシブで
プログラムつくるけど、そうすると引き継いだやつから
こんなプログラム書いていいんですか、といわれる。
理解できないだって。


75 名前: デフォルトの名無しさん 投稿日: 2001/05/01(火) 10:40
>>68 mutable data typeじゃダメか?
変数はどうやっても defineで定義するか lambdaで導入するもの。



76 名前: デフォルトの名無しさん 投稿日: 2001/05/01(火) 10:44
>>74 本来、再帰のほうが自然な構造だと思うけどな。
数学でも再帰のほうがよく使われるし。
Fortranからの悪しき伝統だと思いたい。
#でもやぱり末尾再帰できる形にコードを変換するのは
#面倒だったり



77 名前: デフォルトの名無しさん 投稿日: 2001/05/01(火) 14:24
>>74 >>76

再帰を難しいと思って(思い込んで)いるかどうか?が、
そいつの頭悪い度&プログラマ不向き度(笑)を計る
1つのバロメータだと思われ。

でも
>#でもやぱり末尾再帰できる形にコードを変換するのは

なんかそんなことをわざわざする(しないとならない)
ってのは本末転倒だなとも思う。




78 名前: デフォルトの名無しさん 投稿日: 2001/05/02(水) 00:13
再帰は慣れだと思うけど。
末尾再帰はテンプレートとして覚えれば良いと思う。
↓は末尾再帰
末尾再帰でスタックフレームを生成しない処理系ならばwhile(rest)と同じ。
func(rest) {
return (rest) func(rest - 1) : rest; }
こっちは普通の再帰。+restのせいでスタックフレームが生成される。
func(rest) {
return (rest) func(rest - 1) + rest : rest; }


79 名前: デフォルトの名無しさん 投稿日: 2001/05/02(水) 04:15
再帰を普通のループに直す方法で参考になるサイトありませんか?


80 名前: デフォルトの名無しさん 投稿日: 2001/05/03(木) 16:42
副作用について教えてください。
代入は副作用だそうですが、なぜ関数型言語での代入に相当するような
動作は副作用ではないとされているのですか?


81 名前: デフォルトの名無しさん 投稿日: 2001/05/03(木) 16:48
>関数型言語での代入に相当するような動作
どの事いってるの?
もうちょっと具体的に。


82 名前: 80 投稿日: 2001/05/03(木) 17:04
>>81
例えば、a=1;という文があったとき、これはどう見ても代入に
しか見えないのですが、なぜこれは関数型言語では副作用では
ないのですか?
常に新しい変数を作るからという解説は良く見かけますが、
それだとなぜ副作用にならないんですか?


83 名前: デフォルトの名無しさん 投稿日: 2001/05/03(木) 22:52
あげ。
どの言語ですか?>82


84 名前: デフォルトの名無しさん 投稿日: 2001/05/04(金) 00:04
>>83
だから代入の無い関数型言語だろ。


85 名前: デフォルトの名無しさん 投稿日: 2001/05/04(金) 00:32
>>82
代入じゃなくって定義だと思えば?


86 名前: デフォルトの名無しさん 投稿日: 2001/05/04(金) 14:16
時間軸に沿って見た場合、aの値がずっと同じなら定義。で、変化するなら
代入。って感じかな。Pascalの = と := の違いを思い出す。
ああ、スコープが別な aはもちろん別物として扱ってな。

っていうか、時間軸なんかなくて、本来すべて静的な定義として書くのが
関数型言語の理想。数学にも時間軸はないように。
でも対話的処理とか時間がからむものを書こうとすると
monadとかいって苦労するんだな、これが..


87 名前: デフォルトの名無しさん 投稿日: 2001/05/04(金) 14:56
>>86
ふーん。
ってことは、UMLでいう状態図とシーケンス図は
最も遠い存在ってことか…。

うーん。「数学に時間軸がない」こと自体が既に
(数学を)嫌なんで、やっぱりパスかな俺にとっては。

#でも、ほんとうに数学に時間軸無いの?
#時間軸ある数学だって当然だが構築可能だよね?だよね?


88 名前: 80 投稿日: 2001/05/04(金) 18:56
>>85-86
そういう違いはわかるんだけど、だったら、
なんで定義の方は副作用じゃないんですか?
環境に新しい物を加えるのだから副作用じゃない
のですか?


89 名前: デフォルトの名無しさん 投稿日: 2001/05/04(金) 21:15
object的 identityはない世界だからねえ。
まあ、それがゆえに実世界の問題のモデリングは面倒じゃ、
とは思えなくもない。

数学 (つーか論理学) にも時間が入ったのはあって、
様相論理ってのはその一つだな。◇や□が出てくる。
monadと様相論理が関係あったかどうかは忘れた。
monadと線形論理をからめた論文は見た気がするがな。
見ただけで読んでない。


90 名前: >88 投稿日: 2001/05/04(金) 21:52
「加えた」のではなくて「定義が記述されている」といえば?


91 名前: 80 投稿日: 2001/05/04(金) 23:47
>>90
状況によっては、動的に変数が増えていくことになりますよね?
だから、静的なあらかじめ記述された定義とは根本的に違うような
気がするんです。


92 名前: 80 投稿日: 2001/05/04(金) 23:50
定義にしろなんにしろ、動的にオブジェクトが増えていく場合、これを
副作用と言わないのはなぜでしょうか?
環境は変化していると思いますし、値を返す以上のことを行っている
ように思えます。


93 名前: 某スレの1 投稿日: 2001/05/05(土) 00:13
よくわかりませんが、
Scheme流に言えば、「定義」を「破壊」した時点で、
それはもはや「定義」とは見なせないとは思います。
(define a 1) => aは1、という定義。
(set! a 2) => aは1、という定義を破壊(消滅)し、
新たにaは2、という定義を作る。
=>これが変数。
const-defineなんて構文があったら都合がいいのかな?


94 名前: デフォルトの名無しさん 投稿日: 2001/05/05(土) 00:57
>>89
実世界のモデリングという言い方にはいつも
ひっかかりを覚えるんだけど(^^;、
OOの立場(?)から言えば、
イデアだってメタクラスのインスタンス
でしかないんだよね。
形而上だからってOOのモデルで扱えない
って言いきることは無理なんで、まぁ…


95 名前: 62 投稿日: 2001/05/05(土) 02:15
>>80
>>82
62に書いたことが理論的には答えなんだけど,
論文が見つかったのでもう少し詳しく説明してみるね.

MLでのx=1というのは,既に存在する環境
(変数名と値の対の集まり)を明示するコマンドであり,
式を評価するときに自由変数xの値を使えるように明示すると思えばいい.
これを変えるような操作を代入というわけだけど,
これは時間軸にそって環境が変化することを意味するから
状態を持つことになるので関数型では許されない.

でもやっぱり代入に相当することは欲しいので状態の変化を何とかして表したい.
そこでどうするかというと,ポインタのようなもので
それは単なる値を指しているのではなく
次の状態の環境込みのもの(クロージャ)を指していると考える.
すると,そのクロージャの中の環境にその変数名がまた現れている可能性があるので
ここでぐるぐる回る自己参照のような問題が起こる.
よって,こういうデータを扱えるようにMLの型システムを拡張してやれば
見かけ上代入可能な変数が使えることになる.

これの理論的な意味付けを行った論文が

R. Milner(MLを作った人ね) and M. Tofte
Co-induction in relational semantics
Theoretical Computer Science 87 (1991) 209--200.

であり,例えばOCamlではmutableな変数とimmutableな変数は
理論的には違うものなのでわざわざ区別しているし,
SMLでも代入に見える:=(だっけ?最近書いてないもんで)が
関数型の枠組みで正当化できる.

こういう変数があれば手続き型言語での
ループのカウンタ(ループを回る度に状態が変化する)に使えるので、
そういったループが関数型の枠組みで自然にかけるようになる.
こんなとこかな?


96 名前: 62 投稿日: 2001/05/05(土) 02:48
>>87
時間がない、というのは要するにコンパイル時の静的な(つまり実行する前の)
プログラム解析(型チェックとか型推論とか)に意味を見いだしているから。
時間が入っているような動作も、95のようになんとかして
静的な解析が可能なように理論づけをしようとするわけ。

だから元々実行時のチェックが本質的な応用とはあまり相性がよくない。
それでも継続とかmonadとか使って頑張るわけだが、各monadの定義は
理論上メタレベルで行われる(論理で様相を自分で定義するようなもの)
のでまあ一種の反則ともいえる。


97 名前: デフォルトの名無しさん 投稿日: 2001/05/05(土) 02:54
Schemeの話です。
破壊的代入も環境モデルを使えば素直に理解できると思うが。


98 名前: 62 投稿日: 2001/05/05(土) 03:28
>>97
80-84は副作用のない純粋な関数型言語の話だと思ったけど、違った?
MLは例に過ぎなくて、代入らしきことを副作用のない関数型の枠組みに
どのように取り込むかという話だと思って頂ければ幸いなり。


99 名前: 62 投稿日: 2001/05/05(土) 21:22
>>95
ちょこっと修正.

> こういうデータを扱えるように

こういうモデルで意味が与えられるように

> Theoretical Computer Science 87 (1991) 209--200.

209--220

> SMLでも代入に見える:=(だっけ?最近書いてないもんで)が
> 関数型の枠組みで正当化できる.

SMLでは参照型を導入してそれを:=の左に持ってくることにより実現している.
真面目に調べたい物好きな人向けには

Mads Tofte
Type Inference for Polymorphic References
Information and Computation 89 (1990) 1--34.

に具体的な型システムが載っているので参考までに.

>>88
プログラムの静的な解析が可能ということから
使用する値は最初からどこかの領域に格納されていると考えることができます.
終了しないプログラムもあるので領域は無限にあることもあります.
val x = 1;などで1が格納されたある領域がxという名前で
アクセスできるようになりますが,
その領域は作られたのではなく以前からあったと考えるわけです.
val x = 2;とすると別の場所にある2というデータを
xという名前でアクセスするということになります.
これは以前のxと領域を共有していないので
必要ならば適切に変数の変換をしてやることにより
以前のxとは別の名前と考えることができることが保証されています.
よって本質的には代入ではないわけです.


100 名前: >99 投稿日: 2001/05/06(日) 01:37
本質的には代入じゃないけど、実装は変数とあんま変わらないんだよなあ。
へ理屈というか、考え方が違うって事なんだろうけど。
とりあえずage


101 名前: デフォルトの名無しさん 投稿日: 2001/05/06(日) 02:35
切り番おめあげ


102 名前: 62 投稿日: 2001/05/07(月) 03:04
>>100
そうですね,上の話でも現実には領域は有限だから,
実装では使わなくなった領域をせっせとGCで集めて再利用しています.
このように実装は理論の与える直観そのものでなくても
それと矛盾してなければよいわけですが,一方で良い実装が可能であることは
理論を考えるときでも重要なポイントになります.

あとユーザが理論をそれほどよく知らなくても使えることも重要です
(call/ccなんかはその点でちょっと苦しい).
ですからOCamlやMLの動作をユーザが代入による副作用と理解することが
おかしいと主張しているわけではありません.
ML系の場合,型推論という旨味も失いたくないので
副作用でない新たな理屈付けが必要だったわけですが,
それをユーザの方には参照型とかmutable/immutable(可変/不変)という
比較的理解しやすいと思われる見かけで提示しているわけです.

連休も終わったしそろそろこの話もおしまいかな.


103 名前: デフォルトの名無しさん 投稿日: 2001/05/07(月) 04:31
>>102
代入を許すと型推論が出来なくなるのか?


104 名前: デフォルトの名無しさん 投稿日: 2001/05/07(月) 11:27
>>62 MLみたいな副作用がある片端関数型言語を
正統的理論みたいに宣伝するなゴルァ!
強い型付けと代入の有無は本来直交した概念。
弱い型で代入がない純粋関数型言語ってのもありうるだろう。

まあ、実際代入があると型推論あたりで面倒なことが
起こった気はするがね。それの解決法が [62]だったような。
変数定義時よりも一般的な型が代入される可能性もあるわけだし。


105 名前: 62 投稿日: 2001/05/07(月) 14:03
>> 103
単に代入だけならいくらでも意味は付くけど,
静的で複雑な型が絡むと色々難しいねえ.
MLの型理論の場合は高階型や多相型などの豊かな型と
停止する型推論などの便利さが巧妙にバランスしているので,
なんとかそこから大きく外れずに解決したいというとこかな.

>> 104
おう、好きな言語をどんどん語ってくれぃ.
MLは適度にいい加減で汚いところがいいっす.
SML/NJは好きじゃないけど.

> 弱い型で代入がない純粋関数型言語ってのもありうるだろう。

もちろんっす.その場合も99後半の考え方は使える.
でもそういう言語はドメイン理論を使う方が説明しやすいな.
話の都合上,代入の話と型付きの話が混じってしまったのはスマソ.

さあ仕事仕事。


106 名前: デフォルトの名無しさん 投稿日: 2001/05/07(月) 18:16
>>104
純粋な関数型言語と言っても代入を屁理屈で代入じゃないと
強弁してるだけじゃないの?
型推論のしやすさ等で実質的違いは無いと思うけど。


107 名前: デフォルトの名無しさん 投稿日: 2001/05/08(火) 17:06
ってか、もうちょっと簡単な日本語しゃべりやがれ。
さっぱりわからん(鬱


108 名前: 80 投稿日: 2001/05/08(火) 18:28
>>95
型システムを改良することでどうして代入が扱えるようになるんでしょうか?
さっぱりわかりません。
>Co-induction in relational semantics
この論文はネット上では公開されていないですね。
大学で探してみることにします。

>>99
でもxという名前と値のつながりを変更したことになりますよね?
名前と値のつながりは環境ではないのでしょうか?


109 名前: デフォルトの名無しさん 投稿日: 2001/05/08(火) 19:00
関数型言語の originalである、Backusの FPにはそもそも
変数がないぞ!!
αとか意味不明の記号が出てきてわけわかだけどな。
こっから辿れば、関数型言語における変数なんて、sytactic sugarに
すぎないと思えるもの。


110 名前: デフォルトの名無しさん 投稿日: 2001/05/08(火) 19:46
>>109
syntax sugarのことか?
ま、へ理屈だろ。


111 名前: デフォルトの名無しさん 投稿日: 2001/05/08(火) 21:25
>>108
>でもxという名前と値のつながりを変更したことになりますよね?
変更じゃなくて、定義のスコープが変化して見掛け上、
上書きされたということでは?
(ちょっと違うかもしれないけど、考え方として)
静的なschemeのプログラムの継続をlambdaで表現すると
こんな感じになると思います。
ちなみにschemeの継続はプログラムが終るまで無限に続きます。
(lambda (x1 x)
      ...
 (lambda (x2 y)
      ...
  (lambda (x3 z x)
      ...
      (lambda (xn) )))....)
で、x1x2x3の地点でそれぞれのxの定義は内部のlambdaによって
隠す事ができる。例えばx3のxとx1のxは同じ値を持ってる必要は
無いと。わかりにくいかな?


112 名前: デフォルトの名無しさん 投稿日: 2001/05/08(火) 21:49
ついでに、schemeの継続はプログラム終了まで無限に作られるが、
継続がどこからも参照されてないと証明できればその継続はgc時に
回収される。
(define x 'a)
...
(define x ())
の継続の変化を図にすると、

継続→
**************************************//****|プログラム終端
   ↑x=a ↑x=()

xは次回のgcで回収が見込める部分
*********xxxxxxxxxxxxxx**************//****|プログラム終端
   ↑x=a ↑x=()


113 名前: デフォルトの名無しさん 投稿日: 2001/05/08(火) 21:49
>>111
正解


114 名前: デフォルトの名無しさん 投稿日: 2001/05/08(火) 21:50
ああ、ずれた・・
正しくは↑x=a から↑x=() の間がxxxx..です。


115 名前: デフォルトの名無しさん 投稿日: 2001/05/08(火) 23:19
>>111-112
これ、すごくわかりやすい。
関数型言語のイメージが掴めた様な気がします。ありがとう。

まだ型推論の意味が謎ですが。


116 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 01:59
>>111
新しいxを生成するのは副作用でない?


117 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 02:26
新しいx=仮引数パラメータだから副作用とは言いません。>116


118 名前: 62 投稿日: 2001/05/09(水) 02:33
111さんが継続を使って色々説明をしてくださっていますが,
私の書いていたことに関連する日本語での記述がありました.

コンピュータサイエンス入門 --- アルゴリズムとプログラミング言語
大堀淳,ジャック・ガリグ,西村進 著
岩波書店

の14章で,ラムダ計算の操作的意味論として,
コンビネータへのコンパイル,自然意味論,
SECDマシンへのコンパイル,の三つが簡潔に紹介されています.
このうちの前二者が上で話したことと関係しています.

コンビネータ論理というのは,コンビネータと呼ばれる定数項と
その組み合わせの変形規則からなる体系で,変数は現れません.
>>109で紹介されていたBackusのFPはその一種と考えることができます.
コンビネータ論理では変数がないので
その変形を計算と考えると副作用というものも当然ありません.
そして実はコンビネータとラムダ項は
S → λx.λy.λz.(xz)(yz)
K → λx.λy.x
λx.x → SKK
といった具合いにお互いに翻訳が可能です.
>>99 で述べた変数を隠してしまう変換の極端な場合が
ラムダ項からコンビネータへのコンパイルだと思って頂いても構いません.

一方,Milner-Tofteの論文でrelational semanticsと
呼んでいた意味論がここで言う自然意味論です.
>>95 の説明でも触れたようにここでは式に対応する値に環境をくっつけます.
(これは副作用を導入すると言うより環境を値の一部と考えることに近い).
当然ながらクロージャの意味などは自然に付けることができます.

これらはどれもラムダ計算に対する操作的意味論であり,
同じ計算結果を与えますが,見方の違いにより
ラムダ計算を純粋な関数型の変形と見ることもできるし,
環境を取り込んだものと見ることもできるということです.

同じ言語に対する異なる屁理屈なわけですね.

そしてさらに上記のテキストには書いてありませんが,
>>95 で説明したように,Milner-TofteおよびTofteの論文の手法により
自然意味論を使って参照型に意味を与えることができます.
ただしこのとき環境に循環が発生してしまう可能性があり,
ある種の無限対象として必要がでてくるので,
これを最大不動点として意味を考えて余帰納法(coinduction)で
推論することにより解決しています.
(最大不動点と余帰納法は,無限プロセスなどの無限対象の
厳密な意味と同値性を与えるときによく使われる手法です.
無限のものは全部比較して同値判定するわけにはいかないから
普通の帰納法は使えない).

こう書くと多少はすっきりするかなあ。


119 名前: 62 投稿日: 2001/05/09(水) 03:02
>>118 訂正。

> >>99 で述べた変数を隠してしまう変換の極端な場合が
>>99 で述べた代入を隠してしまう変換の極端な場合が

> ある種の無限対象として必要がでてくるので,
ある種の無限対象として扱う必要がでてくるので,


120 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:06
>>115
型推論
val y = x+1;
+は両辺同じ型でなくてはなら無いのでxは整数型。
よってyも整数型と推論できる。
だから yの型を宣言する必要が無い。
fun z(x) = x;
とすると、xがどの型でも取りうると推論できるから、
関数z(x)は特定の型に捕らわれない関数宣言になる。
fun z(x:int) = x;
とすると、xはint型しか取らないようにできる。
このようにして、状況に応じて、型の限定を利用するのか
型無し言語のような柔軟性を持たせるのか、切り替える
ことができる。


121 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:22
C言語も見方を変えるだけで、代入の無い言語に出来ます。(藁


122 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:25
「新しい x とその値の対応を生成するのは副作用ではない?」
という問いは、実はλ式とはなにか、置き換えとは何か、変数
(仮引数)とはなにか、という本質的問いにつながる大きな質問
なのですが、実際にはそこまで行かずとも通常の言語における
副作用は排除できているので問題なし、という捕らえ方でよい
んだよね?>学術系の人

(変数などの)項書き換え規則の「意味」や「解釈」をさらに後ろから
支える論理体系って、何かあるのだろうか。


123 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:28
いや、バックにくっついている理論によって副作用になったり
ならなかったりするだけで、本当は違いが無いってことだろ?
何が違うのさ?


124 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:35
そりゃ何もかも考え方の違いを除けばすべていっしょ、
なわけだけど、その「考え方の違い」というか記数法の
違いによって、ものごとを考える範囲や考え方が異なって
くる、ってとこに意味があるんじゃないの?

実際、ローマ数字のままで現代数学は発展しえたか、とか。


125 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:39
void*ばかり使ってたらCも型無し言語と同じだがや。
もちろんCのコンパイラは型推論なんてしてくれへんねん。
C++や型推論の使える(可能性がある)型無し言語より分が悪いの。
インライン化やオプチマイヅつーか、そこんとこで。


126 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:40
SMLだと関数を定義するのも変数を定義するのも同じこと。
よって変数を定義するのを副作用というなら
関数の定義も副作用ということになる。


127 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:46
>>125
型推論の使える形無し言語って何だ?
型ありじゃないと型推論なんてありえんぞ。


128 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:48
>>124
そういう意味じゃない。
記数法に実質的違いがないだろ。
関数型言語のx=1だろうがC言語のx=1だろうが、
どれも同じだろ。


129 名前: 125>127 投稿日: 2001/05/09(水) 03:52
>>120 参照。
データ型が1つでも指定されてれば型推論は可能なのねん。
決まったデータ型を返す関数からも、もちろん可能。


130 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:53
void*ばかり使うってのは実質不可能だろ。
キャストしないと演算子が使えなくないか?


131 名前: 127 投稿日: 2001/05/09(水) 03:56
>>129
え?変数の型を推論するのが型推論だろ?


132 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 03:59
>>131
関数の型も推論するよ。


133 名前: 127 投稿日: 2001/05/09(水) 04:00
つか、120を書いたのは俺なんだが。


134 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 04:02
>>133
ワラタ


135 名前: 127 投稿日: 2001/05/09(水) 04:06
>>131
なるほど、確かにそのとおりだ。
しかし、変数に型が無い言語で関数の型を
推論してなんか意味があるのか?


136 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 04:06
lisp/schemeでもデータ型から辿っていって、
型チェックをするってプログラムを書けます。
関数定義がデータと同義なので、
定義自体をデータとして解析できるのです。
当然文法チェッカや型チェッカも作れます。
Cでいうlintが自分のプログラムと同じ階層で走る様な物です。
さらに、動的に部分コンパイルやインライン展開する事もできます。
Cでいうコンパイラが自分のプログラムと同じ階層で走る様な物です。
まさにlisp/scheme言語は誰もが憧れる夢の言語なのです。


137 名前: 132 投稿日: 2001/05/09(水) 04:08
>>135
ごめん。ちゃんと読んでなかった。
型無し言語の話だったのね…。


138 名前: 127 投稿日: 2001/05/09(水) 04:13
>>137
そうなのか。それなら別に良いけど。


139 名前: 125 投稿日: 2001/05/09(水) 04:17
ちょちねぼけてました。すんません


140 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 21:30
Haskellマンセー


141 名前: 62 投稿日: 2001/05/10(木) 00:01
>>136
煽りにマジレスしておくと,夢の言語かどうかは別にして
私もLispの最大の特徴はquoteだと思っています.
これがレスになっていることは分かるよね?>136.

面白いのでこちらに挙げておこう.
http://www.shiro.dreamhost.com/scheme/trans/beating-the-averages-j.html


142 名前: デフォルトの名無しさん 投稿日: 2001/05/10(木) 00:54
>>141
確かにquoteが無いと、マクロが書けないし、
シンボルそのものが欲しいときなどにどうしようもないですね。
'(+ - =)
=>(+ - =)
(list + - =)
;=>(#<prim+> #<prim-> #<prim=>)
`( ,+ ,- ,=)
;=>(#<prim+> #<prim-> #<prim=>)
`,`( ,+ ,- ,=)
;=>(#<prim+> #<prim-> #<prim=>)
`(,@`( ,+ ,- ,=))
;=>(#<prim+> #<prim-> #<prim=>)
(define a `(,@`( ,+ ,- ,=)))
;=>a
(eval '`,a)
;=>(#<prim+> #<prim-> #<prim=>)
(eval '`(,@a))
;=>(#<prim+> #<prim-> #<prim=>)
(eval '(eval '(eval '(eval '`(,@a)]
;=>(#<prim+> #<prim-> #<prim=>)
'quoteマンセー
=>quoteマンセー


143 名前: デフォルトの名無しさん 投稿日: 2001/05/10(木) 01:16
>>141 のリンクから飛べるけど、これおもろいね。
管理職のためのハッカー FAQ
ttp://www1.neweb.ne.jp/wa/yamdas/column/technique/hackerj.html
ハッカーのための管理職 FAQ
ttp://www1.neweb.ne.jp/wa/yamdas/column/technique/managerj.html
ハッカーのための管理職 FAQ(パロディ)
ttp://hp.vector.co.jp/authors/VA009232/stinger/Hackerfaq.html


144 名前: デフォルトの名無しさん 投稿日: 2001/05/10(木) 03:50
evalがある言語なら136の言ってること全部できるじゃん。


145 名前: デフォルトの名無しさん 投稿日: 2001/05/10(木) 05:02
あっそ>144


146 名前: デフォルトの名無しさん 投稿日: 2001/05/10(木) 18:53
up


147 名前: デフォルトの名無しさん 投稿日: 2001/05/10(木) 19:22
Lispの開発効率とHaskellの開発効率ってどっちが高いんだろう。
個人的にはHaskellのような気がする。


148 名前: デフォルトの名無しさん 投稿日: 2001/05/10(木) 23:12
ここの人たちって、MLやHaskellをどこで学んだんですか?
マイナーすぎて本とか全く見ないんですが。


149 名前: 英語わかりましぇん 投稿日: 2001/05/11(金) 00:18
>>148
http://www.amazon.co.jp/exec/obidos/ASIN/4756116418/qid%3D989507729/249-3155492-9933113

Haskellはないのかな?
http://www.amazon.co.jp/exec/obidos/search-handle-form/249-3155492-9933113


150 名前: 149 投稿日: 2001/05/11(金) 00:20
下の奴開けない?
Haskellで検索してもないんだよね。
どうやって勉強したのでしょ?


151 名前: デフォルトの名無しさん 投稿日: 2001/05/11(金) 01:32
>>150
http://www.haskell.org/tutorial
上の日本語訳
http://www.sampou.org/haskell/tutorial-j


152 名前: デフォルトの名無しさん 投稿日: 2001/05/11(金) 14:35
>>151
少し読んでみたが、あんまりやさしい入門じゃない。
SchemeかMLの知識がないとだめだろ。


153 名前: 149 投稿日: 2001/05/11(金) 18:35
>>151
ありがたう。


154 名前: デフォルトの名無しさん 投稿日: 2001/05/11(金) 18:46
age


155 名前: デフォルトの名無しさん 投稿日: 2001/05/11(金) 20:06
Lispとschemeって結構近いやん?
haskellってMLに近いの?
>>1であがってるFPやMirrandaって話題出てないけど
どんな感じなの?


156 名前: デフォルトの名無しさん 投稿日: 2001/05/11(金) 22:04
http://www.cs.chalmers.se/~augustss/AFP/overview.html

Haskell vs. Ada vs. C++ vs Awk vs. ... An
experiment in Software Prototyping Productivity

compares a number of programming languages in a
prototyping experiment conducted by the US
Advanced Research Project Agency (ARPA) and others.
Among the results: The prototype required 83
lines of code and 10 hours of development time
when coded in Haskell. The figures for Ada were
767 lines / 23 hours, and for C++ 1105 lines.
A graduate student who first got 8 days to learn
Haskell wrote a prototype in 8 hours!

ほんまかいな? 論文へのリンクは切れてる。


157 名前: デフォルトの名無しさん 投稿日: 2001/05/11(金) 23:14
>>156
Haskellはすごいって話?
C++は糞ってか?
つーか英語わかんねぇよ。
Haskellでは83行に10時間かかったの?

ああ鬱だ


158 名前: 62 投稿日: 2001/05/12(土) 00:04
>>147
そういえば理論屋でないHaskellな人に聞きたいんだけど
モナドって分かりやすいと思いますか?どのように理解していますか?
元の理論を知っていればそれなりに納得できるだろうけど,
普通のプログラマにとっては取っ掛かりがなくて分かりにくいと思うんだけど.
個人的にはここが気になるのでちょっと最強の言語とは言えないなあ(あ,スレ違いか).


159 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 00:33
>>157
つまり、同じ問題出して一斉に解かせたら、
Haskellの場合、たったの83行のコードで問題を解決することができて、
10時間しか問題解決にかからなかったと言うことだろ。
Adaは767行で23時間。C++は1105行もかかったと。

つまりHaskellは凄すぎるってこと。


160 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 01:03
探したらその論文結構有名なようで、あちこち検索に引っかかった。
論文本体もここにあった。
www.cs.uwa.edu.au/undergraduate/units/230.301/papers/hudak-prototyping.pdf
www.ai.sri.com/~heller/Lisp/jfp.ps.Z

pdfの方は横になって見にくかったので、PostScriptの方を見たが、
Relatinal Lispという言語は3時間で終わってる…(藁
行数はでかくなったようだが。

C++はどうやら時間かかりすぎて計測不能だったようだ。
あと、Haskell初級者の学生が、Haskellで8時間で終わらせてしまったという
結果もある。


161 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 01:14
>>156
論文のpsファイルをここからダウンロードできる。

http://www.ai.sri.com/~heller/Lisp/

アメリカ海軍が問題を提供し評価をしたようだが、論文の著者は
2人とも関数型言語の研究者で、特にPaul HudakはHaskell
コミュニティーの中心的な人物です。かなり眉唾か?


162 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 01:17
prototypeが関数型言語で書きやすい物だったに一票


163 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 01:20
>>161
つーか、その二人目のやつが実際に問題解いたそうだ。
しかし、中心的な人物が学生に負けるとは…


164 名前: 163 投稿日: 2001/05/12(土) 01:23
ん?Paulはファーストアーサーか。
問題解いたのはMarkの方だ。


165 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 03:34
>>136
>型チェックをするってプログラムを書けます。

わざわざ書かなあかんの?


166 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 05:57
わざわざって、そんなに難しい事か?>165


167 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 12:07
それなりに面倒だと思うけど。
それにコンパイラがチェックしてくれるわけでもないなら
あまり意味が無い。


168 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 13:37
意味ないわけないだろ。作りようによっては推測・自動修正して
結果を報告する様にもできるぞ。>167
結局、環境リストと定義リストの探索だから、そんなに難しくはない。
変数(バインドされたシンボル)の使われ方を辿っていって、
外部データ表現(または構造)に辿り着く様であれば、それで変数の
型が特定する。


169 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 13:44
168によって型が特定したら、イリーガルな操作を行なっている部分
を列挙できる。
ちなみに型の特定は、処理系が用意している基本プリミティブや、
入出力の型が確定しているclosureからもできる。


170 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 14:06
Haskellって人の名前なのね。
ML知ってる人はこのスレに何人かいる様だけど、
Haskellって皆無なんじゃ?


171 名前: デフォルトの名無しさん 投稿日: 2001/05/12(土) 17:26
Haskellマンセーとか言ってた人は、使ってんの?


172 名前: デフォルトの名無しさん 投稿日: 2001/05/13(日) 04:22
Haskellマンセーとか言ってた人は、使ってんの?


173 名前: 62 投稿日: 2001/05/13(日) 04:39
型チェックと型推論は区別してくれい.

型チェックは変数や対象の型が整合しているかどうかチェックすること.
型推論は型宣言が省かれた変数や対象の型を導くこと.
例えばCには型チェックはあるが型推論はない.
すべて明示的に型が宣言されているから.

それで単純な型だけならいいんだが,型システムを多相型に拡張しだすと
どちらについてもコンパイル時に行うには困ることが起こる.
例えば,ある種の多相型に部分型を導入すると
型チェックが止まらないケースが出てくるとか,
MLの型システムに普通にレコード型を導入したら
MLの型推論の意味での単一の型が決定できないケースが出てくるとか.

だから,もしオブジェクト指向のようなことができるように
型システムを拡張しようとするなら,そいつは全然簡単じゃない.


174 名前: デフォルトの名無しさん 投稿日: 2001/05/13(日) 08:14
つかったことあるよHaskell
モナドはわかりずらいよね。
Introduction to functional programming using Haskell 2nd ed.
でべんきょした


175 名前: デフォルトの名無しさん 投稿日: 2001/05/13(日) 12:41
すみません。もう1つ猿な話させてください。

関数型なる概念の定義の概略はここの皆さんの発言で
なんとなく判った気はします。

で、Lispって関数型言語だということになっているんですよねえ?

でも書籍「List遊び」を読んだ感じでは、(Emacs)Lispは
Listという「データ構造」をいじる言語である、という風に
読めちゃいました。それは明示的な状態(の一種)だと思う
のですが、すると関数型言語っぽくないということに
なるような気が…?
関数云々というよりも、関数もデータも全部Listと見なしてから
全てを考え始める、というノリに思えました。

(Emacs)Lispはたまたまそういう(関数型としては不純な)
言語であり、それは関数型の本質とは無関係だ、
ということでしょうか?
それともそれ以外のなんらかの意味なんでしょうか?


176 名前: デフォルトの名無しさん 投稿日: 2001/05/13(日) 14:02
>>175
listを弄るとは言っても、入力されたlistを
直接書き換える事では無いって事。
出力するリストはconsで生成するでしょ。
lispは破壊操作を行なわなければ関数型言語と同じ。


177 名前: デフォルトの名無しさん 投稿日: 2001/05/14(月) 00:11
>>168
意味ねぇよ。
その間違った所が実行されきゃ間違った所がわからないだろ。
実行する前に、どこがおかしいか一目瞭然でわかる方が
遥かに良い。


178 名前: デフォルトの名無しさん 投稿日: 2001/05/14(月) 13:33
このスレを眺めて思い浮かんだ言葉。
「象牙の塔」
「砂上の楼閣」


179 名前: デフォルトの名無しさん 投稿日: 2001/05/14(月) 17:13
熱く語っている方々へ。

○○ってすごいぜ。
□□できるし、
△△はあるし。

と各言語をまとめるとどんな感じになります?

例えば、
C++ってすごいぜ。
オブジェクト指向言語だし、
STLはあるし。


180 名前: デフォルトの名無しさん 投稿日: 2001/05/14(月) 17:36
>>178
君のレスを眺めて思い浮かんだ言葉。
「食わず嫌い」

>>179
それぐらいのこと自分で勉強しろ。


181 名前: デフォルトの名無しさん 投稿日: 2001/05/14(月) 17:44
>>178
http://www.shiro.dreamhost.com/scheme/trans/beating-the-averages-j.html
とか読んでみそ。
使える人が少ないから業務で使われたりしないだけで
ほんとは十分実用的。


182 名前: デフォルトの名無しさん 投稿日: 2001/05/14(月) 17:58
>>181
VB厨はほっといたほうが良いかと思われ。


183 名前: デフォルトの名無しさん 投稿日: 2001/05/14(月) 18:12
仕事で必要だったので、Schemeを勉強し、今業務で使っています。
仕事以外でもSchemeやHaskellをいじって遊ぶのはほんとに楽
しい。それだけで十分だと思います。


184 名前: デフォルトの名無しさん 投稿日: 2001/05/14(月) 18:19
>>50とか>>178ってなんなんだろ?
VB厨かな?C++厨?


185 名前: 178=179 投稿日: 2001/05/14(月) 19:13
えーと、このスレで話されてることに非常に惹かれるのですが、
読んでもさっぱりわからないし、一体何故そんなに熱く語れるのか
是非知りたいので質問して見ました。

ちなみに>>107も僕です(鬱


186 名前: デフォルトの名無しさん 投稿日: 2001/05/14(月) 22:07
>>185
とりあえずSICPの第1章だけでも読んでみてください。
http://sicp.arsdigita.org/text/sicp/
1章で関数型プログラミングの基礎を説明しています。言語はSchemeです。


187 名前: 182 投稿日: 2001/05/15(火) 08:15
>>185
VB厨なんていってごめんなさい。
死んでおわびします。
がんばって関数型言語勉強してちょ。


188 名前: 178=179 投稿日: 2001/05/15(火) 12:53
>>186-187
さんきう。
紹介していただいたページのタイトル
'Building Abstractions with Procedures'
のうまい訳がわからずいきなり鬱に入ってますが、
とりあえず読みすすめてみます。


189 名前: 178=179 投稿日: 2001/05/15(火) 12:56
ぬぅ、この分量だと、俺の英語力だと一ヶ月くらいかかりそうだ。
早く、'Satori'を体験して見たいなぁ。
では、またROMに戻るナリ。


190 名前: デフォルトの名無しさん 投稿日: 2001/05/16(水) 01:41
そんなに英語力が無いなら、素直に日本語のSchemeや
ML書籍読めば?


191 名前: >189 投稿日: 2001/05/16(水) 02:06
SICP(計算機プログラムの構造と解釈)は外せないと、思った。
ちょっと古いせいか、マクロや継続の説明は無かったけど。
サンプルコードはMITのサイトにあった様な。


192 名前: デフォルトの名無しさん 投稿日: 2001/05/16(水) 09:19
>>191
SICPはプログラミングの教科書であって、Schemeの解説書では
ないので、使っているSchemeの機能は限定されてますね。ちなみ
に第2版は1996年出版なのでそれほど古くはないと思います。


193 名前: デフォルトの名無しさん 投稿日: 2001/05/16(水) 22:16
age


194 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 04:32
下がってきたので、皆で関数型でのプログラミング経験を書いてみよう。
俺、Haskell5000行くらい。


195 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 07:19
行数?
lisp 昔は結構書いた(今はあんまり)
SML ちょびっと
scheme10kステップぐらい。
関数型言語として書いたのはその半分以下に落ち込むでしょう。


196 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 08:52
Scheme 仕事で3000行ぐらい。遊びでは2万行ぐらい。
>>194
Haskellに憧れているのですが、どんなプログラムを作ったの
ですか。差し支えない程度に教えてください。


197 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 15:16
HaskellよりMLの方がわかりやすい。
ところで、MLってOOPはどうやるの?
クラスのかわりにモジュール使うの?


198 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 15:22
>>197
OOやる必要あるのか?
とりあえず Objective caml とかありますぞ。


199 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 15:49
http://www.linuxdoc.org/HOWTO/mini/Programming-Languages-2.html
に関数型プログラミングはOOPのスーパーセットだと書いてあります。

Functional languages (Lisp for example) are a bit
different breed - among other things, functional
programming is a superset of OOP.

MLはわからないですが、SICPではSchemeでのOOPがでてきますね。


200 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 16:04
>>197
モジュールをクラスにしてファンクタを継承がわりに
するんじゃないか?


201 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 22:05
>196 Haskellで書いたのはコンパイラもどき。

>197 関数型言語がOOPのスーパーセットだっていうのはきつくないか。
OCamlとかはやってるみたいだけど、俺は使ったことない。
俺の友達はやっぱり、関数型とオブジェクト指向って馴染まないと
言っていた。


202 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 22:56
馴染まないって事はないんじゃないか?
HaskellやO'Camlにはクラスはちゃんとあるし。
何を根拠にそんなことを?


203 名前: デフォルトの名無しさん 投稿日: 2001/05/17(木) 23:30
Haskellのクラスはタイプクラスと言うもので
オブジェクト指向のクラスとは異なる。
どっちかと言うとJavaのinterfaceみたいなもの。

Ocamlはオブジェクト指向の要素をとりいれているが
これをつかった友達がしっくり来ないと言っていた。
(自分は使ったことがない)

少なくともHaskellでは状態がないのでOOPでのオブジェクト
は実現が苦しいし、皆が認識しているOOPのプログラミング
スタイルをHaskellのプログラミングスタイルに取り込むの
はきついと思ってるけど。

うーん。説明しづらい。


204 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 00:53
そういう所は適度に副作用を許しているMLやLISPが都合がいいのかもしれないね。


205 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 04:36
Haskellって数学好きの人が使うもの?
難しくない?
CとかRubyとかとは、好む人が本質的に違うような雰囲気。


206 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 06:40
誰かhaskellの特徴的なサンプルコード教えてください。
どこかからのコピペでもいいです。


207 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 07:01
副作用が無いってことは、作った関数群は恒久的に使いまわせる(再利用できる)
と考えていいですか?


208 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 09:53
じゃあ、Haskellでのクイックソート

qsort [] = []
qsort (x:xs) = qsort small ++ [x] ++ qsort large
where
small = [y | y <- xs, y < x]
large = [y | y <- xs, y >= x]

small,largeのとこで使ってるのがList Comprehensionという
Haskellにしかない構文


209 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 09:57
>205 確かに、少し難しいとは思う。かなりプログラムに対する
考え方を変えなければいけないので、Cとかになれてしまっている
人で固執してしまっている人は嫌うんじゃないかな。

>207 そうです。そういった部品(関数)をつなぎ合わせてやっていく
のが関数型のプログラミングともいえるかなぁ。


210 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 10:03
>>206
Haskellでのクイックソート

qsort [] = []
qsort (x:xs) = qsort [a|a<-xs,a<=x] ++ [x] ++ qsort [a|a<-xs,a>x]

>>207
引数が同一なら必ず同じ値が関数から返される、というのが
参照透明性といって関数型プログラミングの基本です。Cでも
関数の使いまわしをしたい場合はそうするでしょう。


211 名前: 210 投稿日: 2001/05/18(金) 10:05
考えていたらかぶってしまった。スマソ。


212 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 11:23
>>207
一瞬ネタかとも思ったが、
そう言われてみれば、状態を変化させないなら
状態を変化させる手続きより使いまわしが数段楽つーか安全
なのは確かなんですね。うーむ。

まぁ、だからといってその見かえりに
状態そのモノを放棄する度胸は、ちょっと…(^^;
OOPは状態を捨てずに救った言語スタイル。


213 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 14:59
「状態がない」ってのは理屈をつけてごねてるだけで、
実際は状態があるのと大差ない。


214 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 17:43
無礼と知っててここに書き込みます。
haskellの質問スレが見つからなかったので。すみません。
実は今学校の課題でhaskellつかっているのですが、
さっぱりわかりません。

課題というのは、
有理数aから区間列{(a-(1/(2^n)),a+(1/(2^n)}を表示するというものです。
それで、

list::Int->[Integer]
list n= let f x = (x*2):(f(x*2)) in take n (f 1)

で2のn乗が計算でき、

list2::Rational->[(Rational,Rational)]
list2 a=[(a-1%(n+1),a+1%(n+1)) | n<- [1..]]

で有理数aから区間列{(a-(1/(n+1)),a+(1/(n+1)}を表示できたのですが、
どうしても2のn乗を表示できません。
どなたか教えていただけませんか?


215 名前: 62 投稿日: 2001/05/18(金) 19:07
>>213
だーかーらー、理屈をこねるのはそれだけの見返りがあるからだってば。


216 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 20:21
見返りが無いとは誰も言ってない気が…


217 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 21:33
>216
文章である以上ちゃんと書かないと伝わらないよ。
で、アンチ的な発言なんですか?


218 名前: デフォルトの名無しさん 投稿日: 2001/05/18(金) 23:21
ちゃんと伝わらないってどういうこと?
アンチ的なのかどうか分類できない発言を、勝手に
間違えてアンチに分類されるってことか?(藁


219 名前: デフォルトの名無しさん 投稿日: 2001/05/19(土) 00:14
>>213はあれだけだとこのスレでさんざん出没した
アンチ側の意見に見えるけど>>218


220 名前: 名無しさん 投稿日: 2001/05/19(土) 00:17
age


221 名前: 名無しさん 投稿日: 2001/05/19(土) 00:17
age


222 名前: 名無しさん 投稿日: 2001/05/19(土) 00:17
age


223 名前: 名無しさん 投稿日: 2001/05/19(土) 00:18
age


224 名前: 名無しさん 投稿日: 2001/05/19(土) 00:18
age


225 名前: デフォルトの名無しさん 投稿日: 2001/05/19(土) 00:41
荒らされてる?


226 名前: デフォルトの名無しさん 投稿日: 2001/05/19(土) 00:41
ありゃりゃ、なんなの?中身のあるカキコしてん>>220-224


227 名前: デフォルトの名無しさん 投稿日: 2001/05/19(土) 00:45
荒らしです>226
00:15〜00:19頃に上位20のスレが狙われた模様


228 名前: デフォルトの名無しさん 投稿日: 2001/05/19(土) 01:07
>>219
そのさんざんあらわれたアンチは、本当にアンチだったんでしょうかね?(藁


229 名前: デフォルトの名無しさん 投稿日: 2001/05/19(土) 02:40
さんざん現れたアンチってどこら辺のこといってるの?


230 名前: デフォルトの名無しさん 投稿日: 2001/05/19(土) 02:51
>>185さんはアンチ発言らしきものをしたがアンチじゃないらしいし。


231 名前: デフォルトの名無しさん 投稿日: 2001/05/19(土) 04:40
めんどっちいから、もうアンチ発言らしきものをした人はアンチでいいじゃん。(w


232 名前: デフォルトの名無しさん 投稿日: 2001/05/20(日) 17:26
比べてもしょうがないかもしれないけど、
副作用がないってことは関数型のほうがOOよりさらに再利用性が高いのかな?

OOPのライブラリとかって、結局大きい塊としてしか扱えないような気がするし。


233 名前: デフォルトの名無しさん 投稿日: 2001/05/20(日) 18:58
細かい使い回しはいろいろ聞くと思うよ。
高階関数もあるし。


234 名前: デフォルトの名無しさん 投稿日: 2001/05/20(日) 19:05
ていうか、副作用が無いことにしたって、プログラムの
考え方が解析しやすくなっただけだろ。
それはプログラムの見方の問題であって、言語の文法
は何ら変わってないだろ?


235 名前: デフォルトの名無しさん 投稿日: 2001/05/20(日) 19:11
再利用もそうだけど、加工が容易な気がする。
見通しが良いからかな?

>>234
基本的に制御構文の考え方ははほとんど変わりないです。


236 名前: デフォルトの名無しさん 投稿日: 2001/05/20(日) 22:30
>>234 なんで文法の話しになったんだかわかんないけど、
Haskellじゃ ifは組み込み構文じゃなくて、
単なる関数になってるよ。


237 名前: デフォルトの名無しさん 投稿日: 2001/05/20(日) 22:38
pow2 = 1 : map (2 *) pow2
series a = [(a - 1%n, a + 1%n) | n <- pow2]
じゃだめ? >>214
先頭 nコが欲しいときは take n (series a)


238 名前: デフォルトの名無しさん 投稿日: 2001/05/20(日) 22:40
>>231 アンチかどうかは call-by-needで評価しようよ


239 名前: デフォルトの名無しさん 投稿日: 2001/05/20(日) 23:26
>>236
関数だったらifの要である、分岐ロジックってどうやってるの?


240 名前: デフォルトの名無しさん 投稿日: 2001/05/20(日) 23:51
そもそもifって副作用とか状態とか関係ないでしょ。


241 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 00:03
>>240
いや、だから
if a then b else c

bやcには関数でどうやって分岐してるのか聞きたいんだけど。


242 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 00:14
ifが関数ならば、if自身の関数定義はどうなってんの?って事か。


243 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 00:29
ちなみにschemeやMLでのifは関数ではなくて、syntax


244 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 00:37
>>239
パターンとかかなぁ。知らないけど。


245 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 00:57
>>241
Cでいうところの関数ポインタ渡すんだよ。


246 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 01:05
>>245
んだんだ。Cで、

IF(int, (void*)(), (void*()));

って関数が書けるもんな。あれの延長だ。
あとは無名つーかInlineな関数(?)を書く機能が
Cにもし有れば、ノリも完全同じなことができたんだが…


247 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 01:16
>>246
> IF(int, (void*)(), (void*()));

これって、内部でif文使うだろ?


248 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 01:35
なんでここでCの話が出てくるんだよ>>245-246
関数のポインタの話なんてしてねえだろ。


249 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 01:40
>>248
話の流れ読めてるか?


250 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 01:46
haskellの「if関数」の定義の話じゃないの?>249


251 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 01:50
>>247 Cプログラマに説明するなら
「 A ? B : C の三項演算子を関数化したようなもの」
といえばすんなり納得してくれると思う。


252 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 01:52
>>249
理解してないのはキミ。
↓これ。

>236 名前:デフォルトの名無しさん 投稿日:2001/05/20(日) 22:30
>>>234 なんで文法の話しになったんだかわかんないけど、
>Haskellじゃ ifは組み込み構文じゃなくて、
>単なる関数になってるよ。

「単なる関数」なら、どうやって定義してんだって話。


253 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 01:57
>251
だから今、Cの話なんてしてないだろ。

haskellのifは>>236が言うには「単なる関数」らしいので、
それをhaskell自身でどうやって定義してるのか示せって言ってるの。

問題
if = [?]
[?]を埋めよ。


254 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:00
だからHaskellの話にCを持ち出して比較することで
話をわかりやすくしようという意図だろ?
そういう目的なら別にCの話を持ち出したっていいだろ。


255 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:03
全然理解してないな。寝てしまえ>254


256 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:04
[?]は外部呼出しなんじゃ?
でもhaskellはパターンマッチがあるんだからifなんて必要なのか?
#Haskellはちょっとかじっただけなのでまったく自信無し


257 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:04
>>254
なんでここで、「Cを持ち出して比較する」必要があるわけ?


258 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:14
矛盾してる。
haskellのifは関数だという。
でもその関数の定義は示せないらしい。
(示そうとする人が現れない)

>>256
>[?]は外部呼出しなんじゃ?
外部呼出しを「単なる関数」とはいいませんよ。

>ifなんて必要なのか?
そんなこと議論してません。


259 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:17
>>257
例えば、「関数である」ということを聞いて、「ほう、Cのあれと同じだな」と
思った人がいて、「CのIF()と同じようなもんさ」と発言する場合など。
その人は間違ってるかもしれないけどね。


260 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:18
つーか>>236 解答おねがいします。


261 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:21
だからC言語の例はあくまでも「喩え話」だから関係無いだろ。>259
haskellでどう定義するかって話。


262 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:22
>>261
例え話を発言しちゃいかんのか?


263 名前: 問題 投稿日: 2001/05/21(月) 02:24
haskellでの関数定義

if = [?]

[?]を埋めよ。


264 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:25
いくら喩え話をした所で問題は解決しないって事>262


265 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:26
>外部呼出しを「単なる関数」とはいいませんよ。
なじぇ?WindowsAPIは単なる関数呼び出しでしょ?

>ifなんて必要なのか?
>そんなこと議論してません。
まあそうだけど、パターンマッチてのはswitch見たいなもんだから、
・・・ってヨーク考えればパターンマッチ使えばifも実装できるね。
#しつこいようだが自信無し


266 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:29
>>265
>パターンマッチ使えばifも実装できるね。
だったらそれを示してくれ。


267 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:32
>>265
>なじぇ?WindowsAPIは単なる関数呼び出しでしょ?
なんでWindowsAPIの話になる。
WindowsAPIでif関数が定義できるのか?


268 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:34
問題

if = [?]

haskellの言語機能のみを使って、関数ifの定義[?]を埋めよ。


269 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:39
>>234-268


270 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:39
>>264
でも話にはなってるだろ?
本人はC言語の例えで解決になってると思って発言してるのかもしれないし。
もう一回ログを読んで、話の流れを読めよ。


271 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:40
手続き型言語しかしらない人に
関数型言語を布教するのによい説明方法を話し合うのも
それなりに生産的な議論だとおもうんだけどな、、、、
果てしなく脱線する可能性が高いけど。


272 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:44
>>268の問題を解いてくれる人を待ってます。
if自身の定義にifを使うのはナシね


273 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:48
if b funcA funcB | b == true    = funcA
         | b == false    = funcB
見たいな感じかなぁ。
#自信無し


274 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:50
lisp schemeスレで、ループを3つのlambdaで表現した人が
いたけど、これもそんな解答になって欲しいなあ。


275 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 02:53
>haskellの言語機能のみを使って
この思い込みはどこからくるの?
ifが外部関数もしくはビルトイン関数であっても、制御構造ではなくて
関数であることには変わりはないと思うのだが。


276 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 03:02
>>273
ありがとう。パターンってそういうことなのね。
でも結局if相当の事は行なうわけか・・


277 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 03:06
それ、制御構造じゃん>275


278 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 03:12
>>275
>外部関数もしくはビルトイン関数
0点。


279 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 09:51
if p then else = case p of
True -> then
False -> else


280 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 15:36
>>278
なんで?


281 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 17:09
<<Haskell
でも実際はthen elseは構文として間に入るから出来ないよ。
あくまでも概念


282 名前: 281 投稿日: 2001/05/21(月) 17:14
Haskellのif "cond" then A else Bは
case "cond" of | True = A
| False = B
のシンタックスシュガーでしょ?


283 名前: 244 投稿日: 2001/05/21(月) 19:58
SMLだと(ifって識別子は使えないけど)
fun if(true,a,b) = a
| if(false,a,b) = b;
で出来るなぁ。


284 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 20:00
なんか見たことない言語がいっぱい(笑


285 名前: 244 投稿日: 2001/05/21(月) 20:03
>>276
僕の言ったパターンてのは>>283ね。
>>273はパターンっぽいけど違うかと。


286 名前: デフォルトの名無しさん 投稿日: 2001/05/21(月) 20:13
>>279
iF :: Bool -> a -> a -> a
iF = \p -> \tHen -> \eLse -> case p of {True -> tHen; False -> eLse}


287 名前: 244 投稿日: 2001/05/21(月) 20:37
>>283
でも遅いし、副作用が無いのが前提か……


288 名前: 214 投稿日: 2001/05/22(火) 02:15
237番のかた、どうもありがとうございました!!
本当にたすかりました。

ていうか、先生が小声で早口でわかりにくいうえに
参考書も英語なんでかなりてこずってます・・・あう。


289 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 02:21
>288
化石レスには引用付けて欲しいなあ・・
>>214 >>237 みたいに。


290 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 02:22
それにしても学校の授業でhaskell使うなんて恵まれてるね。


291 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 02:25
>>290
どーい。


292 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 02:54
どこの大学?
相当偏差値高くない?


293 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 07:22
Haskellでforやwhileループのようなことをやるには
どうしたら良いの?


294 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 11:12
>>293
ループでやるようなことをするのなら
takeWhile や dropWhile なんかを使うかなあ。
ループをリスト上の再帰にしてしまう。そういうことじゃない?


295 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 16:05
Haskellのやさしい入門っていうの、どこかのHPの私訳を一通り読んだけど

はっきりいってむずかしすぎて分からん。
相当頭のいい人が使うものと感じた。
そもそも型の再帰的定義からしてかなり難解。
ひとまずMLの資料を探してみることにします。
ていうか、言語よりはもっと本質的な理論が重要なように感じる。


296 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 16:25
あれはMLを多少知ってた俺でも難しいと思ったからな。


297 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 16:40
単に慣れや覚えた順番の問題じゃないかなあ。
Haskell より ML 方が難しいと思う人もいたりする。


298 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 17:08
先にSchemeやったら、HaskellもMLもみんな
構文が複雑すぎるように感じられる。


299 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 17:40
御意
でも、Scheme に比べれば大抵の言語は複雑な構文だよね。


300 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 18:01
Lispの文法もかなり凄いことになってるよね…


301 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 18:11
SMLはストラクチャ辺りが複雑だと思う。


302 名前: デフォルトの名無しさん 投稿日: 2001/05/22(火) 18:33
HaskellやMLの場合言語の構文が複雑というよりも、主に
研究者が使ってる言語だからドキュメントがやたら難しい
言葉で書かれている。
複数の文を書く方法やfor、while相当の機能の説明が
ずいぶん後の方でちょろっとだけ出てきたりする。
その辺が必要以上に複雑だと思わせているんだと思う。

複雑なところと言ってもルールの組み合わせ方が複雑なん
じゃなくて、機能が豊富だから複雑になってる所がいい。


303 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 00:45
for, while相当のものなんて教えてもらう必要あるのか?
再帰を使うって事だけ知ってりゃ簡単だと思うが。


304 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 01:18
知ってりゃ簡単なんです。てりゃそりゃ。
悩んだ後で、「あっそうか」に辿りつけるかどうか。
ちょこっと、アドバイス、記述があればなんてことないのだが、
それがないと敷居が高いと感じるひともいるかな。


305 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 11:12
再帰を使うってことはなにか?
いちいちfor、while相当のことをさせるのに関数を作らなきゃ
ならんってことか?
なんて不便な言語だ。


306 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 11:20
>>305
おいおい。
関数型言語なんだし、関数作らなきゃ何もはじまりませんよ。
そもそも関数つくるのなんてそんな大変じゃないだろ?
むしろfor,whileよりすっきり、早く書けることのほうが多いんじゃないかな。


307 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 11:41
>>306
いちいちfor使うたびに新しい関数の名前考えなきゃならんのか?
そんな面倒なことやら無くちゃいけないぐらいなら、forが
はじめから定義してあった方が良いに決まってる。
俺だったら結局自分でfor関数定義して使うよ。
つーか、再帰すらわからないやつがいるというのに、
再帰の説明だけでforの代用に気付けといわんばかりの説明は
敷居が高いのは明らかだろ。


308 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 14:01
>>307
一々関数を定義するじゃなくて、
map とか foldr とかのリスト上の標準関数使うだけだと思うけど。


309 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 14:09
>>308
mapやfoldrは引数に関数を取る。


310 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 14:10
Schemeでちょろっと末尾再帰するときはたいていloopという関数名にしている
おれってドキュン?


311 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 14:15
forループを関数にしたら、スコープが変わってしまうだろ。


312 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 14:21
>>311
スコープが変わるとだめですか?
なにのスコープがどう変わると、どうだめなんでしょう。
簡単な例題はないですか。


313 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 14:35
>>312
外側の変数が簡単につかえない。


314 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 14:48
>>313
純関数型なら assignment がないので問題ないような気がします。


315 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 15:08
>>314
ハァ?なんで問題ないの?


316 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 15:23
外側の変数の値を内側で変更するのが問題だということかと思っていました。
私は 313 の意味を勘違いしてるみたい。
どういう意味なんでしょう。


317 名前: 315 投稿日: 2001/05/23(水) 15:40
いや、関数型言語って外側の変数を参照したり変更したりすることって
出来るの?


318 名前: 315 投稿日: 2001/05/23(水) 15:42
それだと、全部の変数がグローバルなのと同じような感じで
ものすごく使いにくいと思うけど。


319 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 15:58
>>317
Haskell なら
変数の参照については外側のスコープのものは参照可能
変数の値についてはいかなる場合も変更は不可能
です。


320 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 18:33
315は、[ごめんこの例はSchemeだけど]
(define (for min max proc) …minからmaxまでカウンタ値を変えて手続きprocを適用する…)
のような関数を使ったときにproc内のスコープがどうなるか
わかってないんだろう。「関数型言語」でひとくくりにしている
ところも痛い。


321 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 19:09
誰かstatic scopeとdynamic scopeの違いをスカっと説明してやれよ


322 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 20:02
>>302
そうそう、そういう所が本質的な議論をしているっていう感じがする。
HelloWorldから始まったりは決してしない、みたいな。


323 名前: 某スレの226 投稿日: 2001/05/23(水) 20:22
>>305 >>310-312
(もしschemeを使用してるならば、ですが。)
lisp schemeスレにforとwhileのサンプルがありますので参考にどうぞ。


324 名前: デフォルトの名無しさん 投稿日: 2001/05/23(水) 21:59
>>322
関数型言語の枠組で
Hello World を説明するのはあまりに難しいからじゃないかな。


325 名前: 某スレの226 投稿日: 2001/05/23(水) 22:37
do〜whileも置いておきました。
あの様に、(マクロとしてですが)継続の部分を除けば、
C言語のfor/while/do〜whileも関数型言語の枠組みだけで実現できます。
用意されていないだけで、相当する処理は書ける事がお分かりになったでしょうか。
(break/continue/returnは継続の様な特殊な物が無いと難しいですけど。)


326 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 01:04
副作用を起こさなければ、正体不明のバグってかなり減るような気がする。
そこが関数型言語の良い所?


327 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 01:17
関数型言語ではこういうのはどうするんですか?

(defvar x 10)

(defun f (y)
(setq x (- x y)))

(f 3) => 7
(f 4) => 3


328 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 01:57
setq使ってる時点でアウト。>327
考え方が関数型になってない。
>(f 3) => 7
>(f 4) => 3
;以後、これはキモイと考えること。


329 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 02:09
Rubyのまつもとは、文字列において、副作用を起こす参照が良くて
複製を作る代入(宣言なら副作用は起こらない)はダサいとか
言ってたよ。(藁


330 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 02:14
>>320
> (define (for min max proc) …minからmaxまでカウンタ値を変えて手続きprocを適用する…)
> のような関数を使ったときにproc内のスコープがどうなるか
> わかってないのだろう

C言語とは違うのか?


331 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 02:16
>>324
モナドってやつですね。


332 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 05:12
MLならforやwhileもあるし、代入もできるYO!


333 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 05:20
代入があるのは逃げ道。本来意図した使い方じゃないんだよ。>332
関数型言語として使いたければ今すぐ代入の使用をやめなさい。


334 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 06:53
なんか、どっかの宗教が輸血拒否したりするのと
同じぐらい愚かだな。


335 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 22:08
信仰とはそういうものだ


336 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 23:20
じゃあ、Haskellでは代入をどうやって避けるんだ?
代入が必要になるたびに新しい名前の変数を作るのか?


337 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 23:24
自分で書いてみたら?>336


338 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 23:35
>>337
わからなかったら書けないだろ。


339 名前: デフォルトの名無しさん 投稿日: 2001/05/24(木) 23:37
>>338
マニュアル読め


340 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 00:50
>>336

Haskell では計算をあまり操作的には考えないです。
プログラムは計算の手順の記述というよりは、値の関係記述の
ように書くという感じです。数学の等式を書くのに似てるかもしれません。

Haskell の変数は値についた名前という意味しかなく。値をいれるいれもので、
値の一時保管庫ではなく、値の出し入れという操作を記述するスタイルの
プログラムとは全然雰囲気の違うプログラムになります。

実行効率の上で代入(assignment)が欲しくなることはあるかも知れませんが、
なにかの値を計算するプログラムを書く上で代入が必要になることは
ないです。


341 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 00:58
使ってみないと実際の所わからないだろう。


342 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 02:07
>>340
つうか、何も情報になってねーよ。
結局の所「代入は使わないのです。」と言ってるだけだろ。
現象を説明してるだけで、全然理由になってない。


343 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 03:36
だから..問題&解法を記述するのに代入は必需品じゃ
ないのです...
なんでそんなに代入操作にこだわるかの理由を述べたほうがいいのでは


344 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 08:51
代入が良く使われてるのは常識でわ。


345 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 09:08
前の方で出てきたやつで言うと、

qsort [] = []
qsort (x:xs) = qsort [a|a<-xs,a<=x] ++ [x] ++ qsort [a|a<-xs,a>x]

このaやxって明らかに代入と一緒じゃん。
代入避けろとか言ってるけど、書き方変えてるだけじゃん。


346 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 09:32
>>345
みかけはともかくこれはλ束縛であって,いわゆる破壊的代入とはちがうよ

qsort(x:xs) = qsort (filter (\a -> a<=x) xs) ++[x]++ qsort (filter (\a -> a>x) xs)


347 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 10:24
>>342
Haskell では代入(assignment)は使わないではなくて、使えないです。
なので、代入を避ける必要はないです。
で、代入を使わなくて何故プログラムがかけるかは私には謎です。
でも、かなりの範囲(主観的ですけど)のプログラムは Haskell で書けます。
で、何故、何のために代入なしの関数型言語を作った人々がいたかですが
プログラムを実行せずにプログラムが正しいことが分かるような記述法が
欲しかったとかかなあ。


348 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 11:19
>プログラムを実行せずにプログラムが正しいことが分かるような記述法

蛇足ですが。
OOPは全然違う方向からその問題に取り組んでる、と
妄想したがってる厨房なワタクシ。

実行文脈をObjectの存在とは切り離しちゃったので、
「走れ」というメソッドを呼ばない限り
(つまりそれ以外のメソッドだけを呼ぶ限り)
非破壊に検証できる、
というObject系を作る「ことができる」はず。

まぁ言語によって強制されていなくて
セマンティックなレベルだけの話なんで、
よわよわだけど。

「実行時」ってものは、そんなに忌避されるもんなのかなあ?
どっちかというと、実行時の使いやすさを向上させる仕組みを
考えるほうが良いようなきもするんですが…


349 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 12:51
http://www.yfcbookshelf.com/ml_lisp_scheme.htm


350 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 15:08
>>346
破壊的代入というなら、Haskellの
a // [(i, v)] のような配列の更新はなんなんだ?
破壊的代入じゃないのか?


351 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 16:25
>>350
破壊的代入ではないです。

a ! 1 の評価結果を 1 であるとして
(a // [(1,2)]) ! 1 の評価結果は 2 ですが、
a ! 1 を評価すると結果は相変わらず 1 です。

let
  a = listArray (1,1) [1]
  b = a // [(1,2)]
in
  (a ! 1) + (b ! 1)

を評価すると結果は 3 です。


352 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 21:10
ふぇふぇふぇ


353 名前: デフォルトの名無しさん 投稿日: 2001/05/25(金) 23:14
>>348
スレ違い。ウザいぞ。


354 名前: 350 投稿日: 2001/05/26(土) 00:13
>>351
なるほど、要するに、更新された配列が右辺に現れるが、
その変化は長期的には反映されないという感じかな。

しかし、それでは、配列を変更したくなるたびに、新たな
配列を作らなくてはならない。

配列をデータとして蓄え、ユーザーの応答に応じてデータを
更新していくようなプログラムを作る場合、同一の配列に
データを保持しておくことができないから、問題があるのでは
ないか?
少なくとも俺にはこうしたプログラムをどうやって作るのかわ
からない。
例えその問題が解決したとしても、更新するたびに配列全体の
コピーが必要になるのではないか?

>>353
別にスレ違いじゃないと思うぞ。


355 名前: 346 投稿日: 2001/05/26(土) 00:30
>>354
その通り.ナイーブにやったのではとてもじゃないが実用にならない.
そこでHaskellなどでは,あくまで意味的には参照透明性を保った上で,
「変更前の配列」に見かけ上新たにアクセスできなくなるモナド(monad)
というメカニズムがある.意味的には純粋な関数型言語のまま,コンパ
イル結果は破壊的代入になっているような,そんな処理系が作れる.
実際,HaskellのコンパイラにはHaskell自体で書かれているものがある
が,テーブルや状態の管理にはモナドを用いて効率をよくしている.

モナドは配列や状態の表現の他に,例外処理や環境にも用いることが
できる.


356 名前: 346 投稿日: 2001/05/26(土) 00:41
ちなみにモナド自体は組み込みの機構ではなく,単に型構成子 M
と2つの関数 unit, bind の組として表現される.unit, bind の
型は以下の通り(a, bは型変数).

unit :: a -> M a
bind :: M a -> (a -> M b) -> Mb

また,unit, bind は以下を満たす.

bind m unit = m
bind (unit x) f = f x
bind (bind m f) g = bind m (\x -> bind (f x) g)

(うろおぼえなので間違ってたらビシバシ指摘しておくれ)
これと等価な定義もいくつかあって,用途によって使い分けること
ができる.

あとは P. Wadler の解説論文でも読んでおいてくれー.


357 名前: 350 投稿日: 2001/05/26(土) 01:02
>>355-356

「破壊的な代入は持たないです。しかしモナドがあるのです。」

こういうのって、従来の言語と何ら変わっちゃいないように
思えるんだよな。

言語のパラダイムにあわせて、「機能の意味」が変わってる
だけ。機能の実態は変わってない。
関数型言語のパラダイムに合わせてプログラムの仕組みを
語る上では便利なのだろうが、それ以上の意味は無いように
思える。


358 名前: デフォルトの名無しさん 投稿日: 2001/05/26(土) 01:47
定性的じゃなくて定量的に見ればいいのかな。
Cに goto文もあるから構造化プログラミングになってない、って
わけでもなくて。
Haskellにモナドがあっても、それなしでもかなりの部分を
くめるわけだし。


359 名前: 62 投稿日: 2001/05/26(土) 02:32
>>357
同じことの繰り返しだけど、
単に語るだけじゃなくて厳密に解析するのに役立つの。
プログラムを厳密に解析するのに
理論的にクリアでないと困るのはわかるでしょう?
クリアでかつ従来の言語でできることを失わない
というのがまずは重要であって、モナドはその一つの解答。
もちろん従来の言語を超えることができればさらによし。
(個人的にはHaskellのモナドはわかりづらいとは思うけど)。

>>356
Moggiの元々の論文はカテゴリーの定義さえ知っていれば
結構わかりやすいと思う。例も多いし。
Wadlerの論文は理論を避けているせいでかえってわかりにくいと感じた。
Haskellのマニュアルとかではおどかし過ぎだと思うぞ。


360 名前: 350 投稿日: 2001/05/26(土) 03:46
>>359
思うんだが、やってることは従来と変わらないのならば、
モナドと言わずに破壊的代入だと言ってしまえばいい
じゃないか?

で、理論的に考える時だけ、破壊的代入と考えずに、関数型な
概念で考えればいい。

そういうやり方ならC言語だって関数型な考え方で捕らえる
ことができるわけだろ?

わざわざ理解困難にする必要はないと思うのだが。


361 名前: デフォルトの名無しさん 投稿日: 2001/05/26(土) 09:45
>>360
計算機上で実行可能なものなのだから、そういう意味では従来のプログラム
とやっていることは変わらないと思います。
Haskell を使うのなら関数プログラミングの考えかたでプログラミング
するほうがいいと思いますが。。。


362 名前: 350 投稿日: 2001/05/26(土) 14:14
>>361
例えば、C言語でHaskellの考え方をすればいいんじゃないの?
破壊的代入が出てきたらHaskellのような別の概念だと考えて分析する。
モナドって良く知らないけど。


363 名前: デフォルトの名無しさん 投稿日: 2001/05/26(土) 15:09
つっこみですけど、
Haskellの弱点ってありますか?
ちなみに、弱点とは関係ないですけど、
fib n = fib (n-1) + fib (n-2)
って定義してフィボナッチ数列を計算すると、fib 100くらいで
すでに遅すぎなんですね。アルゴリズムの問題ですけど。
でも、漸化式の最適化くらい処理系的には簡単に出来そうですけどねえ。
やってまずい理由無いと思うし。


364 名前: デフォルトの名無しさん 投稿日: 2001/05/26(土) 15:14
>>363
どの処理系ですか?


365 名前: 363 投稿日: 2001/05/26(土) 16:08
>>364
最新のHugs (Windows)です。

あと、便乗質問ですが、対話形式で使っているとき、
プロンプトで関数定義をす