新卒採用とか仕事できない人を雇うの止めたほうがいいと常々思うんだけどその理由とか考えたので
お金がもったいない
当然、企業の資本は有限なので予算配分はとても重要
仕事ができる人を集めたかったら企業として教育制度がないことをアピールすると良いと思うんだけど
教育制度に予算を割かず、その分報酬として還元しているとすればいいだけ
採用してる側もその分給料を上げづらい
教育が必要な前提で給料テーブルを決定しているとどうしても給料の上昇が遅れるので
って言うか経年で給料が増えるってどういうことなの?
日本も必要な分だけ必要な人に働いてもらうって言うことになればいいのに
個人が組織に縛られる人生なんておかしいでしょ
そんなのは一部の人だけでよくて他はそれこそ流動的でいいんじゃないのかと思うんだけど、でも組織に身を捧げることによって得られる保証が抗いがたいんだろうな、日本国が健康で文化的な生活を保証してるはずなんだけどね
時間がかかる
今どきの商売なんて早さ勝負なわけでイチイチ教育してできるのを待っているなんてありえない
普通に最初からできる人雇って仕事割り当てればいいだけの話なんだけどな
そんな簡単なことわからないのかな
賭け事なんてするべきじゃない
まともな企業はそんな無謀な賭け事をするべきじゃない
新卒採用して数年教育するとすると
三年想定で毎年500万円ってことは数千万円必要な訳でさ、そんでまさかものにならないなんて酷い話はありえないでしょ
俺ならこんな馬鹿な賭け事しないわ
仮に三年教育してものになったとしても三年の時間と数千万円は必要になるわけだしね
だったら最初から普通にできる人雇えばそれで済む話でさもう本当に考えられないんだけど
最後に今までの体験談なんだけど、いわゆる若い人を教育が必要な人を雇ってさ、そいつに雑用とかやらせてるんだけどこれがそもそもアホらしいと言うかなんて言うか非効率極まりないと思うんだけど
雑用は雑用専門の人を安い給料で雇うべきでその若人は一日でも早く一人前になるべきでそのためにも雑用なんてやってる場合じゃないわけよ
電話番のために横に座ってて仕事ができるようになるわけじゃないから
まったく何も向上しないし好転しないからって当たり前なんだけどさ
お茶出しとかさせる暇があったらその分まともな仕事させて早く仕事できるようになってもらったほうがお互いのためにもいいと思うんだけどね
本当にこういうことやってる会社ってアホじゃないかなと思うわけよ
お前と違ってこっちは別に暇じゃないんだよ
なぜそうなるのか全然わからないのだけどあの空間で過ごすと自然と仕事ができるようになるとでも言うのだろうか
「あの空間でお茶出しやら電話番やらすること」が一体何に作用するのか全く不明なんだけど
そんなもんお茶が出せるようになったり電話番ができるようになるだけな気がするんだけどね
他の能力は一切伸びない気がするんだけど、気のせいなのかな
俺には分かんないな
コンピュータサイエンスの話題、Common Lisp、すこしHaskellにも触れます 求職中 スキルとしてはVisual StudioでC#が得意 Webアプリケーション、データベースの一般的な操作に精通しています 要件定義から設計、実装まで問題なくこなせます 一般的なプログラミング言語なら問題なく扱えます
2019年2月17日
2019年2月14日
保険とか健康保険とかガン保険とかそういうもの
日本人って憲法で文化的な最低限度の生活が保証されているわけでさ、だったら保険とか入ることってなんなの?って話なんだけど
日本国があてにならんと言いたいわけなのか
例えば身体が不自由になってしまったとして、例えば半身不随とかで
そうした場合、当然働けないわけなんだけどそうなったら普通に考えると日本国が文化的な最低限度の生活を保証してくれるわけで、そうなると保険とか入る意味がよくわからんのだけど
加入しなくてもよくね?
最後に本当に鬱陶しいと思うのがこういうことを言うと財源がどうのとか言ってくるヤツいるんだけどさ、本当に鬱陶しいんだけど財源とかひっくるめて実現の方法を考えるために公務員とか国会議員とかいるんだけどね
こういうこと言ってくる人ってなんか人のことを蔑んで俺様頭良い〜って悦に入りたいんだろうな、きっと
日本国があてにならんと言いたいわけなのか
例えば身体が不自由になってしまったとして、例えば半身不随とかで
そうした場合、当然働けないわけなんだけどそうなったら普通に考えると日本国が文化的な最低限度の生活を保証してくれるわけで、そうなると保険とか入る意味がよくわからんのだけど
加入しなくてもよくね?
最後に本当に鬱陶しいと思うのがこういうことを言うと財源がどうのとか言ってくるヤツいるんだけどさ、本当に鬱陶しいんだけど財源とかひっくるめて実現の方法を考えるために公務員とか国会議員とかいるんだけどね
こういうこと言ってくる人ってなんか人のことを蔑んで俺様頭良い〜って悦に入りたいんだろうな、きっと
2019年2月1日
企業における評価方法について
企業って言うか、組織って言うかそんな集団での評価方法について
結局のところ給料ってことでいいと思うんだけどさ、どこの会社か知らなけどとんでもなくしょうもない評価方法を採用しててさ、辟易しちゃうんだけどね
あしたのチームとか言う訳わかんない詐欺集団の提供する方法を採用しちゃってるもんだから参った
本当に会社全体で詐欺に遭ってるようなもんでさ、社長も付き合いとか色々で大変なんだろうけどさこんな変なものに付き合わされて大変なんだろうなと同情したくなるような仕組みで終わってるんだけど
評価基準って普通にどれだけ貢献したかだけで十分だと思うんだけどそれじゃダメらしい、意味わからん
とにかくアピールが重要だと言いたいらしいんだけど、実際そうたいして役に立ってないとしてもなんかやってる感じを出せることがとても重要らしいんだけど、実際やってみて感じるのはなんて言うか実行できない残念な人のためにあるって感じかな
普通になんだかんだでなにかできる人にとっては別のどうでもいいのだけど、能力とか低くてなんもできない人でもなんかやったことにできると言うか見かけだけ取り繕えると言うかそんな制度で本当にこの方法を採用する価値が全く感じられないもう完全に邪魔なだけでこの何の役に立つかわからんものに支払っているお金を普通に配ったほうがいいんじゃないのかとしか思えないんだけどさ
評価方法がわからない悩める経営者にとって朗報みたいな感じなんだけど、評価方法がわからん時点で相当経営者に向いていないから辞めてほしいところではあるんだけどね
だってさ、ある人の行動や成果などが自分の会社にどれだけ役に立っているかわからんって言ってるわけだからね
こんなに酷い話はそんなにないような気がするんだけど
って言うかさ、もし仮にこの評価方法が画期的で会社の発展に大きく貢献するんだったらこのあしたのチームって言う会社はなんでこんなにショボイんだっての
もうさ、それこそ何て言うかマイクロソフトなんて全然目じゃなくてグーグルなんて軽く凌げるような組織になっててもらわないとって思うんだけどね
もしかして遠慮してるのか?
だったらそんな必要全くないからどんどんやってくれって感じなんだけど
結局のところ給料ってことでいいと思うんだけどさ、どこの会社か知らなけどとんでもなくしょうもない評価方法を採用しててさ、辟易しちゃうんだけどね
あしたのチームとか言う訳わかんない詐欺集団の提供する方法を採用しちゃってるもんだから参った
本当に会社全体で詐欺に遭ってるようなもんでさ、社長も付き合いとか色々で大変なんだろうけどさこんな変なものに付き合わされて大変なんだろうなと同情したくなるような仕組みで終わってるんだけど
評価基準って普通にどれだけ貢献したかだけで十分だと思うんだけどそれじゃダメらしい、意味わからん
とにかくアピールが重要だと言いたいらしいんだけど、実際そうたいして役に立ってないとしてもなんかやってる感じを出せることがとても重要らしいんだけど、実際やってみて感じるのはなんて言うか実行できない残念な人のためにあるって感じかな
普通になんだかんだでなにかできる人にとっては別のどうでもいいのだけど、能力とか低くてなんもできない人でもなんかやったことにできると言うか見かけだけ取り繕えると言うかそんな制度で本当にこの方法を採用する価値が全く感じられないもう完全に邪魔なだけでこの何の役に立つかわからんものに支払っているお金を普通に配ったほうがいいんじゃないのかとしか思えないんだけどさ
評価方法がわからない悩める経営者にとって朗報みたいな感じなんだけど、評価方法がわからん時点で相当経営者に向いていないから辞めてほしいところではあるんだけどね
だってさ、ある人の行動や成果などが自分の会社にどれだけ役に立っているかわからんって言ってるわけだからね
こんなに酷い話はそんなにないような気がするんだけど
って言うかさ、もし仮にこの評価方法が画期的で会社の発展に大きく貢献するんだったらこのあしたのチームって言う会社はなんでこんなにショボイんだっての
もうさ、それこそ何て言うかマイクロソフトなんて全然目じゃなくてグーグルなんて軽く凌げるような組織になっててもらわないとって思うんだけどね
もしかして遠慮してるのか?
だったらそんな必要全くないからどんどんやってくれって感じなんだけど
2019年1月20日
企業の採用活動について
まず一言「企業はもっと採用に予算を割くべき」
何社か働いて本当にそう感じる
採用後に施す教育によって伸びる可能性はほぼないかな
結局採用時点、面接時点で未来は決まっていると思うんだけど
だったら教育なんかに予算を使わないで採用とか、他の福利厚生だったり劣悪な労働環境だったり給与や賞与に反映させたほうが絶対有意義だと思う
エクセルのマクロしかできない人をシステム開発とかで採用しちゃうと大変なことになると思うんだよ
って言うか、このエクセルのマクロ程度しかできなくて、でも現代は色々なところから適当なプログラムをダウンロードして、例えばJavaScriptなんかでなにかしら作れたりするから別に普通にできるんじゃないの?と勘違いしちゃってると思う人の存在が相当罪深いと思うのだけど
こういう人の言い分としては「散々な目に遭った」「酷く過酷な仕事を押し付けられて精神的に追い込まれて病気になった」「夜中泣きながら仕事した」「仲間はずれにされた」とかそんなこと言うことになると思うのだけど
働かせる側を擁護するつもりはないけど仕事割り当てる側としてもできるだけまっとうできそうな人に割り当てたいんだけどね
エクセルマクロしかできない人に仕事させたくないっつうの
だったら別に俺がやってもいいよ、そのほうが圧倒的に楽だしさ
今の時代新卒大学生を採用することすら相当なリスクを抱えてると思うね
新卒と言うことで費用かけて教育とかするのだけど、その人が役に立つ人材になる可能性が運だし、辞めちゃうかもしれないしさ
教育コスト費やすに値する対価を得られそうにない
相当な無理ゲー
だったら新卒とかどうでもいいから普通に出来る人雇えばいいのに
そうすればいきなり役に立つ上に教育コストも必要ないし、別に辞めちゃっても普通に働いてもらえて別に損害も無いしさ
新卒採用って相当なリスクがあってこんなものそのへんの中小企業が手を出すもんじゃないよな
新卒学生一年教育で雇うなんてヘタしたら1千万円とか必要になったりしないか?
そこまでいかないか、そこまでいかないにしてもさ、新入りを電話番とかお茶くみとして使うのはもう完全に止めたほうがいいよね
そんなもんパートのおばちゃんとか雇えば終わりで終了な気がするのだけど
だから採用する企業側に安全弁が必要になるんだけど
まあだからその分採用コストも上がるって寸法なわけで
募集に対する応募はそれなりにあるのかもしれないけど最低限の条件を超えた人がどれくらいいるのかが問題のような気もするし
多分
・人事
・管理者
・被採用者
三者で言い分が異なるわけよね
人事としては役に立つ人を採用できたといいたいわけよ
だけど現場からしたらエクセルマクロしかできない人に仕事はさせられないってことで別に頭数が増えただけで手間は全然減ってない、逆に増えてるくらいだと
んで、被採用者にしてみたら酷い目にあったので精神的に病気になった
ってなるわけでさ、こうなると一番効率的なのは人事で篩をかけることがやっぱり一番効率的だと思うんだけどね
エクセルマクロしかできなくても華々しくシステム開発で活躍する夢を見ることは勝手だしさ、プログラムとかチョロいって思うのも勝手なんだけどね
何社か働いて本当にそう感じる
採用後に施す教育によって伸びる可能性はほぼないかな
結局採用時点、面接時点で未来は決まっていると思うんだけど
だったら教育なんかに予算を使わないで採用とか、他の福利厚生だったり劣悪な労働環境だったり給与や賞与に反映させたほうが絶対有意義だと思う
エクセルのマクロしかできない人をシステム開発とかで採用しちゃうと大変なことになると思うんだよ
って言うか、このエクセルのマクロ程度しかできなくて、でも現代は色々なところから適当なプログラムをダウンロードして、例えばJavaScriptなんかでなにかしら作れたりするから別に普通にできるんじゃないの?と勘違いしちゃってると思う人の存在が相当罪深いと思うのだけど
こういう人の言い分としては「散々な目に遭った」「酷く過酷な仕事を押し付けられて精神的に追い込まれて病気になった」「夜中泣きながら仕事した」「仲間はずれにされた」とかそんなこと言うことになると思うのだけど
働かせる側を擁護するつもりはないけど仕事割り当てる側としてもできるだけまっとうできそうな人に割り当てたいんだけどね
エクセルマクロしかできない人に仕事させたくないっつうの
だったら別に俺がやってもいいよ、そのほうが圧倒的に楽だしさ
今の時代新卒大学生を採用することすら相当なリスクを抱えてると思うね
新卒と言うことで費用かけて教育とかするのだけど、その人が役に立つ人材になる可能性が運だし、辞めちゃうかもしれないしさ
教育コスト費やすに値する対価を得られそうにない
相当な無理ゲー
だったら新卒とかどうでもいいから普通に出来る人雇えばいいのに
そうすればいきなり役に立つ上に教育コストも必要ないし、別に辞めちゃっても普通に働いてもらえて別に損害も無いしさ
新卒採用って相当なリスクがあってこんなものそのへんの中小企業が手を出すもんじゃないよな
新卒学生一年教育で雇うなんてヘタしたら1千万円とか必要になったりしないか?
そこまでいかないか、そこまでいかないにしてもさ、新入りを電話番とかお茶くみとして使うのはもう完全に止めたほうがいいよね
そんなもんパートのおばちゃんとか雇えば終わりで終了な気がするのだけど
だから採用する企業側に安全弁が必要になるんだけど
まあだからその分採用コストも上がるって寸法なわけで
募集に対する応募はそれなりにあるのかもしれないけど最低限の条件を超えた人がどれくらいいるのかが問題のような気もするし
多分
・人事
・管理者
・被採用者
三者で言い分が異なるわけよね
人事としては役に立つ人を採用できたといいたいわけよ
だけど現場からしたらエクセルマクロしかできない人に仕事はさせられないってことで別に頭数が増えただけで手間は全然減ってない、逆に増えてるくらいだと
んで、被採用者にしてみたら酷い目にあったので精神的に病気になった
ってなるわけでさ、こうなると一番効率的なのは人事で篩をかけることがやっぱり一番効率的だと思うんだけどね
エクセルマクロしかできなくても華々しくシステム開発で活躍する夢を見ることは勝手だしさ、プログラムとかチョロいって思うのも勝手なんだけどね
2018年11月9日
コーディング規約と言う名の
会社でソースコードの書き方、あるいはルール的なものを決めるとかなんとか言ってるんだけどこの内容が本当にこれこそ噴飯ものと言う表現に相応しいような内容で呆れてるんだけどさ
ただでさえ酷いのに、さらにそれなりに残業しないと終わらないって言うのにそんな何の役に立つのかさっぱりわかんないものを策定するために時間を使ってると言うのが笑えるんだけど
インデントとかのルールを決めるとなにがどうなって品質が向上すると言うのか想像できないんだけどさ
コンパイラって普通にインデントとか無視するんだけどねと思ったりそんな程度のことをあーだこーだと議論してるって言うのがよく分からんのだが
だったら多態性とかについて勉強したほうがよっぽど実になるんじゃないかと思うんだけどさ
あとさ、弊社の取り組みとしてこんな規約を採用してるって言うとどうなると思ってるんだろうか
普通にできる人は面倒なことがある会社だって言うことで避けるんじゃないのかと
って言うかよく分からんルールがあるとソースコードが読みやすくなるらしいんだけど、何て言うか厳密にルールに従っていないと理解できないとかなんか意味がさっぱりわかんないこと言われてるんだけどさ、会社なんだからそういう人を雇わないでおけばいいだけじゃないかと思わないでもないしそういう人に合わせるのは退屈極まりないからなるべくなら避けたいんだけどどうしようかな
ただでさえ酷いのに、さらにそれなりに残業しないと終わらないって言うのにそんな何の役に立つのかさっぱりわかんないものを策定するために時間を使ってると言うのが笑えるんだけど
インデントとかのルールを決めるとなにがどうなって品質が向上すると言うのか想像できないんだけどさ
コンパイラって普通にインデントとか無視するんだけどねと思ったりそんな程度のことをあーだこーだと議論してるって言うのがよく分からんのだが
だったら多態性とかについて勉強したほうがよっぽど実になるんじゃないかと思うんだけどさ
あとさ、弊社の取り組みとしてこんな規約を採用してるって言うとどうなると思ってるんだろうか
普通にできる人は面倒なことがある会社だって言うことで避けるんじゃないのかと
って言うかよく分からんルールがあるとソースコードが読みやすくなるらしいんだけど、何て言うか厳密にルールに従っていないと理解できないとかなんか意味がさっぱりわかんないこと言われてるんだけどさ、会社なんだからそういう人を雇わないでおけばいいだけじゃないかと思わないでもないしそういう人に合わせるのは退屈極まりないからなるべくなら避けたいんだけどどうしようかな
2017年12月13日
self.redirectに全角を渡す場合
Google App Engine
webapp2のredirectについて
Pythonの場合
webapp2.recirectはstrを受け付ける
unicodeは受け付けない
unicodeを渡す場合はunicodeをutf-8でエンコードしてurlエスケープしてformatに渡して出来上がったものをwebapp2.redirectに渡す
例
aa = u'あ'
(aaはunicode)
self.redirect('{0}'.format(urllib.quote(aa.encode('utf-8'))))
webapp2のredirectについて
Pythonの場合
webapp2.recirectはstrを受け付ける
unicodeは受け付けない
unicodeを渡す場合はunicodeをutf-8でエンコードしてurlエスケープしてformatに渡して出来上がったものをwebapp2.redirectに渡す
例
aa = u'あ'
(aaはunicode)
self.redirect('{0}'.format(urllib.quote(aa.encode('utf-8'))))
参考
webapp2.request.get()
<type 'unicode'>
type(u'あ')
<type 'unicode'>
type('あ')
<type 'str'>
type(u'あ'.encode('utf-8'))
<type 'str'>
2017年6月1日
変数を箱と言わないで表現すると
別名が付けられるかな
例えば3.1415926じゃなくてpiと呼べるとか
寿限無寿限無じゃなくてaと呼べるというか
common lispみたいなレキシカルスコープだとなんかこんな感じが強い
変数は箱って言うのはノイマン型コンピュータのアーキテクチャと密接につながった概念だと思うな
だからコンピュータアーキテクチャを説明したい場合は有利なのかもしれないけど、JavaScriptの解説には不向きな気がするよね
時代が時代なだけにJavaScriptを軽く身につけたいって言う人もいると思うんで、そういう人に対して変数が箱って言うのはやっぱり少々わかりにくい気がする
特に変数が箱と言う説明が向いていないのがGCがある環境の場合
GCがある場合とか、JavaScriptみたいにリソースとかもあんまり考えなくても良い場合なんて特に箱は向いていなくて別名でいいんじゃないかなと思う
例えば3.1415926じゃなくてpiと呼べるとか
寿限無寿限無じゃなくてaと呼べるというか
common lispみたいなレキシカルスコープだとなんかこんな感じが強い
変数は箱って言うのはノイマン型コンピュータのアーキテクチャと密接につながった概念だと思うな
だからコンピュータアーキテクチャを説明したい場合は有利なのかもしれないけど、JavaScriptの解説には不向きな気がするよね
時代が時代なだけにJavaScriptを軽く身につけたいって言う人もいると思うんで、そういう人に対して変数が箱って言うのはやっぱり少々わかりにくい気がする
特に変数が箱と言う説明が向いていないのがGCがある環境の場合
GCがある場合とか、JavaScriptみたいにリソースとかもあんまり考えなくても良い場合なんて特に箱は向いていなくて別名でいいんじゃないかなと思う
2016年11月28日
codeiqの広告
頻繁に表示されるcodeiqの広告についてなんですけど
なんかphpとか言うクズ言語のソースが10行程度表示されてましてこれ実行するとどうなるかだってさ
ってかさ、これってphpとか言うクズ言語が使えるかどうかなわけじゃないですか
それって必要なんですかね
そのあたりがイマイチ理解できないところなんですよね
世の中として求められているものがphpとか言うクズ言語の言語仕様を把握しているかどうかってことなわけでさ、それって求職者に対して望むべき能力なんですかね
と言うか、この質問に対していわゆるドヤ顔で鼻息荒く答えはなになにですって答えられたとしたらですけど、そんな人採用対象として失格じゃないでしょうか
ってか、失格対象としますけどね、って思うんだけど
なんかphpとか言うクズ言語のソースが10行程度表示されてましてこれ実行するとどうなるかだってさ
ってかさ、これってphpとか言うクズ言語が使えるかどうかなわけじゃないですか
それって必要なんですかね
そのあたりがイマイチ理解できないところなんですよね
世の中として求められているものがphpとか言うクズ言語の言語仕様を把握しているかどうかってことなわけでさ、それって求職者に対して望むべき能力なんですかね
と言うか、この質問に対していわゆるドヤ顔で鼻息荒く答えはなになにですって答えられたとしたらですけど、そんな人採用対象として失格じゃないでしょうか
ってか、失格対象としますけどね、って思うんだけど
2016年11月9日
センスについて
「プログラムはセンスで書く。インスピレーションで書く。」とか「根性で書く」や「おまじない」等の様な対話について思うこと
こういうことを言う人は、相手に対して説明できるような能力を有していないと言うこと
いわゆる職人とか言われているような集団において、技を盗めだとかそういうことを言うのも近いものがある
要は説明できない、相手が理解できるような説明をすることができないので、やれ「根性」だ「盗め」だ言いたがる、挙句「おまじない」だってさ
自分が好んで参考にする書籍でこのような表現を使っているものが皆無であることの理由は、それら書籍の著者はプログラムについて深い理解をし、それを相手に伝えることができる能力を有しているから
それら書籍においては決して「センス」やら「インスピレーション」やら「根性」なんて単語は登場しない
もし仮に現在「根性」や「おまじない」なんて言ってお茶を濁しているのだったら、それはそのことについて理解が不足している証拠を提示していることにほかならない
その場合は素直に「分からない」「知らない」と言ったほうがより好意的に受け取ってもらえると思う
そこでお互い、説明能力の有無の是非については不問にするとより良いと思うのだが質問時の場合、質問者と回答者の立場の違いによりなかなかそういうわけにもいかないのが問題
質問者が回答者に対して説明能力が無いと正確に認識してくれればいいのだけど、質問者が回答者に対して能力が無いと評価するのが問題になる
いわゆるプログラムの能力の有無と説明能力の有無を切り離せることが必要なのだけど、能力があると当然説明能力も有していることになるところがマズイんだよね
あと、たまに素人に対してあいつは説明能力を有していると勘違いされてさ、肝心のプログラムの能力が乏しい場合があるのがこれまた問題なんじゃないかなと
|1|2|3|4
プログラム能力|x|x|o|o
説明能力 |x|o|x|o
だから4はもう本当に問題ない
多分次にいいのが3で最悪なのが2なんじゃないのかな1はもともと範囲外だからね
って言うか2ってどんな人物のことなのか具体的に思いつかないけど、多分ああいう人のことなんだろうな
こういうことを言う人は、相手に対して説明できるような能力を有していないと言うこと
いわゆる職人とか言われているような集団において、技を盗めだとかそういうことを言うのも近いものがある
要は説明できない、相手が理解できるような説明をすることができないので、やれ「根性」だ「盗め」だ言いたがる、挙句「おまじない」だってさ
自分が好んで参考にする書籍でこのような表現を使っているものが皆無であることの理由は、それら書籍の著者はプログラムについて深い理解をし、それを相手に伝えることができる能力を有しているから
それら書籍においては決して「センス」やら「インスピレーション」やら「根性」なんて単語は登場しない
もし仮に現在「根性」や「おまじない」なんて言ってお茶を濁しているのだったら、それはそのことについて理解が不足している証拠を提示していることにほかならない
その場合は素直に「分からない」「知らない」と言ったほうがより好意的に受け取ってもらえると思う
そこでお互い、説明能力の有無の是非については不問にするとより良いと思うのだが質問時の場合、質問者と回答者の立場の違いによりなかなかそういうわけにもいかないのが問題
質問者が回答者に対して説明能力が無いと正確に認識してくれればいいのだけど、質問者が回答者に対して能力が無いと評価するのが問題になる
いわゆるプログラムの能力の有無と説明能力の有無を切り離せることが必要なのだけど、能力があると当然説明能力も有していることになるところがマズイんだよね
あと、たまに素人に対してあいつは説明能力を有していると勘違いされてさ、肝心のプログラムの能力が乏しい場合があるのがこれまた問題なんじゃないかなと
|1|2|3|4
プログラム能力|x|x|o|o
説明能力 |x|o|x|o
だから4はもう本当に問題ない
多分次にいいのが3で最悪なのが2なんじゃないのかな1はもともと範囲外だからね
って言うか2ってどんな人物のことなのか具体的に思いつかないけど、多分ああいう人のことなんだろうな
2016年10月4日
実践common lisp第24章
一気に難易度上昇、跳ね上がりましたね、これは
やっぱりマクロが登場すると次元が一つ上がると言うか、はっきり言って訳分からんのじゃないかなと
プログラムを生成するプログラムを作ると言うことがこれほどまでに難易度が高いとは
抽象度を上げるということはこういうことなんだと言うことで、抽象度を上げるためにはこういうことをやることになると言うか
一つ一つの関数単位と言うか、各部分は別に難しいことをやっているわけでもなんでもないのだけど、アルゴリズムとかデータ構造が難しいわけでもなんでもないのだけど、一体なにをやっているのかわかりにくいったらありゃしない、のは当然そうなわけなんだけど
ここでやってることって、敢えて類似で例を上げるとするならいわゆるO/Rマッパーを作っていることになるんじゃないかなと
データベースの定義がまあなんかあるとして、仕様書でもなんでもいいのだけど、主キーがなんとかidとかでタイトルと日付とあれやこれやとカラムがあるとして、そのデータを元にO/RのOのソースコードを自動で書かせようって魂胆なんだろうな
O/RのOを作る場合、なんとかidが64bit整数で、タイトルがvarchar(256)で日付があって本文は文字数制限が無いタイプだと言うクラスを作りたいとすると、具体的にC#だとこんな感じのコードを書くことになるのだけど
class BlogRow
{
private long id;
private string title;
private DateTime date;
private string body;
public long ID
{
get { return id;}
set {id = value;}
}
// title,date,bodyに関しても同じようにプロパティを用意すること
}
これを
(define-or-mapper BlogRow (long id) (string title 256) (DateTime date) (string body))
みたいなものから生成させようって言う魂胆ね
このデータベースの定義からソースコードを生成するために必要なものって、このデータベースの定義をパースする処理っていうのが一番骨が折れるところで、それを自動でコンピュータにやらせようってなるとまあこうなっちゃうんだよね
さらに、C#で例を作ったんでC#の話になると、多分C#のO/Rマッパーって動的に生成されると言うか実行時にこういったものを生成しようとすることになるものが多いんじゃないかな
キャストとか、型情報を取り出して、動的に分岐させてOへ変換するって言うか
さらにtitleは256だから、あるストリーム(データベースじゃないけど)から256読み込むみたいな処理まで作ろうとしているのかな
setがストリームを引数として受け取ってtitle = is.read(256)みたいなソースコード生成しようとしてるんじゃないのかな
そこで問題になるのがC#のソースコードを自動で生成するのはちょっと骨が折れるんだよね、でもCommon Lispなら全然難しいことじゃないって言うことがここでは言いたいのだろう
C#と全然違うけど、多分wordpressとかphpとかそういう界隈で提供されているようなものってまあそういうことになってると思うのだけど、そうなるとどうしても実行時に遅くなったり、いちいちコードを書いたものと比べると色々と見劣りするものになっちゃうのだけど、Common Lispの場合はそういうのをコンパイル時に生成してしまおうってことで、こういうややこしいものを作ることによって、実行時のコストを下げることができる
なんでこんなにもややこしいことをするかって言うと、実行時のコストを犠牲にしないで、でも必要な情報はなるべく少なく記述したい、コピペするとかもってのほかで、データベースの情報からあたかもいちいち手でコードを書いたようにしたいと
今回はこれ一つしか利用しないけど、毎日毎日データベースで、テーブル作って、それを読み書きするコードを書いて、表示させて、登録してって言うことをやるんだったら、こうやってソースコードを生成することができるプログラムを作ることによって毎日の作業を軽減することができるというわけで、とてもじゃないけど常人には理解しがたいものでこんなもん説明されたらいやになっちゃうよね
って言うことがここで行われている
ここで実際にやっていることは、いろいろなフォーマットのファイルに柔軟に対応したオブジェクトマッパーの生成プログラムのことについてであって、ここで問題になっているID3ファイルに対してはさっぱり取り上げられていないところを勘違いすると大変なことになる、なりました、はい
そんで多分次章では、ここで作ったマクロを利用してID3ファイルの読み書きを実際に行うことになるんじゃないかなと思います
やっぱりマクロが登場すると次元が一つ上がると言うか、はっきり言って訳分からんのじゃないかなと
プログラムを生成するプログラムを作ると言うことがこれほどまでに難易度が高いとは
抽象度を上げるということはこういうことなんだと言うことで、抽象度を上げるためにはこういうことをやることになると言うか
一つ一つの関数単位と言うか、各部分は別に難しいことをやっているわけでもなんでもないのだけど、アルゴリズムとかデータ構造が難しいわけでもなんでもないのだけど、一体なにをやっているのかわかりにくいったらありゃしない、のは当然そうなわけなんだけど
ここでやってることって、敢えて類似で例を上げるとするならいわゆるO/Rマッパーを作っていることになるんじゃないかなと
データベースの定義がまあなんかあるとして、仕様書でもなんでもいいのだけど、主キーがなんとかidとかでタイトルと日付とあれやこれやとカラムがあるとして、そのデータを元にO/RのOのソースコードを自動で書かせようって魂胆なんだろうな
O/RのOを作る場合、なんとかidが64bit整数で、タイトルがvarchar(256)で日付があって本文は文字数制限が無いタイプだと言うクラスを作りたいとすると、具体的にC#だとこんな感じのコードを書くことになるのだけど
class BlogRow
{
private long id;
private string title;
private DateTime date;
private string body;
public long ID
{
get { return id;}
set {id = value;}
}
// title,date,bodyに関しても同じようにプロパティを用意すること
}
これを
(define-or-mapper BlogRow (long id) (string title 256) (DateTime date) (string body))
みたいなものから生成させようって言う魂胆ね
このデータベースの定義からソースコードを生成するために必要なものって、このデータベースの定義をパースする処理っていうのが一番骨が折れるところで、それを自動でコンピュータにやらせようってなるとまあこうなっちゃうんだよね
さらに、C#で例を作ったんでC#の話になると、多分C#のO/Rマッパーって動的に生成されると言うか実行時にこういったものを生成しようとすることになるものが多いんじゃないかな
キャストとか、型情報を取り出して、動的に分岐させてOへ変換するって言うか
さらにtitleは256だから、あるストリーム(データベースじゃないけど)から256読み込むみたいな処理まで作ろうとしているのかな
setがストリームを引数として受け取ってtitle = is.read(256)みたいなソースコード生成しようとしてるんじゃないのかな
そこで問題になるのがC#のソースコードを自動で生成するのはちょっと骨が折れるんだよね、でもCommon Lispなら全然難しいことじゃないって言うことがここでは言いたいのだろう
C#と全然違うけど、多分wordpressとかphpとかそういう界隈で提供されているようなものってまあそういうことになってると思うのだけど、そうなるとどうしても実行時に遅くなったり、いちいちコードを書いたものと比べると色々と見劣りするものになっちゃうのだけど、Common Lispの場合はそういうのをコンパイル時に生成してしまおうってことで、こういうややこしいものを作ることによって、実行時のコストを下げることができる
なんでこんなにもややこしいことをするかって言うと、実行時のコストを犠牲にしないで、でも必要な情報はなるべく少なく記述したい、コピペするとかもってのほかで、データベースの情報からあたかもいちいち手でコードを書いたようにしたいと
今回はこれ一つしか利用しないけど、毎日毎日データベースで、テーブル作って、それを読み書きするコードを書いて、表示させて、登録してって言うことをやるんだったら、こうやってソースコードを生成することができるプログラムを作ることによって毎日の作業を軽減することができるというわけで、とてもじゃないけど常人には理解しがたいものでこんなもん説明されたらいやになっちゃうよね
って言うことがここで行われている
ここで実際にやっていることは、いろいろなフォーマットのファイルに柔軟に対応したオブジェクトマッパーの生成プログラムのことについてであって、ここで問題になっているID3ファイルに対してはさっぱり取り上げられていないところを勘違いすると大変なことになる、なりました、はい
そんで多分次章では、ここで作ったマクロを利用してID3ファイルの読み書きを実際に行うことになるんじゃないかなと思います
2016年9月29日
実践common lisp第23章
intern-feature関数内でのorの使い方は良く登場する
orは論理演算なのだけど、一つ目がnilの場合は二つ目が実行されるって言うのを利用するためにorでやっているので別にifでもいい
個人的にはこれはあんまり好きじゃないので素直にunlessを使うほうがよさそうだと思っている
Pythonは実現方法は一つと言う方針だけど、Common Lispは実現方法は複数あるとでも言いましょうか
clear-database内のsetfに複数の引数を渡して一括で初期化するのもCommon Lispっぽい
可変長引数と言うか、たまにこういうふうになっているのを見かける
ここでのプログラムは相当細かいものまで分割して実装されている
実際ここまで細かく分割する必要があるかと言う話なのだけど、Common Lispではこれくらい細かくてもいいんじゃないかなって思ってます
特にincrement-countは非常に細かい
けど、この注釈にも記述があるとおり、別のデータ型を定義してincrementの方法を用意したい場合にこの記述が生きてくる
って言うのが拡張性とかそういうことに繋がってくるのだけど、このあたりの話はリファクタリングともかぶってくるので
つまり、拡張するためには現在defunで定義してあるincrement-countをdefmethodにして、さらにdefclassで別のデータ型を作ってって言う作業が必要になると言うことでも十分拡張可能なプログラムになっている
CL-PPCREを利用するメモ
http://weitz.de/cl-ppcre/
上記ページによると
(ql:quickload :cl-ppcre)
らしいので先ずQuicklispと言うものをインストールすると良さそう
https://www.quicklisp.org/beta/
上記ページによるとquicklisp.lispをダウンロードしてインストールするようだ
ちなみにファイルを入手後はCommon Lispのなんか(quicklispページではSBCLを利用していた)を起動してインストールする
その後、コマンドラインから
(load "~/quicklisp/setup.lisp")
とするとquicklispが利用可能になるので、その後cl-ppcreを読みこめば無事利用可能になる
orは論理演算なのだけど、一つ目がnilの場合は二つ目が実行されるって言うのを利用するためにorでやっているので別にifでもいい
個人的にはこれはあんまり好きじゃないので素直にunlessを使うほうがよさそうだと思っている
Pythonは実現方法は一つと言う方針だけど、Common Lispは実現方法は複数あるとでも言いましょうか
clear-database内のsetfに複数の引数を渡して一括で初期化するのもCommon Lispっぽい
可変長引数と言うか、たまにこういうふうになっているのを見かける
ここでのプログラムは相当細かいものまで分割して実装されている
実際ここまで細かく分割する必要があるかと言う話なのだけど、Common Lispではこれくらい細かくてもいいんじゃないかなって思ってます
特にincrement-countは非常に細かい
けど、この注釈にも記述があるとおり、別のデータ型を定義してincrementの方法を用意したい場合にこの記述が生きてくる
って言うのが拡張性とかそういうことに繋がってくるのだけど、このあたりの話はリファクタリングともかぶってくるので
つまり、拡張するためには現在defunで定義してあるincrement-countをdefmethodにして、さらにdefclassで別のデータ型を作ってって言う作業が必要になると言うことでも十分拡張可能なプログラムになっている
CL-PPCREを利用するメモ
http://weitz.de/cl-ppcre/
上記ページによると
(ql:quickload :cl-ppcre)
らしいので先ずQuicklispと言うものをインストールすると良さそう
https://www.quicklisp.org/beta/
上記ページによるとquicklisp.lispをダウンロードしてインストールするようだ
ちなみにファイルを入手後はCommon Lispのなんか(quicklispページではSBCLを利用していた)を起動してインストールする
その後、コマンドラインから
(load "~/quicklisp/setup.lisp")
とするとquicklispが利用可能になるので、その後cl-ppcreを読みこめば無事利用可能になる
実践common lisp第22章
loopも初心者殺しの側面があるのだけど、反面非常に強力な側面もあるんだよね
このloopの理解にもやっぱりソースコード生成の考え方ができるかどうかで理解の仕方も変わってくるような気がするんだけど
あと、まさかこれだけ高機能だと非常に非効率な実行になるとか心配する人もいるのかな
全然非効率じゃないのだけどね
これだけ高度に抽象化されたコードを記述でき、さらに効率的な実行も行えると言うことをわかって欲しいな
そしてさらにスゴイところはこんなことが誰でも可能になるような懐の深さって言うんですかね、Common Lispってやっぱりスゴイな
このloopの理解にもやっぱりソースコード生成の考え方ができるかどうかで理解の仕方も変わってくるような気がするんだけど
あと、まさかこれだけ高機能だと非常に非効率な実行になるとか心配する人もいるのかな
全然非効率じゃないのだけどね
これだけ高度に抽象化されたコードを記述でき、さらに効率的な実行も行えると言うことをわかって欲しいな
そしてさらにスゴイところはこんなことが誰でも可能になるような懐の深さって言うんですかね、Common Lispってやっぱりスゴイな
実践common lisp第20章
関数でもマクロでも実現できないものが特殊オペレータ
でいいのかな
QUOTEは確かに関数でもマクロでも実現できそうにない気がする
せっかくなのでQUOTEについて再度触れておくと、なんでこれが必要なのかっていうことなんですけど、Common Lispのソースコードがリストで表現されていて、そのリストの一つ目は関数名(又はマクロ、特殊オペレータ)、二つ目以降が引数っていうルールがあるから例えば
(+ 1 2 3)
はリストの一つ目の+が関数名、二つ目以降の1 2 3が引数になる
そんで例えば(あんまり有用な例が思いつかない)length関数に静的にリストを渡すとして
(length (1 2 3));間違い
と、してしまうとlength関数に渡している(1 2 3)のリストの一つ目の1が関数名として扱われてしまうから実行時にエラーになってしまう
そこでlengthに渡しているリストは一つ目が値で関数名じゃないですよって言う意味で
(length '(1 2 3))
と記述することができるようにQUOTEが存在している
QUOTEは
(quote (1 2 3))
'(1 2 3)
と等価
IFも関数だと実現できないので
あとこのPROGNって言うのが他の言語にはない珍しいもので、これは単純に言うと複数実行するものを一つにまとめるっていうかただそんだけ
インクリメントして出力するとか複数実行する場合PROGNで囲む
(let ((i 0))
(progn
(incf i)
(format t "~A~%" i)))
例えばifの第二、第三引数は一つのS式しか受け付けられないから
(if pred
(progn
(incf i)
(format t "~A~%" i))
(format t "~A~%" i))
と、PROGNで囲む
ただしwhenやunlessは暗黙でPROGNで囲まれるのでいちいち囲む必要がない
最初はめちゃくちゃややこしかったけどなれるとだんだんと分かるようになります
let、labelsも頻繁に使う
Common Lispは同じ変数名、関数名でもお構いなしに利用できるからめちゃくちゃ便利ですよね
C#だと同じ変数名使えないから匿名関数の引数でいちいち変数名を変えないといけないので
その他の特殊オペレータは正直あんまり使うことないんじゃないかなと思う
フロー制御なんて多分普通使っちゃダメなんじゃないのか
いわゆるgoto的な扱いを受けそう
そういえば昔、C#で制御構造として例外使ってる人いたんだよね
びっくりしたね、プログラムの途中でどうしても呼び出し元に制御を戻したいってことで無理やりthrowしてる人いたな、酷かったな
フロー制御はなんて言うか層が違う部分を構築する際に必要になるんじゃないかな
フレームワーク的な層とアプリケーション層と分けて作る場合に必要というかそんな気がする
多値もあんまり使わないかな
でいいのかな
QUOTEは確かに関数でもマクロでも実現できそうにない気がする
せっかくなのでQUOTEについて再度触れておくと、なんでこれが必要なのかっていうことなんですけど、Common Lispのソースコードがリストで表現されていて、そのリストの一つ目は関数名(又はマクロ、特殊オペレータ)、二つ目以降が引数っていうルールがあるから例えば
(+ 1 2 3)
はリストの一つ目の+が関数名、二つ目以降の1 2 3が引数になる
そんで例えば(あんまり有用な例が思いつかない)length関数に静的にリストを渡すとして
(length (1 2 3));間違い
と、してしまうとlength関数に渡している(1 2 3)のリストの一つ目の1が関数名として扱われてしまうから実行時にエラーになってしまう
そこでlengthに渡しているリストは一つ目が値で関数名じゃないですよって言う意味で
(length '(1 2 3))
と記述することができるようにQUOTEが存在している
QUOTEは
(quote (1 2 3))
'(1 2 3)
と等価
IFも関数だと実現できないので
あとこのPROGNって言うのが他の言語にはない珍しいもので、これは単純に言うと複数実行するものを一つにまとめるっていうかただそんだけ
インクリメントして出力するとか複数実行する場合PROGNで囲む
(let ((i 0))
(progn
(incf i)
(format t "~A~%" i)))
例えばifの第二、第三引数は一つのS式しか受け付けられないから
(if pred
(progn
(incf i)
(format t "~A~%" i))
(format t "~A~%" i))
と、PROGNで囲む
ただしwhenやunlessは暗黙でPROGNで囲まれるのでいちいち囲む必要がない
最初はめちゃくちゃややこしかったけどなれるとだんだんと分かるようになります
let、labelsも頻繁に使う
Common Lispは同じ変数名、関数名でもお構いなしに利用できるからめちゃくちゃ便利ですよね
C#だと同じ変数名使えないから匿名関数の引数でいちいち変数名を変えないといけないので
その他の特殊オペレータは正直あんまり使うことないんじゃないかなと思う
フロー制御なんて多分普通使っちゃダメなんじゃないのか
いわゆるgoto的な扱いを受けそう
そういえば昔、C#で制御構造として例外使ってる人いたんだよね
びっくりしたね、プログラムの途中でどうしても呼び出し元に制御を戻したいってことで無理やりthrowしてる人いたな、酷かったな
フロー制御はなんて言うか層が違う部分を構築する際に必要になるんじゃないかな
フレームワーク的な層とアプリケーション層と分けて作る場合に必要というかそんな気がする
多値もあんまり使わないかな
2016年9月28日
実践common lisp第19章
Common Lispと言うのは、仮想コンピュータ上で実行されているのでここまで話がややこしそうな印象を受けるんじゃないかな
Common Lispの実行環境はコマンドラインみたいなREPL(Read Eval Print Loop)で、そこではファイルのコンパイル、関数のコンパイル等すら用意されている
さらにコンパイルした関数を読み込んで実行することもできる
例えばC言語でのコンパイラ(ここで言うコンパイラと言うのはリンカなどを含めたものを言いたいのだけどどう言ったらいいかよくわかんないので、翻訳と言うよりはC言語においての提供されている一連の機能のことを指したい)の役割のみじゃなくてOS的なものまで提供されている
C言語で書いたプログラムは翻訳して実行ファイルを生成したとして、それを実行するのはOSの役割なのだけど、Common Lispの場合は実行もCommon Lispが請け負っている
だから実行時に介入できるような様々な機能が提供されている
と言うのが第2章に載っていて、第2章の末に記載されている自慢話はまあこういうことですよね、これらの賜物とでも言いましょうか
Common Lispの実行環境はコマンドラインみたいなREPL(Read Eval Print Loop)で、そこではファイルのコンパイル、関数のコンパイル等すら用意されている
さらにコンパイルした関数を読み込んで実行することもできる
例えばC言語でのコンパイラ(ここで言うコンパイラと言うのはリンカなどを含めたものを言いたいのだけどどう言ったらいいかよくわかんないので、翻訳と言うよりはC言語においての提供されている一連の機能のことを指したい)の役割のみじゃなくてOS的なものまで提供されている
C言語で書いたプログラムは翻訳して実行ファイルを生成したとして、それを実行するのはOSの役割なのだけど、Common Lispの場合は実行もCommon Lispが請け負っている
だから実行時に介入できるような様々な機能が提供されている
と言うのが第2章に載っていて、第2章の末に記載されている自慢話はまあこういうことですよね、これらの賜物とでも言いましょうか
実践common lisp第18章
ここにも書いてある通りformatには信者もいればアンチもいると言う意見には賛成
初っ端、載っている例をどう捉えるかによって意見が別れると思う
一行で簡潔に記述できると感じるかわかりづらいと感じるかは人それぞれ
文字列整形で正規表現並の機能を提供しようとしているわけで、それを負担と感じる人の存在は否定できない
と、言うわけでCommon Lispで文字列を整形する場合はformat関数の第一引数にnilを渡すことで実現できると言うことを覚えておきましょう
初っ端、載っている例をどう捉えるかによって意見が別れると思う
一行で簡潔に記述できると感じるかわかりづらいと感じるかは人それぞれ
文字列整形で正規表現並の機能を提供しようとしているわけで、それを負担と感じる人の存在は否定できない
と、言うわけでCommon Lispで文字列を整形する場合はformat関数の第一引数にnilを渡すことで実現できると言うことを覚えておきましょう
実践common lisp第17章
クラスの定義の仕方と継承についてですね
ここで紹介されているクラスの定義はC++的に言うとパブリックなメンバ変数の記述の仕方に相当している
そして継承ですが、CLOSでの継承はメンバ関数に相当する実装は継承できず、あくまでメンバ変数のみの継承にとどまっています
CLOSでは、実装はあくまでdefmethodの役目、defclassはデータ型としての役割を受け持っていると言うことで、それぞれ一つの役割を担当しているところが他のプログラミング言語でのOOPの実現方法と異なるところです
他の言語でOOPを実装する際はdefmethodとdefclassの考え方に基づいて進めると幸せになれると思います
ここで紹介されているクラスの定義はC++的に言うとパブリックなメンバ変数の記述の仕方に相当している
そして継承ですが、CLOSでの継承はメンバ関数に相当する実装は継承できず、あくまでメンバ変数のみの継承にとどまっています
CLOSでは、実装はあくまでdefmethodの役目、defclassはデータ型としての役割を受け持っていると言うことで、それぞれ一つの役割を担当しているところが他のプログラミング言語でのOOPの実現方法と異なるところです
他の言語でOOPを実装する際はdefmethodとdefclassの考え方に基づいて進めると幸せになれると思います
2016年9月26日
実践common lisp第16章
Common LispにおけるOOPへの回答がCLOSですね
一般的に言われているOOPの機能で取り上げられることが多いものは、継承、カブセル化あたりだと思うんですけどCLOSはどっちもサポートが薄いですね
このあたりが特徴的と言うところかもしれませんけど、本来のOOPとしての要求は別に継承でもカプセル化でもないはずなんだよね
いろいろ紆余曲折あっての歴史的な経緯によって継承とカプセル化が取り上げられることが多いのだけど両方共実はイマイチ使い道がないって言うかまあ別に不要って言うか
継承については、実装の継承って言うのはCLOSにおいてはまったく無視されていて、インターフェイスの継承についてのみサポートされている点が素晴らしいところですね
カプセル化なんて別にOOP使わなくてもクロージャで解決できる話でさ、C#とかC++がOOPでやっちゃったから話がややこしくなっちゃってるだけなんじゃないかなと思ってます
頻繁に目にするOOPに対する誤解みたいなものもこのカプセル化を勘違いしちゃってる点が多いと思うし
ここに一発で言い表している素晴らしい表現があるので引用させてもらうと
”オブジェクト指向の基本的なアイデアは、データ型を定義してからそのデータ型に操作を連携させることがプログラムを体系化する強力な手法になるというものだ”
と言うのはまったくその通りで、データ型に対する操作なんだよね、本当にやりたいことって
と言うことで総称関数と言うややこしそうな面倒な名称のものがここに登場します
要は様々なデータ型に対して同じ名称でそのデータ型に対する操作が定義できるというだけなんだけどね
と、言うわけでこのあたりで例示させてもらうと、よく一般的にはこういうコードを見かけるのだけど
(defclass beatles() ((name :initarg :name :accessor beatles-name)))
(let ((members (list (make-instance 'beatles :name "John Lennon")
(make-instance 'beatles :name "Paul McCartney")
(make-instance 'beatles :name "George Harrison"))))
(mapcar (lambda(m) (format t "hi, my name is ~A~%" (beatles-name m))) members))
一般的に言われているOOPの機能で取り上げられることが多いものは、継承、カブセル化あたりだと思うんですけどCLOSはどっちもサポートが薄いですね
このあたりが特徴的と言うところかもしれませんけど、本来のOOPとしての要求は別に継承でもカプセル化でもないはずなんだよね
いろいろ紆余曲折あっての歴史的な経緯によって継承とカプセル化が取り上げられることが多いのだけど両方共実はイマイチ使い道がないって言うかまあ別に不要って言うか
継承については、実装の継承って言うのはCLOSにおいてはまったく無視されていて、インターフェイスの継承についてのみサポートされている点が素晴らしいところですね
カプセル化なんて別にOOP使わなくてもクロージャで解決できる話でさ、C#とかC++がOOPでやっちゃったから話がややこしくなっちゃってるだけなんじゃないかなと思ってます
頻繁に目にするOOPに対する誤解みたいなものもこのカプセル化を勘違いしちゃってる点が多いと思うし
ここに一発で言い表している素晴らしい表現があるので引用させてもらうと
”オブジェクト指向の基本的なアイデアは、データ型を定義してからそのデータ型に操作を連携させることがプログラムを体系化する強力な手法になるというものだ”
と言うのはまったくその通りで、データ型に対する操作なんだよね、本当にやりたいことって
と言うことで総称関数と言うややこしそうな面倒な名称のものがここに登場します
要は様々なデータ型に対して同じ名称でそのデータ型に対する操作が定義できるというだけなんだけどね
と、言うわけでこのあたりで例示させてもらうと、よく一般的にはこういうコードを見かけるのだけど
(defclass beatles() ((name :initarg :name :accessor beatles-name)))
(let ((members (list (make-instance 'beatles :name "John Lennon")
(make-instance 'beatles :name "Paul McCartney")
(make-instance 'beatles :name "George Harrison"))))
(mapcar (lambda(m) (format t "hi, my name is ~A~%" (beatles-name m))) members))
これって悪い例なんですよね
クラスのインスタンスそれぞれに名前を設定して、メンバー関数で名前を呼び出すとかっていうものですね
これって使い方が圧倒的に間違っていると言うか、全然問題が解決されていないって言うかまあそんな感じで、こんなことするためにわざわざクラスとか用意されてないんだよね
よく目にする解決策だとdefmethodとか言う謎の機能がまったく不要だ
じゃあどういうふうにするといいかと言うとこんな感じになる
(defclass john-lennon() ())
(defclass paul-mccartney() ())
(defclass george-harrison() ())
(defmethod get-name((m john-lennon)) "John Lennon")
(defmethod get-name((m paul-mccartney)) "Paul McCartney")
(defmethod get-name((m george-harrison)) "George Harrison")
(let ((members (list (make-instance 'john-lennon)
(make-instance 'paul-mccartney)
(make-instance 'george-harrison))))
(mapcar (lambda(m) (format t "hi, my name is ~A~%" (get-name m))) members))
まず、必要なだけデータ型を定義する
ここでは三人分のデータ型を定義する
そしてそれぞれのデータ型に対して操作を個別に定義する
悪い例の方だとインスタンスを生成する時にどんな名前かわかっていないといけないわけよ
それって至極面倒なことなんでそうなるとこんな感じの補助関数が必要になってくる
(defun make-john-lennon-instance()
(make-instance 'beatles :name "John Lennon"))
そしてmembersリストを生成する段階でmake-john-lennon-instance関数を呼び出すって言うのは本当に本末転倒と言うかなにやってるんだかわかったもんじゃない
素直にjohn lennonインスタンスの名前はJohn Lennonだということで話は簡単になると言う素晴らしい解決策がdefclassとdefmethodを利用することによって可能となる素晴らしいCLOS
さらに、この例で言うと継承もカプセル化も利用してない
別に継承もカプセル化も利用しなくてもOOPを十分、存分に利用できるということが分かるともっとプログラミングが楽しくなると思うのだけど
だから各インスタンにいちいち名前とか設定するなんてやめて総称関数的なやり方で表現できるように努めると幸せになれるんじゃないかなと思います
参考までにJavaScriptで同等のコードを掲載します
function beatles(name){
this.getname = function(){
return name;
};
}
[new beatles("John Lennon"), new beatles("Paul McCartney"), new beatles("George Harrison")].forEach(function(a){
console.log("Hi, my name is " + a.getname());
});
参考までにJavaScriptで同等のコードを掲載します
function beatles(name){
this.getname = function(){
return name;
};
}
[new beatles("John Lennon"), new beatles("Paul McCartney"), new beatles("George Harrison")].forEach(function(a){
console.log("Hi, my name is " + a.getname());
});
function johnlennon(){
this.getname = function(){
return "John Lennon";
};
}
function paulmccartney(){
this.getname = function(){
return "Paul McCartney";
};
}
function georgeharrison(){
this.getname = function(){
return "George Harrison";
};
}
[new johnlennon(), new paulmccartney(), new georgeharrison()].forEach(function(a){
console.log("Hi, my name is " + a.getname());
});
2016年9月23日
実践common lisp第15章
ポータブルなコードの書き方が載っています
ディレクトリ列挙するだけでこれだけ面倒なんだって言う感じ
.Net FrameworkでC#とかやってる人にとってはなんじゃこりゃって思うんだろうな
ディレクトリ列挙するだけでこれだけ面倒なんだって言う感じ
.Net FrameworkでC#とかやってる人にとってはなんじゃこりゃって思うんだろうな
実践common lisp第14章
ここでの注目はやっぱりファイル名の扱いについてですね
このあたりの混沌とした感じがLispの古さや抽象度の高さを表しているなと
Lispはめちゃくちゃ古い言語だから、今どきだったら普通のものが取り入れられていないっていうところが本当に新鮮に感じますよね
この微妙に不便なところを体感して、やっぱり進化して作業がしやすくなったなと感謝する機会ですね
このあたりの混沌とした感じがLispの古さや抽象度の高さを表しているなと
Lispはめちゃくちゃ古い言語だから、今どきだったら普通のものが取り入れられていないっていうところが本当に新鮮に感じますよね
この微妙に不便なところを体感して、やっぱり進化して作業がしやすくなったなと感謝する機会ですね
登録:
投稿 (Atom)