Lisp-quick-guide
LISP-概要
ジョンマッカーシーは、FORTRANの開発直後の1958年にLISPを発明しました。 これは、IBM 704コンピューターでSteve Russellによって最初に実装されました。
シンボリック情報を効果的に処理するため、人工知能プログラムに特に適しています。
Common Lispは、1980年代と1990年代に、ZetaLispやNIL(Lispの新しい実装)など、Maclispの後継であるいくつかの実装グループの作業を統合しようとして生まれました。
これは、特定の実装用に簡単に拡張できる共通言語として機能します。
Common LISPで記述されたプログラムは、語長などのマシン固有の特性に依存しません。
Common LISPの機能
- マシンに依存しません
- 反復的な設計方法論と簡単な拡張性を使用します。
- プログラムを動的に更新できます。
- 高レベルのデバッグを提供します。
- 高度なオブジェクト指向プログラミングを提供します。
- 便利なマクロシステムを提供します。
- オブジェクト、構造、リスト、ベクトル、調整可能な配列、ハッシュテーブル、シンボルなどの幅広いデータ型を提供します。
- 式ベースです。
- オブジェクト指向の条件システムを提供します。
- 完全なI/Oライブラリを提供します。
- 広範な制御構造を提供します。
LISPに組み込まれたアプリケーション
Lispで構築された大成功のアプリケーション。
- Emacs
- G2
- AutoCad
- イゴール彫刻家
- ヤフーストア
LISP-環境設定
ローカル環境のセットアップ
Lispプログラミング言語用に環境をセットアップする場合は、コンピューター上で次の2つのソフトウェア、(a)Text Editorおよび(b)The Lisp Executerが必要です。
テキストエディタ
これは、プログラムの入力に使用されます。 いくつかのエディターの例には、Windows Notepad、OS Editコマンド、Brief、Epsilon、EMACS、vimまたはviが含まれます。
テキストエディタの名前とバージョンは、オペレーティングシステムによって異なる場合があります。 たとえば、メモ帳はWindowsで使用され、vimまたはviはLinuxまたはUNIXだけでなくWindowsでも使用できます。
エディターで作成するファイルはソースファイルと呼ばれ、プログラムのソースコードが含まれています。 Lispプログラムのソースファイルには、通常、拡張子「 .lisp 」が付いています。
プログラミングを開始する前に、テキストエディタが1つあることを確認し、コンピュータプログラムを作成し、ファイルに保存し、最後に実行する十分な経験があることを確認してください。
Lisp実行者
ソースファイルに記述されたソースコードは、プログラムの人間が読めるソースです。 CPUが指定された指示に従って実際にプログラムを実行できるように、機械語に変換するには「実行」する必要があります。
このLispプログラミング言語は、ソースコードを実行して最終的な実行可能プログラムにするために使用されます。 プログラミング言語に関する基本的な知識があることを前提としています。
CLISPは、WindowsでLISPをセットアップするために使用されるGNU Common LISPマルチアーキテクチャコンパイラです。 Windowsバージョンは、WindowsでMingWを使用してUNIX環境をエミュレートします。 インストーラーがこれを処理し、clispをWindowsのPATH変数に自動的に追加します。
ここからWindows用の最新のCLISPを入手できます-https://sourceforge.net/projects/clisp/files/latest/download
デフォルトでは、行ごとのインタープリター用にショートカットが[スタート]メニューに作成されます。
CLISPの使用方法
インストール中、オプションを選択すると、 clisp がPATH変数に自動的に追加されます(推奨)。これは、新しいコマンドプロンプトウィンドウを開き、「clisp」と入力してコンパイラを起動できることを意味します。
- .lispまたは* .lspファイルを実行するには、単に使用します-
LISP-プログラム構造
LISP式は、シンボリック式またはs式と呼ばれます。 s-expressionsは、3つの有効なオブジェクト、アトム、リスト、および文字列で構成されています。
すべてのs式は有効なプログラムです。
LISPプログラムは、*インタープリター*または*コンパイル済みコード*で実行されます。
インタープリターは、反復評価ループでソースコードをチェックします。これは、読み取り-評価-印刷ループ(REPL)とも呼ばれます。 プログラムコードを読み取り、評価し、プログラムから返された値を出力します。
簡単なプログラム
s-expressionを記述して、3つの数値7、9、および11の合計を見つけましょう。 これを行うには、インタープリタープロンプトで入力します。
LISPは結果を返します-
コンパイルされたコードと同じプログラムを実行する場合は、myprog.lispという名前のLISPソースコードファイルを作成し、その中に次のコードを入力します。
実行ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は-
LISPはプレフィックス表記を使用します
LISPは* prefix notation。*を使用していることに気づいたかもしれません。
上記のプログラムでは、+記号は数字の合計プロセスの関数名として機能します。
プレフィックス表記では、演算子はオペランドの前に記述されます。 たとえば、式
として書かれます-
別の例を見てみましょう、60 ^ o ^ Fの華氏温度を摂氏スケールに変換するコードを書きましょう-
この変換の数式は次のようになります-
main.lispという名前のソースコードファイルを作成し、次のコードを入力します。
[実行]ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は-
LISPプログラムの評価
LISPプログラムの評価には2つの部分があります-
- リーダープログラムによるプログラムテキストのLispオブジェクトへの翻訳
- 評価プログラムによるこれらのオブジェクトに関する言語のセマンティクスの実装
評価プロセスは、次の手順を実行します-
- リーダーは、文字列をLISPオブジェクトまたは s-expressions に変換します。 評価者は、s式から構築されるLisp フォーム*の構文を定義します。 この第2レベルの評価では、どの s-expressions がLISP形式であるかを決定する構文を定義します。
- 評価者は、有効なLISP形式を引数として受け取り、値を返す関数として機能します。 これが、式/フォーム全体を引数として評価者に送信しているため、LISP式をかっこで囲む理由です。
「Hello World」プログラム
新しいプログラミング言語を学ぶことは、その言語で全世界に挨拶する方法を学ぶまで、実際にはうまくいきません!
したがって、main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力してください。
実行ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は-
LISP-基本的な構文
LISPの基本的な構成要素
LISPプログラムは3つの基本的なビルディングブロックで構成されています-
atom
list
ひも
以下は、いくつかの有効な原子の例です-
- リスト*は、括弧で囲まれた一連のアトムおよび/または他のリストです。
以下はいくつかの有効なリストの例です-
以下は、いくつかの有効な文字列の例です-
コメントを追加する
セミコロン記号(;)は、コメント行を示すために使用されます。
例えば、
実行ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は-
次へ進む前の注目すべきポイント
以下は、注意すべき重要な点の一部です-
- LISPの基本的な数値演算は、+、-、*、および/です。
- LISPは、関数呼び出しf(x)を(f x)として表します。たとえば、cos(45)はcos 45として記述されます。
- LISP式は大文字と小文字を区別せず、cos 45またはCOS 45は同じです。
- LISPは、関数の引数を含むすべてを評価しようとします。 3種類の要素のみが定数であり、常に独自の値を返します
- 番号
- 論理的な真を表す文字* t、*。
- 空のリストと同様に、論理falseを表す値* nil、*。
LISPフォームについてもう少し
前の章で、LISPコードの評価プロセスは次のステップを踏むことを述べました。
- リーダーは、文字列をLISPオブジェクトまたは s-expressions に変換します。 評価者は、s式から構築されるLisp フォーム*の構文を定義します。 この第2レベルの評価は、どのS式がLISP形式であるかを決定する構文を定義します。
これで、LISPフォームが可能になります。
- アトム
- 空または非リスト
- 最初の要素として記号を含むリスト
評価者は、有効なLISP形式を引数として受け取り、値を返す関数として機能します。 これが、式/フォーム全体を引数として評価者に送信しているため、* LISP式をかっこで囲む理由です。
LISPの命名規則
名前または記号は、空白、開き括弧と閉じ括弧、二重引用符と単一引用符、バックスラッシュ、コンマ、コロン、セミコロン、垂直バー以外の任意の数の英数字で構成できます。 名前にこれらの文字を使用するには、エスケープ文字(\)を使用する必要があります。
名前には数字を含めることができますが、数字だけで読み取られるため、完全に数字で構成されるわけではありません。 同様に、名前にピリオドを含めることができますが、ピリオドだけで名前を作成することはできません。
単一引用符の使用
LISPは、関数の引数やリストメンバーを含むすべてを評価します。
時には、文字どおりアトムまたはリストを取得する必要があり、それらを評価したり、関数呼び出しとして処理したりしないようにします。
これを行うには、アトムまたはリストの前に単一引用符を付ける必要があります。
次の例はこれを示しています。
main.lispという名前のファイルを作成し、次のコードを入力します。
実行ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は-
LISP-データ型
LISPでは、変数は入力されませんが、データオブジェクトは入力されます。
LISPデータ型は次のように分類できます。
- スカラー型-たとえば、数値型、文字、記号など
- データ構造-たとえば、リスト、ベクトル、ビットベクトル、文字列。
明示的に宣言していない限り、どの変数もその値として任意のLISPオブジェクトを取ることができます。
ただし、LISP変数のデータ型を指定する必要はありませんが、特定のループ展開、メソッド宣言、および後の章で説明するその他の状況で役立ちます。
データ型は階層に配置されます。 データタイプはLISPオブジェクトのセットであり、多くのオブジェクトはそのようなセットの1つに属する場合があります。
LISPのタイプ指定子
型指定子は、データ型のシステム定義のシンボルです。
array | fixnum | package | simple-string |
atom | float | pathname | simple-vector |
bignum | function | random-state | single-float |
bit | hash-table | ratio | standard-char |
bit-vector | integer | rational | stream |
character | keyword | readtable | string |
[common] | list | sequence | [string-char] |
compiled-function | long-float | short-float | symbol |
complex | nill | signed-byte | t |
cons | null | simple-array | unsigned-byte |
double-float | number | simple-bit-vector | vector |
これらのシステム定義型とは別に、独自のデータ型を作成できます。 defstruct 関数を使用して構造タイプが定義されている場合、構造タイプの名前は有効なタイプシンボルになります。
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
実行ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は-
例2
次に、前の例で使用した変数のタイプを確認しましょう。 mainという名前の新しいソースコードファイルを作成します。 lispに次のコードを入力します。
実行ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は-
LISP-マクロ
マクロを使用すると、標準のLISPの構文を拡張できます。
技術的には、マクロは引数としてs-expressionを取り、評価されるLISPフォームを返す関数です。
マクロを定義する
LISPでは、名前付きマクロは、* defmacro。*という名前の別のマクロを使用して定義されます。マクロを定義するための構文は-
マクロ定義は、マクロの名前、パラメーターリスト、オプションのドキュメント文字列、およびマクロによって実行されるジョブを定義するLisp式の本体で構成されます。
例
setTo10という名前の簡単なマクロを作成してみましょう。このマクロは数値を取得し、その値を10に設定します。
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
実行ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は-
LISP-変数
LISPでは、各変数は*記号*で表されます。 変数の名前はシンボルの名前であり、シンボルのストレージセルに保存されます。
グローバル変数
グローバル変数はLISPシステム全体で永続的な値を持ち、新しい値が指定されるまで有効です。
通常、グローバル変数は defvar 構造を使用して宣言されます。
例えば
[実行]ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は
LISPには変数の型宣言がないため、 setq コンストラクトでシンボルの値を直接指定します。
例えば
上記の式は、値10を変数xに割り当てます。 式としてシンボル自体を使用して、変数を参照できます。
例えば
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
[実行]ボタンをクリックするか、Ctrl + Eを入力すると、LISPがすぐに実行し、返される結果が返されます。
ローカル変数
ローカル変数は、特定のプロシージャ内で定義されます。 関数定義内の引数として指定されたパラメーターもローカル変数です。 ローカル変数は、それぞれの関数内でのみアクセス可能です。
グローバル変数と同様に、ローカル変数も setq コンストラクトを使用して作成できます。
ローカル変数を作成するための let と prog の2つの構造があります。
let構文の構文は次のとおりです。
ここで、var1、var2、.. varnは変数名、val1、val2、.. valnは、それぞれの変数に割り当てられた初期値です。
変数の初期値を含めない場合、* nil。*に割り当てられます
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
[実行]ボタンをクリックするか、Ctrl + Eを入力すると、LISPがすぐに実行し、返される結果が返されます。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
[実行]ボタンをクリックするか、Ctrl + Eを入力すると、LISPがすぐに実行し、返される結果が返されます。
LISP-定数
LISPでは、定数はプログラムの実行中に値を変更しない変数です。 定数は defconstant コンストラクトを使用して宣言されます。
例
次の例は、グローバル定数PIを宣言し、後で円の面積を計算する_area-circle_という名前の関数内でこの値を使用することを示しています。
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
[実行]ボタンをクリックするか、Ctrl + Eを入力すると、LISPがすぐに実行し、返される結果が返されます。
LISP-オペレーター
演算子は、特定の数学的または論理的な操作を実行するようコンパイラーに指示する記号です。 LISPでは、さまざまな機能、マクロ、およびその他の構成要素によってサポートされる、データに対する多数の操作が可能です。
データで許可された操作は次のように分類できます-
- 算術演算
- 比較操作
- 論理演算
- ビット演算
算術演算
次の表は、LISPでサポートされているすべての算術演算子を示しています。 変数 A が10を保持し、変数 B が20を保持すると仮定します-
Operator | Description | Example |
---|---|---|
+ | Adds two operands | (+A B) will give 30 |
- | Subtracts second operand from the first | (- A B) will give -10 |
* | Multiplies both operands | (* A B) will give 200 |
/ | Divides numerator by de-numerator | (/B A) will give 2 |
mod,rem | Modulus Operator and remainder of after an integer division | (mod B A )will give 0 |
incf | Increments operator increases integer value by the second argument specified | (incf A 3) will give 13 |
decf | Decrements operator decreases integer value by the second argument specified | (decf A 4) will give 9 |
比較操作
次の表は、数値を比較するLISPがサポートするすべての関係演算子を示しています。 ただし、他の言語の関係演算子とは異なり、LISP比較演算子は3つ以上のオペランドを取ることができ、数字のみで機能します。
変数 A が10を保持し、変数 B が20を保持すると仮定します-
Operator | Description | Example |
---|---|---|
= | Checks if the values of the operands are all equal or not, if yes then condition becomes true. | (= A B) is not true. |
/= | Checks if the values of the operands are all different or not, if values are not equal then condition becomes true. | (/= A B) is true. |
> | Checks if the values of the operands are monotonically decreasing. | (> A B) is not true. |
< | Checks if the values of the operands are monotonically increasing. | (< A B) is true. |
>= | Checks if the value of any left operand is greater than or equal to the value of next right operand, if yes then condition becomes true. | (>= A B) is not true. |
⇐ | Checks if the value of any left operand is less than or equal to the value of its right operand, if yes then condition becomes true. | (⇐ A B) is true. |
max | It compares two or more arguments and returns the maximum value. | (max A B) returns 20 |
min | It compares two or more arguments and returns the minimum value. | (min A B) returns 10 |
ブール値の論理演算
Common LISPは、ブール値を操作する* and、or、、 *not の3つの論理演算子を提供します。 A の値がnilで、 B の値が5であると仮定します-
Operator | Description | Example |
---|---|---|
and | It takes any number of arguments. The arguments are evaluated left to right. If all arguments evaluate to non-nil, then the value of the last argument is returned. Otherwise nil is returned. | (and A B) will return NIL. |
or | It takes any number of arguments. The arguments are evaluated left to right until one evaluates to non-nil, in such case the argument value is returned, otherwise it returns nil. | (or A B) will return 5. |
not | It takes one argument and returns t *if the argument evaluates to nil.* | (not A) will return T. |
数値のビット演算
ビットごとの演算子はビットに対して機能し、ビットごとの操作を実行します。 ビットごとのAND、OR、およびXOR演算の真理値表は次のとおりです-
p | q | p and q | p or q | p xor q |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 1 |
次の表に、LISPでサポートされているビット単位の演算子を示します。 変数 A が60を保持し、変数 B が13を保持すると仮定します-
Operator | Description | Example |
---|---|---|
logand | This returns the bit-wise logical AND of its arguments. If no argument is given, then the result is -1, which is an identity for this operation. | (logand a b)) will give 12 |
logior | This returns the bit-wise logical INCLUSIVE OR of its arguments. If no argument is given, then the result is zero, which is an identity for this operation. | (logior a b) will give 61 |
logxor | This returns the bit-wise logical EXCLUSIVE OR of its arguments. If no argument is given, then the result is zero, which is an identity for this operation. | (logxor a b) will give 49 |
lognor | This returns the bit-wise NOT of its arguments. If no argument is given, then the result is -1, which is an identity for this operation. | (lognor a b) will give -62, |
logeqv | This returns the bit-wise logical EQUIVALENCE (also known as exclusive nor) of its arguments. If no argument is given, then the result is -1, which is an identity for this operation. | (logeqv a b) will give -50 |
LISP-意思決定
意思決定構造では、プログラマーが、プログラムによって評価またはテストされる1つ以上の条件を、条件が真であると判断された場合に実行されるステートメント、およびオプションで条件が実行された場合に実行される他のステートメントとともに指定する必要があります偽と判断されます。
以下は、ほとんどのプログラミング言語で見られる典型的な意思決定構造の一般的な形式です-
LISPは、次のタイプの意思決定構造を提供します。 詳細を確認するには、次のリンクをクリックしてください。
Sr.No. | Construct & Description |
---|---|
1 |
このコンストラクトは、複数のテストアクション句のチェックに使用されます。 他のプログラミング言語のネストされたifステートメントと比較できます。 |
2 |
if構造にはさまざまな形式があります。 最も単純な形式では、テスト句、テストアクション、およびその他の結果アクションが続きます。 test句がtrueと評価されると、テストアクションが実行されます。それ以外の場合、結果句が評価されます。 |
3 |
最も単純な形式では、テスト句とテストアクションが後に続きます。 test句がtrueと評価されると、テストアクションが実行されます。それ以外の場合、結果句が評価されます。 |
4 |
この構造は、cond構造のような複数のtest-action句を実装します。 ただし、キーフォームを評価し、そのキーフォームの評価に基づいて複数のアクション句を許可します。 |
LISP-ループ
コードのブロックを何度も実行する必要がある場合があります。 ループステートメントを使用すると、ステートメントまたはステートメントのグループを複数回実行できます。ほとんどのプログラミング言語では、以下がループステートメントの一般的な形式です。
LISPは、ループ要件を処理するために次のタイプの構造を提供します。 詳細を確認するには、次のリンクをクリックしてください。
Sr.No. | Construct & Description |
---|---|
1 |
|
2 |
ループの構成により、他の言語で最も一般的な反復のようなforループを実装できます。 |
3 |
doコンストラクトは、LISPを使用して反復を実行するためにも使用されます。 反復の構造化された形式を提供します。 |
4 |
dotimesコンストラクトにより、一定の反復回数のループが可能になります。 |
5 |
dolistコンストラクトにより、リストの各要素を反復処理できます。 |
ブロックを正常に終了する
次の例はこれを示しています-
例
main.lispという名前の新しいソースコードファイルを作成し、その中に次のコードを入力します-
実行ボタンをクリックするか、Ctrl + Eを入力すると、LISPはすぐに実行し、返される結果は-
LISP-機能
関数は、一緒にタスクを実行するステートメントのグループです。
コードを別々の機能に分割できます。 コードを異なる関数に分割する方法はユーザー次第ですが、論理的には通常、各関数が特定のタスクを実行するように分割されます。
LISPでの関数の定義
- 機能名
- 関数のパラメーター
- 関数の本体
defunの構文は-
簡単な例で概念を説明しましょう。
例1
4つの数値の平均を出力する_averagenum_という名前の関数を作成してみましょう。 これらの数値をパラメーターとして送信します。
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
例2
円の半径が引数として与えられたときに円の面積を計算する関数を定義して呼び出しましょう。
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
次のことに注意してください-
- パラメーターとして空のリストを指定できます。つまり、関数は引数をとらず、リストは空で、()と記述されます。
- LISPでは、オプションの引数、複数の引数、およびキーワードの引数も使用できます。
- ドキュメント文字列は、関数の目的を説明しています。 これは関数の名前に関連付けられており、 documentation 関数を使用して取得できます。
- 関数の本体は、任意の数のLisp式で構成できます。
- 本体の最後の式の値は、関数の値として返されます。
- return-from 特殊演算子を使用して、関数から値を返すこともできます。
上記の概念について簡単に説明します。 詳細を見つけるために次のリンクをクリックしてください-
- リンク:/lisp/lisp_optional_parameters [オプションパラメータ]
- リンク:/lisp/lisp_rest_parameters [残りのパラメーター]
- リンク:/lisp/lisp_keyword_parameters [キーワードパラメータ]
- リンク:/lisp/lisp_returning_values_functions [関数から値を返す]
- リンク:/lisp/lisp_lambda_functions [ラムダ関数]
- リンク:/lisp/lisp_mapping_functions [マッピング関数]
LISP-述語
述語は、特定の条件について引数をテストし、条件がfalseの場合、またはnil以外の値が条件がtrueの場合にnilを返す関数です。
次の表は、最も一般的に使用される述語のいくつかを示しています-
Sr.No. | Predicate & Description |
---|---|
1 |
atom 1つの引数を取り、引数がアトムの場合はtを返し、そうでない場合はnilを返します。 |
2 |
equal 2つの引数を取り、それらが構造的に等しい場合は t を返し、そうでない場合は nil を返します。 |
3 |
eq 2つの引数を取り、同じメモリ位置を共有する同じオブジェクトである場合は t を返し、そうでない場合は nil を返します。 |
4 |
eql 2つの引数を取り、引数が eq であるか、同じ値の同じ型の数であるか、同じ文字を表す文字オブジェクトであるか、そうでない場合は nil の場合、 t を返します。 |
5 |
evenp 1つの数値引数を取り、引数が偶数の場合は t を返し、そうでない場合は nil を返します。 |
6 |
oddp 1つの数値引数を取り、引数が奇数の場合は t を返し、そうでない場合は nil を返します。 |
7 |
zerop 1つの数値引数を取り、引数がゼロの場合は t を返し、そうでない場合は nil を返します。 |
8 |
null 1つの引数を取り、引数の評価がnilの場合は t を返し、それ以外の場合は nil を返します。 |
9 |
listp 1つの引数を取り、引数がリストに評価される場合は t を返し、そうでない場合は nil を返します。 |
10 |
greaterp 1つ以上の引数を取り、単一の引数がある場合、または引数が左から右に連続して大きい場合は t を返し、そうでない場合は nil を返します。 |
11 |
lessp 1つ以上の引数を取り、単一の引数がある場合、または引数が左から右に連続して小さい場合は t を返し、そうでない場合は nil を返します。 |
12 |
numberp 1つの引数を取り、引数が数値の場合は t を返し、そうでない場合は nil を返します。 |
13 |
symbolp 1つの引数を取り、引数がシンボルの場合は t を返し、それ以外の場合は nil を返します。 |
14 |
integerp 1つの引数を取り、引数が整数の場合は t を返し、それ以外の場合は nil を返します。 |
15 |
rationalp 1つの引数を取り、引数が有理数(比率または数値)の場合は t を返し、それ以外の場合は nil を返します。 |
16 |
floatp 1つの引数を取り、引数が浮動小数点数の場合は t を返し、それ以外の場合は nil を返します。 |
17 |
realp 1つの引数を取り、引数が実数の場合は t を返し、それ以外の場合は nil を返します。 |
18 |
complexp 1つの引数を取り、引数が複素数の場合は t を返します。それ以外の場合は* nil。*を返します |
19 |
characterp 1つの引数を取り、引数が文字の場合は t を返し、それ以外の場合は nil を返します。 |
20 |
stringp 1つの引数を取り、引数が文字列オブジェクトの場合は t を返します。それ以外の場合は nil を返します。 |
21 |
arrayp 1つの引数を取り、引数が配列オブジェクトの場合は t を返し、そうでない場合は nil を返します。 |
22 |
packagep 1つの引数を取り、引数がパッケージの場合は t を返します。それ以外の場合は* nil。*を返します |
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
例2
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-数字
Common Lispは、いくつかの種類の数値を定義します。 number データタイプには、LISPでサポートされるさまざまな種類の数値が含まれます。
LISPでサポートされている番号タイプは-
- 整数
- 比率
- 浮動小数点数 *複素数
次の図は、LISPで使用可能な番号階層とさまざまな数値データ型を示しています-
LISPのさまざまな数値タイプ
次の表は、LISPで利用可能なさまざまな数値型データを示しています-
Sr.No. | Data type & Description |
---|---|
1 |
このデータ型は、大きすぎず、主に-215〜215-1の範囲の整数を表します(マシンに依存) |
2 |
bignum これらは、LISPに割り当てられたメモリの量によってサイズが制限される非常に大きな数値であり、fixnumの数値ではありません。 |
3 |
ratio 分子/分母形式の2つの数値の比率を表します。/関数は、引数が整数の場合、常に結果を比率で生成します。 |
4 |
float 非整数の数値を表します。 精度が向上する4つのfloatデータ型があります。 |
5 |
complex
|
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
数字関数
次の表は、いくつかの一般的に使用される数値関数を説明しています-
Sr.No. | Function & Description |
---|---|
1 |
+, -, *,/ それぞれの算術演算 |
2 |
sin, cos, tan, acos, asin, atan それぞれの三角関数。 |
3 |
sinh, cosh, tanh, acosh, asinh, atanh それぞれの双曲線関数。 |
4 |
exp べき乗関数。 e ^ x ^を計算します |
5 |
expt 指数関数は、ベースとパワーの両方を取ります。 |
6 |
sqrt 数値の平方根を計算します。 |
7 |
log 対数関数。 1つのパラメーターが与えられた後、自然対数を計算します。それ以外の場合、2番目のパラメーターがベースとして使用されます。 |
8 |
conjugate 数値の複素共役を計算します。 実数の場合、数値自体を返します。 |
9 |
abs 数値の絶対値(または大きさ)を返します。 |
10 |
gcd 指定された数値の最大公約数を計算します。 |
11 |
lcm 指定された数値の最小公倍数を計算します。 |
12 |
isqrt 指定された自然数の正確な平方根以下の最大整数を提供します。 |
13 |
floor, ceiling, truncate, round これらの関数はすべて、2つの引数を数値として受け取り、商を返します。 floor はratioより大きくない最大の整数を返します。 ceiling はratioよりも小さい小さい整数を選択します。そして、 round はratioに最も近い整数を選択します。 |
14 |
ffloor, fceiling, ftruncate, fround 上記と同じですが、商を浮動小数点数として返します。 |
15 |
mod, rem 除算の剰余を返します。 |
16 |
float 実数を浮動小数点数に変換します。 |
17 |
rational, rationalize 実数を有理数に変換します。 |
18 |
numerator, denominator 有理数のそれぞれの部分を返します。 |
19 |
realpart, imagpart 複素数の実数部と虚数部を返します。 |
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-キャラクター
LISPでは、文字は* character。*型のデータオブジェクトとして表されます。
文字自体の前に#\の前にある文字オブジェクトを示すことができます。 たとえば、#\ aは文字aを意味します。
スペースおよびその他の特殊文字は、文字の名前の前に#\を付けることで示すことができます。 たとえば、#\ SPACEはスペース文字を表します。
次の例はこれを示しています-
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
特殊文字
Common LISPでは、コードで次の特殊文字を使用できます。 それらは準標準文字と呼ばれます。
- #\ Backspace
- #\タブ
- #\改行
- #\ページ
- #\ Return
- #\ Rubout
文字比較関数
<および>などの数値比較関数および演算子は、文字に対して機能しません。 Common LISPは、コード内の文字を比較するための他の2つの関数セットを提供します。
1つのセットは大文字と小文字を区別し、もう1つのセットは大文字と小文字を区別しません。
次の表は、機能を提供します-
Case Sensitive Functions | Case-insensitive Functions | Description |
---|---|---|
char= | char-equal | Checks if the values of the operands are all equal or not, if yes then condition becomes true. |
char/= | char-not-equal | Checks if the values of the operands are all different or not, if values are not equal then condition becomes true. |
char< | char-lessp | Checks if the values of the operands are monotonically decreasing. |
char> | char-greaterp | Checks if the values of the operands are monotonically increasing. |
char⇐ | char-not-greaterp | Checks if the value of any left operand is greater than or equal to the value of next right operand, if yes then condition becomes true. |
char>= | char-not-lessp | Checks if the value of any left operand is less than or equal to the value of its right operand, if yes then condition becomes true. |
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-配列
LISPでは、 make-array 関数を使用して、単一または複数次元の配列を定義できます。 配列は、任意のLISPオブジェクトを要素として保存できます。
すべての配列は、連続したメモリ位置で構成されています。 最下位アドレスは最初の要素に対応し、最上位アドレスは最後の要素に対応します。
配列の次元数は、ランクと呼ばれます。
LISPでは、配列要素は非負の整数インデックスのシーケンスによって指定されます。 シーケンスの長さは、配列のランクと等しくなければなりません。 インデックスはゼロから始まります。
たとえば、my-arrayという名前の10セルの配列を作成するには、次のように記述できます-
aref関数を使用すると、セルのコンテンツにアクセスできます。 配列の名前とインデックス値の2つの引数を取ります。
たとえば、10番目のセルのコンテンツにアクセスするには、次のように記述します-
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
例2
3行3列の配列を作成しましょう。
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
実施例3
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
make-array関数の完全な構文
make-array関数は、他の多くの引数を取ります。 この関数の完全な構文を見てみましょう-
_dimensions_引数を除き、他のすべての引数はキーワードです。 次の表に、引数の簡単な説明を示します。
Sr.No. | Argument & Description |
---|---|
1 |
配列の次元を提供します。 これは、1次元配列の数であり、多次元配列のリストです。 |
2 |
:element-type これは型指定子であり、デフォルト値はTです。 いかなるタイプ |
3 |
:initial-element 初期要素の値。 すべての要素が特定の値に初期化された配列を作成します。 |
4 |
:initial-content オブジェクトとしての初期コンテンツ。 |
5 |
:adjustable 基になるメモリのサイズを変更できるサイズ変更可能な(または調整可能な)ベクトルを作成するのに役立ちます。 引数は、配列が調整可能かどうかを示すブール値で、デフォルト値はNILです。 |
6 |
:fill-pointer サイズ変更可能なベクターに実際に保存されている要素の数を追跡します。 |
7 |
:displaced-to これは、指定された配列と内容を共有する、置き換えられた配列または共有配列の作成に役立ちます。 両方の配列の要素タイプは同じである必要があります。 :displaced-toオプションは、:initial-elementまたは:initial-contentsオプションと一緒に使用することはできません。 この引数のデフォルトはnilです。 |
8 |
:displaced-index-offset 作成された共有配列のインデックスオフセットを提供します。 |
実施例4
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
変位した配列が二次元である場合-
あなたがコードを実行すると、それは次の結果を返します-
変位したインデックスオフセットを5に変更してみましょう-
あなたがコードを実行すると、それは次の結果を返します-
実施例5
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-文字列
Common Lispの文字列はベクトル、つまり文字の1次元配列です。
文字列リテラルは二重引用符で囲みます。 文字セットでサポートされている文字は、二重引用符( ")とエスケープ文字(\)を除き、二重引用符で囲んで文字列を作成できます。 ただし、これらをバックスラッシュ(\)でエスケープすることで含めることができます。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
文字列比較関数
<および>などの数値比較関数および演算子は、文字列では機能しません。 Common LISPは、コード内の文字列を比較するための他の2つの関数セットを提供します。 1つのセットは大文字と小文字を区別し、もう1つのセットは大文字と小文字を区別しません。
次の表は、機能を提供します-
Case Sensitive Functions | Case-insensitive Functions | Description |
---|---|---|
string= | string-equal | Checks if the values of the operands are all equal or not, if yes then condition becomes true. |
string/= | string-not-equal | Checks if the values of the operands are all different or not, if values are not equal then condition becomes true. |
string< | string-lessp | Checks if the values of the operands are monotonically decreasing. |
string> | string-greaterp | Checks if the values of the operands are monotonically increasing. |
string⇐ | string-not-greaterp | Checks if the value of any left operand is greater than or equal to the value of next right operand, if yes then condition becomes true. |
string>= | string-not-lessp | Checks if the value of any left operand is less than or equal to the value of its right operand, if yes then condition becomes true. |
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
ケース制御機能
次の表は、ケース制御機能について説明しています-
Sr.No. | Function & Description |
---|---|
1 |
string-upcase 文字列を大文字に変換します |
2 |
string-downcase 文字列を小文字に変換します |
3 |
string-capitalize 文字列の各単語を大文字にします |
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
ストリングのトリミング
次の表では、文字列のトリミング機能について説明します-
Sr.No. | Function & Description |
---|---|
1 |
string-trim 最初の引数として文字列を、2番目の引数として文字列を取り、最初の引数にあるすべての文字が引数文字列から削除された部分文字列を返します。 |
2 |
String-left-trim 最初の引数として文字列を、2番目の引数として文字列を取り、最初の引数にあるすべての文字が引数文字列の先頭から削除された部分文字列を返します。 |
3 |
String-right-trim 最初の引数として文字列文字を、2番目の引数として文字列を取り、最初の引数にあるすべての文字が引数文字列の末尾から削除された部分文字列を返します。 |
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
その他の文字列関数
LISPの文字列は配列であるため、シーケンスでもあります。 これらのデータ型については、今後のチュートリアルで説明します。 配列およびシーケンスに適用可能なすべての関数は、文字列にも適用されます。 ただし、さまざまな例を使用して、一般的に使用されるいくつかの機能を示します。
長さの計算
部分文字列の抽出
文字列内の文字へのアクセス
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
文字列のソートとマージ
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
文字列の反転
たとえば、main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
文字列の連結
concatenate関数は、2つの文字列を連結します。 これは汎用シーケンス関数であり、最初の引数として結果タイプを提供する必要があります。
たとえば、main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-シーケンス
シーケンスは、LISPの抽象データ型です。 ベクターとリストは、このデータ型の2つの具体的なサブタイプです。 シーケンスデータタイプで定義されたすべての機能は、実際にはすべてのベクトルおよびリストタイプに適用されます。
このセクションでは、シーケンスで最も一般的に使用される関数について説明します。
シーケンス(ベクターやリストなど)を操作するさまざまな方法を開始する前に、使用可能なすべての関数のリストを見てみましょう。
シーケンスを作成する
関数make-sequenceを使用すると、任意のタイプのシーケンスを作成できます。 この関数の構文は次のとおりです-
タイプ_sqtype_および長さ_sqsize._のシーケンスを作成します
オプションで、_:initial-element_引数を使用して値を指定することもできます。その場合、各要素はこの値に初期化されます。
たとえば、main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
シーケンスの汎用関数
Sr.No. | Function & Description |
---|---|
1 |
elt 整数インデックスを介して個々の要素にアクセスできます。 |
2 |
length シーケンスの長さを返します。 |
3 |
subseq 特定のインデックスで始まり、特定の終了インデックスまたはシーケンスの終わりまで続くサブシーケンスを抽出することにより、サブシーケンスを返します。 |
4 |
copy-seq 引数と同じ要素を含むシーケンスを返します。 |
5 |
fill シーケンスの複数の要素を単一の値に設定するために使用されます。 |
6 |
replace 2つのシーケンスを取り、最初の引数シーケンスは、2番目の引数シーケンスから連続した要素をコピーすることにより破壊的に変更されます。 |
7 |
count アイテムとシーケンスを受け取り、アイテムがシーケンスに表示される回数を返します。 |
8 |
reverse 引数の同じ要素を逆順で含むシーケンスを返します。 |
9 |
nreverse シーケンスと同じ要素を含む同じシーケンスを逆順で返します。 |
10 |
concatenate 任意の数のシーケンスの連結を含む新しいシーケンスを作成します。 |
11 |
position アイテムとシーケンスを受け取り、シーケンス内のアイテムのインデックスまたはnilを返します。 |
12 |
find アイテムとシーケンスが必要です。 シーケンス内のアイテムを見つけて返し、見つからない場合はnilを返します。 |
13 |
sort シーケンスと2つの引数の述語を取り、シーケンスのソートされたバージョンを返します。 |
14 |
merge 2つのシーケンスと1つの述語を取り、述語に従って2つのシーケンスをマージして生成されたシーケンスを返します。 |
15 |
map n引数の関数とn個のシーケンスを受け取り、関数をシーケンスの後続の要素に適用した結果を含む新しいシーケンスを返します。 |
16 |
some 述語を引数として受け取り、引数シーケンスを反復処理し、述語によって返される最初の非NIL値を返すか、述語が満たされない場合はfalseを返します。 |
17 |
every 述語を引数として受け取り、引数シーケンスを反復処理し、述語が失敗するとすぐに終了し、falseを返します。 述語が常に満たされる場合、trueを返します。 |
18 |
notany 述語を引数として受け取り、引数シーケンスを反復処理し、述語が満たされるとすぐにfalseを返し、満たされない場合はtrueを返します。 |
19 |
notevery 述語を引数として受け取り、引数シーケンスを反復処理し、述語が失敗するとすぐにtrueを返し、述語が常に満たされる場合はfalseを返します。 |
20 |
reduce 単一のシーケンスにマッピングし、最初にシーケンスの最初の2つの要素に2引数関数を適用し、次に関数とシーケンスの後続の要素によって返される値に適用します。 |
21 |
search シーケンスを検索して、テストを満たす1つ以上の要素を見つけます。 |
22 |
remove アイテムとシーケンスを受け取り、アイテムのインスタンスが削除されたシーケンスを返します。 |
23 |
delete これもアイテムとシーケンスを取り、アイテムを除いて同じ要素を持つ引数シーケンスと同じ種類のシーケンスを返します。 |
24 |
substitute 新しいアイテム、既存のアイテム、およびシーケンスを受け取り、既存のアイテムのインスタンスが新しいアイテムに置き換えられたシーケンスを返します。 |
25 |
nsubstitute 新しいアイテム、既存のアイテム、およびシーケンスを受け取り、既存のアイテムのインスタンスが新しいアイテムに置き換えられた同じシーケンスを返します。 |
26 |
mismatch 2つのシーケンスを取り、不一致の要素の最初のペアのインデックスを返します。 |
標準シーケンス関数のキーワード引数
Argument | Meaning | Default Value |
---|---|---|
:test | It is a two-argument function used to compare item (or value extracted by :key function) to element. | EQL |
:key | One-argument function to extract key value from actual sequence element. NIL means use element as is. | NIL |
:start | Starting index (inclusive) of subsequence. | 0 |
:end | Ending index (exclusive) of subsequence. NIL indicates end of sequence. | NIL |
:from-end | If true, the sequence will be traversed in reverse order, from end to start. | NIL |
:count | Number indicating the number of elements to remove or substitute or NIL to indicate all (REMOVE and SUBSTITUTE only). | NIL |
シーケンスで動作するこれらの関数の引数として使用されるさまざまな関数とキーワードについて説明しました。 次のセクションでは、例を使用してこれらの関数を使用する方法を説明します。
長さと要素を見つける
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
シーケンスの変更
一部のシーケンス関数を使用すると、シーケンスを繰り返し処理し、明示的なループを記述せずに特定の要素を検索、削除、カウント、またはフィルタリングするなどの操作を実行できます。
次の例はこれを示しています-
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
例2
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
シーケンスのソートとマージ
ソート関数は、シーケンスと2つの引数の述語を取り、シーケンスのソートされたバージョンを返します。
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
例2
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
シーケンス述語
関数every、some、notany、noteveryは、シーケンス述部と呼ばれます。
これらの関数はシーケンスを反復処理し、ブール述語をテストします。
これらの関数はすべて、最初の引数として述語を取り、残りの引数はシーケンスです。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
マッピングシーケンス
マッピング関数についてはすでに説明しました。 同様に、 map 関数を使用すると、1つ以上のシーケンスの後続の要素に関数を適用できます。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-リスト
リストは、従来のLISPで最も重要かつ主要な複合データ構造でした。 現在のCommon LISPは、ベクター、ハッシュテーブル、クラス、または構造などの他のデータ構造を提供します。
リストは、単一のリンクリストです。 LISPでは、リストは一緒にリンクされた cons という名前の単純なレコード構造のチェーンとして構築されます。
短所レコード構造
コンスセルまたはコンスオブジェクトは、関数* cons。*を使用して作成される値のペアです。
2番目の値がnilまたは別のコンスセルでない場合、値は括弧で囲まれたドットペアとして出力されます。
コンスセルの2つの値は、 car および* cdr。と呼ばれます。 *car 関数は、最初の値にアクセスするために使用され、 cdr 関数は、2番目の値にアクセスするために使用されます。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
上記の例は、コンス構造を使用して単一のリンクリストを作成する方法を示しています。たとえば、リスト(A B C)は、_cdrs_でリンクされた3つのコンスセルで構成されています。
概略的に、それは次のように表現できます-
LISPのリスト
コンスセルを使用してリストを作成できますが、ネストされた cons 関数呼び出しからリストを作成することは最良の解決策にはなりません。 list 関数は、LISPでリストを作成するために使用されます。
リスト関数は任意の数の引数を取ることができ、関数であるため、引数を評価します。
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
例2
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
リスト操作関数
次の表に、一般的に使用されるリスト操作関数を示します。
Sr.No. | Function & Description |
---|---|
1 |
引数としてリストを取り、その最初の要素を返します。 |
2 |
cdr 引数としてリストを取り、最初の要素のないリストを返します |
3 |
cons 要素とリストの2つの引数を取り、要素が最初に挿入されたリストを返します。 |
4 |
list 任意の数の引数を取り、引数をリストのメンバー要素として含むリストを返します。 |
5 |
append 2つ以上のリストを1つにマージします。 |
6 |
last リストを受け取り、最後の要素を含むリストを返します。 |
7 |
member 最初の引数が2番目の引数のメンバーである場合、2番目の引数がリストでなければならない2つの引数を取り、最初の引数で始まるリストの残りを返します。 |
8 |
reverse リストを取得し、上位要素を逆順に並べたリストを返します。 |
すべてのシーケンス機能はリストに適用できることに注意してください。
実施例3
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
carとcdr関数の連結
ただし、carおよびcdr関数のシーケンスは、文字cおよびr内のcarの文字aとcdrの文字dを連結することにより短縮できます。
たとえば、関数呼び出しのシーケンス-car cdr car cdrを短縮するためにcadadrを書くことができます。
したがって、(cadadr '(a(c d)(e f g)))はdを返します
実施例4
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-シンボル
LISPでは、シンボルはデータオブジェクトを表す名前であり、興味深いことに、データオブジェクトでもあります。
シンボルを特別なものにしているのは、 property list または* plist。*というコンポーネントがあることです。
プロパティリスト
LISPでは、プロパティをシンボルに割り当てることができます。 たとえば、「person」オブジェクトがあるとします。 この「人物」オブジェクトには、名前、性別、身長、体重、住所、職業などのプロパティが必要です。 プロパティは属性名のようなものです。
プロパティリストは、偶数(おそらくゼロ)の要素を持つリストとして実装されます。 リスト内の要素の各ペアはエントリを構成します。最初の項目は*指標*で、2番目の項目は*値*です
シンボルが作成されると、そのプロパティリストは最初は空です。 プロパティは、 setf フォーム内で get を使用して作成されます。
たとえば、次のステートメントにより、プロパティのタイトル、作成者、発行者、およびそれぞれの値を(シンボル) 'book’という名前のオブジェクトに割り当てることができます。
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
さまざまなプロパティリスト関数を使用すると、プロパティを割り当てたり、シンボルのプロパティを取得、置換、削除したりできます。
例2
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
実施例3
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
実施例4
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-ベクトル
ベクトルは1次元配列であるため、配列のサブタイプです。 ベクターとリストは、まとめてシーケンスと呼ばれます。 したがって、これまでに説明したすべてのシーケンスジェネリック関数と配列関数は、ベクトルに作用します。
ベクターの作成
ベクトル関数を使用すると、特定の値を持つ固定サイズのベクトルを作成できます。 任意の数の引数を取り、それらの引数を含むベクトルを返します。
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISPは、ベクトルのリテラル表記として#(…)構文を使用することに注意してください。 これを使用できます#(… )コードにリテラルベクトルを作成して含める構文。
ただし、これらはリテラルベクトルであるため、それらを変更することはLISPで定義されていません。 したがって、プログラミングの場合は、常に vector 関数、またはより一般的な関数 make-array を使用して、変更する予定のベクトルを作成する必要があります。
例2
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
塗りつぶしポインタ
関数の fill-pointer 引数は、ベクターに実際に保存されている要素の数を追跡します。 要素をベクターに追加するときに埋められる次の位置のインデックスです。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
ベクトルはシーケンスであり、すべてのシーケンス関数はベクトルに適用できます。 ベクトル関数については、シーケンスの章を参照してください。
LISP-セット
Common Lispは、セットデータ型を提供しません。 ただし、リストに対してセット操作を実行できる多くの機能を提供します。
さまざまな基準に基づいて、リスト内のアイテムを追加、削除、および検索できます。 ユニオン、インターセクション、セット差分などのさまざまなセット操作を実行することもできます。
LISPでのセットの実装
リストのようなセットは通常、コンスセルの観点から実装されます。 ただし、このまさに理由で、集合が大きくなるほど集合演算の効率は低下します。
adjoin関数は元のリストを変更しないため、リスト自体に変更を加えるには、adjoinによって返される値を元のリストに割り当てるか、マクロ pushnew を使用してアイテムを追加する必要がありますセット。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
メンバーシップの確認
関数のメンバーグループを使用すると、要素がセットのメンバーであるかどうかを確認できます。
以下は、これらの関数の構文です-
これらの関数は、テストを満たす特定のアイテムの特定のリストを検索します。 そのような項目が見つからない場合、関数は* nil。*を返します。それ以外の場合、最初の要素として要素を持つリストの末尾が返されます。
検索はトップレベルでのみ行われます。
これらの関数は、述部として使用できます。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
ユニオンを設定
ユニオン関数グループを使用すると、テストに基づいてこれらの関数の引数として提供された2つのリストで集合ユニオンを実行できます。
以下は、これらの関数の構文です-
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
ご注意ください
ユニオン関数は、3つのベクトルのリストに対して*:test-not# 'mismatch 引数がないと期待どおりに機能しません。 これは、リストがコンスセルで構成されており、値が一見同じように見えても、セルの *cdr 部分が一致しないため、LISPインタープリター/コンパイラーとまったく同じではないためです。 という訳だ;リストを使用して大きなセットを実装することはお勧めしません。 ただし、小さなセットには問題ありません。
交差点を設定
関数の共通部分グループを使用すると、テストに基づいてこれらの関数の引数として提供される2つのリストで共通部分を実行できます。
以下は、これらの関数の構文です-
これらの関数は2つのリストを取り、両方の引数リストにあるすべての要素を含む新しいリストを返します。 いずれかのリストに重複エントリがある場合、冗長エントリが結果に表示される場合と表示されない場合があります。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
交差機能は、交差の破壊的なバージョンです。つまり、元のリストを破壊する可能性があります。
差を設定
関数のset-differenceグループを使用すると、テストに基づいてこれらの関数への引数として提供される2つのリストに対してset-differenceを実行できます。
以下は、これらの関数の構文です-
set-difference関数は、2番目のリストに表示されない最初のリストの要素のリストを返します。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-ツリー
リストのリストとして、コンスセルからツリーデータ構造を構築できます。
ツリー構造を実装するには、コンスセルを特定の順序(たとえば、バイナリツリーの事前順序、順序、および順序)を横断する機能を設計する必要があります。
リストのリストとしてのツリー
私たちはリストの次のリストを形成するコンスセルで構成されたツリー構造を考えてみましょう-
((1 2)(3 4)(5 6))。
概略的に、それは次のように表現できます-
LISPのツリー関数
ほとんどの場合、特定のニーズに応じて独自のツリー機能を記述する必要がありますが、LISPには、使用できるツリー関数がいくつか用意されています。
すべてのリスト関数とは別に、次の関数は特にツリー構造で動作します-
Sr.No. | Function & Description |
---|---|
1 |
コンスセルxのツリーのコピーを返します。 車とcdrの両方の方向を再帰的にコピーします。 xがコンスセルでない場合、関数は単にxを変更せずに返します。 オプションのvecp引数がtrueの場合、この関数はコンスセルと同様にベクトルを(再帰的に)コピーします。 |
2 |
コンスセルの2つのツリーを比較します。 xとyが両方ともコンスセルの場合、車とCDRが再帰的に比較されます。 xもyもコンスセルでない場合、それらはeqlによって、または指定されたテストに従って比較されます。 :key関数が指定されている場合、両方のツリーの要素に適用されます。 |
3 |
指定された古いアイテムのオカレンスを、コンスセルのツリーである_tree_の_new_アイテムに置き換えます。 |
4 |
substと同じように機能しますが、元のツリーを破壊します。 |
5 |
substのように機能しますが、古いリストと新しいペアの関連付けリスト_alist_を使用します。 ツリーの各要素(もしあれば、:key関数を適用した後)は、alistのcarと比較されます。一致する場合、対応するcdrに置き換えられます。 |
6 |
sublisと同じように機能しますが、破壊的なバージョンです。 |
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
例2
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
独自のツリーを構築する
LISPで使用可能なリスト関数を使用して、独自のツリーを構築してみましょう。
まず、データを含む新しいノードを作成しましょう
次に、ツリーに子ノードを追加します。2つのツリーノードを取り、2番目のツリーを最初のツリーの子として追加します。
この関数は、指定されたツリーの最初の子を返します。ツリーノードを取得し、そのノードの最初の子を返します。このノードに子ノードがない場合は、nilを返します。
この関数は、指定されたノードの次の兄弟を返します。引数としてツリーノードを取り、次の兄弟ノードへの参照を返します。ノードにノードがない場合はnilを返します。
最後に、ノード内の情報を返す関数が必要です-
例
この例では、上記の機能を使用しています-
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-ハッシュテーブル
ハッシュテーブルのデータ構造は、キーのハッシュコードに基づいて編成された*キーと値*のペアのコレクションを表します。 キーを使用して、コレクション内の要素にアクセスします。
ハッシュテーブルは、キーを使用して要素にアクセスする必要があるときに使用され、有用なキー値を識別できます。 ハッシュテーブルの各アイテムにはキー/値のペアがあります。 キーは、コレクション内のアイテムにアクセスするために使用されます。
LISPでハッシュテーブルを作成する
Common LISPでは、ハッシュテーブルは汎用コレクションです。 任意のオブジェクトをキーまたはインデックスとして使用できます。
ハッシュテーブルに値を格納する場合、キーと値のペアを作成し、そのキーの下に格納します。 後で、同じキーを使用してハッシュテーブルから値を取得できます。 各キーは単一の値にマッピングされますが、新しい値をキーに保存できます。
LISPのハッシュテーブルは、キーの比較方法に基づいて、eq、eql、またはequalの3つのタイプに分類できます。 ハッシュテーブルがLISPオブジェクトでハッシュされる場合、キーはeqまたはeqlと比較されます。 ハッシュテーブルがツリー構造でハッシュする場合、等しいを使用して比較されます。
どこ-
- key 引数はキーを提供します。
- *:test *引数は、キーの比較方法を決定します-3つの値# 'eq、#' eql、# 'equalのいずれか、または3つのシンボルeq、eql、またはequalのいずれかを持つ必要があります。 指定しない場合は、eqlが想定されます。
- *:size *引数は、ハッシュテーブルの初期サイズを設定します。 これはゼロより大きい整数でなければなりません。
- *:rehash-size *引数は、ハッシュテーブルがいっぱいになったときにサイズをどれだけ増やすかを指定します。 これは、追加するエントリの数であるゼロより大きい整数、または古いサイズに対する新しいサイズの比率である1より大きい浮動小数点数にすることができます。 この引数のデフォルト値は実装依存です。
- *:rehash-threshold *引数は、ハッシュテーブルが成長しなければならない前に、ハッシュテーブルがどれだけいっぱいになるかを指定します。 これは、ゼロより大きく:rehash-sizeより小さい整数(この場合、テーブルが成長するたびにスケーリングされます)か、ゼロと1の間の浮動小数点数です。 この引数のデフォルト値は実装依存です。
引数なしでmake-hash-table関数を呼び出すこともできます。
ハッシュテーブルからのアイテムの取得とハッシュテーブルへのアイテムの追加
次の構文があります-
ここで-
key:関連するキーです
ハッシュテーブル:検索するハッシュテーブルです
デフォルト:エントリが見つからない場合に返される値、指定されていない場合はnil
ハッシュテーブルにアイテムを追加するには、 setf 関数と gethash 関数を使用できます。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
エントリーの削除
この関数の構文は次のとおりです-
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
maphash関数
関数とハッシュテーブルの2つの引数を取り、ハッシュテーブル内のキー/値のペアごとに1回関数を呼び出します。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-入力および出力
Common LISPは、多数の入出力機能を提供します。 すでにformat関数とprint関数を出力に使用しています。 このセクションでは、LISPで提供される最も一般的に使用される入出力関数のいくつかを見ていきます。
入力機能
次の表は、LISPの最も一般的に使用される入力関数を示しています-
Sr.No. | Function & Description |
---|---|
1 |
入力ストリームからLispオブジェクトの印刷された表現を読み込み、対応するLispオブジェクトを構築し、オブジェクトを返します。 |
2 |
これは、拡張トークンを終了した文字を正確に判別することが望ましい特殊な状況で使用されます。 |
3 |
改行で終わるテキスト行を読み取ります。 |
4 |
入力ストリームから1文字を取得し、文字オブジェクトとして返します。 |
5 |
入力ストリームから最後に読み込まれた文字を入力ストリームの前面に配置します。 |
6 |
入力ストリームから実際に削除せずに、入力ストリームから読み取られる次の文字を返します。 |
7 |
input-streamからすぐに使用できる文字がある場合、述語 listen はtrueで、ない場合はfalseです。 |
8 |
read-char-no-hang & optional input-stream eof-error-p eof-value recursive-p これは read-char と似ていますが、文字を取得しない場合、文字を待たずにすぐにnilを返します。 |
9 |
_input-stream._に関連付けられたバッファリングされた入力をクリアします |
10 |
文字列の文字を連続して取得し、LISPオブジェクトを構築してオブジェクトを返します。 また、場合によっては、読み取られていない文字列の最初の文字のインデックス、または文字列の長さ(または長さ+1)も返します。 |
11 |
:startと:endで区切られた文字列の部分文字列を調べます(デフォルトは文字列の先頭と末尾です)。 空白文字をスキップし、整数の解析を試みます。 |
12 |
binary-input-streamから1バイトを読み取り、整数の形式で返します。 |
キーボードからの入力の読み取り
たとえば、コードスニペットを考慮してください-
ユーザーがSTDIN入力から10.2を入力すると、それが返され、
read関数は、入力ストリームから文字を読み取り、Lispオブジェクトの表現として解析することで文字を解釈します。
例
main.lispという名前の新しいソースコードファイルを作成し、その中に次のコードを入力します-
あなたがコードを実行すると、それは次の結果を返します-
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
出力関数
LISPのすべての出力関数は、出力が送信される_output-streamと呼ばれるオプションの引数を取ります。 言及されていない場合、または_nil、_ output-streamはデフォルトで変数 standard-output の値になります。
次の表は、LISPの最も一般的に使用される出力関数を示しています-
Sr.No. | Function and Description |
---|---|
1 |
write object & key :stream :escape :radix :base :circle :pretty :level :length :case :gensym :array
どちらも:streamで指定された出力ストリームにオブジェクトを書き込みます。デフォルトは standard-output の値です。 他の値は、印刷用に設定された対応するグローバル変数にデフォルト設定されます。 |
2 |
prin1 object & optional output-stream
これらの関数はすべて、オブジェクトの出力表現を_output-stream_に出力します。 ただし、次の違いがあります-
|
3 |
文字列への書き込み object&キー:エスケープ:基数:ベース:サークル:きれい:レベル:長さ:ケース:gensym:配列:読み取り可能:右マージン:その他の幅:ライン:pprint-dispatch
オブジェクトは効果的に印刷され、出力文字は文字列に変換されて返されます。 |
4 |
文字を_output-stream、_に出力し、文字を返します。 |
5 |
_string_の指定された部分文字列の文字を_output-stream._に書き込みます。 |
6 |
write-stringと同じように機能しますが、その後に改行を出力します。 |
7 |
_output-stream._に改行を出力します |
8 |
ストリームが行の先頭にない場合にのみ、改行を出力します。 |
9 |
|
10 |
write-byte integer binary-output-stream _integer._の値である1バイトを書き込みます |
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
フォーマットされた出力
関数 format は、適切にフォーマットされたテキストを生成するために使用されます。 次の構文があります-
どこで、
- 宛先は標準出力です
- control-stringは、出力される文字と印刷ディレクティブを保持します。
- formatディレクティブ*は、チルダ(〜)、コンマで区切られたオプションのプレフィックスパラメーター、オプションのコロン(:)およびアットマーク(@)修飾子、およびこれがどのようなディレクティブであるかを示す単一の文字で構成されます。
プレフィックスパラメータは通常、整数であり、オプションで符号付き10進数として表記されます。
次の表は、一般的に使用されるディレクティブの簡単な説明を提供します-
Sr.No. | Directive & Description |
---|---|
1 |
~A ASCII引数が後に続きます。 |
2 |
~S S式が続きます。 |
3 |
~D 10進引数の場合。 |
4 |
~B バイナリ引数用。 |
5 |
~O 8進引数の場合。 |
6 |
~X 16進引数の場合。 |
7 |
~C 文字引数用。 |
8 |
~F 固定形式の浮動小数点引数の場合。 |
9 |
~E 指数浮動小数点引数。 |
10 |
~$ ドルと浮動小数点の引数。 |
11 |
~% 新しい行が印刷されます。 |
12 |
~* 次の引数は無視されます。 |
13 |
~? 間接。 次の引数は文字列で、その後の引数はリストでなければなりません。 |
例
円の面積を計算するプログラムを書き直しましょう-
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-ファイルI/O
一般的なLISPによる標準の入力と出力の処理方法について説明しました。 これらの関数はすべて、テキストファイルとバイナリファイルの読み取りと書き込みにも機能します。 唯一の違いは、この場合、使用するストリームは標準の入力または出力ではなく、ファイルへの書き込みまたはファイルからの読み取りという特定の目的のために作成されたストリームです。
この章では、LISPがデータストレージ用のテキストファイルまたはバイナリファイルを作成、開く、閉じる方法について説明します。
ファイルは一連のバイトを表し、テキストファイルまたはバイナリファイルのどちらでもかまいません。 この章では、ファイル管理のための重要な機能/マクロについて説明します。
ファイルを開く
ファイルが開かれると、LISP環境でそれを表すストリームオブジェクトが作成されます。 ストリームに対するすべての操作は、基本的にファイルに対する操作と同等です。
どこで、
- _filename_引数は、開くまたは作成するファイルの名前です。
- _keyword_引数は、ストリームのタイプとエラー処理方法を指定します。
- *:direction *キーワードは、ストリームが入力、出力、またはその両方を処理するかどうかを指定し、次の値を取ります-
- :input-入力ストリーム用(デフォルト値)
- :output-出力ストリーム用
- :io-双方向ストリーム用
- :probe-ファイルの存在を確認するだけ。ストリームを開いてから閉じます。
- *:element-type *は、ストリームのトランザクション単位のタイプを指定します。
- *:if-exists *引数は、:directionが:outputまたは:ioで、指定された名前のファイルが既に存在する場合に実行されるアクションを指定します。 方向が:inputまたは:probeの場合、この引数は無視されます。 それは次の値を取ります-
- :error-エラーを通知します。
- :new-version-同じ名前でより大きなバージョン番号を持つ新しいファイルを作成します。
- :rename-既存のファイルの名前を変更します。
- :rename-and-delete-既存のファイルの名前を変更してから削除します。
- :append-既存のファイルに追加します。
- :supersede-既存のファイルを置き換えます。
- nil-ファイルを作成せず、ストリームでもnilを返すだけで失敗を示します。
- *:if-does-not-exist *引数は、指定された名前のファイルがまだ存在しない場合に実行されるアクションを指定します。 それは次の値を取ります-
- :error-エラーを通知します。
- :create-指定された名前で空のファイルを作成し、それを使用します。
- nil-ファイルもストリームも作成しませんが、代わりに単に失敗を示すためにnilを返します。
- *:external-format *引数は、ファイル内の文字を表すための実装認識スキームを指定します。
たとえば、次のように/tmpフォルダに保存されているmyfile.txtという名前のファイルを開くことができます-
ファイルへの書き込みとファイルからの読み取り
次の構文があります-
- _filename_は、開くファイルの名前です。文字列、パス名、またはストリームの場合があります。 *_options_は、関数openのキーワード引数と同じです。
例1
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
terpriやformatなど、前の章で説明したすべての入出力関数は、ここで作成したファイルに書き込むために機能していることに注意してください。
コードを実行すると、何も返されません。ただし、データはファイルに書き込まれます。* :direction:output *キーワードはこれを可能にします。
ただし、 read-line 関数を使用してこのファイルから読み取ることができます。
例2
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
ファイルを閉じる
LISP-構造
構造はユーザー定義のデータ型の1つであり、異なる種類のデータ項目を組み合わせることができます。
構造は、レコードを表すために使用されます。 図書館で本を追跡したいとします。 あなたは、各本に関する次の属性を追跡することができます-
- タイトル
- 著者
- 件名
- ブックID
構造の定義
LISPの defstruct マクロを使用すると、抽象レコード構造を定義できます。 defstruct ステートメントは、プログラムに複数のメンバーを持つ新しいデータ型を定義します。
ご注意ください
- 上記の宣言は、4つの*名前付きコンポーネント*を含むブック構造を作成します。したがって、作成されるすべてのブックはこの構造のオブジェクトになります。
- book-title、book-author、book-subject、book-book-idという名前の4つの関数を定義します。これらは1つの引数、ブック構造を取り、フィールドのタイトル、著者、サブジェクト、ブックのbook-idを返します。オブジェクト。 これらの関数は*アクセス関数*と呼ばれます。
- シンボルブックはデータ型になり、 typep 述語を使用して確認できます。
- また、* book-pという名前の暗黙的な関数もあります。これは述語であり、引数が本の場合はtrue、それ以外の場合はfalseです。
- make-book という名前の別の暗黙関数が作成されます。これは、呼び出されると、アクセス関数での使用に適した4つのコンポーネントを持つデータ構造を作成する constructor です。
- *#S構文*は構造を指し、それを使用して本のインスタンスを読んだり印刷したりできます。
- 1つの引数のcopy-bookという名前の暗黙的な関数も定義されています。 ブックオブジェクトを取得し、最初のオブジェクトのコピーである別のブックオブジェクトを作成します。 この機能は*コピー機能*と呼ばれます。
- setf を使用して、ブックのコンポーネントを変更できます。たとえば、
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-パッケージ
プログラミング言語の一般的な用語では、パッケージは、名前のセットを別のセットから分離する方法を提供するために設計されています。 あるパッケージで宣言されたシンボルは、別のパッケージで宣言された同じシンボルと競合しません。 このようにして、パッケージは独立したコードモジュール間の名前の競合を減らします。
LISPリーダーは、検出したすべてのシンボルのテーブルを保持しています。 新しい文字シーケンスを見つけると、新しいシンボルを作成し、シンボルテーブルに保存します。 このテーブルはパッケージと呼ばれます。
現在のパッケージは、特別な変数 package によって参照されます。
LISPには2つの定義済みパッケージがあります-
- common-lisp -定義されたすべての関数と変数のシンボルが含まれています。
- common-lisp-user -common-lispパッケージと、編集およびデバッグツールを備えた他のすべてのパッケージを使用します。要するにcl-userと呼ばれます
LISPのパッケージ関数
次の表は、パッケージの作成、使用、操作に使用される最も一般的に使用される機能を示しています-
Sr.No. | Function and Description |
---|---|
1 |
指定されたパッケージ名で新しいパッケージを作成して返します。 |
2 |
パッケージを最新にします。 |
3 |
このマクロは、 package をnameという名前のパッケージに設定します。これは、シンボルまたは文字列でなければなりません。 |
4 |
パッケージを検索します。 その名前またはニックネームを持つパッケージが返されます。そのようなパッケージが存在しない場合、find-packageはnilを返します。 |
5 |
パッケージの名前を変更します。 |
6 |
この関数は、現在Lispシステムに存在するすべてのパッケージのリストを返します。 |
7 |
delete-package package パッケージを削除します。 |
LISPパッケージの作成
どこで、
package-nameはパッケージの名前です。
:useキーワードは、このパッケージに必要なパッケージ、つまり、このパッケージのコードで使用される機能を定義するパッケージを指定します。
:exportキーワードは、このパッケージの外部にあるシンボルを指定します。
引数とキーワードの意味は以前と同じです。
パッケージを使用する
パッケージを作成したら、それを現在のパッケージにすることで、このパッケージのコードを使用できます。 in-package マクロは、環境内でパッケージを最新にします。
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
パッケージを削除する
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-エラー処理
一般的なLISPの用語では、例外は条件と呼ばれます。
実際、条件は従来のプログラミング言語の例外よりも一般的です。*条件*は、さまざまなレベルの関数呼び出しスタックに影響を与える可能性のある発生、エラー、またはエラーを表すためです。
LISPの条件処理メカニズムは、コールスタックの上位レベルのコードが作業を継続できる一方で、条件を使用して警告を通知する(たとえば、警告を出力する)ようにそのような状況を処理します。
LISPの条件処理システムには3つの部分があります-
- 状態の通知
- 状態の処理
- プロセスを再起動します
条件の処理
ここで概念を説明するために、ゼロ除算条件から生じる条件を処理する例を取り上げましょう。
条件を処理するには、次の手順を実行する必要があります-
- 条件の定義-「条件とは、クラスが条件の一般的な性質を示し、インスタンスデータが条件の通知につながる特定の状況の詳細に関する情報を保持するオブジェクトです」。 +定義条件マクロは、次の構文を持つ条件を定義するために使用されます-
- 新しい条件オブジェクトは、MAKE-CONDITIONマクロを使用して作成されます。このマクロは、*:initargs *引数に基づいて新しい条件のスロットを初期化します。
私たちの例では、次のコードは条件を定義します-
- ハンドラーの記述-条件ハンドラーは、その上で通知された条件を処理するために使用されるコードです。 通常、エラー関数を呼び出す上位レベル関数の1つで記述されます。 条件が通知されると、通知メカニズムは条件のクラスに基づいて適切なハンドラーを検索します。 +各ハンドラーは-
- タイプ指定子。処理できる条件のタイプを示します
- 単一の引数、条件をとる関数 +条件が通知されると、通知メカニズムは、条件タイプと互換性のある最も新しく確立されたハンドラーを見つけ、その関数を呼び出します。 +マクロ handler-case は条件ハンドラーを確立します。 ハンドラーケースの基本形-
ここで、各エラー句は次の形式です-
- フェーズの再開 * +これは実際にプログラムをエラーから回復するコードであり、条件ハンドラーは適切な再起動を呼び出すことで条件を処理できます。 通常、再起動コードは中間レベルまたは低レベルの関数に配置され、条件ハンドラーはアプリケーションの上位レベルに配置されます。 + handler-bind マクロを使用すると、再起動関数を提供でき、関数呼び出しスタックを巻き戻さずに下位レベルの関数で続行できます。 言い換えると、制御の流れは依然として下位レベルの機能にあります。 + *handler-bind の基本形式は次のとおりです-
各バインディングは次のリストです-
条件タイプ
1つの引数のハンドラー関数
複数回再起動することができます。
例
この例では、除数引数がゼロの場合にエラー条件を作成するdivision-functionという名前の関数を記述することにより、上記の概念を示します。 値1を返すこと、除数2を送信して再計算すること、または1を返すことの3つの方法を提供する3つの匿名関数があります。
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
前述の「条件システム」とは別に、Common LISPはエラーを通知するために呼び出されるさまざまな機能も提供します。 ただし、エラーが通知された場合の処理は、実装に依存します。
LISPのエラーシグナル関数
次の表は、警告、ブレーク、致命的ではない致命的エラーを通知する一般的に使用される機能を示しています。
ユーザープログラムはエラーメッセージ(文字列)を指定します。 関数はこのメッセージを処理し、ユーザーに表示する場合としない場合があります。
エラーメッセージは、 format 関数を適用して作成する必要があり、先頭または末尾に改行文字を含めることはできません。また、エラーを示す必要はありません。LISPシステムは、優先スタイルに従ってこれらを処理します。
Sr.No. | Function and Description |
---|---|
1 |
致命的なエラーを通知します。 この種のエラーから続行することは不可能です。したがって、エラーは呼び出し元に戻ることはありません。 |
2 |
エラーを通知し、デバッガーに入ります。 ただし、エラーを解決した後、デバッガーからプログラムを続行できます。 |
3 |
エラーメッセージを出力しますが、通常はデバッガーには入りません |
4 |
プログラムされたエラー処理機能によるインターセプトの可能性を許可せずに、メッセージを出力し、デバッガーに直接入ります。 |
例
この例では、階乗関数は数値の階乗を計算します。ただし、引数が負の場合、エラー条件が発生します。
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
LISP-CLOS
Common LISPは、オブジェクト指向プログラミングの進歩よりも数十年前に先んじました。 ただし、オブジェクト指向は後の段階で組み込まれました。
クラスの定義
スロットは、データまたはフィールドを格納する変数です。
スロット記述の形式は(slot-name slot-option *)です。各オプションは、名前、式、その他のオプションが続くキーワードです。 最も一般的に使用されるスロットオプションは-
- *:accessor *関数名
- *:initform *式
- *:initarg *シンボル
たとえば、3つのスロットの長さ、幅、高さを持つBoxクラスを定義してみましょう。
スロットへのアクセスおよび読み取り/書き込み制御の提供
スロットにアクセス、読み取り、または書き込みできる値がない限り、クラスはほとんど役に立ちません。
クラスを定義するときに、各スロットに accessors を指定できます。 たとえば、私たちのBoxクラスを取ります-
スロットの読み取りと書き込みに別々の accessor 名を指定することもできます。
クラスのインスタンスの作成
汎用関数 make-instance は、クラスの新しいインスタンスを作成して返します。
次の構文があります-
例
長さ、幅、高さの3つのスロットを持つBoxクラスを作成しましょう。 これらのフィールドに値を設定するには、3つのスロットアクセサーを使用します。
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
クラスメソッドの定義
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-
継承
LISPでは、オブジェクトを別のオブジェクトの観点から定義できます。 これは* inheritance。*と呼ばれます。新しいまたは異なる機能を追加することで、派生クラスを作成できます。 派生クラスは、親クラスの機能を継承します。
次の例はこれを説明します-
例
main.lispという名前の新しいソースコードファイルを作成し、次のコードを入力します。
あなたがコードを実行すると、それは次の結果を返します-