2016年11月28日

codeiqの広告

頻繁に表示されるcodeiqの広告についてなんですけど
なんかphpとか言うクズ言語のソースが10行程度表示されてましてこれ実行するとどうなるかだってさ
ってかさ、これってphpとか言うクズ言語が使えるかどうかなわけじゃないですか
それって必要なんですかね
そのあたりがイマイチ理解できないところなんですよね
世の中として求められているものがphpとか言うクズ言語の言語仕様を把握しているかどうかってことなわけでさ、それって求職者に対して望むべき能力なんですかね
と言うか、この質問に対していわゆるドヤ顔で鼻息荒く答えはなになにですって答えられたとしたらですけど、そんな人採用対象として失格じゃないでしょうか
ってか、失格対象としますけどね、って思うんだけど

2016年11月9日

センスについて

「プログラムはセンスで書く。インスピレーションで書く。」とか「根性で書く」や「おまじない」等の様な対話について思うこと
こういうことを言う人は、相手に対して説明できるような能力を有していないと言うこと
いわゆる職人とか言われているような集団において、技を盗めだとかそういうことを言うのも近いものがある
要は説明できない、相手が理解できるような説明をすることができないので、やれ「根性」だ「盗め」だ言いたがる、挙句「おまじない」だってさ
自分が好んで参考にする書籍でこのような表現を使っているものが皆無であることの理由は、それら書籍の著者はプログラムについて深い理解をし、それを相手に伝えることができる能力を有しているから
それら書籍においては決して「センス」やら「インスピレーション」やら「根性」なんて単語は登場しない
もし仮に現在「根性」や「おまじない」なんて言ってお茶を濁しているのだったら、それはそのことについて理解が不足している証拠を提示していることにほかならない
その場合は素直に「分からない」「知らない」と言ったほうがより好意的に受け取ってもらえると思う
そこでお互い、説明能力の有無の是非については不問にするとより良いと思うのだが質問時の場合、質問者と回答者の立場の違いによりなかなかそういうわけにもいかないのが問題
質問者が回答者に対して説明能力が無いと正確に認識してくれればいいのだけど、質問者が回答者に対して能力が無いと評価するのが問題になる
いわゆるプログラムの能力の有無と説明能力の有無を切り離せることが必要なのだけど、能力があると当然説明能力も有していることになるところがマズイんだよね
あと、たまに素人に対してあいつは説明能力を有していると勘違いされてさ、肝心のプログラムの能力が乏しい場合があるのがこれまた問題なんじゃないかなと
       |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ファイルの読み書きを実際に行うことになるんじゃないかなと思います

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を読みこめば無事利用可能になる

実践common lisp第22章

loopも初心者殺しの側面があるのだけど、反面非常に強力な側面もあるんだよね
このloopの理解にもやっぱりソースコード生成の考え方ができるかどうかで理解の仕方も変わってくるような気がするんだけど
あと、まさかこれだけ高機能だと非常に非効率な実行になるとか心配する人もいるのかな
全然非効率じゃないのだけどね
これだけ高度に抽象化されたコードを記述でき、さらに効率的な実行も行えると言うことをわかって欲しいな
そしてさらにスゴイところはこんなことが誰でも可能になるような懐の深さって言うんですかね、Common Lispってやっぱりスゴイな

実践common lisp第21章

よくある名前空間の話

実践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してる人いたな、酷かったな
フロー制御はなんて言うか層が違う部分を構築する際に必要になるんじゃないかな
フレームワーク的な層とアプリケーション層と分けて作る場合に必要というかそんな気がする
多値もあんまり使わないかな

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第18章

ここにも書いてある通りformatには信者もいればアンチもいると言う意見には賛成
初っ端、載っている例をどう捉えるかによって意見が別れると思う
一行で簡潔に記述できると感じるかわかりづらいと感じるかは人それぞれ
文字列整形で正規表現並の機能を提供しようとしているわけで、それを負担と感じる人の存在は否定できない
と、言うわけでCommon Lispで文字列を整形する場合はformat関数の第一引数にnilを渡すことで実現できると言うことを覚えておきましょう

実践common lisp第17章

クラスの定義の仕方と継承についてですね
ここで紹介されているクラスの定義は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))
これって悪い例なんですよね
クラスのインスタンスそれぞれに名前を設定して、メンバー関数で名前を呼び出すとかっていうものですね
これって使い方が圧倒的に間違っていると言うか、全然問題が解決されていないって言うかまあそんな感じで、こんなことするためにわざわざクラスとか用意されてないんだよね
よく目にする解決策だと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());
});

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#とかやってる人にとってはなんじゃこりゃって思うんだろうな

実践common lisp第14章

ここでの注目はやっぱりファイル名の扱いについてですね
このあたりの混沌とした感じがLispの古さや抽象度の高さを表しているなと
Lispはめちゃくちゃ古い言語だから、今どきだったら普通のものが取り入れられていないっていうところが本当に新鮮に感じますよね
この微妙に不便なところを体感して、やっぱり進化して作業がしやすくなったなと感謝する機会ですね

実践common lisp第13章

リスト操作について章が一つ割かれている理由は、Lispのソースコードはリストデータとして扱えるから
リストのデータが自在に操れると言うことは、Lispのソースコードを自在に生成できることになるので、マクロの理解が進むはず
だから、Lispでリストの操作方法を覚える目的としては、なにかの実装でリスト構造を利用すると言うよりはマクロでソースコードを生成するためというほうがより理にかなっているかも
実装で実際利用するデータ構造において、リスト構造って有利になる機会があんまりないんだよね
だからここで説明されている内容は実装ではあまりお目にかからないかも
でもマクロではお世話になることになると思う

2016年9月22日

実践common lisp第12章

ちなみにcarは
Contents of the Address part of Register numberの略らしい
cdrは
Contents of the Decrements part of Register numberの略らしい
だったらcadrは
Contents of the Address Decrements part of Register numberと言うことになり、cddddrは
Contents of the Decrements Decrements Decrements Decrements part of Register numberになるのかな

Common Lispにはリストを操作する方法が沢山用意されているのでしばらく戸惑うようになると思う
reduce,mapcarを頻繁に使うことになる
mapcarには複数のリストが渡せる
Haskellにあるzipは(mapcar #'cons list0 list1)みたいに記述できる

Common Lispが関数型もできる言語というのは、この破壊的な操作が用意されているところに現れている

2016年9月21日

実践common lisp第11章

Lispにも配列がありますよ、安心してください
高階関数で色々操作することもできます
注意点としては、破壊、非破壊がある点ですね
sortする場合は例にあるとおり真似しましょう
(setf my-sequence (sort my-sequence #'string<))

実践common lisp第10章

分数があるところが珍しい
文字列は文字の配列
文字比較、文字列比較の演算が用意されている
この章については特に触れることがないかな

2016年9月19日

実践common lisp第9章

これも非常に良いマクロの例ですね
今までのマクロの例題とは一味違う、本当にマクロでしかできない、かつ利用しがいがあるところが素晴らしい例題
ここまで良質の例題ってなかなか無いような
なにが良いかって言うとここに書いてあることってマクロ以外で実際やろうと思うと本当に面倒なんだもん
マクロが無い環境でやろうと思うと、いちいちコピペとか駆使してっていうバカバカしいことを本当にやらないといけなくて、非常に原始的な、原始人なんじゃないかって思えてくることがマクロを使うことによって素晴らしい解決策が得られる点が本当に偉大だと思う

実践common lisp第8章

書き写すしかなかったソースコードを自動で生成してくれるものと言うことかな
ソースコードを生成するプログラムを作る、作れる、素晴らしい
マクロ展開時と言うのは、プリプロセスとか言うこともある
defunとdefmacroはソックリだ
その違いを一つだけ付け加えるなら、defunは引数が評価されるが、defmacroは引数を評価しない
コンパイル時、実行時と言うのを意識できるといい
バッククオート、カンマはdefmacro内だけで利用できるわけではない、好きな時に利用できる
だから便利ならどんどん使うべきだ
「漏れをふさぐ」は結構重要、今、分からなくてもマクロを利用するなら必ず必要になる
そんな面倒ならマクロイラネって言うのは本当に勿体ないのだけどこれは仕方がない
with-gensymsはめちゃくちゃ重要だと思う、マクロ使うなら結構な頻度で利用することになると思う
これこそマクロって感じがする
と、言うのは漏れをふさぐで登場するgensymって言うのは結構頻繁に記述しないといけないわけよ
そうなるとイチイチletでgensymってやるのって本当に面倒なんだよ
だからこそのソースコード生成マクロwith-gensymsってめちゃくちゃ理にかなっている

2016年9月16日

実践common lisp第7章

いきなりわけわかんない、いつものLisperウザいって言う形容詞がぴったりの文章が始まりますけどここは一つ深呼吸して心を落ち着けて欲しいところですね
ここでは非常に重要なことを言っているんですよね
「コアに標準ライブラリを追加したもの」って言う点なんですけど、理解されていない方が多いと感じるのがこれで、言語としての機能とライブラリでの機能とごっちゃになっちゃってるんですよ
だからLispって標準ライブラリが昨今の開発環境の中ではそうとう貧相だから敬遠されているのですけど、Common Lispって別に標準ライブラリで勝負していないんですよね
標準ライブラリを含めない言語のコア機能だけで見た時、Common Lispは素晴らしいものだと言うことを理解してほしいです
残りで紹介しているものは本当に些細な例です
ここでなんじゃこりゃって思わないでほしいな
って言うか改めてここを読み返してみても酷いと思うわ
whenが標準で用意されていないとでも見受けられるこの部分は酷いよね
でも、これは逆にこういうことも自分で思い通りにすることができると言う、是非前向きに捉えていただきたいと思います
しかも追い打ちをかけるようにwhenはこうやってdefmacroで実装できるって、これ完全に追い打ちの泣き面に蜂以外のなにものでもない
この時点でこんなもん提示されて分かるわけ無いんだよね
ちなみにソースコード上でのカンマが区切り文字に見えなくなったらかなり達者になったと思ってもいいんじゃないでしょうか
ちなみにこのwhenについて説明すると
(defmacro when (condition &rest body)
  `(if ,condition (progn ,@body)))
と言うマクロは、こんなソースコード
(when (spam-p current-message)
  (file-in-spam-folder current-message)
  (update-spam-database current-message))
を、こう
(if (spam-p current-message)
  (progn
    (file-in-spam-folder current-message)
    (update-spam-database current-message)))
変形させる
まずバッククオートで囲まれているものはそのまま出力されるので
ifが出力される
次のconditionはカンマが付いているので、置き換えられる
置き換え対象はwhenマクロ呼び出し時の第一引数である(spam-p current-message)
そして次のprognもそのまま出力される
最後に残ったbodyには,@が付いているので第二引数以降のもの、つまりリストが展開されて出力される
そうすることによって自分でifなになにprognなになにって言うのを自分で入力したものとまったく同じものを得ることができるというわけですね

実践common lisp第6章

個人的にはダイナミック変数っているの?って思うのだけど
レキシカル変数のみでなんとかできるんじゃないかなって言うかそんな気がするのだが
と、言う話は置いておいて、ここでも登場するletですけど、これも変数を宣言するための関数って言うか、特殊オペレータなんですよね
これも4章の流れを引き継いでいるLispの素晴らしいところですね
あと、これ非常に使いやすい素晴らしい機能の隠すってやつですね、これって良いですね
匿名関数と非常に相性がいいと思いますね
今はどうか知らないけどC#ってこれが無理だからめちゃくちゃ面倒だった覚えがある
そしてクロージャですね
なんとなく変数に対して印象持ってるのがあるんですけど、スコープ抜けると破棄されるって言うやつ、あるじゃないですか
あれってそもそも変なんですよ、理想的には変数が破棄されるタイミングって言うのはスコープとは無関係で、不要になったら破棄されるべきものなんですよね
でも、コンパイラ作ったり、実行環境、要はGCなんですけどそういうのを用意するのが嫌だったからスコープ抜けたら破棄するってなってるんですよね
それの是非は置いておいてですね、変数は不要になったら破棄、これがLispに特有と言うわけじゃないですけどクロージャの特徴ですよね、これって
ダイナミック変数って別に使わなくてもそんなに不便無い気がするのだけど、定数も別にいらないんじゃないかな、使わないよね?
そして代入ですね、これも4章のやつね、代入するのも関数って言う素晴らしい一貫性がやっぱり何度言っても言い足りないくらい素晴らしいLispですね

2016年9月15日

実践common lisp第5章

関数ですね
defunですね
defunってなんなのかってことなんですけど、関数なんですよ、繰り返しますけど関数なんですよ
関数を定義する関数ってことなんですよね
でも本当はdefunはマクロなんですけどね
マクロについてまだ登場してないんで説明しにくいんですけど、関数を定義することも言語の機能の一部なんですよ
これがLispがすごいところでして、とにかく関数ばっかり
他の言語と圧倒的に違うところですね
Lispでは予約語が圧倒的にすくなくてですね、前章であったとおりなんでもかんでもあの形式ですまそうとしてるんで、こういうことになっちゃってるんですよ
他の言語だと関数定義はこれこれこういう風な文法で記述する、なになにはこの書式でやるっていう方法を取ってまして、それが要は高級言語ってことなんですけど、Lispはそのあたりは非常に低級な言語なんですよ
なんでもかんでも前章でのとおり記述できるようにしていますんで
んで、なんでこんなことになっているかってことなんですけど、今後登場するであろうことを先に言っておくと、関数定義すら自動生成しようって魂胆があるんですよね
早口言葉みたいですけど、関数定義をする関数とか作ることが可能になるんですよ
だからこんなことになっています
パラメータについてはここに書いてある通りです、そのままです
高階関数、匿名関数についてもこのままです

ついでなんで書いておきますけど、Lispと言うかCommon Lispは関数型じゃないっていう記述を見かけます
なんとなくLispは関数型って言う印象が強いっぽいのだけど、Lispでは関数型って言うのはSchemeのことが多くて、Common Lispは関数型もできるって言う立ち位置です
Schemeはあんまり詳しくない(SICPで扱ったことがあるだけ)から例題とか正確に記述できないのだけど、Common Lispは高階関数はfuncallでイチイチ実行しないといけないんだよね
例えばある関数に匿名関数を渡したとして、その関数を呼び出すためには、Schemeならそのまま直接引数を関数として扱えるのだけど、Common Lispの場合はfuncall、applyで呼び出さないといけない
これは前に説明した通り関数定義テーブルと変数定義テーブルが別になっているからなんだよね

defunなんですけど、気にしなければどうでもいいことなのかもしれませんけどね、マクロなんで関数を定義するソースコードを生成してるんですよね
気になる人は以下を実行するといいと思います
(macroexpand-1 '(defun f(a b) (+ a b)))
これを実行すると(defun f(a b) (+ a b))からどういうソースコードが生成されるかわかりますんで
で、Common Lispにおいて関数を定義しようと思うと要はこういうソースコードを描かないといけないんですよ
でもdefunって言うマクロっていうものが用意されてて、そのマクロを使うと
(defun f(a b) (+ a b))
でfが定義できるっていうことですよね

2016年9月14日

実践common lisp第4章

ここでは、とにかくこれですね
(function-name arguments*)
Lispのコンパイラが比較的簡単に作れる理由がこれ
ソースコード上はfunction-nameの部分がマクロだったり特殊オペレータだったりするのだけど、一見するとソースコード上では区別がつかないので、こう覚えてしまっても差し支えないかな
逆に、これだけ単純なんだということがわかればいいのではというくらい
他の言語みたいに文だ式だ二項だ単項だとか宣言だとかそういったことなんもなくてとにかく全部これで記述できるんだよね
あと、後々でてくるのだけど、いわゆる変数宣言も関数で表現するのがCommon Lispの素晴らしいところですね
特殊オペレーターについては、一言で言うと関数では実現できないものを特殊オペレーターとして実現していると言うこと
だけど、ソースコード上では区別する必要がない、し、わざわざ区別させないようにしたのだろう
例えば、JavaScriptだったとすると、JavaScriptだったらシンタックスは比較的緩めかもしれないけど、じゃあJavaScriptソースを入力として受け取るものを作ろうって思うと結構大変だと思うんだよね
例えば関数宣言、変数宣言、代入してるとか、っていうものを解析しようと思うと正規表現ではとてもじゃないけど手に負えないような代物なんですけど、Lispは相当単純にソースコードが解析できる
具体的に言うと
function f(a){
}
ってあると、まずfunctionって記述があるので次のfは関数名、aはその引数だってなるのだけど、とにかくそれが大変
対するLispはそれがない、functionって記述があるから次の単語の意味が変わるとかなくて、とにかくリストの一つ目がfunction-name、二つ目以降が引数っていうルールに一貫性があるのでパースしやすい、とにかく簡単
だからEmacsの設定にも利用されているように、そういったものには非常に利用しやすい
多分、完全に想像なんですけど、Emacsの設定ファイルってLispなんだけど、これをC言語かなんかに変換するような仕組みがあるんじゃないかなと思うんだよね
簡易のLispでそれなりの動作ができるようなものを用意しておいて、それを利用してエディタに柔軟さを持たせるわけでさ
例えばなのだけど、Apacheとかでの設定ファイルとか.htaccessとかそういうのにも使いやすいと思うんだよね、Lispの文法っていうやつは
そんでさらになんでこんなことになっているかと言うことなのだけど、読み込むのが簡単と言うことを目指したわけじゃなくて、生成が楽なことを目指したんじゃないかなと
想像してほしいのだけど、JavaScriptのソースコードを記述するプログラムを書くことがどれほど大変なことかと
逆にこれだけ単純にLispのソースコードを生成するプログラムって簡単に書けそうじゃない
マクロも特殊オペレーターもソースコード上ではまったく区別しないって言うのはソースコードを生成することが簡単になるからなわけで

2016年9月13日

実践common lisp第3章

この段階でこの章の内容を正しく理解しようとは思わないほうがいいかも
とてもじゃないけど理解できるような代物じゃないかな

先ず属性リスト、これは連想配列と似ているものですね
dic["title"] = "title"
のようなもの

formatの書式指定子でチルダが登場するところがLispっぽいところなのでこのあたりは存分に堪能しましょう

#'について、Common Lispでは名前空間が関数と変数で分かれているのでこういうものが必要になる
ここに単純にevenpと書いてしまうとそれは変数の名前空間を検索することになるのですよ
#'evenpと表記することによってevenpは関数の空間に属しているのでそちらから探してねっていうことになる
だから、evenpと言う関数と変数があっても問題ない
例えばJavaScriptなんかだと、名前空間が関数と変数でわかれていないからevenpって言う関数を定義して、さらにevenpって言う変数を定義したらevenpは変数になっちゃってevenpの関数にアクセスできなくなるわけで、どちらが良いとかじゃなくて根本的な考え方の違いでこういうことになっているところが注意点ですかね
この違いは高階関数が記述できるものでとくに違いが顕著になりますね
多分CとかC++なんかでも名前空間は別れてないんじゃないかな
C#も分かれてなくてとにかく関数、変数ごっちゃで管理して、それぞれに属性情報が付与されてそう

whereについてどうこう言っているあたりは、要はコンパイル時に判明することはコンパイル時に解決して実行時までもちこさないようにしましょうと言うことを言っている
つまりタイトルだけで検索したいときにいちいちアーティストについてとやかく言うのは無駄以外のなにものでもないと
そして普通のプログラミング言語においては、無駄でもいちいちifを動作させて、無駄と知っていてもいちいち条件分岐を実行させるのだけど、Common Lispにおいてはそんな無駄なことしなくてもいいよって言っている
厳密に言うと他のプログラミング言語でも無駄を省くことは可能なのだけど、そうするためにはいちいち条件文をソースに記述してまわらないといけないんだよね
ifで無駄な条件分岐させるか、いちいち効率的なコードを書いてまわるかのどちらか
でも、Common Lispでは標準でコード生成の仕組みが用意されているので効率的に実行できるコードをコンパイラに記述させることができるといっている
whereをマクロにすることによって、アーティストが必要なところではアーティストのみ、タイトルが必要なところではタイトルのみ検索対象とするような効率的なコードを生成することが簡単にできると言いたい
要は自慢ですね、だから訳分かんなくてもまったく気にする必要ないですけど、いつかはものにできるといいですね

実践common lisp第2章

Common Lispはとにかくオープンな技術なので、実行環境もとにかく沢山あるのですよ
そしてデファクトスタンダードが確立される程普及していないのでとりあえずここに書いてある通りのオススメを利用することが無難ですね
REPLに関してはとりあえずこういうものが利用できる程度でいいと思います
この章の最後にLispの自慢話が載っているので大きな声でへ〜と言いましょう

実践common lisp第1章

とりあえず安心してLispを使ってくれと言っているのだろうな
そして、Lisp以外のプログラミング言語は、なにかを成し遂げるための道具として利用すればいいのだけど、Lispだけはちょっと違って、何かを作るとかそういうことじゃなくて、プログラミングとはいったいなんなんだろうかと言うことが知りたいなら使うといいことがあるんじゃないかなとか、なんかひらめきそうな気がするなとかそんな類のものなんだと言いたいと思う
そして、Lispをやる場合においては他の言語の経験とか殆ど役に立たないからなにがやったことあるとか全然どうでもいいので、興味あったら読み進めましょう
例えばだけど、HaskellやるならOCamlの経験が役に立つとかErlang使うならなになにが役に立つとかそういうことが言いたいのだけど、多分どうでもいいです

2016年7月11日

google app engine dbからndbへ移行メモ

dbからndbへ移行した際に実際に変更した箇所
上がdb、下がndb
しかし、こんなにも簡単に移行できるなんて素晴らしい対策をしてくれて感謝ですよね

all
query

run
iter

str(model_instance.key())
model_instance.key.urlsafe()

db.get(key)
ndb.Key(urlsafe=key).get()

row.delete()
row.key.delete()

filter('property in', [])
filter(Model.KeyProperty.IN([]))

db.StringProperty()のmultiline削除

db.ReferenceProperty()
ndb.KeyProperty()

db.StringListProperty()
ndb.StringProperty(repeated=True)

db.LinkProperty()
ndb.StringProperty()

db.BlobPropertyにpickle.dumps({})を代入する時、db.Blobオブジェクトにして
db.Blob(pickle.dumps({}))としていたものをdb.Blobを削除してpickle.dumpsしたものをそのまま代入

order('-date')とかを
order(-Model.KeyProperty)

db.ListProperty(db.Key)
ndb.KeyProperty(repeated=True)

2016年6月29日

javascriptにあるcall,applyについて

なんでこんなものが用意されているか意味不明なんですけど、これってcommon lispのfuncall,applyと似ているのだけど、だとしたらjavascriptにcall,applyは不要って言うかそんな気がするのだけど
common lispになぜfuncall,applyが必要なのかと言うと名前空間が変数用と関数用で分かれているからで、名前空間の扱いがscheme系のjavascriptではfuncall,applyが不要なんじゃないかなと

そもそもjavascriptって言語仕様がschemeっぽいけど、schemeにもfuncall,applyってあるんですかね
少し調べてみましたがやっぱりschemeではfuncall,applyが不要なのでそもそも存在しないっぽいのだけど

しかし、call,applyとは直接関係ないけど、この件でjavascriptのことを検索してたけど、出てくるもの、酷いものが多いな
クラス的と言うかオブジェクト指向の使い方の勘違い方も酷い例が多くて、これら記事を見てjavascriptで一歩進んだプログラムを書いてみたいな、なんて思ってる人達が混乱すると思うのだけど
混乱するって言うか、故意に不用意にプログラムが複雑化するだけで、ややこしくなるだけで、良いことなんてないのだけど、こういう複雑で理解しにくいプログラムが書けるって一歩上達したとか思っちゃうのかな
実際は全然上達してなくて迷惑なだけなんだけどな

2016年6月22日

Pythonでハマった件

変数のスコープでハマった

例えばこんな感じのコードで
row = #データベースから一行取得したもの---1
entrants = #データベースから複数行取得したもの
entrantnames = [row.name for row in entrants]
#とすると1のrowが上書きされてしまう

rowがリスト内包表記内のみで有効な変数だと思ったら、リスト内包表記のその側の変数を上書すると考えもしずハマってしまった
Lispのようにブロック毎に変数のテーブルが生成されるのかと勝手に勘違いしてしまった
まあ後から冷静に考えたら1のrowはもっと後で利用するんで、1の文自体をもっと後に、今回は上書きされてしまったリスト内包表記の後に記述するべきで、そうすれば変な上書き問題も発生しなかったのかなと思います
やっぱり変数は利用する直前で記述するべきですね

2016年6月2日

HyperDev

fog creekからHyperDevと言うWebアプリが発表されています

https://hyperdev.com/about/

内容はほぼGoogle App Engine、Windows AzurでPaaSって言うんですかね、ウェブサーバーとかOSとかまったく意識しなくてもいいって言うやつね
って言うか内容はほぼApp Engineなんだが
オンラインでソースコードが記述できるんで、App Engineとの違いはデプロイしなくてもいいっていうところかな
そんでもデプロイしてでもローカルで開発したいような気もしないでもないけど
あと、サンプルを少しだけみただけなんだけど、永続化がいまいちわかんなかったって言うかグローバルオブジェクトがそのまま残るみたいでして、これがうまい事クエリとかできるんだったら結構面白いかも
データベースとか意識しないでORマッパーとかもイチイチ意識しなくてデータベースがオブジェクトとして扱えるみたいで、LINQみたいなものがあればなおいいんじゃないかなと思った
データベースを激しく利用しないけど、少しだけ永続化は必要って言う場合には最適だと思うけど、データ量が多くなってきた時にどうなるかはちょっとわからないかな、未知数
まあ、なんかデータベースの途中から切り出すような操作は絶対用意されていると思うんだけど

あとこういうのを「full-stack web apps」と言うんだと言うことが分かった

2016年1月15日

AWK基礎

$0 行全て
$1,$2... 空白、タブ区切りの「欄」
パターン {アクション}の組み合わせ
基本入力行1行ずつ走査する、パターンに適合する行に対してアクションを行う
パターン、アクションどちらか省略できる
$ awk 'プログラム' 入力ファイル群
$ awk -f programfile 入力ファイル群
数と文字列 二つの型のみ
{ pring $1,$3} 特定の欄の印字
1行読みその行を欄に分解する

NF 欄の数
{print NF, $1, $NF} 欄数、最初と最後の欄を印字

NR 行番号

論理演算
&& || !

制御文
if else while for

配列
名前[添字] = 123

コメント
#行末まで

パターン

入力を読み込む前に実行
複数記述できる
BEGIN

すべての入力を読み終えた後実行
複数記述できる
END

比較演算子
比較は文字列にも使える
<
<=
==
!=
>=
>
~文字列照合
!~文字列照合

/正規表現/

式 ~ /正規表現/

式 !~ /正規表現/

正規表現
超文字
\ ^ $ . [] | () * + ?

エスケープ・シーケンス
\b
\f
\n
\r
\t
\ddd 8進数
\c cそのもの

範囲指定
NR==10, NR==20


アクション
print 式の並び
printf(書式, 式の並び)
if (式) 文
if (式) 文 else 文
while (式) 文
for (式; 式; 式) 文
for (変数 in 配列) 文
do 文 while (式)
break
continue
next
exit
exit 式
{ 文の並び }