문제

체계는 함수 또는 기타 유형의 값에 의한 여부에 관계없이 모든 변수에 대해 단일 네임 스페이스를 사용합니다. 공통 LISP는 식별자 "hello"가 한 컨텍스트에서 함수를 참조하고 다른 문자열의 문자열을 참조 할 수 있도록 둘을 분리합니다.

(주 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)

따라서 일관성을 넘어서, 공통 LISP 대 체계와 일반적으로 기능 및 비 기능 값에 대한 별도의 별도에 대한 단일 네임 스페이스의 장점과 단점은 무엇입니까?

도움이 되었습니까?

해결책

두 가지 다른 접근법에는 이름이 있습니다 : LISP-1과 LISP-2. LISP-1에는 변수와 함수 모두에 대한 단일 네임 스페이스 (체계에서와 같이)가 있고 LISP-2에는 변수 및 함수에 대한 별도의 네임 스페이스가 있습니다 (공통 LISP에서와 같이). 나는 당신이 당신의 질문에서 그것을 언급하지 않았기 때문에 당신이 용어를 알지 못할 수도 있기 때문에 이것을 언급합니다.

위키 백과 이 토론을 말합니다:

기능을위한 별도의 네임 스페이스가 유리한 지 여부는 LISP 커뮤니티에서 경합의 원천입니다. 일반적으로 LISP-1 대 LISP-2 토론이라고합니다. LISP-1은 Scheme의 모델을 말하고 LISP-2는 일반적인 LISP 모델을 말합니다. 이 이름은 Richard P. Gabriel과 Kent Pitman이 1988 년 논문으로 만들어졌으며, 이는 두 가지 접근법을 광범위하게 비교합니다.

Gabriel과 Pitman의 논문 기능 셀 및 가치 세포의 분리의 기술적 문제 이 문제를 해결합니다.

다른 팁

실제로, 요약 된대로 Richard Gabriel과 Kent Pitman의 논문, 논쟁은 LISP-6에 대한 LISP-5에 관한 것입니다. 논문에는 이미 유형 이름, 태그 이름, 블록 이름 및 선언 이름이 언급되어 있기 때문입니다. 편집 : Rainer가 주석에서 지적했듯이 이것은 잘못된 것 같습니다. 계획은 실제로 LISP-1 인 것 같습니다. 그러나 다음은이 오류의 영향을받지 않습니다.

기호가 실행 될 무언가를 나타내는 지 또는 언급 할 것을 나타내는 지 여부는 항상 문맥에서 명확합니다. 함수와 변수를 동일한 네임 스페이스에 던지는 것은 주로 제한입니다. 프로그래머는 동일한 이름과 행동에 동일한 이름을 사용할 수 없습니다. LISP-5가 이것으로부터 얻는 것은 현재 컨텍스트가 암시하는 것과 다른 네임 스페이스에서 무언가를 참조하기위한 일부 구문 오버 헤드가 피하는 것입니다. 편집 : 이것은 전체 그림이 아니라 표면입니다.

나는 LISP-5 지지자들이 함수가 데이터라는 사실과 같은 사실을 알고 있으며, 이는 언어 핵심으로 표현된다는 것을 알고 있습니다. 나는 컴파일러를 혼동하지 않고 목록 "목록"과 자동차 "자동차"를 호출 할 수 있다는 사실을 좋아하며 기능은 어쨌든 근본적으로 특별한 종류의 데이터입니다. 편집 : 이것은 나의 주요 요점입니다. 별도의 네임 스페이스는 전혀 사마귀가 아닙니다.

나도 좋아했다 Pascal Constanza가 말한 것 이것에 관해서.

나는 Python (Unified Namespace) vs Ruby에서 비슷한 차이점을 충족했습니다 (메소드 대 메소드가 아닌 방법을위한 별개의 네임 스페이스). 그런 맥락에서, 나는 Python의 접근 방식을 선호합니다. 예를 들어, 그 접근법의 경우, 물건 목록을 만들고 싶다면 일부는 기능이지만 다른 일부는 그렇지 않지만 이름과 다른 일을 할 필요가 없습니다. 예를 들어, "기능성"에 따라 기능 객체가 호출되지 않고 (고차 함수 등의 인수 및 반환 값 등) 주위에 묶여야하는 모든 경우에도 비슷한 고려 사항이 적용됩니다.

비 기능도 호출 할 수 있습니다 (클래스가 정의하는 경우 __call__, Python의 경우 - "연산자 과부하"의 특별한 경우) "문맥 구별"도 반드시 명확하지는 않습니다.

그러나 내 "Lisp-Oid"경험은 대부분 공통 LISP가 아닌 체계가 있었으므로 결국 그 경험에서 비롯된 균일 한 네임 스페이스에 대한 친숙 함에 의해 무의식적으로 편향 될 수 있습니다.

체계에서 함수의 이름은 함수가 값으로 변수 일뿐입니다. 내가하는지 (define x (y) (z y)) 또는 (let ((x (lambda (y) (z y)))), 나는 내가 호출 할 수있는 함수를 정의하고있다. 따라서 "가변 이름이 거의 나타나지 않을 것"이라는 아이디어는 계획에 관한 한 일종의 독점적입니다.

체계는 특징적으로 기능적인 언어이므로 기능을 데이터로 취급하는 것은 신조 중 하나입니다. 기능을 갖는 것은 다른 모든 데이터와 같이 저장되는 자체의 유형입니다. 아이디어를 수행하는 방법입니다.

적어도 일반적인 LISP의 가장 큰 단점은 이해력입니다. 우리는 변수와 함수에 다른 네임 스페이스를 사용한다는 데 동의 할 수 있지만 몇 개가 있습니까? PAIP에서 Norvig는 "적어도 7 개의"네임 스페이스를 가지고 있음을 보여주었습니다.

존경받는 프로그래머가 저술 한 언어의 고전적인 책 중 하나가 출판 된 책에서 확실하게 말할 수 없을 때 문제가 있다고 생각합니다. 나는 여러 네임 스페이스에 문제가 없지만 언어가 적어도 단순하기를 바랍니다. 어떤 사람 이 측면을 완전히 이해할 수 있습니다.

나는 변수와 함수에 대해 동일한 기호를 사용하는 것이 편하지 만 더 모호한 영역에서는 두려움에서 다른 이름을 사용하는 데 의지합니다 (충돌 네임 스페이스는 실제로 디버그하기가 어려울 수 있습니다!). 사례.

두 가지 접근 방식에 좋은 것이 있습니다. 그러나 중요 할 때는 기능 목록과 AA 변수 목록을 모두 잘못 철자하는 것보다 선호합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top