Java 8에서 함수 유형을 제거하는 이유


12

JDK 8 Lambda Expert Group (EG)이 새로운 기능 유형을 Java 프로그래밍 언어에 포함시키지 않기로 결정한 이유를 이해하려고 노력했습니다.

메일 링리스트를 살펴보면 함수 유형 제거에 대한 토론이있는 스레드를 찾았습니다 .

문맥이 부족하고 경우에 따라 유형 시스템 구현에 대한 제한된 지식 때문에 많은 진술이 모호합니다.

그러나이 사이트에서 의미를 더 잘 이해하도록 돕기 위해이 사이트에서 안전하게 공식화 할 수 있다고 생각되는 몇 가지 질문이 있습니다.

메일 링리스트에서 질문을 할 수는 있지만 스레드는 오래되었고 모든 결정이 이미 이루어 졌으므로이 사람들이 이미 계획을 연기하고 있다는 사실을 무시할 가능성이 높습니다.

Brian Goetz는 함수 유형 제거를 지원하고 SAM 유형 사용을 승인한다는 그의 대답에서 다음과 같이 말합니다.

통일이 없습니다. 함수 유형을 구체화하는 데 얼마나 유용한 지에 대한 긴 스레드가있었습니다. 통일없이 기능 유형이 혼잡합니다.

그가 언급 한 실을 찾을 수 없었습니다. 이제 구조적 함수 유형의 도입이 Java의 대부분 공칭 유형 시스템에서 특정 합병증을 암시 할 수 있음을 이해할 수 있습니다. 이해할 수없는 것은 매개 변수화 된 SAM 유형이 조정 측면에서 어떻게 다른지입니다.

둘 다 동일한 통일 문제를 겪지 않습니까? 누구든지 함수 측면에서 기능화가 SAM 유형과 어떻게 다른지 이해 하는가?

다른 의견에서 Goetz는 다음과 같이 말합니다.

타이핑에는 두 가지 기본 접근 방식이 있습니다 : 명목 및 구조. 명목상의 정체성은 그 이름에 기초한다. 구조적 유형의 정체성은 그것이 구성되는 것에 기초한다 (예를 들어, "tuple of int, int"또는 "int에서 float 로의 함수"). 대부분의 언어는 대부분 공칭 또는 대부분 구조를 선택한다. "가장자리 주변"을 제외하고 명목 및 구조적 타이핑을 성공적으로 혼합 한 언어는 많지 않습니다. Java는 거의 전적으로 공칭입니다 (몇 가지 예외는 있지만 배열은 구조적 유형이지만 맨 아래에는 항상 명목 요소 유형이 있습니다. 제네릭에는 공칭과 구조가 혼합되어 있으며 이는 실제로 많은 소스의 일부입니다 제네릭에 대한 사람들의 불만.) Java에 구조적 유형 시스템 (함수 유형) 접목 공칭 유형 시스템은 새로운 복잡성과 에지 사례를 의미합니다. 기능 유형의 이점이 가치가 있습니까?

타입 시스템 구현 경험이있는 분들 여기에 언급 된 이러한 복잡성 또는 엣지 사례에 대한 예를 알고 있습니까?

솔직히 나는 JVM을 기반으로하는 Scala와 같은 프로그래밍 언어가 기본 플랫폼의 수정 문제에도 불구하고 함수 및 튜플과 같은 구조 유형을 지원한다고 생각할 때 이러한 주장에 혼란스러워합니다.

내가 틀리지 말고, 함수 유형이 SAM 유형보다 낫다는 말은 아닙니다. 나는 그들이 왜 이런 결정을 내 렸는지 이해하고 싶습니다.


4
"공칭 유형 시스템에 구조 유형 시스템 (함수 유형)을 이식하는 것은 새로운 복잡성을 의미합니다." -이는 사용자가 언어를 사용하기 위해 더 많은 것을 배워야하는 복잡성을 의미 합니다 . 같은 뭔가 간단하고 자바를 사용하기 쉬운 C ++ 배울 복잡하고 어려운처럼되고 그런 물건을. 메일 링리스트 회원 가능성이 하나 눈에 띄는 예를되고, 이전에 "개선의 큰 파도 '에 대한 비판을 암시 수있는 자바 5 짜증 클린턴 문서의 MyBatis의 시작
모기

3
"간단하고 사용하기 쉬운 Java는 복잡하고 C ++을 배우기가 어렵습니다."불행하게도, 주류 프로그래밍 언어의 한 가지 문제점은 이전 버전과의 호환성을 유지해야하므로 너무 복잡 해지는 경향이 있다는 것입니다. 따라서 IMHO (C ++과 Java 모두에서 수년간 경험을 쌓은)는이 진술에 진실이 있습니다. 나는 종종 자바가 얼어 붙어야하고 대신 새로운 언어가 개발되어야한다는 느낌을 받는다. 그러나 오라클은 그러한 위험을 감수 할 수 없습니다.
Giorgio

4
@edalorzo : Clojure, Groovy, Scala 및 기타 언어에서 알 수 있듯이 (1) 새로운 언어를 정의하고 (2) 이전 버전과의 호환성을 유지하면서 Java로 이미 작성된 모든 라이브러리와 도구를 사용할 수 있습니다. Java 프로그래머는 Java를 사용할 것인지, 다른 언어로 전환 할 것인지 또는 둘 다 사용할 것인지를 자유롭게 선택할 수 있습니다. 기존 언어를 무기한 확장하는 IMO는 휴대 전화 회사가 항상 새로운 모델을 만들어야하는 것과 같은 방식으로 고객을 유지하기위한 전략입니다.
Giorgio

2
Java의 SAMbdas에서 이해 한 것처럼 그 이유 중 하나는 일부 라이브러리 (컬렉션)를 이전 버전과 호환 가능하게 유지하는 데 문제가 있기 때문입니다.
Petr Pudlák

2
Goetz 의이 다른 게시물로 연결되는 SO 관련 게시물 .
assylias

답변:


6

SAM 접근 방식은 실제로 Scala (및 C ++ 11)가 익명 함수 (Scala =>연산자 또는 C ++ 11 []()(lambda) 구문으로 생성)를 사용하여 수행하는 것과 다소 유사합니다 .

Java 측에서 대답해야 할 첫 번째 질문은 람다 명령문의 리턴 유형이 새로운 프리미티브 유형 ( int또는 같은) 인지 또는 byte일종의 객체 유형인지 여부입니다. 스칼라,이 없다 하더라도 정수 클래스의 객체 인 - 더 원시적 형 Int- 및 기능이 클래스의 상이되는 물체도 Function1, Function2, 등, 인자의 개수에 따라 기능이 걸린다.

C ++ 11, 루비 및 파이썬에는 비슷하게 명시 적 또는 암시 적 방식으로 호출 가능한 객체를 반환하는 람다식이 있습니다. 반환 된 객체에는 표준 메소드가 있습니다 (예 : #call함수로 호출하는 데 사용할 수 있음). 예를 들어 C ++ 11은 std::function오버로드 되는 유형을 사용 operator()하여 객체의 호출 메소드 호출이 텍스트 호출처럼 함수 호출처럼 보이도록 합니다. :-)

Java에 대한 새로운 제안이 지저분 해지는 경우 구조적 타이핑을 사용하여 이러한 메소드를 다른 오브젝트에 지정할 수 있습니다 (예 : 이름이 다른Comparator 단일 기본 메소드 가있는 메소드) . 이것은 어떤면에서는 개념적으로 구역질 있지만, 그것은 수행 결과 객체가 콜백, 비교기를 나타내는 객체를 가지고 기존의 기능에 전달, 등등, 그리고 잘 정의 된 하나를 호출 할 수있을 것으로 예상 할 수 있음을 의미 방법 등 #compare이나 #callback. C ++의 재정의 트릭은 operator()C ++ 11 이전 에도이 문제를 깔끔하게 피했습니다. 콜백 옵션은 모두 같은 방식으로 호출 할 수 있으므로 S ++은 C ++ 11 람다를 사용할 수 있도록 조정할 필요가 없었기 때문에sort등등. 과거에 이러한 객체에 표준 명명을 사용하지 않은 Java는 (아마도 연산자 오버로드와 같은 트릭이 단일 접근 방식을 분명하게 만들지 않았기 때문에) 그렇게 운이 좋지 않으므로이 해킹으로 인해 기존 API를 많이 변경하지 않아도됩니다. .


1
아이러니하게도, 어떤 종류의 "함수 같은 것"을 나타내는 수많은 서로 다른 호환되지 않는 타입을 가지고 있다면 문제를 만드는 실제 리터럴 구문과는 상관없이 라이브러리에 표준 함수 타입을 추가함으로써 깔끔하게 피할 수있었습니다. 이 있었다면 java.util.Function2<T1, T2, R>자바 1.0, 다음 더 없을 것 Comparator대신에 모든 방법이 걸릴 것이다, 인터페이스 Function2<T1, T2, int>. (글쎄, Function2TT_int<T1, T2>프리미티브 때문에 인터페이스의 전체가 있었지만 내 요점을 알 수 있습니다.)
Jörg W Mittag
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.