ISLisp 関数の使い方

  • 0
    いいね
  • 0
    コメント

    はじめに

    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"
    >