Java의 새로운 개발은 Scala 및 Clojure와 같은 언어와의 상호 운용성에 어떤 영향을 미칩니 까?


11

내가 이해하는 한, Scala와 Clojure는 모두 새로운 언어로 설계되었습니다.

  1. JVM에 의존하고
  2. Scala 및 Clojure 코드 내에서 Java 클래스를 사용할 수 있다는 점에서 Java 코드와 쉽게 통합됩니다.

Java 8부터 (그리고 이후 버전의 Java에서는 더 강력하게) Java 언어의 의미에 변화가있을 것입니다.

이러한 변경 사항이 Java와 Scala / Clojure 간의 상호 운용성에 어떤 영향을 미치며 그 결과는 무엇인지 묻고 싶었습니다. 예를 들어 Java 8의 람다는 객체가 아니므로 (예 : 여기 참조 ) Scala와 Clojure는 객체가 아닌 Java 값을 처리해야 할 수도 있습니다. 이것이 문제입니까?

다음과 같은 시나리오를 생각할 수 있습니다.

  1. Scala 또는 Clojure 언어는 새로운 Java 의미에 적응하고 (새로운 비 객체 값을 처리하기 위해) Java와의 상호 운용성을 지원하도록 확장 될 것입니다.
  2. 스칼라 또는 클로저 언어는 확장 되지 않습니다 . 함수 값과 같은 새로운 Java 기능을 기존 개념에 맵핑 할 수있는 경우에만 가능합니다. 예를 들어 스칼라에서는 함수조차 객체이므로 Java 함수가 스칼라에 표시되면 다시 일종의 객체로 래핑됩니다.
  3. Scala 또는 Clojure 언어는 최신 Java 개발을 수행하지 않고도 Java 6 또는 7까지의 상호 운용성을 계속 지원합니다. 이를 위해서는 이전 버전의 Java를 계속 지원해야합니다 (적어도 OpenJDK 또는 다른 프로젝트에서). 이러한 언어는보다 보수적이고 안정적인 Java 분기를 기반으로 할 수 있습니다.

요약 : 향후 Java 개발이 Java와의 상호 운용성을 유지하기 위해 Scala 및 Clojure와 같은 언어에 영향을 미칠 것으로 예상 할 수 있습니까? 이 주제에 대해 이미 진행중인 토론이 있습니까?

노트

Scala, Clojure 및 기타 JVM 기반 언어에는 새로운 버전의 JVM으로 구현을 업데이트하는 데 큰 문제가 없을 것입니다 (그리고 새로운 JVM 기능으로 인해이 구현이 훨씬 쉬워 질 것입니다). 필자의 질문은 언어로서의 Java 기능과 JVM 기반 언어가 최신 JVM에서 실행 될지 여부가 아니라 다른 JVM 언어가 이러한 새로운 기능을 "확인"/ 사용할 수 있는지 여부에 초점을 맞추고 있습니다.


6
스칼라 등이 Java에 의존한다고 말하는 것은 부정확합니다. JVM 바이트 코드에 의존합니다. 모든 상호 운용성 기능은 Java 언어 소스 코드가 아닌 바이트 코드를 처리하므로 Java 자체에 대한 변경 사항은 위협이되지 않습니다. JVM의 변경 사항 만 이러한 언어에 영향을 줄 수 있으며 JVM은 매우 보수적입니다. 기본적으로 아무것도 지원하지 않습니다. 실제로 요즘 JVM의 대부분의 변경 사항은 특히 최신 동적 언어를 위한 것 입니다.
Kilian Foth

@ 킬리언 Foth : 내가 아는 한 스칼라 String는 Java String입니다. 스칼라는 특정 Java 라이브러리 클래스를 사용합니다. 그러나 너무 강하다고 생각되면 공식을 변경할 수 있습니다.
Giorgio

@ 킬리언 Foth : 내 질문의 초점이 Scala와 Java resp 간의 상호 운용성 있기 때문에 의존 이라는 용어를 제거했습니다 . 클로저와 자바.
Giorgio

@KilianFoth 이것은 질문의 주요 관심사를 다루기 때문에 답이되어야합니다. 새로운 Java 릴리스의 첫 번째 목표는 이전 버전과의 호환성입니다.
maple_shaft

3
@maple_shaft : 질문을 수정하고 "종속"이라는 단어를 제거했습니다. 다른 의견에서 지적했듯이, 내 문제는 Scala 또는 Clojure가 Java 또는 JVM 기능에 의존하는 방법이 아니라 Scala / Clojure가 Java 기능을 "볼"수있는 방법입니다. 내가 아는 한 클래스, 인터페이스, 객체, 메소드, 기본 데이터 유형과 같은 Java 6 기능을 볼 수 있습니다. 이를 통해 Scala / Clojure는 Java 6 코드를 호출 할 수 있습니다. 내 질문은,이 언어들이 미래의 Java 언어 구조를 "보게"(따라서 사용할 수 있을까) 아니면 Scala / Clojure 언어의 확장이 필요한가?
Giorgio

답변:


15

실제로 Java 8은 Java와 상호 작용하는 다른 JVM 언어에 해를 끼치는 많은 것을 소개하지 않습니다. Lambdas에 대한 작업은 invokedynamic, MethodHandles, MethodReferences 등과 관련된 여러 가지 작은 문제를 해결하는 데 도움이되었지만 정상적으로 수행되는 것과는 별개입니다. 즉, 다른 JVM 언어가 잠재적으로 호출 할 수있는 완전히 새로운 API가 있습니다. 기본적으로 어떤 것을 사용할 지에 달려 있습니다.

interop에 영향을 미치는 가장 큰 변경 사항은 실제로 JVM 내에서 동적 / 늦은 바인딩 호출을 허용하는 invokedynamic 바이트 코드와 함께 Java 7과 함께 제공되었습니다. 처음에는 JVM의 다른 언어를 위해 설계되었습니다. 이후 Lamdbas에 매우 유용하게 적용되었으므로 Java 8부터 Java는 실제로 이러한 바이트 코드를 방출하기 시작합니다.

일부 언어 (예 : JRuby)는 이미 invokedynamic을 많이 사용하는 반면, 다른 언어 (Scala, Groovy 등)는 여전히 그 사용을 조사 중이거나 패치 초기 단계에 있습니다. Java는 이전에 강제로 사용했던 수많은 느린 해결 방법과 달리 호출을 호출합니다.

Java 9는 프로젝트 Jigsaw가 플랫폼에 도입되면서 JVM 언어에 더 많은 도전을 가져 오며 이는 전통적으로 JVM의 클래스로드 및 클래스 경로의 시작이 될 것입니다. JVM 언어 사람들은 이것을 잘 알고 있으며 합리적인 협력이 이루어질 것으로 기대합니다.


1
그러나 내가 아는 한 스칼라 폐쇄는 대상입니다.
Giorgio

1
네. 스칼라는 최근에야 Java 1.5에 대한 지원을 중단했습니다 . 1.6이 떨어지기까지는 오랜 시간이 걸릴 것입니다.
Jörg W Mittag

1
@Giorgio Java의 언어 기능은 어쨌든 컴파일 할 때 바이트 코드 트릭과 동일하므로 중요하지 않습니다. 새로운 바이트 코드가 도입 되더라도 JVM이 항상 이전 버전과 호환된다는 사실을 받아들이면 Scala는 영향을받지 않으며 편리하게 새 JVM 기능을 활용할 수 있습니다.
maple_shaft

1
"어쨌든 컴파일 할 때 대부분의 바이트 코드 트릭과 동일하기 때문에 Java의 언어 기능은 중요하지 않습니다.": 다른 언어가 Java 구문을 사용하려면 해당 구문에 대해 생성 된 바이트 코드를 인식 할 수 있어야합니다. Java가 새로운 바이트 코드에 매핑되는 새로운 구문을 도입하는 경우 호스트 언어는 최소한 새로운 래퍼 / 인터페이스를 구현하여 새로운 바이트 코드를 인식하고 사용해야합니다. 예를 들어 Java 8 람다가 객체를 만들지 않고 새로운 특정 바이트 코드로 새로운 구조를 만들면 호스트 언어를 인식해야합니다.
Giorgio

2
@Giorgio : 물론, Java 8 플랫폼에 대한 변경은 계획되어 있지 않습니다. 사실, JVMS은 확장 된 두 번 2003 년과 2010 년에, Java 플랫폼의 전체 역사에서, 두 번째 시간 (의 도입 invokedynamic바이트 코드) 지원 언어에 특별히이었다 다른 자바에 비해; 실제로 Java 7 언어 해당 바이트 코드를 지원하거나 사용 하지 않습니다 .
Jörg W Mittag

2

스칼라 람다는 Java 람다가 사용되는 컨텍스트에 따라 유형을 지정하기 때문에 Java가 람다를 추가하면 남겨질 예정입니다.

executor.execute(() -> { System.out.println("hello world"); });

Java 8에서 Scala로 다음과 같이 작성할 수 있습니다.

executor execute new Runnable {
    override def run() { println("hello world") }
}

Scala의 () => Unit을 Runnable로 변환하는 일부 래퍼를 사용하거나 쓰지 않는 한.


답변과 내 질문에 답변 해 주셔서 감사합니다 (+1). 올바르게 이해하면 Scala는 Java 8 람다가 Scala 람다와 다른 의미를 갖기 때문에 Java 8이 람다를 사용하는 컨텍스트에서 인터페이스를 인스턴스화하기 위해 익명 클래스를 계속 사용해야합니다. 나에게 분명하지 않은 또 다른 요점은 Java 메소드가 Java 람다를 반환하면 어떻게 될지입니다. 스칼라 클래스가 해당 메소드를 호출하면 어떻게됩니까? 스칼라의 반품 유형은 무엇입니까?
Giorgio

1
@Giorgio Java 8에서 람다 식은 단일 메서드를 선언하고 컨텍스트에 의해 지연되는 인터페이스 인스턴스를 만드는 언어 수준 바로 가기입니다. 따라서 Java 8 메소드가 람다를 리턴하면 실제로 메소드의 리턴 유형으로 선언 된 인터페이스 인스턴스를 리턴합니다. 스칼라 2.9.1부터 리턴 타입은 단순히 스칼라 람다로 처리 할 수 없는 인터페이스 (Runnable 또는 Comparator)의 인스턴스 일뿐 입니다. 스칼라 라이브러리의 향후 릴리스에서 암시 적 변환을 도입하지 않는 한 스칼라 람다 유형에 대한 인터페이스.
hellodanylo

@SkyDan : 좋습니다. 따라서 Scala는 Java 람다를 인터페이스를 구현하는 객체로 간주합니다. 이 점은 나에게 분명하지 않았다. Java가 객체와 다른 바이트 코드를 생성 할 것이라고 생각했다. 그러나 그것은 후드 아래의 객체 여야합니다. 그렇지 않으면 인터페이스의 구현으로 인식되지 않습니다. 나는 지금 그것을 얻었다 생각합니다.
Giorgio

@Giorgio, Java 8의 람다 관련 변경 사항에 대해 더 알고 싶다면 이러한 변경 사항을 적용해야합니다 . Lambda 프로젝트에 대한매혹적이고 자세한 개요 를 읽어 보시기 바랍니다 .
hellodanylo

@ SkyDan : 지금 읽고 있습니다. 람다가 나에게 보인다 (유형 / 인터페이스가 정의 된 문맥에서 추론하더라도) 객체를 나타냅니다. 따라서 mail.openjdk.java.net/pipermail/lambda-dev/2011-August/…에 제공된 정보 ( " lambdas 는 객체가 아닙니다")가 잘못되었거나 적어도 오도의 소지가 있습니다.
Giorgio
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.