「高階関数」を含む日記 RSS

はてなキーワード: 高階関数とは

2018-04-03

haskell勉強

高階関数遅延評価とか参照透過性とか結構面白い概念でやってて楽しいんだけど

デフォルト遅延評価だったり参照透過性だから実行中に何しても値変えられないとかやっぱ頭おかしいわ

でもこれ好き、癖になりそう

2017-04-07

http://anond.hatelabo.jp/20170407112743

意識低い企業研究者です。プログラミングはサブウエポン。だけど趣味でも勉強してる。

働き方改革のせいで早く帰れって言われて、酒のみながら今これを書いてる。

C言語とかC++・・・これで作らないといけないものが今の所ないし、これでお金を稼ぐのはハードルが高いし、

WindowsAPIを使って複雑なプログラムを作りたいわけじゃないのでwhileとかifとか基本的な構文だけ覚えるだけで満足。

組み込みプログラミングではC言語はいまだに現役。お金普通に稼げると思うよ!次代のCOBOLと化しそうで怖いとこはあるけど。

Java・・・使える人が多いからあえて今から学習しなくてもいいような気がする。

文字列の結合だけでもダメやり方と良いやり方があるらしくて、何かPHPのようにその言語特有セオリーみたいなのを覚えるのが面倒くさそうなので入門の時点で学習するのをやめた。

セオリーとかあるかもしんないけど速度とか気に揉むまえに書いて測れ。たいていは杞憂か、あるいはCPUパワーで殴れるから

Go・・・HTTP/2が使えるから学習してる。他の言語だとnghttp2をインストールしないといけないようなのでGo便利だと思ってる。

ライブラリ選択肢が多すぎるのでこういうのが作りたいってときにこれを使うのがいいよっていうのが知りたい。

GUI作るのにライブラリありすぎてどうやって選べばいいのかさっぱりわかんない。

Goデータベース扱うならこれを使え、だけどMySQLしか使わないならこれを使え、あっSQLiteならこっちのライブラリ使うと便利みたいなこういう情報が欲しい。

GoGUIつくるの?あんまり普通じゃない気がする。軽量プロセスうまみがそんなない(詳しい人に否定されそうだけど)

普通にC#(mono/.net)かwebアプリにするかで良くないか

ただ、言語をあれもこれも覚えるのって僕は意味があるのかなという思いもある。

20言語Hello World出来るより、1つの言語でいろんなアルゴリズムを知っている方がすごいと思う。

コミュ症がフランス語英語ドイツ語覚えても、使う機会がないとまったく価値がないと思う。

アルゴリズムは使うものだ書くものではない!!

広く浅く学習するより、狭く深くいきたいとおもうけど、paizaでCランクしか取れない。

twitterで有名な人てやっぱりSランクとか余裕なのかな、こういうのもいろんなプログラマーに聞いてみたい。

一応著名なプログラマーTwitterフォローしてるけど、ご飯の画像を載せてたり、若者の僕には通じない寒いギャク連発してたり、ロリっぽい画像RTしてたりと、twitterはメインの情報収集としては利用してない。

twitterやってるプログラマーって勉強会とかオフ会に参加してるようなリア充の人ばっかりなので、肩身が狭いか自分からリプは送ったりはしない。

ファンがたくさんいるのに最近ニコ生配信してくれないchokudai先生みたいに、アルゴリズムを学ぶのがいいのかな。

深さ優先探索とか理解できない。

コード写経しても覚えられないし、仕組みは理解したけど自力コードが書けない。

コードにする能力ってどうやって鍛えるのか知りたい。

アルゴリズムは使うものだ書くものではない!高階関数とかテンプレートプログラミングとかその辺勉強するといい。

あと計算制限時間内に終わるなら総当たりが最速で品質も高いぞ。

エディタサクラエディタからVimに変えた。

どうしてVimかというとプラグインが多いしIDEっぽくできるから

Vim使う一番の理由は補完が強いのが気に入ってるから

Vimってハードル高いイメージあったけど、入門記事がたくさんあるので助かっている。

NetBeansが重すぎるんだよ。補完ボックスが表示されるの遅すぎて警告メッセージが出た。補完ボックスが表示されるまで7秒ぐらい経過すると警告メッセージが表示されたと思う。

Vim知らない。Linux使うならVimemacs使えるだろみたいな雰囲気あるけど、GUIならgedit, CUIならnanoでいいよね。

パソコンスペックもどのくらいのものを用意したらいいのかわからない。

10年前のVistaが搭載されていた頃の家電量販店で一番安かったCeleron 1コア メモリ1GB グラボなしノートからプログラミングに向いてないのかもしれない。

VirtualBox上のubuntuMySQLコンパイルすると2時間20分ぐらいかかった記憶がある。

CPUが1コアなのでコンパイル中にそれ以外の作業なんて重くてできない。

スペックお金をかけることで時間節約ツール選択肢が増える

EclipseなどのIDEが支障なく使えるレベルスペックってどのくらいするんだろう。

ノートCore i3メモリ4GBにランクアップしたらいけるのかな。

他人がどんなスペックPCで何のツール使ってプログラミングしているか知りたい。

3年前のCore i7, SSD, 8GB。最近はもっぱらJupyter。

もっと早いPCが欲しいけど、年度末に買うのを忘れた。

Python・・・機械学習する上で避けて通れないけど、今のPCだと無理。

例題が豊富逆引き辞典みたいなサイトや本がほしい。

あと、クレジットカード持てないのでAWS上で機械学習するのだけは遠慮したい。

過大請求されるの怖いし、トラブルが起きた時に英語コミュニケーション出来ないから。

Pythonはいいぞ、機械学習だけじゃなく計算系はエクセルじゃなくてJupyter使う。でも周りはエクセルつかってる、勿体ない。

使ってないけど最先端研究では機械学習使って当たり前感があってそろそろヤバい

僕は中学生の頃、いじめにより心の余裕なんてなかったか勉強どころではなかったけどもっと英語勉強しておけばよかったと後悔している。

やっぱり子供の頃の生活環境って大事だなと思う。

今は英検3級に向けて勉強中。

APIドキュメント頑張って読もう。俺も頑張って読んでる。

何を学習したらいいのか本当にわかんない。

迷宮にいる感じ。

なんとなく、プログラミングじゃないほうがいい気がするなあ。

とりあえずバイトしてPC買わない?プログラミングバイトでもいいと思うよ。

働き方改革最前線からは以上です。

2016-02-26

関数型プログラミングのことは嫌いにならないでください!

高階関数はいいぞ!

lambdaはいいぞ!

ミュータブルはいいぞ!

homoiconicはいいぞ!

マクロはいいぞ!

Clojureはいいぞ!

2015-05-18

関数型言語が普及しない理由が分かった

関数型言語なんて、多くのプログラマにとって猫に小判、豚に真珠ということだ。

コミュニティ文化独自とか、学習コストが高いとか言われているが、それは本当の理由じゃない。

本当の理由は、オブジェクト指向言語すら使いこなせていないのに、関数型言語なんて必要ないという理由だ。

オブジェクト指向言語を使い倒していれば、同じ概念関数型言語ではずっと楽に実現できることにすぐに気づく。

逆にオブジェクト指向言語で無理して使っている概念(例えば高階関数など)がないと利点に全く気づけない。

普段余計な一手間を加えてでも、実現したい便利で強力な概念を、そもそも使っていないのでは、関数型言語を書く意味はない。

関数型言語でもオブジェクト指向言語でも、やることは変わらないとずっと思ってきたし、それなのになぜ関数型言語が普及しないのか、ずっと不思議だった。

しかし未熟なプログラマには無用長物だということだ。

2015-02-11

関数型とオブジェクト指向って……

毛の壁以降、色んなところであーだこーだ再定義言われてるけど、結局名前が悪いんだよなぁ。

どちらかというとオブジェクト指向の方が「何もかもサブルーチン(ただし値を覚えていてくれるおまけつき)」で、関数型の方が「何もかもが値(関数も)」なんだけど、まず名前からだと逆っぽく聞こえる。

加えて、この二つの概念が対立すると思われてしまうけれど、んなこたーないのはjavascript見れば分かる。何もかも値かつサブルーチン、でOK。

両立しにくいのは、オブジェクト概念高階関数概念ではなく、オブジェクト指向言語採用してきた型システムと、関数型言語採用してきた型システムだ。

まりC++やらJavaやらが採用してきたサブタイプ多相をベースにしたクラスによる型付けと、ML言語採用してきた代数データ型が噛み合わない。致命的に。

いやまぁScalaは頑張って統合したけど、コンパイル遅いわ書き方次第で型チェックが無限ループになるわで、色々と無茶しやがって感ある。

これからは「サブタイプ多相言語」と「代数データ言語」って分けて呼ぶべきなんじゃないか?

2014-09-14

「手に職」って詐欺みたいなもんなんだな

当方いわゆるwebプログラマ30代。大学卒業に失敗しているので学歴としては高卒年収は800万に届かない程度。webプログラマインターネット上で目立っている有名プログラマも多くて、彼らと自分を比べると絶望するくらいに自分スキルは低い。でも最低限の能力はあると思う(参考までに、 GitHub 上で一番starをもらっているリポジトリは 14 star というレベルの実力。150 star くらいあるリポジトリに PullRequest を送って取り込んでもらったことがあるという程度)。

で、このレベル人間が周りの年上プログラマを見てると、「なんだ、こいつらが食って行けるなら、俺は楽勝で食って行けるじゃん」って思うことが多い。「その辺のちょっとだけできる大学生のほうがよほどまともだぞ」みたいなコード書く人間がのうのうとプログラマとして食って行ってる。ほんとうにひどいやつらが多くて、一番笑えたのが「経験豊富だしどん欲に学習してきたのでどんな言語対応できます」って言ってた39歳の人間で、彼は「高階関数」という概念がまったく理解できなかった。「関数ポインタ引数で渡すみたいなもんですよ」って言ったら「関数ポインタとか実務で使うことないしwwwwwww」みたいに返されて絶句した。よく 2chプログラマ板で「if と for がわかればなんでも書けるし」みたいなこと言ってるやついるけど、「あーこういう人間がああい書き込みするんだな」って変に納得できた。

でもそのひとは会社からそこそこの金をもらってた。それ見て思ったんだけど、いくらひどいコードであっても、「とりあえず動くものが作れる」っていうのはスキルの一種であることには違いないんだな。正直絶対に一緒に働きたくないし、そいつが書いたコードは絶対にメンテしたくないけど、メンテナンス性がどれだけ大事かってことを理解している経営層っていうのは少ないみたいで(これは経営層じゃなくてむしろプログラマ側のコミュニケーションスキル問題の気がする)、とりあえず動いているように見えるものを作ることさえできれば、お金を握っているひとからお金を引き出すことは可能なんだな、ってことをそいつを見て理解した(またこいつが「コード読めないひと」をだますのがうまいんだ)。

で、ここで初めてタイトルにつながるんだけど、ようするにそれが「手に職」ってことなんだな、って思ったんだ。

詐欺ってのは言い過ぎにしても、「手に職」って言われる職業ってだいたい寡占なんだよね。たとえば資格がないとできない職業資格を持った人間の寡占状態にある。プログラムを書くのに資格必要ないけど、プログラムの読み書きは未だに特殊技能で(これは教育問題だと思う)、コードメンテナンス性の善し悪しを判断できるのもまたプログラマだけであるという意味でやっぱり寡占状態にある。

自分プログラマからこの寡占状態に恩恵にあずかっている側で、おかげで「ひとまず職にあぶれることはなさそうだな」っていう安心を得ることができているんだけど、この寡占状態って絶対不健全で、たとえば誰の目にも数字という形でわかりやすく現れてくる営業(一方から勝手見方で、営業の世界にもいろいろあるのかもしれない、イメージで語ってゴメン)だったら、「あい数字悪いな、切ろうぜ」ってなるレベル人間が「まあでも我々にはプログラマ世界はわからないからなぁ、彼は優秀っぽい雰囲気があるし」みたいな感じでお金をもらうことができるんだもん。

からやっぱり「手に職」って詐欺っぽい要素があると思う。だってそもそも「手に職があれば食うに困らない」って時点でおかしいじゃん。最低レベルの営業職と、最低レベル技術職、どっちも最低のはずなのに「俺は技術職で手に職があるから困らない」ってどう考えてもおかしくない?やっぱり詐欺だよこれって。

2014-07-17

関数型入門以前

これ読んでも関数型分からないけど、入り口の前あたりに立つために

関数型言語覚えたらなんの役に立つの

プログラマとしての引き出しが増える。

って書くと「そんなもんどんなプログラミングテクニックだって一緒だわ」って言われそうだけど、でもそうとしか言い様がない。

とりあえず、オブジェクト指向と同じで、プログラム構造化して、複数レイヤーに切り分けて部品化していくテクニックだとは言える。

ただオブジェクト指向とは大分切り口が違う。何ていうか、割と直交する切り口でプログラム構造を切り分けていく。

なので、関数型とオブジェクト指向と両方憶えるだけで、大分切り口の引き出しが増える。

オブジェクト指向関数型両方憶えると、プログラマとしての引き出し増やすのに効率が良い、って思えば良いかも。

具体的にどう切り分け方が違うの?

オブジェクト指向は、プログラムの各部品を「あれの中のこれの中のそれの中にあるあれ」みたいな感じで組み合わせる。

部品が更に細かい別の各部品で構成されていて、それぞれの部品が噛み合わさって、複雑な一つのプログラムを構成するような切り方。

関数型言語は、プログラム部品を「あれをした物にこれをした物にそれをした物にあれをする」みたいな感じで組み合わせる。

もっというとプログラム全体を簡単に記述するできるDSLがあって、そのDSLを簡単に実装するためのDSLがあって、DSLの入れ子構造で一番小さい部品シンプル関数、みたいな切り方。

どう使い分けたら良いの?

ケースバイケース。

ではあるんだけれど、シンプル部品を大量に組み合わせて構成するのがしっくりくるならオブジェクトで、部品数が少ないんだけど一個一個が複雑な動作する構成にしっくりくるのが関数型……かも?

関数型言語の紹介見てると、何かひたすらイミュータブルなデータを弄繰り回す説明ばっかり出てくるんだけど…

関数型言語たる条件として「関数が第一級オブジェクト」ってのがあるんだけど、関数が第一級オブジェクトだとイミュータブルなデータを素直に扱える。

で、イミュータブルなデータ構造使うと色々便利、ってことで実例として一番出てくるという。

何か型型言ってるんだけど、型くらいC言語にすらあるわ。メモリ領域の確保量を示すあれが何でそんなに重要なの?

関数型言語エポックメイキング的な言語が三つくらいあって、元祖Lispとその流れ汲んだMLMLの一種で関数型をある種の到達点に持っていったHaskellって感じ(独断偏見)。

で、このうちのMLって奴が、プログラミング言語に型システムがついてるんじゃなくて、型システムプログラミング言語がついてきた存在だったりする。

型で色々やるために生まれたわけで、まぁなんというかそもそも型と密接な関係にあって、Haskellもその流れを汲んでて、こいつが超有名になった、って感じ。

おかげさまで、型使って色々やったりする方法が日々考えられているわけです、静的型付関数型の世界では。

クロージャって、大まかな概念wikiとかで理解したけど、関数型でどう使われてるの?

関数型言語ではよく「関数関数を引き取って、合成した関数を返す関数」みたいなのが使われるんだけど、関数関数の合成って、それ合成された関数がもともと引数として与えられていた関数憶えてないと無理やん? 自分自身の構成部品憶えてられないわけだから

クロージャあると憶えててくれるわけですよ。

そんな感じで高階関数実用的なレベルで使うのには大体必須と言う。

モナドとやらは何に使うものなの? 何が便利なん?

関数型言語DSLを作りまくる言語みたいに書いたけど、モナドちょっと複雑なDSLを簡単に作らせてくれる仕組みだと思っとけば良い。

Haskell副作用が一切ない純粋関数型言語って言うけど、副作用なしでどうやって入出力してるの?

まず純粋定義だけど「全ての関数は同じ引数を与えられた際、必ず同じ値を返す」ってことで、これがいわゆる副作用がないって状態だ。

で、これって逆に言えば「プログラムである関数に対して、絶対に同じ引数を与えさえしなければ、その関数がどんな値を返したところで、事実上純粋だと言えてしまう」ってことでもある。

本末転倒感があるんだけど、HaskellではIOモナドという仕組みと特別main関数を使って「呼び出すたびに絶対に違う引数自動的関数に与えてくれる仕組み」を実現していて、こいつを使って入出力する。

うん……凄い本末転倒。ちなみにこの自動的に与えられる引数はRealWorldって名前がついていて、要は「刻一刻と変わり続け絶対に同じ状況にならない現実世界の状態を引数に取っちまっているようなもんだからしょうがないだろ?」的な感じ。

2011-09-23

「続 新しいプログラミングパラダイム」の目次


第1章 並行プログラミングGHC (上田和紀)
	1.1 はじめに
	1.2 ターゲットを明確にしよう
	1.3 はじめが大切
	1.4 GHCが与える並行計算の枠組み
		1.4.1 GHCにおける計算とは,外界との情報のやりとり(通信)である
		1.4.2 計算を行う主体は,互いに,および外界と通信し合うプロセスの集まりである
		1.4.3 プロセスは,停止するとは限らない
		1.4.4 プロセスは,開いた系(open system)をモデル化する
		1.4.5 情報とは変数と値との結付き(結合)のことである
		1.4.6 プロセスは,結合の観測と生成を行う
		1.4.7 プロセスは,書換え規則を用いて定義する
		1.4.8 通信は,プロセス間の共有変数を用いて行う
		1.4.9 外貨も,プロセスとしてモデル化される
		1.4.10 通信は,非同期的である
		1.4.11 プロセスのふるまいは,非決定的でありうる
	1.5 もう少し具体的なパラダイム
		1.5.1 ストリームと双方向通信
		1.5.2 履歴のあるオブジェクト表現
		1.5.3 データ駆動計算と要求駆動計算
		1.5.4 モジュラリティと差分プログラミング
		1.5.5 プロセスによるデータ表現
	1.6 歴史的背景と文献案内
	1.7 並行プログラミング効率
	1.8 まとめ


第2章 様相論理テンポラル・プログラミング (桜川貴司)
	2.1 はじめに
	2.2 様相論理
	2.3 時制論理
	2.4 多世界モデル
	2.5 到達可能性と局所性
	2.6 純論理プログラミングへ向けて
	2.7 Temporal Prolog
	2.8 RACCO
	2.9 実現
	2.10 まとめと参考文献案内


第3章 レコードプログラミング (横田一正)
	3.1 はじめに
	3.2 レコードと述語の表現
	3.3 レコード構造とφ-項
		3.3.1 φ-項の定義
		3.3.2 型の半順序と束
		3.3.3 KBLLOGIN
	3.4 応用――データベース視点から
		3.4.1 演繹データベース
		3.4.2 レコードプログラミングデータベース
		3.4.3 いくつかの例
	3.5 まとめ
	3.6 文献案内


第4章 抽象データ型とOBJ2 (二木厚吉・中川 中)
	4.1 はじめに
	4.2 抽象データ型と代数言語
		4.2.1 抽象データ型
		4.2.2 代数言語
		4.2.3 始代数
		4.2.4 項代数
		4.2.5 項書換えシステム
	4.3 OBJ2
		4.3.1 OBJ2の基本構造
		4.3.2 モジュールの参照方法
		4.3.3 混置関数記号
		4.3.4 モジュールパラメータ化
		4.3.5 パラメータ機構による高階関数記述
		4.3.6 順序ソート
		4.3.7 属性つきパターンマッチング
		4.3.8 評価戦略の指定
		4.3.9 モジュール表現
	4.4 おわりに


第5章 プログラム代数FP (富樫 敦)
	5.1 はじめに
	5.2 プログラミングシステム FP
		5.2.1 オブジェクト
		5.2.2 基本関数
		5.2.3 プログラム構成子
		5.2.4 関数定義
		5.2.5 FPプログラミングスタイル
	5.3 プログラム代数
		5.3.1 プログラム代数則
		5.3.2 代数則の証明
		5.3.3 代数則とプログラム
	5.4 ラムダ計算拡張
		5.4.1 ラムダ式拡張
		5.4.2 拡張されたラムダ計算の簡約規則
		5.4.3 そのほかのリスト操作演算子
		5.4.4 相互再帰定義式
		5.4.5 ストリーム(無限リスト)処理
	5.5 FPプログラム翻訳
		5.5.1 オブジェクト翻訳
		5.5.2 基本関数翻訳
		5.5.3 プログラム構成子の翻訳
		5.5.4 簡約規則を用いた代数則の検証
	5.6 おわりに


第6章 カテゴリカル・プログラミング (横内寛文)
	6.1 はじめに
	6.2 値からルフィズムへ
	6.3 カテゴリカル・コンビネータ
		6.3.1 ラムダ計算意味論
		6.3.2 モルフィズムによる意味論
		6.3.3 カテゴリカル・コンビネータ理論CCL
	6.4 関数型プログラミングへの応用
		6.4.1 関数型プログラミング言語ML/O
		6.4.2 CCLの拡張
		6.4.3 CCLに基づいた処理系
		6.4.4 公理系に基づいた最適化
	6.5 まとめ


第7章 最大公約数――普遍代数多項式イデアル自動証明におけるユークリッドの互除法 (外山芳人)
	7.1 はじめに
	7.2 完備化アルゴリズム
		7.2.1 グラス置換えパズル
		7.2.2 リダクションシステム
		7.2.3 完備なシステム
		7.2.4 完備化
		7.2.5 パズルの答
	7.3 普遍代数における完備化アルゴリズム
		7.3.1 群論の語の問題
		7.3.2 群の公理の完備化
		7.3.3 Knuth-Bendix完備化アルゴリズム
	7.4 多項式イデアル理論における完備化アルゴリズム
		7.4.1 ユークリッドの互除法
		7.4.2 多項式イデアル
		7.4.3 Buchbergerアルゴリズム
	7.5 一階述語論理における完備化アルゴリズム
		7.5.1 レゾリューション法
		7.5.2 Hsiangのアイデア
	7.6 おわりに


第8章 構成的プログラミング (林 晋)
	8.1 構成的プログラミング?
	8.2 型付きラムダ計算
	8.3 論理としての型付きラムダ計算
	8.4 構成的プログラミングとは
	8.5 構成的プログラミングにおける再帰呼び出し
	8.6 おわりに:構成的プログラミング未来はあるか?


第9章 メタプログラミングリフレクション (田中二郎)
	9.1 はじめに
	9.2 計算システム
		9.2.1 因果結合システム
		9.2.2 メタシステム
		9.2.3 リフレクティブシステム
	9.3 3-Lisp
	9.4 リフレクティブタワー
	9.5 GHCにおけるリフレクション
		9.5.1 並列論理言語GHC
		9.5.2 GHC言語仕様
		9.5.3 GHCメタインタプリタ
		9.5.4 リフレクティブ述語のインプリメント
	9.6 まとめ

「新しいプログラミングパラダイム」の目次


第1章 新しいプログラミングパラダイムをめぐって (井田哲雄)
	1.1 はじめに
	1.2 プログラミングパラダイムの形成
	1.3 プログラミングパラダイムの展開
	1.4 パラダイム作法構造プログラミング
	1.5 構造プログラミングを超えて
	1.6 関数型プログラミング論理プログラミング,対象指向プログラミング
	1.7 新しいプログラミングパラダイム
	1.8 まとめ


第2章 ラムダ計算と高階プログラミング (横内寛文)
	2.1 はじめに
	2.2 ラムダ計算
	2.3 最左戦略
	2.4 コンビネータによる計算
	2.5 まとめ


第3章 マルセイユPrologProlog Ⅱ,Prolog Ⅲ
	3.1 はじめに
	3.2 準備
		3.2.1 述語
		3.2.2 項
		3.2.3 項の単一化
		3.2.4 節およびHorn節
		3.2.5 論理式の意味
		3.2.6 論理的帰結と導出
	3.3 マルセイユProlog
		3.3.1 Prolog記法
		3.3.2 Prolog計算規則
		3.3.3 Prologプログラムの例
		3.3.4 カットオペレータ
		3.3.5 DEC-10 Prologとの相違
	3.4 Prolog Ⅱ
		3.4.1 difオペレータ
		3.4.2 freeze
		3.4.3 ループ構造
		3.4.4 Prolog Ⅱのインプリメンテーション
	3.5 Prolog Ⅲ
		3.5.1 制約の枠組
		3.5.2 Prolog Ⅲのプログラム例
		3.5.3 束縛の領域と制約系
		3.5.4 Prolog Ⅲのインプリメンテーション
	3.6 まとめ


第4章 制約論理プログラム (相場 亮)
	4.1 はじめに
	4.2 制約プログラミング
	4.3 制約の分類
	4.4 プログラムの実行
	4.5 制約の評価
	4.6 まとめ


第5章 オブジェクト指向 (柴山悦哉)
	5.1 はじめに
	5.2 モジュラリティと抽象化
		5.2.1 抽象化
		5.2.2 手続抽象
		5.2.3 データ抽象
		5.2.4 オブジェクトによる抽象化
		5.2.5 並列オブジェクトによる抽象化
	5.3 共有
		5.3.1 多相型
		5.3.2 継承
		5.3.3 多重継承
		5.3.4 Self
		5.3.5 動的束縛の意義
	5.4 対話性
		5.4.1 クラスの再定義
		5.4.2 表示機能の一体化
	5.5 オブジェクト指向の弱点
	5.6 まとめ


第6章 型推論ML (横田一正)
	6.1 はじめに
	6.2 LCFの超言語からMLへ
	6.3 プログラミング言語と型
	6.4 ML表現と型宣言
	6.5 ML型推論
	6.6 LCFへの応用
	6.7 まとめ


第7章 Miranda (加藤和彦)
	7.1 はじめに
	7.2 Miranda概観
		7.2.1 等式による定義
		7.2.2 基本データ型と基本演算子
		7.2.3 ガード付き等式とスコープルール
		7.2.4 高階関数カリー化
		7.2.5 パターンマッチング
		7.2.6 ノンストリクト性と遅延評価
		7.2.7 ドット式とZF式
	7.3 型
		7.3.1 強い型付けと静的な型付け
		7.3.2 多相型
		7.3.3 型類義
		7.3.4 代数データ型
		7.3.5 抽象データ型
	7.4 処理系
	7.5 まとめ
	7.6 文献の紹介


第8章 項書換えシステムと完備化手続き (大須賀昭彦)
	8.1 はじめに
	8.2 項書換えシステム
	8.3 TRSの停止性
		8.3.1 意味順序
		8.3.2 構文順序
	8.4 TRSの合流性
		8.4.1 完備なTRS
		8.4.2 危険対
		8.4.3 危険対を用いたTRSの合流性判定
	8.5 Knuth-Bendixの完備化手続き
	8.6 KBの応用
		8.6.1 帰納的な定理証明への応用
		8.6.2 等号論理定理証明への応用
	8.7 まとめ


第9章 等式プログラミングから融合型プログラミングへ (富樫 敦)
	9.1 はじめに
	9.2 等式プログラミング
		9.2.1 等式プログラム
		9.2.2 代表的な等式プログラム
		9.2.3 プログラミング技法
		9.2.4 正則プログラム正規化戦略
	9.3 条件付き等式プログラム
		9.3.1 条件付き書換え規則
		9.3.2 条件の種類
		9.3.3 利点と問題点
	9.4 融合型プログラミング
		9.4.1 AMLOGシステム
		9.4.2 向付き等式
		9.4.3 実行戦略の変更
		9.4.4 代入操作
		9.4.5 合流するプログラムへの変換
	9.5 まとめ

2007-11-10

関数プログラミングにおけるFizzBuzz問題

いくつか考えてみた

(問1)高階関数再帰関数を必ず使って数値を要素とするリストの要素の総和を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。

(問2)二つの引数をとり二つのうち大きいほうを返す関数高階関数再帰関数をつかって数値のリストの最大値を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。

というのは簡単すぎるか?簡単すぎるなら

(問3)高階関数再帰関数を必ず使ってある数値に5を足し、10かけて2で割った数を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。

こっちの方がいいかな。でもトリッキーすぎる気もする。

一応問題を出したので、SchemePythonで自分で想定している答えを書いておいた。はてなではSchemeが人気のようなので、あまり知らなかったけど関数言語ではSchemeで書いておいた。Pythonで書くのはSchemeだけだとわかりにくいので、なにかスクリプト言語で書いておこうと思ったから。Rubyの方が人気なので、はじめはRubyで書こうと思ったけど挫折した。だれかRubyで書いてくれないかな・・・。コードオブジェクトってなによ。というか関数オブジェクトなのに引数にできないの?なんで?(以下疑問と愚痴の嵐なので略)Perlは古株が多くてユーザー数も多そうだけど、・・・その・・・無理です・・・。あの言語仕様はやる気がしない。ぶっちゃけ理解できない。Pythonを知らないひとは多そうだけど、知らなくてもSchemeよりは感じは掴めると思うのでPythonでも書いておくことにした。

Scheme

http://anond.hatelabo.jp/20071110215936

Python

http://anond.hatelabo.jp/20071110220132

これで大部分のひとがこの問題に興味をもたなくて解答するひとがいなくても、興味を持ったひとは安心だね!

追記:

問3で次のは無しとしておきたい。

Scheme

(define continuous-apply
    (lambda (lst obj)
        (cond
            ((null? lst)
                obj)
            (else
                (continuous-apply (cdr lst) ((car lst) obj))))))

(define plus5
    (lambda (num)
        (+ num 5)))

(define times10
    (lambda (num)
        (* num 10)))

(define divide2
    (lambda (num)
        (/ num 2)))

(define plus5-times10-divide2
    (lambda (num)
        (continuous-apply (list plus5 times10 divide2) num)))

(plus5-times10-divide2 2)

Python

def continuousApply(lst, obj):
    if lst:
        return continuousApply(lst[1:], lst[0](obj))
    else:
        return obj

def plus5(num):
    return num + 5

def times10(num):
    return num * 10

def divide2(num):
    return num / 2

def plus5_times10_divide2(num):
    return continuousApply([plus5, times10, divide2], 2)

plus5_times10_divide2(2)

Schemeによる解答

あくまで自分でこう答えるという話。

(問1)

(define fold-left
    (lambda (func obj lst)
        (cond
            ((null? lst)
                obj)
            (else
                (fold-left func (func obj (car lst)) (cdr lst))))))

(define my-sum
    (lambda (lst)
        (fold-left + (car lst) (cdr lst))))

・例

(my-sum '(1 2 3 4 5 6 7 8 9 10))


(問2)

(define fold-left
    (lambda (func obj lst)
        (cond
            ((null? lst)
                obj)
            (else
                (fold-left func (func obj (car lst)) (cdr lst))))))

(define large
    (lambda (x y)
        (cond
            ((>= x y)
                x)
            (else
                y))))

(define my-max
    (lambda (lst)
        (fold-left large (car lst) (cdr lst))))

・例

(my-max '(58 90 1 2 4 3 100))

(問3)

(define fold-right
    (lambda (func lst obj)
        (cond
            ((null? lst)
                obj)
            (else
                (func (car lst) (fold-right func (cdr lst) obj))))))

(define my-apply
    (lambda (func obj)
        (func obj)))

(define plus5
    (lambda (num)
        (+ num 5)))

(define times10
    (lambda (num)
        (* num 10)))

(define divide2
    (lambda (num)
        (/ num 2)))

(define plus5-times10-divide2
    (lambda (num)
        (let ((lst (list plus5 times10 divide2)))
            (fold-right my-apply (reverse lst) num))))

・例

(plus5-times10-divide2 5)

全部畳み込み関数を使っているのは、はじめ使い道がないと思ってたのにかなり使い道があることがわかったので、それを示したかったから。あとmap関数あたりはほかの言語でもあるから、すぐに思いつくだろうし。

というか最後のやつは手続きを抽象化することでリストの形で扱えるようにしているから、関数プログラミングでは重要だと思う。関数プログラミングの肝は計算によって手続きを含めたすべて表すことができることだと思っている。その例だと思うんだけどね。例えばSchemeなら上記の答えを応用して、似たような「手続き」を生み出す関数を作ることができる。

(define make-proceduce
    (lambda (fst . rest)
        (let ((lst (cons fst rest)))
            (lambda (num)
                (fold-right my-apply (reverse lst) num)))))

これを使うと次のようにできる。

(define divide2-plus5-times10
    (make-proceduce divide2 plus5 times10))

(divide2-plus5-times10 2)

(define divide2-times10-plus5
    (make-proceduce divide2 times10 plus5))

(divide2-times10-plus5 2)

関数合成がつかえるならそっちのほうが楽だけど、リストという形で「手続き」をつくり出していることがわかるだろうか?手続きをリストで操作できるのだ。こういうのが関数プログラミングの肝だと勝手に思っている。

こうやってくると型推論や多相型の重要性もわかると思うんだよ。上記のようなことはPythonでもできる。でも高階関数はつかいすぎるとわかりにくい。どっかにバグが入ってくるかもしれない。それを機械的に防ぐのが型推論。型という観点から型推論でおかしいところを探し出してくれる。それならC言語でもいいのではないかという人もいるかもしれない。だがC言語は融通が利かない。例えばapply関数にしても引数の型が数値なら数値、文字なら文字と決まっている必要がある。だから数値に向けにapply関数を作っても文字には使えない。こうした型のデメリットをなくす一方、そのメリットを享受するためにあるのが多相型。これによってapply関数map関数を一般的に作ることができ、型のメリットを享受しながらデメリットをなくすことができる。このように関数で手続きなんかを抽象化するときに型推論や多相型があると便利なのだ。

2007-11-09

Pythonではなぜ string.len() でなく len() なのか?

http://anond.hatelabo.jp/20071021143442

その理由は知らないが、なければ作ればいいじゃないか。

class MyString(str):
    def length(self):
        return len(self)

というクラスを作って

string = MyString("Hello world")
print string.count("o"), string.length()

Rubyライクにやれば

2 11

とでるよ。え、リストもlist.length()が使いたいって?それも簡単。

class MyList(list):
    def length(self):
        return len(self)

l = MyList([1, 2, 3, 4, 5, 6])
l.length()

6

きちんと他のメソッドも使えるよ。

l[1:]

[2, 3, 4, 5, 6]

l.reverse()
l

[6, 5, 4, 3, 2, 1]

ね。簡単でしょ。

Pythonは仕組みが統一されているものが多いので、いじりやすいのですよ。上の例のやつは組み込みクラスオブジェクトユーザー定義のクラスオブジェクトがおおむね統一されているからこそ簡単にできる。他にも関数なんかもほかのオブジェクトと同じオブジェクトなので、高階関数なんてもの簡単に作ることができて関数プログラミングぽくできる。例えば今はなきapply関数なんかは

def myApply(func, *args):
    return func.__call__(*args)

と定義できる。実際に

def sumUpThree(num1, num2, num3):
    return num1 + num2 + num3

でためしてみる。

myApply(sumUpThree, 1, 2, 3)

結果はちゃんと

6

とでる。将来廃止されそうなmap関数も簡単に定義できる。他にも複数の引数をもつ関数の部分適用のようなことを行う関数も次のように簡単に定義できる。

def partial(func, *oldArgs):
    def wrapper(*newArgs):
        return func.__call__(*(oldArgs + newArgs))
    return wrapper

sumUpThree関数テストすると

sum_1 = partial(sumUpThree, 1)
sum_1(2, 3)

6

sum_1_5 = partial(sum_1, 5)
sum_1_5(9)

15

sum_10_20 = partial(sumUpThree, 10, 20)
sum_10_20(30)

60

こういう風に高階関数が簡単にできるのは関数オブジェクト関数の実行とはメソッドの呼び出しにすぎないからだ。以上のように組み込みオブジェクトユーザー定義オブジェクトの差があまりないことや関数オブジェクトであることに見られるようにPythonは仕組みが統一されていてシンプルだ。そのためひとつのことがわかれば他のこともわかることが多いし、簡単にいじることもできる。

だからなければpythonをいじればいいと思うよ。

最後にラムダ式信者のためにpartialをラムダ式を使って書いておく。

def partial(func, *oldArgs):
    return lambda *newArgs:func.__call__(*(oldArgs + newArgs))

Pythonラムダ式がだめだといわれているが、こんな風にかけたとして何がうれしいというのだ。

2007-09-01

9月になったし、もうそろそろ書いておくか

これから就職活動するバカはいないだろうけど、そういう人もいるだろうから少し書いておこう。

どちらかというと、アンチMS派なUnix技術者Windowsだけの世界で仕事をする辛さを。

Unix技術者は、業務実績にSolaris/AIX/Linuxって書いてあってもちゃんと質問しろ。Windows仕事は無いですよね?って。

僕が食べるために職を手にしているこのIT業界というのは、バッドノウハウMicroSoftExcelで出来ている。

その為、僕が手にしたUnixの知識は、特定の仕事以外でしか役に立たないし、使わない。

viだろうが、TeXだろうが、Xの知識よりも、MFCVBAのちょっとした知識のあるヤツが上にみられる。

ExcelWindowsの知識があればそれだけで仕事になるからだ。

いいか、viTeX、Xなんて捨てちまえ、Excelがあればそれでいいのだ。

Unix技術者でいうハッカーとはなんだろう。

MSでは、ActiveXを使ってCOMを操作し、クライアントレジストリを操作し、IE単体でできないことをやってしまうヤツがハッカーと思われている。

VBAマクロで作ったなんちゃってツールを3時間で作れるほうが、

perlruby/pythonで、より少ない時間で作ったツールよりも凄く思われてしまう。

そして、それができるヤツの方が、Unix技術者よりもよりハッカーであり、技術力があると思われている。

ブラウザを例にしたが、

javascriptでalert/confirmを出すよりも、vbscriptでMsgBoxの方が多くのことができるから、

javascriptNumberの計算よりも、vbscriptでDecimalを使った方が倍密度の計算ができるから、

vbscriptを駆使できるヤツは、凄く重宝される。

いいか、javascriptで汎用的に書くのなんてナンセンスだ。javascriptなんて捨てちまえ、覚えるのはJScript実装(WSH)だ。

この業界、何が不満になるかというと、

MSの、もっというとWindowsのことしか知らないヤツが多すぎるということ。

そういうヤツらは、Windowsだったらこんなこともできるのに、なぜUnix/Linuxだとこんなこともできないのか。と言う

そういうヤツらは、Windowsの未修正バグの合間を縫いながら中途半端な実装しかしない。

だって、中途半端(もしくは大雑把)な実装で動いているものの中で動くから。それ以上に実装しようとしてもできないのだ。

いいか、win32のメッセージングの仕組を覚えるんだ。無理矢理send_keyみたいなコードを書けるようにしろ。

コマンドを連結するよりも、結果に近いコードを書くんだ。線形になろうがヤツらは気にしないだろう。

ヤツらは、javapythonをバカにする。

何故か。

それは、.NETで作ればお客さんの要望が実現でき、Excelと連携できるからだ。

ヤツらは、C/Sの世界でこそ役に立つ技術者だが、Webの世界に連れてきてはならない。すぐに実装がIEだけになる。

ヤツらにLLを覚えさせるのは無理だ。

クロージャなんて知らないし、高階関数カリーなんてコードを教えてみろ。後から辛くなるのは自分だ。

ヤツらにはPHPを教えておけ、それだけで満足する。すごいヤツになった気にさせれる。

バッドノウハウ慣れしているヤツらはそれを使ってコードを書いてもらえ、rubyで書かせるよりも修正が20倍楽だ。

いいか、まとめるぞ。

今まで一生懸命Unix勉強してきたのは無駄だ。いますぐ忘れるんだ。

Excelを今から覚えろ。VBAを覚えろ。そしてMSの動きを身に着けるんだ。

Windowsでは単位がFormだ。それが標準出力標準入力と思え。ときどきSheetとかWorkbookになるぞ。

ストリームファイル操作には気をつけろ。Unixの気分でいると思わぬところで抜けが出るぞ。

IRCは使うな。Jabberを使うな。メッセンジャーを使え。移行のお薦めはGaimだ。Windows版がある。

viの使用頻度を減らせ、変なコマンドを身に着ける前に、秀丸マクロを書けるようにしろ、Notepadのショートカットを覚えとけ。

BindとかApache(Httpd)の知識はいらない。IISだ。ActiveDirectoryだ。

文字コードはCp943cを何がなんでも押せ。Shift_JISっていう大雑把な伝えかたはダメだ。絶対cp943cにしろ。UTF8/UTF7との格闘で身も心もぼろぼろになるぞ。

汎用性なんて無いんだ。Windowsというプラットフォームがあれば。



ああ、心が渇いていく。

 
アーカイブ ヘルプ
ログイン ユーザー登録
ようこそ ゲスト さん