31

スキームは、変数が関数または他のタイプの値にバインドされているかどうかに関係なく、すべての変数に対して単一の名前空間を使用します。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 の両方で、また一般的に、すべての値に対して単一の名前空間を使用する場合と、関数と関数以外の値を個別に使用する場合の利点と欠点は何ですか?

4

6 に答える 6

1

少なくとも Common Lisp の最大の欠点は、わかりやすさです。変数と関数に異なる名前空間を使用していることには誰もが同意できますが、いくつあるのでしょうか? PAIP では、Norvig は「少なくとも 7 つの」名前空間を持つことを示しました。

非常に尊敬されているプログラマーによって書かれた言語の古典的な本の 1 つが、出版された本で確実に言うことさえできない場合、私は問題があると思います。複数の名前空間に問題はありませんが、言語が少なくとも、誰かがこの側面を完全に理解できるほど単純であることを望みます.

私は変数と関数に同じシンボルを使用することに問題はありませんが、よりあいまいな領域では、恐怖から別の名前を使用することに頼っています (名前空間の衝突はデバッグが非常に困難になる可能性があります!)。場合。

于 2009-06-22T17:34:04.120 に答える
0

どちらのアプローチにも良い点があります。ただし、重要な場合は、関数 LIST と変数 LIST の両方を使用する方が、どちらかのスペルを間違えるよりも好ましいことがわかりました。

于 2009-06-21T20:00:52.057 に答える