lisp
ISLisp

ISLisp 関数の使い方

More than 1 year has passed since last update.

はじめに

ISLispの組込み関数、特殊形式について五月雨式に書き込んでいきます。全部をいっぺんに書き上げるのはたいへんそうでした。時間のある時に細切れ時間を利用して書いていこうと思っています。

編集リクエスト 歓迎

筆者はわりとおっちょこちょいです。間違った記述、スペルミスなどありましたら、編集リクエストお送りいただければ幸いです。

Funtions

(functionp obj) -> boolean

objが普通の関数あるいは包括関数であるときにtを返し、そうでなければnilを返します。

> (functionp (function car))
T
> 

(function fn) -> function

fnが関数名であるとき、その実体を返します。#'と書く省略記法もあります。

> (function -)
<subr>
> (funcall (function -) 3)
-3
> (apply #'- '(4 3))
1
> 

ISLispはCommon Lispと同様にLISP-2と言われるものです。関数名と変数名とが違う名前空間で管理されています。変数名はそのままで使えるのですが、関数名からその実体を呼び出すときにはfunctionを付ける必要があります。

(lambda lambda-list form) -> function

ラムダ式です。Schemeにおけるそれと使い方は同じです。関数ではありますがfunctionを付加する必要はありません。そのまま使えます。

> ((lambda (x y) (+ x y)) 3 4)
7
> 

(labels ((fn lambda-list form) ...) body-form)

局所定義をする特殊形式です。再帰する局所関数定義を書くときに使います。

(labels ((evenp (n)
                (if (= n 0)
                    t
                    (oddp (- n 1))))
         (oddp (n)
               (if (= n 0)
                   nil
                   (evenp (- n 1)))))
  (evenp 88))

> T
>

(flet ((fn lambda-list form) ...) body-form)

labelsと同様に局所的関数定義に使えます。fletが異なるのは再帰的な定義には使えないことです。局所定義が参照するのは直前の定義です。例を参照してください。

> (flet ((f (x) (+ x 3)))
    (flet ((f (x) (+ x (f x))))
      (f 7)))
17
>

(apply function obj... list) -> object

関数に引数を適用してその結果を返します。与える引数は最初は個々の引数で、最後はリストにまとめた引数です。リストだけでも構いません。

> (apply #'max '(1 2 3 4 5))
5
> (apply #'max 1 2 '(3 4 5))
5
> 

(funcall function obj ...) -> object

関数に引数を適用してその結果を返します。applyと似ていますがfuncallではリストは使いません。funcallはappyを使って次のように定義されます。

定義
(defun funcall (functioon :rest arguments)
  (apply function arguments))
> (funcall #'+ 1 2 3)
6
> 

Defining operators

(defconstant name form) -> symbol

定数を定義します。その定数の値を変更しようとするとエラーになります。

> (defconstant e (exp 1))
E
> e
2.718281828459045
> (setq e 1)
Can't modify at setq E
> 

(defglobal name form) -> symbol

大域変数を定義します。

> (defglobal today 'wednsday)
TODAY
> today
WEDNSDAY
> 

(defdynamic name form) -> symbol

ISLispの特徴的なところです。ISLispは基本的に静的スコープです。しかし、動的スコープがあった方が良い場合もあります。defdynamicは動的変数を定義します。静的変数と動的変数は名前空間が分かれています。静的変数は単にシンボルですが、動的変数は(dynamic x)のようにして値を得ます。

> (defdynamic *color* 'red)
*COLOR*
> (dynamic *color*)
RED
> (defun what-color () (dynamic *color*))
WHAT-COLOR
> (what-color)
RED
> *color*
Unbound variable at eval *COLOR*
> 

(defun fn lambda-list form) -> symbol

defunは関数定義のために使います。Common Lisp と同じです。

> (defun caar (x) (car (car x)))
CAAR
> (caar '((a b) c))
A
> 

Number class

(numberp obj) -> booleal

数かとうかを判定します。

> (numberp 3)
T
> (numberp -0.3)
T
> (numberp '(a b c))
NIL
> (numberp "17")
NIL
> 

(parse-number string) -> number

文字列を数に変換します。

> (parse-number "123.34")
123.34
> (parse-number "#XFACE")
64206
>

(max x1 x2 ... xn) -> number

最大値を返します。

> (max -5 3)
3
> 

(min x1 x2 ... xn) -> number

最小値を返します。

> (min 1 5 2 4 3)
1

(abs x) -. number

絶対値を返します。

> (abs -3)
3

(sin x) -> number

正弦

(cos x) -> number

余弦

(tan x) -> number

正接

(sinh x) -> number

双曲線正弦

(cosh x) -> number

双曲線余弦

(tanh x) -> number

双曲線正接

(atanh x) -> number

双曲線正接の逆関数

Float class

*most0positive-float* -> float

処理系で扱える最大正の浮動小数点数

most-negative-float -> float

処理系で扱える最大負の浮動小数点数

(floatp obj) -> boolean

objが浮動小数点数のときにtを返し、そうでないときにはnilを返します。

(float x) -> float

数xを浮動小数点数に変換して返します。

Stream

(create-string-input-stream string) -> stream

入力用の文字列ストリームを生成します。文字列ストリームはちょっとしたメモに便利です。

> (let ((str (create-string-input-stream "this is a string")))
    (list (read str) (read str) (read str)))
(THIS IS A)
> 

(create-string-output-stream) -> stream

出力用の文字列ストリームを生成します。

> (let ((str (create-string-output-stream)))
    (format str "hello")
    (format str "world")
(get-output-stream-string str))
"helloworld"
> 

(get-output-stream-string stream) -> string

文字列ストリームから文字列を取り出します。

> (let ((str (create-string-output-stream)))
    (format str "hello")
    (format str "world")
(get-output-stream-string str))
"helloworld"
>