スキームは、変数が関数または他のタイプの値にバインドされているかどうかに関係なく、すべての変数に対して単一の名前空間を使用します。Common Lisp では、識別子 "hello" が 1 つのコンテキストでは関数を参照し、別のコンテキストでは文字列を参照するように、2 つを分離します。
(注1:この質問には上記の例が必要です。自由に編集して追加するか、元の作成者に電子メールで送信してください。そうします。)
ただし、関数をパラメーターとして他の関数に渡すなどの一部のコンテキストでは、プログラマーは、次のように を使用して、関数以外の変数ではなく関数変数を指定していることを明示的に区別する必要があります#'
。
(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)
私はいつもこれを少しいぼだと考えてきましたが、最近、これは実際には機能であるという議論に出くわしました:
...重要な違いは、実際にはオブジェクトの型ではなく、フォームの構文にあります。関連するランタイム値について何も知らなくても、関数形式の最初の要素が関数でなければならないことは明らかです。CL はこの事実を取り入れて、静的に決定できる (そして決定しなければならない) マクロおよび特殊なフォームと共に、言語の一部にします。だから私の質問は、関数名の主な用途が、変数名がめったに現れたくない場所に現れることであるのに、なぜ関数の名前と変数の名前を同じ名前空間に入れたいのですか?
クラス名の場合を考えてみましょう: FOO という名前のクラスが FOO という名前の変数の使用を禁止する必要があるのはなぜですか? FOO という名前でクラスを参照するのは、クラス名が必要なコンテキストだけです。まれに、クラス名 FOO にバインドされているクラス オブジェクトを取得する必要がある場合は、FIND-CLASS があります。
この議論は、経験から私にはある程度理にかなっています。フィールドにアクセスするために使用される関数でもあるフィールド名を持つ Haskell で同様のケースがあります。これは少し厄介です:
data Point = Point { x, y :: Double {- lots of other fields as well --} }
isOrigin p = (x p == 0) && (y p == 0)
NamedFieldPuns
これは、拡張機能によって特に優れた、少し余分な構文によって解決されます。
isOrigin2 Point{x,y} = (x == 0) && (y == 0)
では、一貫性を超えた質問に対して、Common Lisp と Scheme の両方で、また一般的に、すべての値に対して単一の名前空間を使用する場合と、関数と関数以外の値を個別に使用する場合の利点と欠点は何ですか?