문제

입력 클래스 보 큰 가능성을 쓰는 일반적이고 재사용할 수 있는 기능을에서 매우 일관성,효율적이며 확장 가능한 방법입니다.하지만 아직도 no "주류 언어는"그에 반: 개념, 는 매우 유추,아이디어가 있었다 에서는 다음 C++!

What's 추론에 대한 업스트림 소스?분명히 많은 언어가를 찾고있는 방법을 다루는 유사한 문제점:.NET 소개한 일반적인 제약 조건과 같은 인터페이스 IComparable 할 수있는 기능

T Max<T>(T a, T b) where T : IComparable<T> { // }

에서 작동하는 모든 형식 인터페이스를 구현하십시오.

밀라노를 대신 사용하의 조합 특성 그래서 불 암시적 매개변수/보기계, 자동으로 전달되는 일반적인 기능입니다.

하지만 두 개념을 여기에 표시된 큰 단점-인터페이스를 상속성 기반 따라서는 상대적으로 느리게 간접하고 또한의 가능성은 없시키는 기존 형식으로 이행한다.

우리가 필요한 추상화에 대한 Monoid,우리는 꽤 잘 쓰는 인터페이스와 우리의 형식이 구현,하지만 종류 내장 int 지 않을 수 운영에서 당신의 기능을 자체적으로 제공합니다.

암시적 매개 변수를 대신 일치하지 않으로 일반 인터페이스/traits.

유형의 클래스,거기에 문제가 되지 않을 것 이다(의사 코드)

typeclass Monoid of A where
    static operator (+) (x : A, y : A) : A
    static val Zero : A 
end

instance Int of Monoid where
   static operator (+) (x : Int, y : Int) : Int = x + y
   static val Zero : Int = 0
end

그럼 왜 우리가 사용하는 형식인가요?그들은 심각한 단점들.

편집:혼동하지 마세요 업스트림 소스와 함께 구조 입력,순수한 C++템플릿 또는 오리 입력합니다.A typeclass 가 명시적으로 인스턴스화 에 의해 유형 및 그냥 만족 의약.또한 그것이 나를 수 있는 유용한 구현에서는 단지 정의하는 인터페이스입니다.

도움이 되었습니까?

해결책

개념을 제외되었기 때문에 위원회는 생각하지 않았다 그것들을 얻을 수 있습에서 바로 시간과가 없기 때문에 필수적인 것으로 간주됩니다.그것은 그들이라 생각하지 않는 좋은 아이디어,그들은 단지 생각하지 않는 식이 그들을 위한 C++로 성숙: http://herbsutter.wordpress.com/2009/07/21/trip-report/

정적 유형을 방지하기 위해 시도를 통과 개체수는 하지 않의 요구사항을 충족하는 기능입니다.C++에서 이것은 거대한 큰 거래기 때문에,시간에 객체에 액세스 코드가 없는 그게 올바른 것입니다.

개념을 방지하기 위해 시도를 통과 템플릿을 매개 변수는 없는 요구 사항을 충족합니다.하지만 시간 템플릿을 매개 변수에 의해 액세스 컴파일러,이미 거기 를 확인하는 것은 옳은 일도 없는 개념이 있습니다.하려는 경우에 그것을 사용하지 않는 방식으로 지원,당신이 컴파일한 오류[*].의 경우에는 무거운 템플릿을 사용하여 코드를 얻을 수 있습니다 세 개의 화면 전체의 각괄호하지만,원칙적으로는 유익한 메시지입니다.의 필요를 잡는 오류하기 전에 실패한 컴파일이 더 적은 긴급하는 것 외에는 오류를 잡기 전에 정의되지 않은 행동을 수 있습니다.

개념을 쉽게 지정 템플 인터페이스 작동하는 에 걸쳐 여러 인스턴스.이것은 중요하지만,훨씬 적은 시급한 문제를 지정하는 기능을 인터페이스는 작업에 걸쳐 여러 번 호출.

질문에 대한 답변에서-모든 공식적인 문에서"나는 이 인터페이스를 구현은"하나 큰 단점은,필요한 인터페이스를 발명하기 전에 구현입니다.형추 시스템은 없지만,그들은 큰 불리는 언어에서 일반적인 수 익스프레스의 전체를 사용하여 인터페이스 유형,그래서 당신이 있는 객체는 유추를 올바른 형식만을 가지고 있지 않는 의미를 관찰하는 유형입니다.당신의 언어로 주소를 인터페이스 모두에서(특정과 일치하는 경우에는 그들을 클래스),다음 AFAIK 당신 자세를 가지고 가기를 선택하는 단점이 있다.

[*]습니다.몇 가지 예외가 있다는 예를 들어,C++유형 시스템에서 현재까지 사용하지 못하는 입력 반복기 것처럼 앞으로 반복기입니다.당신이 필요로 반복기 특성입니다.오리 입력하는 혼자서 멈추지 않는다 당신이 통과되는 개를 산책을,수영과 돌팔이 의사,하지만 가까이에 검사를 하지 않는 실제로 모든 것들의 방법 오리지 않고,놀랐다는 것을 배우는 당신이 생각했던 것;-)

다른 팁

인터페이스는 상속 기반 일 필요는 없습니다 ... 그것은 다르고 별도의 설계 결정입니다. 새로운 가다 언어에는 인터페이스가 있지만 상속이 없습니다. 예를 들어 "유형은 메소드의 하위 집합을 지정하는 모든 인터페이스를 자동으로 만족시킵니다", GO. 자주하는 질문 그것을 넣습니다. Simionato 's Musings GO의 최근 출시로 인한 상속 및 인터페이스에 대해 읽을 가치가있을 수 있습니다.

나는 타입 클래스가 훨씬 더 강력하다는 것을 동의합니다. 초록 기본 클래스, 그들은 당신이 유용한 코드를 추가로 지정할 수있게 해주겠습니다 (베이스 클래스와 일치하지만 x 자체를 정의하지 않는 모든 유형에 대해 다른 유형에 대해 다른 방법 x 정의) - ABC가 거의 불가피하게 운반하는 상속 수하물없이 . 거의 예를 들어, Python의 ABCS는 그들이 제공하는 개념화 측면에서 상속을 포함한다고 "믿게"하기 때문에 ... 그러나 실제로는 상속 기반이 될 필요는 없기 때문입니다 (많은 사람들은 단지 특정의 존재와 서명을 확인하고 있습니다. 방법, Go의 인터페이스처럼).

왜 언어 디자이너 (Python의 경우 Guido와 같은)가 Python 's ABC와 같은 "양의 옷의 늑대"를 2002 년 이후로 제안한 더 간단한 Haskell과 유사한 선고를 선택하는 이유는 무엇입니까? 답변에 대한 질문. 결국, Python이 Haskell의 차용 개념에 대한 성능을 가지고있는 것처럼 보이지 않습니다 (예 : 목록 이해 / 발전기 표현식 - Python은 여기에 이중성이 필요하지만 Haskell은 "Lazy"이기 때문에 Haskell은 그렇지 않습니다). 내가 제공 할 수있는 가장 좋은 가설은 지금까지 대부분의 프로그래머에게 매우 친숙하다는 것입니다. 대부분의 언어 디자이너는 그런 식으로 물건을 캐스팅하여 쉽게 수용 할 수 있다고 생각합니다 (Go의 디자이너는 그렇게하지 않기 위해 칭찬해야합니다).

대담한 시작하겠습니다 : 나는 그것을 갖는 동기를 완벽하게 이해하고 어떤 사람들이 그것에 대해 논쟁 할 동기를 이해할 수 없습니다 ...

당신이 원하는 것은 비 초당의 임시 다형성.

  • 임시 : 구현은 다를 수 있습니다
  • 비 약독 : 성능 이유로; 컴파일 타임 파견

나머지는 제 생각에 설탕입니다.

C ++는 이미 템플릿을 통해 임시 다형성을 가지고 있습니다. 그러나 "개념"은 사용자 정의 된 엔티티에서 어떤 종류의 임시 다형성 기능을 사용하는지 명확하게 설명합니다.

C#에는 할 수있는 방법이 없습니다. 접근 방식 비 초가가 아닐 것입니다: Float와 같은 유형이 "unumeric"또는 "iaddable"(...)과 같은 것을 구현한다면 최소한 Generic Min, Max, Lerp를 쓸 수 있으며 해당 클램프, MapRange, Bezier (... ). 그러나 빠르지 않을 것입니다. 당신은 그것을 원하지 않습니다.

이 문제를 해결하는 방법 : .NET가 JIT 컴파일을 수행하므로 어쨌든 다른 코드도 생성합니다. List<int> 보다 List<MyClass> (값과 참조 유형의 차이로 인해) 아마도 임시 다형성 부분에 대해 다른 코드를 생성하기 위해 오버 헤드를 많이 추가하지 않을 것입니다. C# 언어는이를 표현하는 방법이 필요합니다. 일방 통행 당신이 스케치 한 것입니다.

또 다른 방법은 함수에 유형 제약 조건을 추가하는 것입니다. 사용 임시 다형성 기능 :

    U SuperSquare<T, U>(T a) applying{ 
         nonvirtual operator (*) T (T, T) 
         nonvirtual Foo U (T)
    }
    {
        return Foo(a * a);
    }

물론 FOO를 사용하는 막대를 구현할 때 점점 더 많은 제약을받을 수 있습니다. 따라서 정기적으로 사용하는 몇 가지 제약 조건에 이름을 부여하는 메커니즘을 원할 수도 있습니다. 그러나 이것은 다시 설탕이며 접근하는 한 가지 방법은 TypeClass 개념을 사용하는 것입니다 ...

몇 가지 제약 조건에 이름을 부여하는 유형 클래스를 정의하는 것과는 다르지만, 임의의 기능 유형 제약 조건의 임의의 수집을위한 설탕을위한 일종의 약어 메커니즘으로보고 싶습니다.

    // adhoc is like an interface: it is about collecting signatures
    // but it is not a type: it dissolves during compilation 
    adhoc AMyNeeds<T, U>
    {
         nonvirtual operator (*) T (T, T) 
         nonvirtual Foo U (T)
    } 

    U SuperSquare<T, U>(T a) applying AMyNeeds<T, U>        
    {
        return Foo(a * a);
    }

어떤 곳에서 "메인"에서 모든 유형의 인수는 알려져 있으며 모든 것이 구체화되고 함께 컴파일 될 수 있습니다.

여전히 누락 된 것은 다른 구현을 생성하지 못하는 것입니다. 상단 예에서 우리는 단지 사용된 다형성 기능을하고 모두에게 알리십시오 ...

구현은 다시 확장 방법을 따라갈 수 있습니다.

 public static class SomeAdhocImplementations
 {
    public nonvirtual int Foo(float x)
    {
        return round(x);
    }
 }

메인에서는 이제 다음을 쓸 수 있습니다.

    int a = SuperSquare(3.0f); // 3.0 * 3.0 = 9.0 rounded should return 9

컴파일러는 모든 "비 빈번한"임시 함수를 확인하고 내장 플로트 (*) 연산자와 A를 찾습니다. int Foo (float) 따라서 해당 라인을 컴파일 할 수 있습니다.

임시 다형성은 물론 올바른 구현이 삽입되도록 각 컴파일 시간 유형에 대해 다시 컴파일 해야하는 단점과 함께 제공됩니다. 그리고 아마도 IL은 DLL에 넣는 것을지지하지 않을 것입니다. 하지만 어쨌든 그들은 어쨌든 일할 수도 있습니다 ...

나는 유형 클래스 구성의 시동이 실제로 필요하지 않다고 생각합니다. 컴파일에 실패하면 제약 조건의 오류가 발생하거나 "ADHOC"CodeCLock과 함께 오류 메시지가 발생하는 경우. ~할 수 있었다 더 읽기 쉬운 것입니다.

    MyColor a = SuperSquare(3.0f); 
    // error: There are no ad hoc implementations of AMyNeeds<float, MyColor> 
    // in particular there is no implementation for MyColor Foo(float)

그러나 물론 유형 클래스 / "Adhoc polymorphism interface"의 시동도 생각할 수 있습니다. 그런 다음 오류 메시지가 표시됩니다. "The AMyNeeds constraint of SuperSquare has not been matched. AMyNeeds is available as StandardNeeds : AMyNeeds<float, int> as defined in MyStandardLib". 구현을 다른 방법과 함께 클래스에 넣고 지원되는 인터페이스 목록에"ADHOC 인터페이스 "를 추가 할 수도 있습니다.

그러나 특정 언어 설계와 독립적으로 : 나는 그들을 어떤 식 으로든 추가하는 단점을 보지 못합니다. 정적으로 타이핑 된 언어를 저장하는 언어는 항상 표현력의 경계를 밀어야합니다. 너무 적게 허용하기 시작했기 때문에 정상적인 프로그래머가 가능할 것으로 예상되는 작은 표현력 세트 인 경향이 있습니다 ...

TLDR : 나는 당신 편입니다. 이와 같은 것들은 주류 정적으로 입력 한 언어로 짜증납니다. Haskell은 길을 보여주었습니다.

What's 추론에 대한 업스트림 소스?

구현 복잡성을 위한 컴파일러 작가이 항상 고려할 때에는 새롭고 향상된 기능을 제공합니다.C++에서 이미 그 실수를 그리고 우리는 이미 고통 년의 버그 C++컴파일러로 결과입니다.

인터페이스를 상속성 기반 따라서는 상대적으로 느리게 간접하고 또한의 가능성은 없시키는 기존의 형식을 구현할

진실하지 않습니다.보 OCaml 의 구조적으로 입력체 시스템,예를 들어:

# let foo obj = obj#bar;;
val foo : < bar : 'a; .. > -> 'a = <fun>

foo 함수 개체의 모든 유형을 제공하는 데 필요한 bar 방법입니다.

에 대해 동일한 ML 의 높은 순서 모듈 시스템입니다.사실,심지어 공식적인 간의 동일하고 종류됩니다.실제로,클래스 형식을 위해 더 나은 작은 규모의 추상화와 같은 운영자 과부하는 반면 더 높은 순서 모듈에 대한 더 나은 큰 규모의 추상화와 같은 Okasaki 의 매개 변수화의 catenable 목록 큐에 있습니다.

그들은 심각한 단점들.

보신의 자신의 예를 들어,일반적인 산술입니다.F#할 수 있는 실제로 이미를 처리하는 특별한 경우 감사 INumeric 인터페이스입니다.F# Matrix 형식을 사용하는 접근 방식이다.

그러나,당신은 단지 대체계에 대한 코드를 추가 동적으로 파견하여 별도의 기능을 연산 주문 크기의 느립니다.대부분의 응용 프로그램에서는 쓸데 느립니다.를 해결할 수 있는 문제가에 의해 수행하는 전체 프로그램 최적화 하고 있는 명백한 단점이 있습니다.또한,이 작은 공통점 사이의 수치해법을 intfloat 로 인해 수 견고 그의 추상화도 실질적으로 쓸모가 없다.

질문하실 수 있습니다.:할 수 있는 사람들에게 경쟁력 있는 경우 의 채택을 입력하십니까?

그러나 여전히 "주류 언어"는 [유형 클래스]를 제공하지 않습니다.

이 질문이 요청되면 이것은 사실 일 수 있습니다. 오늘날 Haskell 및 Clojure와 같은 언어에 훨씬 더 큰 관심이 있습니다. Haskell에는 유형 클래스가 있습니다 (class / instance), Clojure 1.2+가 있습니다 프로토콜 (defprotocol / extend).

유형 클래스]에 대한 추론은 무엇입니까?

나는 유형 클래스가 다른 다형성 메커니즘보다 객관적으로 "더 나쁘다"고 생각하지 않습니다. 그들은 단지 다른 접근법을 따릅니다. 실제 질문은 특정 프로그래밍 언어에 잘 맞습니까?

유형 클래스가 Java 또는 C#과 같은 언어의 인터페이스와 어떻게 다른지 간단히 생각해 봅시다. 이 언어에서 클래스는 해당 클래스의 정의에서 명시 적으로 언급되고 구현 된 인터페이스 만 지원합니다. 그러나 유형 클래스는 다른 모듈에서도 이미 정의 된 유형에 추가 할 수있는 인터페이스입니다. 이러한 종류의 유형 확장 성은 특정 "주류"OO 언어의 메커니즘과 분명히 다릅니다.


이제 몇 가지 주류 프로그래밍 언어에 대한 유형 클래스를 고려해 봅시다.

Haskell:이 언어가 있다고 말할 필요가 없습니다 유형 클래스.

Clojure: 위에서 말했듯이 Clojure는 다음의 형태의 유형 클래스와 같은 것을 가지고 있습니다. 프로토콜.

C ++: 당신이 스스로 말했듯이 개념 C ++ 11 사양에서 삭제되었습니다.

반대로 : 매우 유사한 아이디어 인 개념은 다음 C ++에서 제외되었습니다!

나는이 결정에 대한 전체 토론을 따르지 않았다. 내가 읽은 바에 따르면, 개념은 아직 "준비되지 않았다"는 것이 아니 었습니다. 컨셉 맵에 대한 논쟁이 여전히있었습니다. 그러나 개념은 완전히 포기되지 않았으며 다음 버전의 C ++로 만들 것으로 예상됩니다.

씨#: 언어 버전 3을 사용하여 C#은 본질적으로 객체 지향 및 기능적 프로그래밍 패러다임의 하이브리드가되었습니다. 유형 클래스와 개념적으로 매우 유사한 언어에 한 가지 추가가 추가되었습니다. 확장 방법. 주요 차이점은 인터페이스가 아닌 기존 유형에 새 메소드를 첨부하는 것입니다.

(확장 방법 메커니즘은 Haskell 's만큼 우아하지 않습니다. instance … where 통사론. 확장 방법은 유형에 "진정으로"첨부되지 않으며 구문 변형으로 구현됩니다. 그러나 결국 이것은 매우 큰 실용적인 차이를 만들지 않습니다.)

나는 이것이 곧 일어날 것이라고 생각하지 않습니다. 언어 디자이너는 아마도 확장을 추가하지 않을 것입니다. 속성 언어와 확장 인터페이스 그보다 한 걸음 더 나아갈 것입니다.

(vb.net: Microsoft는 한동안 C# 및 vb.net 언어를 "공동 진화"해 왔으므로 C#에 대한 내 진술도 vb.net에도 유효합니다.)

자바: 나는 Java를 잘 모르지만, 언어 C ++, C# 및 Java의 언어는 아마도 "가장 순수한"언어 일 것입니다. 나는 유형 클래스가 어떻게이 언어에 자연스럽게 맞는지 알지 못합니다.

에프#: 설명하는 포럼 게시물을 찾았습니다 유형 클래스가 F#에 도입되지 않는 이유. 이 설명은 F#이 구조적 유형 시스템이 아니라 명목상이 있다는 사실을 중심으로합니다. (이것이 F#이 유형 클래스를 갖지 않는 충분한 이유인지 확실하지는 않지만.)

우리가하는 일인 Matroid를 정의 해보십시오 (로그, 구두로 말하지 않고). 여전히 C 구조물과 같은 것일 수 있습니다.Liskov 원칙 (최신 Turing Medalist)는 너무 추상적이고 범주 적, 이론적이며 실제 데이터를 덜 처리하고 더 순수한 이론적 클래스 시스템, Handson Pragmatic Problembling을 위해, 프롤로그처럼 보이는 Code에 대한 코드에 대한 코드 ... 알고리즘은 종이 나 칠판에서 이해하는 시퀀스와 여행을 설명합니다. 최소한의 코드 또는 대부분의 초록으로 문제를 해결하는 목표에 따라 다릅니다.

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