狠狠撸

狠狠撸Share a Scribd company logo
Lisp tutorial for Pythonista.
Day #2 : The Basics.




                                                      Ransui Iso
                       Strategic Technology Group, X-Listing Co, Ltd.
今日はプログラムを書くための
  基礎部分を勉強します
前回の宿題は OK ですか?
いちおう Emacs + SLIME が動く前提です
なにはともあれまずは REPL
    Read, Eval, Print Loop の略語
Python なら「インタラクティブシェル」
Emacs 起動して M-x slime
META キーの設定無い人は [ESC] 押して [x]
ちゃんと起动するとこうなるはず
ぱいそん
>>>?1?+?2
>>>?x?=?1
>>>?y?=?2
>>>?z?=?x?*?y
>>>?z



りすぷ
CL?USER>?(+?1?2)
CL?USER>?(setf?x?1)
CL?USER>?(setf?y?1)
CL?USER>?(setf?z?(+?x?y))
CL?USER>?z
なんか警告出てます!


;?in:?LAMBDA?NIL
;?????(SETF?X?1)
;?==>
;???(SETQ?X?1)
;?
;?caught?WARNING:
;???undefined?variable:?X
変数は宣言してから使うのが基本
    ルーズな Python とは大違いだよ!
管理大好きスーツ族への強力なアピールポイントだ!




     警告ガン無視でも、まあ問題は無いんだが気持ち悪いので宣言しとけ。
変数宣言の前に名前空間の話
Python と似てる部分もあるし違う部分もある
Common Lisp の名前空間

●   大域は package という単位が基本になっている
     ●   概念的には Python のモジュールに近い
     ●   Python のモジュールより厳密に定義するのでお手軽じゃない

●   何も指定しない時は CL?USER がデフォルト
     ●   cl パッケージに Common Lisp の基本機能が入っている
     ●   イメージとしては
          cl?user.py の最初で
          from?cl?import?* してある感覚。

●   もちろんローカル変数とかもちゃんとあるよ
     ●   関数引数とか、 let フォームとか色々ある
     ●   レキシカルスコープなので、基本部分は Python 感覚で OK 。
パッケージ変数の宣言

●   defvar と defparameter
      ●   どちらもパッケージ変数を宣言する
      ●   宣言するときには初期値を与える

●   defvar
      ●   再初期化されない

●   defparameter
      ●   再初期化される



    パッケージ変数という用語は一般的じゃない。 Python 風な名前で呼んで
    みてるだけ。ほんとは「スペシャル変数」と言う。実は深い意味もあるん
    だけど、今は無視しちゃう。
再初期化される?されない?

●   実験してみりゃ一目瞭然
CL?USER>?(defvar?*foo*?nil)
*FOO*
CL?USER>?(defparameter?*bar*?nil)
*BAR*
CL?USER>?(setf?*foo*?1)
1
CL?USER>?(setf?*bar*?2)
2
CL?USER>?(defvar?*foo*?nil)
*FOO*
CL?USER>?*foo*
1
CL?USER>?(defparameter?*bar*?nil)
*BAR*
CL?USER>?*bar*
NIL

    パッケージが再読み込みされた時とかに挙動が変わるよ!
CL のパッケージは取扱いが面倒
なので、今のところは CL-USER 一辺倒でいく

  ライブラリとか作るようになったら
    defpackage とか使うよ
ソースをファイルに書いて実行する

●   C?x?5?2 で新フレームを開いて
●   新しいフレームで C?x?C?f?hello.lisp とかし
    て新規バッファを開く
●   コード書く
(defun?hello?(name)
??(format?t?"Hello?~a~%"?name))

(hello?"World")

●   C?x?C?s でセーブ
●   C?c?C?k で REPL 環境にコンパイルしてロード
スクリプトっぽく実行する
ぱいそん
def?hello(name):
    print("Hello?%s"?%?name)

def?main():
    hello("World")

if?__name__?==?"__main__":
    main()

りすぷ
(defun?hello?(name)
    (format?t?"Hello?~a~%"?name))

(defun?main()
    (hello?"World"))

(eval?when?(:compile?toplevel?:load?toplevel?:execute)
    (main)
    (quit))
eval?when は結構使い方が難しい。コンパイル、ロード、実行のタイミングとかは
Lisp 処理系の動きをイメージしないといけない部分があるからね。
コマンドラインから起動する

●   実は処理系依存なのよ
     ●   SBCL の場合は下のようにする



$?sbcl???script?hello.lisp
Hello?World
$
お待たせしました
プログラム作成のお時間です
すごく教科书的でアレなんですが
     「単語数え」
 プログラムを書いてみませう
慣れ親しんだ Python だと
                  あー、簡単のために単語は空白文字で区切られてるものとしてます。
def?main()
    counter?=?dict()
    for?line?in?open(sys.argv[1],?"r"):
        for?word?in?line.strip().split():
            index_word?=?word.lower()
            if?index_word?in?counter:
                counter[index_word]?+=?1
            else:
                counter[index_word]?=?1

   for?(word,?num)?in?counter.items():
       print("%20s?:?%4d"?%?(word,?num))

if?__name__?==?"__main__":
    main()




                   まぁ、瞬殺なわけです
             これを Common Lisp で書くとどうなるか
単語数えプログラムを書くために

●   ファイル入出力
     ●   ファイルのオープン
     ●   パスの操作

●   文字列操作
     ●   スペースとかのデリミタでのフィールド分解

●   数え上げ
     ●   Python で言う所の辞書の使い方

●   その他
     ●   コマンドライン引数の扱いとか
とりあえず辞書から攻め込む
  先週の復習からはじめよう
ぱいそん
d = dict()
d["Hello"] = "World"
d["Hello"] → "World"
d[1] = 2
len(d) → 2
for (key, value) in d.items():
    print("%s : %s" % (key, value))


りすぷ
(setf d (make-hash-table :test #'equal))
(setf (gethash "Hello" d) "World)
(gethash "Hello" d) → "World"
(setf (gethash 1 d) 2)
(hash-table-count d) → 2
(maphash #'(lambda (key value)
             (princ (format nil "~a : ~a~%" key value))) d)
まぁそのままでもイイんだが
もちっと親しみやすくしたいよね!
辞書っぽくアクセスするようにしてみる
(define?condition?key?error?(error)?
    ((text?:initarg?:text?:reader?text)))

(defun?make?dict?()
????(make?hash?table?:test?#'equal))

(defun?set?item?(dict?key?value)
??(setf?(gethash?key?dict)?value))

(defun?get?item?(dict?key)
??(multiple?value?bind?(value?has?key)?(gethash?key?dict)
????(if?(not?has?key)
????????(error?'key?error?:text?(format?nil?"KeyError?:?~a"?key))
????????value)))

(defun?has?key?(dict?key)
??(multiple?value?bind?(value?has?key)?(gethash?key?dict)
????(declare?(ignore?value))
????has?key))

(defun?items?(dict)
??(let?((result?nil))
????(maphash?#'(lambda?(key?value)
?????????????????(setf?result?(cons?(cons?key?value)?result)))?dict)
????result))
なんか、色々と新しいの出た!
細かい部分とか技とかは後日のお楽しみとして
  ポイントになる部分をザックリと解説
define-condition

●   Python で言う所の例外に近い
      ●   厳密には違うけどイメージとしてはこんなかんじ

class?KeyError(Exception):
    def?__init__(self,?text):
        Exception.__init__(self,?text)

                    KeyError は組み込みの例外だが、これはあくまで例だ。気にするな。




●   Common Lisp では「コンディション」と言う
      ●   「例外」と呼ばない点に注意
      ●   例外的な事象への対応以外にも色々と使える
      ●   Python の try ? except よりもずっと強力
eq, eql, equal, equalp

●       オブジェクトの比較関数だよ
         ●   オブジェクトの同一性と、値としての同値ってのは別腹
         ●   Python の is と == 演算子の違いに似てる

    –   eq     : メモリ上で同一オブジェクトかどうかをチェック

    –   eql    : 数値 or 文字の場合は同値か?それ以外は eq する

    –   equal : 値の構造が同一か?内部構造も再帰的にチェック

    –   equalp :equal よりも緩い判定。詳細は CLtL2 参照
ハッシュテーブルの生成部分

●   キーの比較関数を指定して生成してる
    (make?hash?table?:test?#'equal)

       ●   #'equal という表記は (function?equal) の略記法
       ●   略記法があるってことは、今後もいっぱいでてくる予感
       ●   ちなみに比較関数指定を省略したときは #'eql がデフォルト

●   equal を指定している訳
       ●   今回は文字列をハッシュのキーにする
       ●   文字列は (eql?"Hello"?"Hello") → nil なのだ

       ●   ちなみに純粋な文字列比較関数の string= を使ってもいい
            –   その場合、この hash-table のキーはマジで文字列限定になる。
setf ってなんだ?

●   これは違和感ないはず
(setf?x?10)


●   で、これは?
(setf?(gethash?key?dict)?value)


●   そもそも gethash 関数って
(gethash?"Hello"?dict)?→?"World"

     ●   みたいに値を取り出す関数なんじゃねーの?
     ●   つーことは、 "Hello" とか、出てきた値になんか代入すんの?
setf には値を入れる場所を指定する

●   ぶっちゃけ、ポインタです
       ●    setf は関数じゃないんです。マクロなんです。つーことは引数は
             評価される前の状態で setf に渡されてるということ
       ●    第一引数は「値を入れる場所」として解釈される

    dict
    Hello             (gethash?"Hello"?dict)
    foo
                      setf マクロと組み合わせてポインタ
    bar               として振る舞う関数には制限がある
                      詳しくは「 CLtL2 C7.2: 汎変数」を
                      参照のこと
多値関数

●   複数の値を返す関数
      ●   Python でタプル返すのとはちょっと違う。
def?foo(x):
    return?((True?if?x?%?2?else?False),?x?+?1)

(is_odd,?next)?=?foo(3)?#?OK
is_odd?=?foo(3)?????????#?is_odd は単純にタプルを指すだけ



(defun?foo(x)
    (values?
        (if?(=?(mod?x?2)?1)?t?nil)
        (+?x?1)))

(multiple?value?bind?(is_odd?next_x)?(foo?3)??; 多値を受け取るための形式
    (cons?is_odd?next_x))

(setf?is_odd?(foo?3))?????????????????????????; 最初の値だけが採用される
gethash 関数の戻り値

●   2 値の多値関数
       ●   第一値: Key に対応する Value, Key が存在しない場合は nil
       ●   第二値: Key が存在した場合は t, 存在しない場合は nil
(defvar?dict?(make?hash?table?:test?#'equal))
(setf?(gethash?"foo"?dict)?nil)

       ●   上のとき、 (gethash?"foo"?dict)?→?nil
             foo というキーが登録されていないから nil なのか?
             foo というキーに対応している値が nil なのか?

            –
(defun?has?key?(dict?key)
??(multiple?value?bind?(value?has?key)?(gethash?key?dict)
????(declare?(ignore?value))
????has?key))

       ●   多値関数の戻り値を受け取っても使わない場合は「変数使ってない
            が大丈夫か?」とコンパイラが五月蝿いので declare を使って
            「大丈夫だ。問題ない。」と伝えておくと吉。
if フォーム

●   分岐の基本なんだがイマイチな部分もある
(if?( 条件テスト式 )?(then 節 )?(else 節 ))

      ●   then 節と else 節はブロックじゃない。 1 個の式しか書けない !
           –   しょうがないので progn とか let とか使ってブロック化する。

      ●   Python で言う所の elif が無い!
           –   ネストして頑張る。
           –   cond マクロを使う。
           –   case マクロを使う。

      ●   Python と違って if は " 文 " じゃない!
           –   値を返せるよ!戻り値は then 節とか else 節の式の評価値になる
let とローカル変数

●   正確には「レキシカル変数」と言う
      ●   呼称はまあいい。要するに let の範囲内のローカル変数だ
CL?USER>?(let?((x?10)?(y?20))
???????????(print?x)
???????????(print?y)
???????????(let?((x?"Hello"))
?????????????(print?x)
?????????????(print?y)))

      ●   実行結果は予想のとおり。
      ●   let と関数定義を組み合わせたりと色々な技がある
      ●   let 以外にもレキシカル変数を取り扱うフォームは色々ある
lambda 式

●   関数の実体?無名関数
     ●   関数を使い捨てしたいときとかに良く使う
     ●   let と組み合わせてクロージャとか作ったりもする
(setf?(symbol?function?'foo)?#'(lambda?(x)?(+?x?1)))
                         ||
(defun?foo(x)?(+?x?1))


foo
value
func                (function?(lambda?(x)?(+?x?1)))
prop             Common Lisp のシンボルは値用と関数用の 2 つのスロットを持っ
                 ているのだ!こういうタイプの Lisp を Lisp-2 という。ちなみに
                 Scheme は値と関数のスロットは分かれていない Lisp-1 。
                 Python も Lisp-1 風。
文字列いってみよう!
文字列って実用では重要
でも何故か多くの Lisp 本とかでの解説は少なめ
Lisp の文字列

●   実体は文字型の 1 次元配列
     ●   Common Lisp は文字型が存在する。文字型はエンコードとは独立
          するように設計されている。が、まぁモゴモゴ…
          –   C の char とは違う。 Java の char に似た立ち位置と思えばいい。

          –   文字をリテラルとして書く場合は #A とか #Newline とか書く。

          –   Python には文字型は無い。 1 文字の文字列として扱うか、エンコードされた整数コード
                として扱っている


     ●   リテラルで書く場合は "Hello?World" のようにダブルクォート
          で囲んで書く。 'Hello' のようにシングルクオートはダメ

     ●   Common Lisp の文字列は mutable に振る舞う。取扱い注意。
文字列が mutable なので

●   こんなことができちゃいます
(defvar?s1?"Hello?World")
(defvar?s2?s1)
(eq?s1?s2)
(setf?(char?s?5)?#?)
s1
s2
(eq?s1?s2)


     ●   REPL 環境で実験してみて!
     ●   シンボル s1 と s2 は「同一の」文字列を参照している
     ●   setf はやっぱりポインタ操作でしょ?
     ●   メモリ上の文字列を直接書換えてるイメージなわけですよ。
文字列の操作

●   文字の配列なので配列の操作関数が使える
      ●   さらに配列はシーケンスの一種なのでシーケンス操作関数が使える
      ●   なので、文字列特有の解説が少ないのかも
      ●   文字列用に特別に準備された関数もいくつかある
ぱいそん
s?=?"Hello?World"
s[3]
s[3:5]
s?=?s.strip()
s?=?s.lower()

りすぷ
(defvar?s?"Hello?World")
(char?s?3)
(subseq?s?3?5)
(setf?s?(string?trim?'(#Space?#Tab?#Newline)?s))
(setf?s?(string?downcase?s))
split を作る
(defmacro?while?(test?exp?&body?body)
??`(do?()?((not?,test?exp))?,@body))

(defun?string?split?(target?str?&key?(separators?'(#Space?#Tab)))
??(let?((result?nil)
????????(startpos?0)
????????(curpos?0)
????????(endpos?(length?target?str)))

????(while?(<?curpos?endpos)
??????(if?(member?(char?target?str?curpos)?separators)
??????????(progn
????????????(setf?result?(cons?(subseq?target?str?startpos?curpos)?result))
????????????(setf?startpos?(+?curpos?1))))

??????(setf?curpos?(+?curpos?1)))

????(setf?result?(cons?(subseq?target?str?startpos?endpos)?result))
????(nreverse?result)))

                                         loop マクロ使って格好良くもできるけど分かり易さ重視のベタ実装。
使い方                                      にしても、ちょっと不格好過ぎ。コンパイル結果は以外といい。


CL?USER>?(string?split?"Hello?World?foo?bar? 波浪ワールド ")
("Hello"?"World"?"foo"?"bar"?" 波浪ワールド ")
関数のキーワード引数

●   Python と同じようにキーワード引数が使えるよ
      ●   関数の引数部分に &key というマークに続けて書く
      ●   デフォルト値を与える&与えないの選択可

ぱいそん
def?foo(x,?y,?z=100):
    return?x?+?y?+?z

foo(10,?20)
foo(10,?20,?z=50)

りすぷ
(defun?foo?(x?y?&key?(z?100))
????(+?x?y?z))

(foo?10?20)
(foo?10?20?:z?50)
cons 関数                     リストは cons セルで構成されている。
 (X?Y)            (X?.?Y)
                            セルの左側を car
                            セルの右側を cdr

                            と呼ぶ。長大な薀蓄を聞きたいのでなけれ
                            ば、なんで left, right とかじゃないのかと
  X       Y        X    Y   いう質問はしないこと。



(cons?1?'(a?b))
                       cons 関数は新しい cons セルを用意して、第一引
                       数を car 部に第二引数を cdr 部にセットする。

                       これを繰り返せば、どんな複雑なリストの構造も作
                       成できる。

  1                    まぁ実際は cons だけでは面倒くさいので色々と便
                       利関数は用意されている

                       リストのあれこれ tips については後日っす。
      a       b
cons をもう少し
L1                        L2


        X       Y                1       2


     (cons?l1?(cons?l2?nil)) → ((x?y)?(1?2))




        X       Y        1       2
setf をリストに使うときの注意

●   リストに対して setf してみると…
CL?USER>?(defvar?lst?'(a?b?c))
CL?USER>?(setf?(cdr?lst)?'(1?2))
CL?USER>?lst

      ●   上の結果はどうなるか?

lst


              A            B       C



                                       1   2
setf をリストに使う時の注意

 ●    新しいセル作らずに無理やりポインタ書換え!
 CL?USER>?(defvar?lst?'(a?b?c))
 CL?USER>?(setf?(cdr?lst)?'(1?2))
 CL?USER>?lst



lst
                      (cdr?lst) の位置
                      を強制的に書換えた!
             A                         B        C


                                      これらのオブジェクトはもう参照
                                      できない!いずれ GC の餌食にな
                                      る
                  1            2
次はファイルの読み込み
結構簡単よ!
ぱいそん
with?open("/tmp/foobar.txt",?"r")?as?input_file:
   for?line?in?input_file:
       print?line

りすぷ
(with?open?file?(input?file?"/tmp/foobar.txt"?:direction?:input)
    (loop?for?line?=?(read?line?input?file)
        while?line
        do?(princ?(format?nil?"~a~%"?line))?))

       ●   loop マクロは相変わらず魔法だけど何となく分かるでしょ?
       ●   format 関数は超便利。後日まとめて機能を紹介するですよ
コマンドライン引数の取得

●   *posix?argv* というグローバル変数に入ってる
(defun?main()
??(dolist?(arg?*posix?argv*)
????(princ?(format?nil?"~a~%"?arg))))

(eval?when?(:compile?toplevel?:load?toplevel?:execute)
??(main)
??(quit))

$?sbcl???script?argtest.lisp?foo?bar?baz



       ●   dolist フォームの使い方。上の例で十分に分かるかと。
課題演習
「単語数え」プログラム
  もう作れるよね?

More Related Content

What's hot (20)

中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
Genya Murakami
?
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami
?
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
Tsuyoshi Matsudate
?
组み込みでこそ颁++を使う10の理由
组み込みでこそ颁++を使う10の理由组み込みでこそ颁++を使う10の理由
组み込みでこそ颁++を使う10の理由
kikairoya
?
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
Ryosuke839
?
Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
CHY72
?
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
parrotstudio
?
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScript
bleis tift
?
叠辞辞蝉迟础蝉颈辞で可読性を求めるのは间违っているだろうか
叠辞辞蝉迟础蝉颈辞で可読性を求めるのは间违っているだろうか叠辞辞蝉迟础蝉颈辞で可読性を求めるのは间违っているだろうか
叠辞辞蝉迟础蝉颈辞で可読性を求めるのは间违っているだろうか
Yuki Miyatake
?
厂肠补濒补のオブジェクトの话
厂肠补濒补のオブジェクトの话厂肠补濒补のオブジェクトの话
厂肠补濒补のオブジェクトの话
Yasuyuki Maeda
?
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
nekko1119
?
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi
?
笔测迟丑辞苍勉强会4-制御构文とパッケージ
笔测迟丑辞苍勉强会4-制御构文とパッケージ笔测迟丑辞苍勉强会4-制御构文とパッケージ
笔测迟丑辞苍勉强会4-制御构文とパッケージ
理 小林
?
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツール
Nobuhisa Koizumi
?
颁++コミュニティーの中心で颁++を顿滨厂る
颁++コミュニティーの中心で颁++を顿滨厂る颁++コミュニティーの中心で颁++を顿滨厂る
颁++コミュニティーの中心で颁++を顿滨厂る
Hideyuki Tanaka
?
Haskell勉強会 in ie
Haskell勉強会 in ieHaskell勉強会 in ie
Haskell勉強会 in ie
maeken2010
?
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
Akihiko Matuura
?
Power of Scala
Power of ScalaPower of Scala
Power of Scala
Kota Mizushima
?
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
?
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
Genya Murakami
?
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami
?
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
Tsuyoshi Matsudate
?
组み込みでこそ颁++を使う10の理由
组み込みでこそ颁++を使う10の理由组み込みでこそ颁++を使う10の理由
组み込みでこそ颁++を使う10の理由
kikairoya
?
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
Ryosuke839
?
Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
CHY72
?
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
parrotstudio
?
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScript
bleis tift
?
叠辞辞蝉迟础蝉颈辞で可読性を求めるのは间违っているだろうか
叠辞辞蝉迟础蝉颈辞で可読性を求めるのは间违っているだろうか叠辞辞蝉迟础蝉颈辞で可読性を求めるのは间违っているだろうか
叠辞辞蝉迟础蝉颈辞で可読性を求めるのは间违っているだろうか
Yuki Miyatake
?
厂肠补濒补のオブジェクトの话
厂肠补濒补のオブジェクトの话厂肠补濒补のオブジェクトの话
厂肠补濒补のオブジェクトの话
Yasuyuki Maeda
?
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
nekko1119
?
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi
?
笔测迟丑辞苍勉强会4-制御构文とパッケージ
笔测迟丑辞苍勉强会4-制御构文とパッケージ笔测迟丑辞苍勉强会4-制御构文とパッケージ
笔测迟丑辞苍勉强会4-制御构文とパッケージ
理 小林
?
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツール
Nobuhisa Koizumi
?
颁++コミュニティーの中心で颁++を顿滨厂る
颁++コミュニティーの中心で颁++を顿滨厂る颁++コミュニティーの中心で颁++を顿滨厂る
颁++コミュニティーの中心で颁++を顿滨厂る
Hideyuki Tanaka
?
Haskell勉強会 in ie
Haskell勉強会 in ieHaskell勉強会 in ie
Haskell勉強会 in ie
maeken2010
?
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
Akihiko Matuura
?
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
?

Viewers also liked (8)

小中学生贬补肠办-补-迟丑辞苍にオッサンが乗り込んだ话
小中学生贬补肠办-补-迟丑辞苍にオッサンが乗り込んだ话小中学生贬补肠办-补-迟丑辞苍にオッサンが乗り込んだ话
小中学生贬补肠办-补-迟丑辞苍にオッサンが乗り込んだ话
Ransui Iso
?
Playing with curses
Playing with cursesPlaying with curses
Playing with curses
Ransui Iso
?
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
Ransui Iso
?
XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由
Ransui Iso
?
笔测迟丑辞苍で作る俺様サウンドエフェクター
笔测迟丑辞苍で作る俺様サウンドエフェクター笔测迟丑辞苍で作る俺様サウンドエフェクター
笔测迟丑辞苍で作る俺様サウンドエフェクター
Ransui Iso
?
ソフトシンセを作りながら学ぶ笔测迟丑辞苍プログラミング
ソフトシンセを作りながら学ぶ笔测迟丑辞苍プログラミングソフトシンセを作りながら学ぶ笔测迟丑辞苍プログラミング
ソフトシンセを作りながら学ぶ笔测迟丑辞苍プログラミング
Ransui Iso
?
笔测蚕迟ではじめる骋鲍滨プログラミング
笔测蚕迟ではじめる骋鲍滨プログラミング笔测蚕迟ではじめる骋鲍滨プログラミング
笔测蚕迟ではじめる骋鲍滨プログラミング
Ransui Iso
?
My client wanted their apps synced, and I made it with Go
My client wanted their apps synced, and I made it with GoMy client wanted their apps synced, and I made it with Go
My client wanted their apps synced, and I made it with Go
Toru Furukawa
?
小中学生贬补肠办-补-迟丑辞苍にオッサンが乗り込んだ话
小中学生贬补肠办-补-迟丑辞苍にオッサンが乗り込んだ话小中学生贬补肠办-补-迟丑辞苍にオッサンが乗り込んだ话
小中学生贬补肠办-补-迟丑辞苍にオッサンが乗り込んだ话
Ransui Iso
?
Playing with curses
Playing with cursesPlaying with curses
Playing with curses
Ransui Iso
?
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
Ransui Iso
?
XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由
Ransui Iso
?
笔测迟丑辞苍で作る俺様サウンドエフェクター
笔测迟丑辞苍で作る俺様サウンドエフェクター笔测迟丑辞苍で作る俺様サウンドエフェクター
笔测迟丑辞苍で作る俺様サウンドエフェクター
Ransui Iso
?
ソフトシンセを作りながら学ぶ笔测迟丑辞苍プログラミング
ソフトシンセを作りながら学ぶ笔测迟丑辞苍プログラミングソフトシンセを作りながら学ぶ笔测迟丑辞苍プログラミング
ソフトシンセを作りながら学ぶ笔测迟丑辞苍プログラミング
Ransui Iso
?
笔测蚕迟ではじめる骋鲍滨プログラミング
笔测蚕迟ではじめる骋鲍滨プログラミング笔测蚕迟ではじめる骋鲍滨プログラミング
笔测蚕迟ではじめる骋鲍滨プログラミング
Ransui Iso
?
My client wanted their apps synced, and I made it with Go
My client wanted their apps synced, and I made it with GoMy client wanted their apps synced, and I made it with Go
My client wanted their apps synced, and I made it with Go
Toru Furukawa
?

Similar to Lisp tutorial for Pythonista : Day 2 (20)

モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
bleis tift
?
関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』
Kenta USAMI
?
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
Masao Kato
?
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
Naoki Kitora
?
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
Ouka Yuka
?
関数型言语&补尘辫;形式的手法セミナー(3)
関数型言语&补尘辫;形式的手法セミナー(3)関数型言语&补尘辫;形式的手法セミナー(3)
関数型言语&补尘辫;形式的手法セミナー(3)
啓 小笠原
?
X hago2 shortcoding 20110827
X hago2 shortcoding 20110827X hago2 shortcoding 20110827
X hago2 shortcoding 20110827
uskey512
?
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
mitim
?
テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式
digitalghost
?
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
Ra Zon
?
初心者讲习会资料(翱蝉补办补.搁#7)
初心者讲习会资料(翱蝉补办补.搁#7)初心者讲习会资料(翱蝉补办补.搁#7)
初心者讲习会资料(翱蝉补办补.搁#7)
Masahiro Hayashi
?
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Satoshi imai
?
初心者讲习会资料(翱蝉补办补.谤#6)
初心者讲习会资料(翱蝉补办补.谤#6)初心者讲习会资料(翱蝉补办补.谤#6)
初心者讲习会资料(翱蝉补办补.谤#6)
Masahiro Hayashi
?
普通のプログラミング言语搁
普通のプログラミング言语搁普通のプログラミング言语搁
普通のプログラミング言语搁
Shuyo Nakatani
?
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1
Susisu
?
尝颈蝉辫でやる记号微分
尝颈蝉辫でやる记号微分尝颈蝉辫でやる记号微分
尝颈蝉辫でやる记号微分
Keiichi Watanabe
?
How wonderful to be (statically) typed ?型が付くってスバラシイ?
How wonderful to be (statically) typed ?型が付くってスバラシイ?How wonderful to be (statically) typed ?型が付くってスバラシイ?
How wonderful to be (statically) typed ?型が付くってスバラシイ?
Hiromi Ishii
?
厂肠补濒补で萌える関数型プログラミング摆完全版闭
厂肠补濒补で萌える関数型プログラミング摆完全版闭厂肠补濒补で萌える関数型プログラミング摆完全版闭
厂肠补濒补で萌える関数型プログラミング摆完全版闭
Ra Zon
?
関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013
Esehara Shigeo
?
纯粋関数型アルゴリズム入门
纯粋関数型アルゴリズム入门纯粋関数型アルゴリズム入门
纯粋関数型アルゴリズム入门
Kimikazu Kato
?
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
bleis tift
?
関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』
Kenta USAMI
?
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
Masao Kato
?
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
Naoki Kitora
?
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
Ouka Yuka
?
関数型言语&补尘辫;形式的手法セミナー(3)
関数型言语&补尘辫;形式的手法セミナー(3)関数型言语&补尘辫;形式的手法セミナー(3)
関数型言语&补尘辫;形式的手法セミナー(3)
啓 小笠原
?
X hago2 shortcoding 20110827
X hago2 shortcoding 20110827X hago2 shortcoding 20110827
X hago2 shortcoding 20110827
uskey512
?
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
mitim
?
テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式
digitalghost
?
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
Ra Zon
?
初心者讲习会资料(翱蝉补办补.搁#7)
初心者讲习会资料(翱蝉补办补.搁#7)初心者讲习会资料(翱蝉补办补.搁#7)
初心者讲习会资料(翱蝉补办补.搁#7)
Masahiro Hayashi
?
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Satoshi imai
?
初心者讲习会资料(翱蝉补办补.谤#6)
初心者讲习会资料(翱蝉补办补.谤#6)初心者讲习会资料(翱蝉补办补.谤#6)
初心者讲习会资料(翱蝉补办补.谤#6)
Masahiro Hayashi
?
普通のプログラミング言语搁
普通のプログラミング言语搁普通のプログラミング言语搁
普通のプログラミング言语搁
Shuyo Nakatani
?
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1
Susisu
?
尝颈蝉辫でやる记号微分
尝颈蝉辫でやる记号微分尝颈蝉辫でやる记号微分
尝颈蝉辫でやる记号微分
Keiichi Watanabe
?
How wonderful to be (statically) typed ?型が付くってスバラシイ?
How wonderful to be (statically) typed ?型が付くってスバラシイ?How wonderful to be (statically) typed ?型が付くってスバラシイ?
How wonderful to be (statically) typed ?型が付くってスバラシイ?
Hiromi Ishii
?
厂肠补濒补で萌える関数型プログラミング摆完全版闭
厂肠补濒补で萌える関数型プログラミング摆完全版闭厂肠补濒补で萌える関数型プログラミング摆完全版闭
厂肠补濒补で萌える関数型プログラミング摆完全版闭
Ra Zon
?
関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013
Esehara Shigeo
?
纯粋関数型アルゴリズム入门
纯粋関数型アルゴリズム入门纯粋関数型アルゴリズム入门
纯粋関数型アルゴリズム入门
Kimikazu Kato
?

More from Ransui Iso (7)

「笔测迟丑辞苍でやってみた」~広がるプログラミングの愉しみ~
「笔测迟丑辞苍でやってみた」~広がるプログラミングの愉しみ~「笔测迟丑辞苍でやってみた」~広がるプログラミングの愉しみ~
「笔测迟丑辞苍でやってみた」~広がるプログラミングの愉しみ~
Ransui Iso
?
アドテクを支える人と技术
アドテクを支える人と技术アドテクを支える人と技术
アドテクを支える人と技术
Ransui Iso
?
Introduction of ToySynth
Introduction of ToySynthIntroduction of ToySynth
Introduction of ToySynth
Ransui Iso
?
PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.
Ransui Iso
?
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
Ransui Iso
?
Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5
Ransui Iso
?
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4
Ransui Iso
?
「笔测迟丑辞苍でやってみた」~広がるプログラミングの愉しみ~
「笔测迟丑辞苍でやってみた」~広がるプログラミングの愉しみ~「笔测迟丑辞苍でやってみた」~広がるプログラミングの愉しみ~
「笔测迟丑辞苍でやってみた」~広がるプログラミングの愉しみ~
Ransui Iso
?
アドテクを支える人と技术
アドテクを支える人と技术アドテクを支える人と技术
アドテクを支える人と技术
Ransui Iso
?
Introduction of ToySynth
Introduction of ToySynthIntroduction of ToySynth
Introduction of ToySynth
Ransui Iso
?
PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.
Ransui Iso
?
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
Ransui Iso
?
Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5
Ransui Iso
?
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4
Ransui Iso
?

Recently uploaded (6)

惭测厂蚕尝30周年&ユーザ会25周年记念イベント冯発表资料(2025年3月25日开催)
惭测厂蚕尝30周年&ユーザ会25周年记念イベント冯発表资料(2025年3月25日开催)惭测厂蚕尝30周年&ユーザ会25周年记念イベント冯発表资料(2025年3月25日开催)
惭测厂蚕尝30周年&ユーザ会25周年记念イベント冯発表资料(2025年3月25日开催)
馮 富久
?
自由に移动する复数の?々に异なる映像を提?するテ?ィスフ?レイシステムについての基础検讨
自由に移动する复数の?々に异なる映像を提?するテ?ィスフ?レイシステムについての基础検讨自由に移动する复数の?々に异なる映像を提?するテ?ィスフ?レイシステムについての基础検讨
自由に移动する复数の?々に异なる映像を提?するテ?ィスフ?レイシステムについての基础検讨
sugiuralab
?
カスタム厂尝惭「贬补尘蝉迟别谤」冲軽量でセキュアな専用言语モデル冲础滨エージェント冲チャットボット冲マッチングアプリ构筑のコアパッケージ
カスタム厂尝惭「贬补尘蝉迟别谤」冲軽量でセキュアな専用言语モデル冲础滨エージェント冲チャットボット冲マッチングアプリ构筑のコアパッケージカスタム厂尝惭「贬补尘蝉迟别谤」冲軽量でセキュアな専用言语モデル冲础滨エージェント冲チャットボット冲マッチングアプリ构筑のコアパッケージ
カスタム厂尝惭「贬补尘蝉迟别谤」冲軽量でセキュアな専用言语モデル冲础滨エージェント冲チャットボット冲マッチングアプリ构筑のコアパッケージ
info819904
?
量子リザバソフトウェア冲时系列データ(农业?核融合?需要予测)効果検証冲导入による成果
量子リザバソフトウェア冲时系列データ(农业?核融合?需要予测)効果検証冲导入による成果量子リザバソフトウェア冲时系列データ(农业?核融合?需要予测)効果検証冲导入による成果
量子リザバソフトウェア冲时系列データ(农业?核融合?需要予测)効果検証冲导入による成果
info819904
?
2019飞冲东京大学大学院茂木研究室冲学生研究员杉田翔栄冲搁罢贰最终発表会スライト?.辫诲蹿
2019飞冲东京大学大学院茂木研究室冲学生研究员杉田翔栄冲搁罢贰最终発表会スライト?.辫诲蹿2019飞冲东京大学大学院茂木研究室冲学生研究员杉田翔栄冲搁罢贰最终発表会スライト?.辫诲蹿
2019飞冲东京大学大学院茂木研究室冲学生研究员杉田翔栄冲搁罢贰最终発表会スライト?.辫诲蹿
翔栄 杉田
?
松下光范「街歩き型ストーリーリーダーの実施」,もうひとつの十叁未来会议(有识者编)
松下光范「街歩き型ストーリーリーダーの実施」,もうひとつの十叁未来会议(有识者编)松下光范「街歩き型ストーリーリーダーの実施」,もうひとつの十叁未来会议(有识者编)
松下光范「街歩き型ストーリーリーダーの実施」,もうひとつの十叁未来会议(有识者编)
Matsushita Laboratory
?
惭测厂蚕尝30周年&ユーザ会25周年记念イベント冯発表资料(2025年3月25日开催)
惭测厂蚕尝30周年&ユーザ会25周年记念イベント冯発表资料(2025年3月25日开催)惭测厂蚕尝30周年&ユーザ会25周年记念イベント冯発表资料(2025年3月25日开催)
惭测厂蚕尝30周年&ユーザ会25周年记念イベント冯発表资料(2025年3月25日开催)
馮 富久
?
自由に移动する复数の?々に异なる映像を提?するテ?ィスフ?レイシステムについての基础検讨
自由に移动する复数の?々に异なる映像を提?するテ?ィスフ?レイシステムについての基础検讨自由に移动する复数の?々に异なる映像を提?するテ?ィスフ?レイシステムについての基础検讨
自由に移动する复数の?々に异なる映像を提?するテ?ィスフ?レイシステムについての基础検讨
sugiuralab
?
カスタム厂尝惭「贬补尘蝉迟别谤」冲軽量でセキュアな専用言语モデル冲础滨エージェント冲チャットボット冲マッチングアプリ构筑のコアパッケージ
カスタム厂尝惭「贬补尘蝉迟别谤」冲軽量でセキュアな専用言语モデル冲础滨エージェント冲チャットボット冲マッチングアプリ构筑のコアパッケージカスタム厂尝惭「贬补尘蝉迟别谤」冲軽量でセキュアな専用言语モデル冲础滨エージェント冲チャットボット冲マッチングアプリ构筑のコアパッケージ
カスタム厂尝惭「贬补尘蝉迟别谤」冲軽量でセキュアな専用言语モデル冲础滨エージェント冲チャットボット冲マッチングアプリ构筑のコアパッケージ
info819904
?
量子リザバソフトウェア冲时系列データ(农业?核融合?需要予测)効果検証冲导入による成果
量子リザバソフトウェア冲时系列データ(农业?核融合?需要予测)効果検証冲导入による成果量子リザバソフトウェア冲时系列データ(农业?核融合?需要予测)効果検証冲导入による成果
量子リザバソフトウェア冲时系列データ(农业?核融合?需要予测)効果検証冲导入による成果
info819904
?
2019飞冲东京大学大学院茂木研究室冲学生研究员杉田翔栄冲搁罢贰最终発表会スライト?.辫诲蹿
2019飞冲东京大学大学院茂木研究室冲学生研究员杉田翔栄冲搁罢贰最终発表会スライト?.辫诲蹿2019飞冲东京大学大学院茂木研究室冲学生研究员杉田翔栄冲搁罢贰最终発表会スライト?.辫诲蹿
2019飞冲东京大学大学院茂木研究室冲学生研究员杉田翔栄冲搁罢贰最终発表会スライト?.辫诲蹿
翔栄 杉田
?
松下光范「街歩き型ストーリーリーダーの実施」,もうひとつの十叁未来会议(有识者编)
松下光范「街歩き型ストーリーリーダーの実施」,もうひとつの十叁未来会议(有识者编)松下光范「街歩き型ストーリーリーダーの実施」,もうひとつの十叁未来会议(有识者编)
松下光范「街歩き型ストーリーリーダーの実施」,もうひとつの十叁未来会议(有识者编)
Matsushita Laboratory
?

Lisp tutorial for Pythonista : Day 2

  • 1. Lisp tutorial for Pythonista. Day #2 : The Basics. Ransui Iso Strategic Technology Group, X-Listing Co, Ltd.
  • 3. 前回の宿題は OK ですか? いちおう Emacs + SLIME が動く前提です
  • 4. なにはともあれまずは REPL Read, Eval, Print Loop の略語 Python なら「インタラクティブシェル」
  • 5. Emacs 起動して M-x slime META キーの設定無い人は [ESC] 押して [x]
  • 9. 変数は宣言してから使うのが基本 ルーズな Python とは大違いだよ! 管理大好きスーツ族への強力なアピールポイントだ! 警告ガン無視でも、まあ問題は無いんだが気持ち悪いので宣言しとけ。
  • 11. Common Lisp の名前空間 ● 大域は package という単位が基本になっている ● 概念的には Python のモジュールに近い ● Python のモジュールより厳密に定義するのでお手軽じゃない ● 何も指定しない時は CL?USER がデフォルト ● cl パッケージに Common Lisp の基本機能が入っている ● イメージとしては cl?user.py の最初で from?cl?import?* してある感覚。 ● もちろんローカル変数とかもちゃんとあるよ ● 関数引数とか、 let フォームとか色々ある ● レキシカルスコープなので、基本部分は Python 感覚で OK 。
  • 12. パッケージ変数の宣言 ● defvar と defparameter ● どちらもパッケージ変数を宣言する ● 宣言するときには初期値を与える ● defvar ● 再初期化されない ● defparameter ● 再初期化される パッケージ変数という用語は一般的じゃない。 Python 風な名前で呼んで みてるだけ。ほんとは「スペシャル変数」と言う。実は深い意味もあるん だけど、今は無視しちゃう。
  • 13. 再初期化される?されない? ● 実験してみりゃ一目瞭然 CL?USER>?(defvar?*foo*?nil) *FOO* CL?USER>?(defparameter?*bar*?nil) *BAR* CL?USER>?(setf?*foo*?1) 1 CL?USER>?(setf?*bar*?2) 2 CL?USER>?(defvar?*foo*?nil) *FOO* CL?USER>?*foo* 1 CL?USER>?(defparameter?*bar*?nil) *BAR* CL?USER>?*bar* NIL パッケージが再読み込みされた時とかに挙動が変わるよ!
  • 14. CL のパッケージは取扱いが面倒 なので、今のところは CL-USER 一辺倒でいく ライブラリとか作るようになったら defpackage とか使うよ
  • 15. ソースをファイルに書いて実行する ● C?x?5?2 で新フレームを開いて ● 新しいフレームで C?x?C?f?hello.lisp とかし て新規バッファを開く ● コード書く (defun?hello?(name) ??(format?t?"Hello?~a~%"?name)) (hello?"World") ● C?x?C?s でセーブ ● C?c?C?k で REPL 環境にコンパイルしてロード
  • 16. スクリプトっぽく実行する ぱいそん def?hello(name): print("Hello?%s"?%?name) def?main(): hello("World") if?__name__?==?"__main__": main() りすぷ (defun?hello?(name) (format?t?"Hello?~a~%"?name)) (defun?main() (hello?"World")) (eval?when?(:compile?toplevel?:load?toplevel?:execute) (main) (quit)) eval?when は結構使い方が難しい。コンパイル、ロード、実行のタイミングとかは Lisp 処理系の動きをイメージしないといけない部分があるからね。
  • 17. コマンドラインから起動する ● 実は処理系依存なのよ ● SBCL の場合は下のようにする $?sbcl???script?hello.lisp Hello?World $
  • 19. すごく教科书的でアレなんですが 「単語数え」 プログラムを書いてみませう
  • 20. 慣れ親しんだ Python だと あー、簡単のために単語は空白文字で区切られてるものとしてます。 def?main() counter?=?dict() for?line?in?open(sys.argv[1],?"r"): for?word?in?line.strip().split(): index_word?=?word.lower() if?index_word?in?counter: counter[index_word]?+=?1 else: counter[index_word]?=?1 for?(word,?num)?in?counter.items(): print("%20s?:?%4d"?%?(word,?num)) if?__name__?==?"__main__": main() まぁ、瞬殺なわけです これを Common Lisp で書くとどうなるか
  • 21. 単語数えプログラムを書くために ● ファイル入出力 ● ファイルのオープン ● パスの操作 ● 文字列操作 ● スペースとかのデリミタでのフィールド分解 ● 数え上げ ● Python で言う所の辞書の使い方 ● その他 ● コマンドライン引数の扱いとか
  • 23. ぱいそん d = dict() d["Hello"] = "World" d["Hello"] → "World" d[1] = 2 len(d) → 2 for (key, value) in d.items(): print("%s : %s" % (key, value)) りすぷ (setf d (make-hash-table :test #'equal)) (setf (gethash "Hello" d) "World) (gethash "Hello" d) → "World" (setf (gethash 1 d) 2) (hash-table-count d) → 2 (maphash #'(lambda (key value) (princ (format nil "~a : ~a~%" key value))) d)
  • 25. 辞書っぽくアクセスするようにしてみる (define?condition?key?error?(error)? ((text?:initarg?:text?:reader?text))) (defun?make?dict?() ????(make?hash?table?:test?#'equal)) (defun?set?item?(dict?key?value) ??(setf?(gethash?key?dict)?value)) (defun?get?item?(dict?key) ??(multiple?value?bind?(value?has?key)?(gethash?key?dict) ????(if?(not?has?key) ????????(error?'key?error?:text?(format?nil?"KeyError?:?~a"?key)) ????????value))) (defun?has?key?(dict?key) ??(multiple?value?bind?(value?has?key)?(gethash?key?dict) ????(declare?(ignore?value)) ????has?key)) (defun?items?(dict) ??(let?((result?nil)) ????(maphash?#'(lambda?(key?value) ?????????????????(setf?result?(cons?(cons?key?value)?result)))?dict) ????result))
  • 27. define-condition ● Python で言う所の例外に近い ● 厳密には違うけどイメージとしてはこんなかんじ class?KeyError(Exception): def?__init__(self,?text): Exception.__init__(self,?text) KeyError は組み込みの例外だが、これはあくまで例だ。気にするな。 ● Common Lisp では「コンディション」と言う ● 「例外」と呼ばない点に注意 ● 例外的な事象への対応以外にも色々と使える ● Python の try ? except よりもずっと強力
  • 28. eq, eql, equal, equalp ● オブジェクトの比較関数だよ ● オブジェクトの同一性と、値としての同値ってのは別腹 ● Python の is と == 演算子の違いに似てる – eq : メモリ上で同一オブジェクトかどうかをチェック – eql : 数値 or 文字の場合は同値か?それ以外は eq する – equal : 値の構造が同一か?内部構造も再帰的にチェック – equalp :equal よりも緩い判定。詳細は CLtL2 参照
  • 29. ハッシュテーブルの生成部分 ● キーの比較関数を指定して生成してる (make?hash?table?:test?#'equal) ● #'equal という表記は (function?equal) の略記法 ● 略記法があるってことは、今後もいっぱいでてくる予感 ● ちなみに比較関数指定を省略したときは #'eql がデフォルト ● equal を指定している訳 ● 今回は文字列をハッシュのキーにする ● 文字列は (eql?"Hello"?"Hello") → nil なのだ ● ちなみに純粋な文字列比較関数の string= を使ってもいい – その場合、この hash-table のキーはマジで文字列限定になる。
  • 30. setf ってなんだ? ● これは違和感ないはず (setf?x?10) ● で、これは? (setf?(gethash?key?dict)?value) ● そもそも gethash 関数って (gethash?"Hello"?dict)?→?"World" ● みたいに値を取り出す関数なんじゃねーの? ● つーことは、 "Hello" とか、出てきた値になんか代入すんの?
  • 31. setf には値を入れる場所を指定する ● ぶっちゃけ、ポインタです ● setf は関数じゃないんです。マクロなんです。つーことは引数は 評価される前の状態で setf に渡されてるということ ● 第一引数は「値を入れる場所」として解釈される dict Hello (gethash?"Hello"?dict) foo setf マクロと組み合わせてポインタ bar として振る舞う関数には制限がある 詳しくは「 CLtL2 C7.2: 汎変数」を 参照のこと
  • 32. 多値関数 ● 複数の値を返す関数 ● Python でタプル返すのとはちょっと違う。 def?foo(x): return?((True?if?x?%?2?else?False),?x?+?1) (is_odd,?next)?=?foo(3)?#?OK is_odd?=?foo(3)?????????#?is_odd は単純にタプルを指すだけ (defun?foo(x) (values? (if?(=?(mod?x?2)?1)?t?nil) (+?x?1))) (multiple?value?bind?(is_odd?next_x)?(foo?3)??; 多値を受け取るための形式 (cons?is_odd?next_x)) (setf?is_odd?(foo?3))?????????????????????????; 最初の値だけが採用される
  • 33. gethash 関数の戻り値 ● 2 値の多値関数 ● 第一値: Key に対応する Value, Key が存在しない場合は nil ● 第二値: Key が存在した場合は t, 存在しない場合は nil (defvar?dict?(make?hash?table?:test?#'equal)) (setf?(gethash?"foo"?dict)?nil) ● 上のとき、 (gethash?"foo"?dict)?→?nil foo というキーが登録されていないから nil なのか? foo というキーに対応している値が nil なのか? – (defun?has?key?(dict?key) ??(multiple?value?bind?(value?has?key)?(gethash?key?dict) ????(declare?(ignore?value)) ????has?key)) ● 多値関数の戻り値を受け取っても使わない場合は「変数使ってない が大丈夫か?」とコンパイラが五月蝿いので declare を使って 「大丈夫だ。問題ない。」と伝えておくと吉。
  • 34. if フォーム ● 分岐の基本なんだがイマイチな部分もある (if?( 条件テスト式 )?(then 節 )?(else 節 )) ● then 節と else 節はブロックじゃない。 1 個の式しか書けない ! – しょうがないので progn とか let とか使ってブロック化する。 ● Python で言う所の elif が無い! – ネストして頑張る。 – cond マクロを使う。 – case マクロを使う。 ● Python と違って if は " 文 " じゃない! – 値を返せるよ!戻り値は then 節とか else 節の式の評価値になる
  • 35. let とローカル変数 ● 正確には「レキシカル変数」と言う ● 呼称はまあいい。要するに let の範囲内のローカル変数だ CL?USER>?(let?((x?10)?(y?20)) ???????????(print?x) ???????????(print?y) ???????????(let?((x?"Hello")) ?????????????(print?x) ?????????????(print?y))) ● 実行結果は予想のとおり。 ● let と関数定義を組み合わせたりと色々な技がある ● let 以外にもレキシカル変数を取り扱うフォームは色々ある
  • 36. lambda 式 ● 関数の実体?無名関数 ● 関数を使い捨てしたいときとかに良く使う ● let と組み合わせてクロージャとか作ったりもする (setf?(symbol?function?'foo)?#'(lambda?(x)?(+?x?1))) || (defun?foo(x)?(+?x?1)) foo value func (function?(lambda?(x)?(+?x?1))) prop Common Lisp のシンボルは値用と関数用の 2 つのスロットを持っ ているのだ!こういうタイプの Lisp を Lisp-2 という。ちなみに Scheme は値と関数のスロットは分かれていない Lisp-1 。 Python も Lisp-1 風。
  • 39. Lisp の文字列 ● 実体は文字型の 1 次元配列 ● Common Lisp は文字型が存在する。文字型はエンコードとは独立 するように設計されている。が、まぁモゴモゴ… – C の char とは違う。 Java の char に似た立ち位置と思えばいい。 – 文字をリテラルとして書く場合は #A とか #Newline とか書く。 – Python には文字型は無い。 1 文字の文字列として扱うか、エンコードされた整数コード として扱っている ● リテラルで書く場合は "Hello?World" のようにダブルクォート で囲んで書く。 'Hello' のようにシングルクオートはダメ ● Common Lisp の文字列は mutable に振る舞う。取扱い注意。
  • 40. 文字列が mutable なので ● こんなことができちゃいます (defvar?s1?"Hello?World") (defvar?s2?s1) (eq?s1?s2) (setf?(char?s?5)?#?) s1 s2 (eq?s1?s2) ● REPL 環境で実験してみて! ● シンボル s1 と s2 は「同一の」文字列を参照している ● setf はやっぱりポインタ操作でしょ? ● メモリ上の文字列を直接書換えてるイメージなわけですよ。
  • 41. 文字列の操作 ● 文字の配列なので配列の操作関数が使える ● さらに配列はシーケンスの一種なのでシーケンス操作関数が使える ● なので、文字列特有の解説が少ないのかも ● 文字列用に特別に準備された関数もいくつかある ぱいそん s?=?"Hello?World" s[3] s[3:5] s?=?s.strip() s?=?s.lower() りすぷ (defvar?s?"Hello?World") (char?s?3) (subseq?s?3?5) (setf?s?(string?trim?'(#Space?#Tab?#Newline)?s)) (setf?s?(string?downcase?s))
  • 42. split を作る (defmacro?while?(test?exp?&body?body) ??`(do?()?((not?,test?exp))?,@body)) (defun?string?split?(target?str?&key?(separators?'(#Space?#Tab))) ??(let?((result?nil) ????????(startpos?0) ????????(curpos?0) ????????(endpos?(length?target?str))) ????(while?(<?curpos?endpos) ??????(if?(member?(char?target?str?curpos)?separators) ??????????(progn ????????????(setf?result?(cons?(subseq?target?str?startpos?curpos)?result)) ????????????(setf?startpos?(+?curpos?1)))) ??????(setf?curpos?(+?curpos?1))) ????(setf?result?(cons?(subseq?target?str?startpos?endpos)?result)) ????(nreverse?result))) loop マクロ使って格好良くもできるけど分かり易さ重視のベタ実装。 使い方 にしても、ちょっと不格好過ぎ。コンパイル結果は以外といい。 CL?USER>?(string?split?"Hello?World?foo?bar? 波浪ワールド ") ("Hello"?"World"?"foo"?"bar"?" 波浪ワールド ")
  • 43. 関数のキーワード引数 ● Python と同じようにキーワード引数が使えるよ ● 関数の引数部分に &key というマークに続けて書く ● デフォルト値を与える&与えないの選択可 ぱいそん def?foo(x,?y,?z=100): return?x?+?y?+?z foo(10,?20) foo(10,?20,?z=50) りすぷ (defun?foo?(x?y?&key?(z?100)) ????(+?x?y?z)) (foo?10?20) (foo?10?20?:z?50)
  • 44. cons 関数 リストは cons セルで構成されている。 (X?Y) (X?.?Y) セルの左側を car セルの右側を cdr と呼ぶ。長大な薀蓄を聞きたいのでなけれ ば、なんで left, right とかじゃないのかと X Y X Y いう質問はしないこと。 (cons?1?'(a?b)) cons 関数は新しい cons セルを用意して、第一引 数を car 部に第二引数を cdr 部にセットする。 これを繰り返せば、どんな複雑なリストの構造も作 成できる。 1 まぁ実際は cons だけでは面倒くさいので色々と便 利関数は用意されている リストのあれこれ tips については後日っす。 a b
  • 45. cons をもう少し L1 L2 X Y 1 2 (cons?l1?(cons?l2?nil)) → ((x?y)?(1?2)) X Y 1 2
  • 46. setf をリストに使うときの注意 ● リストに対して setf してみると… CL?USER>?(defvar?lst?'(a?b?c)) CL?USER>?(setf?(cdr?lst)?'(1?2)) CL?USER>?lst ● 上の結果はどうなるか? lst A B C 1 2
  • 47. setf をリストに使う時の注意 ● 新しいセル作らずに無理やりポインタ書換え! CL?USER>?(defvar?lst?'(a?b?c)) CL?USER>?(setf?(cdr?lst)?'(1?2)) CL?USER>?lst lst (cdr?lst) の位置 を強制的に書換えた! A B C これらのオブジェクトはもう参照 できない!いずれ GC の餌食にな る 1 2
  • 49. 結構簡単よ! ぱいそん with?open("/tmp/foobar.txt",?"r")?as?input_file: for?line?in?input_file: print?line りすぷ (with?open?file?(input?file?"/tmp/foobar.txt"?:direction?:input) (loop?for?line?=?(read?line?input?file) while?line do?(princ?(format?nil?"~a~%"?line))?)) ● loop マクロは相変わらず魔法だけど何となく分かるでしょ? ● format 関数は超便利。後日まとめて機能を紹介するですよ
  • 50. コマンドライン引数の取得 ● *posix?argv* というグローバル変数に入ってる (defun?main() ??(dolist?(arg?*posix?argv*) ????(princ?(format?nil?"~a~%"?arg)))) (eval?when?(:compile?toplevel?:load?toplevel?:execute) ??(main) ??(quit)) $?sbcl???script?argtest.lisp?foo?bar?baz ● dolist フォームの使い方。上の例で十分に分かるかと。