読者です 読者をやめる 読者になる 読者になる

by shigemk2

当面は技術的なことしか書かない

Land of Lisp 1章-2章 メモ

Lisp

勉強会1章-2章(社内)のメモ

はじめに

Lispはすごい

(+ 3 (* 2 4))

Lispを使っている企業(たぶんドメイン名前解決できていない) http://snipurl.com/e3lv9/

なぜLispが学ばれないか

人は以下の様なものを学びたがる。

  • 他のみんなが学んでるもの(微積分とか C++ とか)
  • 簡単に学べるもの(フラフープとか Ruby とか)
  • 学んだことの価値が簡単にわかるもの(核融合物理学とか、あるいは指を口に入れてとんでもなく大きな音を出せる口笛とか)

そして、Lispはそのどれにも属さないが、本気でプログラミングを学びたい人にとっては、Lispは良い経験になるだろう

Lisp はどこから来たのか

ほぼ省略。

  • ENIACとかのスイッチ
  • アセンブラ
  • Lisp/FORTRAN/C/COBOL
  • C++/Java

アセンブラ高級言語説。

Lisp の力はどこから来るのか

Lispは以下の点で、パワフルな言語である。

  1. 言語にたくさんの機能が最初から組み込まれている
  2. 言語の内部の深いところまで手を入れて、それによって自分のやりたいことを言語にさせられるようにできる

これらの性質は、時に相反する性質であり、とくにJavaやCだとすごく大変。

第1部 Lispは力なり

第1章 さあLispを始めてみよう

  • Common Lisp/Scheme

Guile/Clisp

clisp
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.49 (2010-07-07) <http://clisp.cons.org/>

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2010

Type :h and hit Enter for context help.

[1]> (+ 3 (* 2 4))
11
[2]>
  • Common Lisp と Scheme がLisp二大方言。本書ではCommon Lispを扱う
  • Common Lisp はマルチパラダイム言語であり、様々なプログラミング手法をサポートする。
  • CLISP は Common Lisp の実装の一つで、簡単にインストールできる。(yum install -y clisp/brew install clisp)
  • CLISP の REPLで簡単にごにょごにょ出来る。
  • 入力を間違えてCLISPが訳の分からない動作を始めたら、:qで直る。

第2章 はじめての Lisp プログラム

グローバル変数

defparameterでグローバル変数を定義できる

[1]> (defparameter *small* 1)
*SMALL*
[2]> (defparameter *big* 1)
*BIG*

変数再定義(defparameter)

[4]> (defparameter *foo* 5)
*FOO*
[5]> *foo*
5
[6]> (defparameter *foo* 6)
*FOO*
[7]> *foo*
6

グローバル変数(defvar)

[1]> (defvar *foo* 5)
*FOO*
[2]> *foo*
5
[3]> (defvar *foo* 6)
*FOO*
[4]> *foo*
5

Lispのエチケット

[5]> (defparameter *small* 1)
*SMALL*
-- こういう方法もできちゃう
[6]>  ( defparameter
 *small* 1)
*SMALL*
[7]> *small*
1

グローバル関数定義

(use defun)

[11]> (ash 11 1)
22
[12]> (ash 11 2)
44
[13]> (ash 11 3)
88
[14]> (ash 11 -1)
5
[15]> (defparameter *small* 1)
*SMALL*
[16]> (defparameter *big* 100)
*BIG*
[17]> (defun guess-my-number()
         (ash (+ *small* *big*) -1))
GUESS-MY-NUMBER
[18]> (guess-my-number)
50
[19]> (defun smaller ()
    (setf *big* (1- (guess-my-number)))
    (guess-my-number))
SMALLER
[20]> (defun bigger ()
    (setf *small* (1+ (guess-my-number)))
    (guess-my-number))
BIGGER
[21]> (bigger)
75
[22]> (smaller)
62
[23]> (smaller)
56

let/flet/labels

  • ローカル変数にはlet/ローカル関数にはflet
  • 自分自身を呼び出せるローカル関数はlabels
[26]> (labels ((a (n)
(+ n 5))
(b (n)
(+ (a n) 6)))
(b 10))
21
[27]> (flet ((a (n)
(+ n 5))
(b (n)
(+ (a n) 6)))
(b 10))

*** - EVAL: undefined function A
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of (FDEFINITION 'A).
RETRY          :R2      Retry
STORE-VALUE    :R3      Input a new value for (FDEFINITION 'A).
ABORT          :R4      Abort main loop
Break 1 [28]> :q

letとflet

[37]> (let ((a 5)
(b 6))
(+ a b))
11
[38]> (flet ((a 5)
(b 6))
(+ a b))

*** - FUNCTION: lambda-list for A should be a list, not 5
The following restarts are available:
ABORT          :R1      Abort main loop
Break 1 [39]> :q
[43]> (let (a 3))

*** - LET: illegal variable specification 3
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead.
ABORT          :R2      Abort main loop
Break 1 [44]> :q
[45]> (let ((a 5) (b 6)))
NIL
[46]> (let ((a 5) (b 6)) (+ a b))
11