Clojure가 클래스를 정의하는 데 하나가 아닌 5 가지 방법이있는 이유는 무엇입니까?


84

Clojure는 gen-class, reify, proxy 및 deftype 및 defrecord를 사용하여 새로운 클래스와 유사한 데이터 유형을 정의합니다. 구문의 단순성을 중요시하고 불필요한 복잡성을 싫어하는 언어의 경우 일탈처럼 보입니다. 누군가 그 이유를 설명 할 수 있습니까? Common Lisp 스타일의 defclass가 충분할까요?

답변:


90

다음은 세 가지 요소가 혼합 된 것입니다.

  1. jvm의 특정 유형 시스템
  2. 유형을 정의 할 때 다양한 사용 사례에 대해 약간 다른 의미 체계가 필요합니다.
  3. 이들 중 일부는 언어가 진화함에 따라 더 일찍 개발되었고 일부는 나중에 개발되었다는 사실.

따라서 먼저 이것이 무엇을하는지 고려해 봅시다. deftypegen-class 는 둘 다 사전 컴파일을 위해 명명 된 클래스를 정의한다는 점에서 유사합니다. Gen-class가 먼저 왔고 clojure 1.2에서 deftype이 그 뒤를이었습니다. Deftype이 선호되고 성능 특성이 더 좋지만 더 제한적입니다. deftype 클래스는 인터페이스를 준수 할 수 있지만 다른 클래스에서 상속 할 수 없습니다.

Reify프록시 는 모두 런타임에 익명 클래스의 인스턴스를 동적으로 만드는 데 사용됩니다. 프록시가 먼저 왔고 reify는 clojure 1.2에서 deftype 및 defrecord와 함께 제공되었습니다. Reify는 의미가 너무 제한적이지 않은 deftype과 마찬가지로 선호됩니다.

그것은 왜 deftype과 defrecord가 동시에 나타나고 비슷한 역할을하는지에 대한 의문을 남깁니다. 대부분의 목적을 위해 우리는 defrecord를 사용하고 싶을 것입니다. 그것은 우리가 알고 사랑하는 모든 클로저의 장점을 가지고 있습니다. Deftype은 다른 데이터 구조의 구현을위한 저수준 빌딩 블록으로 사용하기위한 것입니다. 일반 클로저 인터페이스는 포함하지 않지만 변경 가능한 필드 옵션이 있습니다 (기본값은 아님).

자세한 내용은 다음을 확인하세요.

clojure.org 데이터 유형 페이지

deftype 및 reify가 도입 된 Google 그룹 스레드


1
Google 그룹 스레드는 매우 귀중했습니다. 내 이해는 java-interop 프록시에 대한 것이며 gen-class는 대부분 reify 및 deftype으로 대체됩니다. 현재 유형을 정의하는 '권장'방법이 적어 기쁩니다.
Salil

2
@Trylks : 객체를 일련의 키-값 쌍으로 처리하는 기능. 클로저에 고유 한 거의 모든 것이 시퀀스로 취급 될 수 있으며 이는 매우 강력합니다.
Rob Lachlan

proxy런타임에 메서드를 수정할 수 있기 때문에 때때로 선호됩니다. (예 : The Joy of Clojure , 2nd ed.는 이것이 웹 핸들러에서 콜백을 수정하는 데 유용 할 수 있다고 제안합니다.)
Mars

52

짧은 대답은 모두 다르고 유용한 목적을 가지고 있다는 것입니다. 복잡성은 기본 JVM의 다양한 기능과 효과적으로 상호 운용되어야하기 때문입니다.

Java interop이 필요하지 않은 경우 99 %의 시간 동안 defrecord 또는 간단한 Clojure 맵을 사용하는 것이 가장 좋습니다.

  • 프로토콜을 사용하려면 defrecord를 사용하십시오.
  • 그렇지 않으면 일반 Clojure 맵이 가장 간단하고 이해하기 쉽습니다.

요구 사항이 더 복잡한 경우 다음 순서도는 다른 옵션 중 하나를 선택하는 이유를 설명하는 훌륭한 도구입니다.

http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

올바른 클로저 유형 정의 양식을 선택하기위한 순서도


1
순서도 링크에 감사드립니다. 블로그가 O'reilly 's-Programming Clojure의 공동 저자 인 것이 도움이됩니다. 이 의사 결정은 매우 복잡하다고 생각합니다. 인터페이스와 구체적인 클래스의 차이 또는 정적 메서드를 정의해야하는지 여부 또는 명명 된 유형 또는 익명 유형이 너무 커서 다른 언어 구조가 필요합니까?
Salil 2011-08-22

4
차이가 크지는 않지만 달성하려는 목표에있어서 철학적으로 다릅니다 . Clojure의 여러 접근 방식은 이러한 근본적인 차이점을 반영한다고 생각합니다. 이것이 다른 이름을 지정해야하는 좋은 이유입니다.
mikera 2011-08-22

순서도는 훌륭하지만 하나 또는 다른 옵션 또는 이들의 조합을 사용하는 모든 가능성이나 이유를 다루지는 않습니다. 단순한 차트는 할 수 없습니다.
Mars
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.