はてなブログ1周年おめでとう! id:hatenablog
腐女子のためのlisp入門 #2
こんばんは。第二回腐lispの時間です。
今回はループ処理と高階関数について説明します。そして最後にfizzbuzz問題のアレンジ版を作ってみますよ。
ループ
一番単純なループはwhileです。書き方はこちら。
(while 条件式
フォーム1
フォーム2
)
whileを使って、1からlimitまでのリストを作る関数を作ってみます。
fizzbuzzなので1から15までのリストを作ります。
(defun generate-list (limit) (let ((i 1) ret) (while (<= i limit) (setq ret (cons i ret)) (setq i (1+ i))) (reverse ret))) (generate-list 15) ; (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
高階関数
高階関数というのは引数に関数をとれたり、関数を戻り値にできる関数のことです。
まぁピンとこないかもしれませんが、次のように理解してもあんまり問題ないと思います。
(mapcar '攻め関数 '受けリスト)
mapcar関数は受けリストの各要素について攻め関数を呼び出してリストを返します。
つまり×の役割といえますね!
では早速、さきほどの受けリストを使ってfizzbuzz関数を適用させてみます。
ただ、普通のfizzbuzzでは面白くないので、
ここでは3と5の倍数の時にホモになって15の倍数の時にほられるという仕様にします。
(defun yaranaika (num) (cond ((= (% num 15) 0) "アッー!") ((= (% num 3) 0) "やらないか") ((= (% num 5) 0) "ウホッ!いい男") (t num))) (defun fizzbuzz (limit) (mapcar 'yaranaika (generate-list limit))) (fizzbuzz 15)
結果は以下のようになります。
(1 2 "やらないか" 4 "ウホッ!いい男" "やらないか" 7 8 "やらないか" "ウホッ!いい男" 11 "やらないか" 13 14 "アッー!")
台詞は自由に変えるといいでしょう。もはや全くfizzbuzzではありませんがそれは気にしないでください。
# 連載と銘打っていますが実はほぼノープランなので、またネタを思いついたら書くことにします。
おわり
腐女子のためのlisp入門 #1
腐lispの第一回です。いきなりですが、関数定義についての話をします。
かけざん関数をつくる
というわけで、早速、みなさんにはおなじみのあのかけざんをする関数をつくっちゃいましょう☆★☆★☆
(defun × (seme uke) (message "%s × %s" seme uke)) (× 'kusakabe 'sajo) ; "kusakabe × sajo"と表示される
簡単ですね。
上のコードはEmacsのscratchバッファに書いてすぐに試すことができるので、好きなだけかけざんしましょう。
括弧について
最初は括弧が多くて戸惑うかもしれません。でも慣れればかわいく見えてくるので大丈夫です。
それでも信じられないという方は、開き括弧"("を攻め、閉じ括弧")"を受けだと思って、もう一度上のコードを見てください。
どうですか???括弧が愛おしく感じてきませんか???
そしていつの間にか")"が健気な美少年に見えてくるはずです。
多くの障壁を抱えつつも強くひきつけあう二人の愛に感動し涙するかもしれません。
# けれど、障害のない愛()は空っぽ(nil)と評価されてしまうのだから皮肉ですよね。
ついてこられたあなたはもう元には戻れません。おとなしくlisperの道をすすみましょう。
最後は私の妄想が暴走してしまう感じになってしまいました。ごめんなさい。
次回もこんな感じで書きたいこと書くつもりです。では第二回をお楽しみに。
おわり
腐女子のためのlisp入門 #0
はじめに
ネットにlispの入門記事はたくさんあるのですが、腐女子のために書かれた記事はまだなかったので思いつきで始めてみました。lisp入門と書きましたが、EmacsLispを扱うことにします。Schemeでも書くかもしれません。まぁネタなので適当です。
腐女子がlispを勉強するべきたった一つの理由
id:shim0mura氏のblogの2011年テキストエディタ界の動向まとめと、来年次のvimエディタ普及に向けた対策資料という記事に衝撃的な記述がありました。
emacsユーザーは今、ホモに興味がある。
elispでカップリングするcoupling.el
この記事はEmacs Advent Calendar jp: 2011 の 18 日目です。17 日目は、@masutakaさんの私の.emacsからピックアップした設定3つ #EmacsAdventJP [Emacs]でした。
こんばんは。Emacs(腐)女子のおきゃんです。今年も皆さんが役立つTipsをあげてくださっている中、こんなネタ記事しか書けず大変申し訳ない気分でいっぱいですがどうか箸休め的な感じで見ていってください。
coupling.elについて
ということで、coupling.elの紹介です。
coupling.elは、指定したディレクトリの拡張子を取り除いたファイル名のリストから、ランダムにカップリングを生成してミニバッファーに表示するelispです。
意外な組み合わせが、アイディアを生み出すヒントになるかもしれません!
# タイトルはelispで〜とありますが、デフォルトをelispのディレクトリにしているだけでどこでもありです。
インストール
使う人がいるとは思えませんが、インストール方法です。
https://gist.github.com/1493361からダウンロードし、ロードパスの通ったところに置いて、init.elなり.emacsなりに以下のように記述します。
coupling-source-directoryは適当に好きなディレクトリ名を設定してください。デフォルトは"~/.emacs.d/elisp"になっています。
;; coupling (require 'coupling) (setq coupling-source-directory "~/.emacs.d/elisp/test") ; 任意のディレクトリ (global-set-key (kbd "C-c b") 'coupling-from-directory) ;; key-chordインストール済みの場合 (key-chord-define-global "bl" 'coupling-from-directory)
これで、key-chordを使っている人なら、blと打つだけで次々とミニバッファーにカップリングが生成される!!!素敵!!!!!
経緯と今後の方針
elispで掛け算するのが趣味なので、自動的に生成できたら面白いかなと思って作りました。なので、ファイル名でカップリングするというちょっと気持ち悪いことをしています。が、気が向いたら、ディレクトリを複数指定できるようにしたりとか、マンガやアニメキャラのリストを用意してそこから選べるようにしたりとかできたら楽しいかなとか考えています。
明日は@myuheさんの sheephead: Stay hungry Stay foolishです。では引き続きEmacs Advent Calendar:2011をお楽しみください。
reverse
テスト。
(define A "abcde") (define B "1234") (define rev-list (lambda (list new-list) (cond ((null? list) new-list) (else (rev-list (cdr list) (cons (car list) new-list)))))) (define rev (lambda (str) (cond ((null? str) null) (else (list->string (rev-list (string->list str) '())))))) (rev (string-append (rev A) (rev B))) ;1234abcde
reverse
例の30minプログラミングから。
問題1
文字列 A と B があり、C を A+B とする。文字列を逆順にする関数 rev() をつかって、
rev(rev(A) + rev(B)) という操作をすると結果はどうなるか。
まず予想したあと、実際にプログラムを書いて確かめよ。
例: A="abcde"、B="1234"、C="abcde1234"
予想はC="1234abcde"
Schemeで書きました。
(define A "abcde") (define B "1234") (define rev-list (lambda (list new-list) (cond ((null? list) new-list) (else (rev-list (cdr list) (cons (car list) new-list)))))) (define rev (lambda (str) (cond ((null? str) null) (else (list->string (rev-list (string->list str) '())))))) (rev (string-append (rev A) (rev B))) ;1234abcde
# ハイライトされてないけど…
実行結果
http://ideone.com/oXJPh
# ideoneだとwriteしないとoutputに出なかったのでちょっと変えています。
rev()を使ってswapができますよという話でした。でも再帰向いてないですよね。
あとこの時の勉強会で、何割のプログラマが再帰を使ったプログラムが書けるかという話になり、9割、3割、1割、1%という意見が出ました。さあどれくらいいるでしょう。