Sự phát triển mới của Java sẽ ảnh hưởng đến khả năng tương tác của nó với các ngôn ngữ như Scala và Clojure như thế nào?


11

Theo tôi hiểu, cả Scala và Clojure đều được thiết kế như những ngôn ngữ mới

  1. phụ thuộc vào JVM và
  2. dễ dàng tích hợp với mã Java, theo nghĩa là chúng cho phép sử dụng các lớp Java bên trong mã Scala và Clojure.

Bắt đầu với Java 8 (và thậm chí có thể mạnh hơn với các phiên bản tiếp theo của Java), sẽ có những thay đổi về ngữ nghĩa của ngôn ngữ Java.

Tôi muốn hỏi làm thế nào những thay đổi này sẽ ảnh hưởng đến khả năng tương tác giữa Java và Scala / Clojure và hậu quả sẽ ra sao. Ví dụ, vì lambdas trong Java 8 không phải là đối tượng (xem ví dụ ở đây ), Scala và Clojure có thể phải xử lý các giá trị Java không phải là đối tượng. Đây sẽ là một vấn đề?

Tôi có thể nghĩ về các tình huống sau:

  1. Ngôn ngữ Scala hoặc Clojure sẽ được mở rộng để thích ứng với ngữ nghĩa Java mới (để xử lý các giá trị phi đối tượng mới) và hỗ trợ khả năng tương tác với Java.
  2. Ngôn ngữ Scala hoặc Clojure sẽ không được mở rộng. Điều này chỉ có thể nếu các tính năng Java mới như giá trị hàm có thể được ánh xạ tới các khái niệm hiện có. Ví dụ, trong Scala, ngay cả một hàm là một đối tượng, vì vậy tôi đoán các hàm Java sẽ lại được bọc vào một số loại đối tượng khi chúng hiển thị với Scala.
  3. Ngôn ngữ Scala hoặc Clojure sẽ tiếp tục hỗ trợ khả năng tương tác lên tới Java 6 hoặc 7, mà không tuân theo sự phát triển mới nhất của Java. Điều này sẽ yêu cầu các phiên bản Java cũ hơn vẫn được hỗ trợ (ít nhất là bởi OpenJDK hoặc dự án khác), để các ngôn ngữ này có thể dựa trên một nhánh Java bảo thủ / ổn định hơn.

Tóm tắt: chúng ta có thể hy vọng rằng sự phát triển trong tương lai của Java sẽ có tác động đến các ngôn ngữ như Scala và Clojure để duy trì khả năng tương tác với Java không? Có một số (liên kết đến) thảo luận liên tục về chủ đề này đã?

Ghi chú

Tôi có thể tưởng tượng rằng Scala, Clojure và các ngôn ngữ dựa trên JVM khác sẽ không có bất kỳ vấn đề lớn nào khi cập nhật triển khai của chúng lên các phiên bản JVM mới hơn (và các tính năng JVM mới sẽ giúp việc triển khai này trở nên dễ dàng hơn). Câu hỏi của tôi tập trung vào các tính năng của Java như một ngôn ngữ và liệu ngôn ngữ JVM khác có thể "nhìn thấy" / sử dụng các tính năng mới này hay không, không phải là liệu các ngôn ngữ dựa trên JVM sẽ chạy trên JVM mới nhất.


6
Thật không chính xác khi nói rằng Scala, vv phụ thuộc vào Java. Chúng phụ thuộc vào mã byte JVM. Tất cả các tính năng tương tác đều xử lý mã byte, không phải mã nguồn ngôn ngữ Java, do đó, bất kỳ thay đổi nào được thực hiện đối với chính Java đều không có mối đe dọa. Chỉ những thay đổi được thực hiện đối với JVM mới có thể ảnh hưởng đến các ngôn ngữ này và JVM cực kỳ bảo thủ - về cơ bản nó không bao giờ loại bỏ hỗ trợ cho bất cứ điều gì. Trong thực tế, hầu hết các thay đổi trong JVM hiện nay được dành riêng cho các ngôn ngữ động mới hơn.
Kilian Foth

@Kilian Foth: Theo như tôi biết thì Scala Stringlà Java String. Vì vậy, Scala sử dụng các lớp thư viện Java nhất định. Nhưng tôi có thể thay đổi công thức nếu bạn nghĩ nó quá mạnh.
Giorgio

@Kilian Foth: Tôi đã loại bỏ thuật ngữ phụ thuộc vì trọng tâm của câu hỏi của tôi là thay vào đó là khả năng tương tác giữa Scala và Java resp. Clojure và Java.
Giorgio

@KilianFoth Đây phải là một câu trả lời vì nó giải quyết mối quan tâm chính của câu hỏi. Mục tiêu số một của bất kỳ bản phát hành Java mới nào là khả năng tương thích ngược.
maple_shaft

3
@maple_shaft: Tôi đã sửa câu hỏi của mình và xóa từ "lệ thuộc". Như tôi đã chỉ ra trong một bình luận khác, vấn đề của tôi không phải là Scala hay Clojure phụ thuộc vào các tính năng Java hay JVM như thế nào, mà là cách Scala / Clojure có thể "nhìn thấy" các tính năng Java. Theo tôi biết họ có thể thấy các tính năng của Java 6 như các lớp, giao diện, đối tượng, phương thức, kiểu dữ liệu nguyên thủy. Điều này cho phép Scala / Clojure sử dụng (gọi) mã Java 6. Câu hỏi của tôi là, các ngôn ngữ này cũng sẽ "nhìn thấy" (và, do đó, có thể sử dụng) các cấu trúc ngôn ngữ Java trong tương lai hay điều này sẽ yêu cầu các phần mở rộng cho các ngôn ngữ Scala / Clojure?
Giorgio

Câu trả lời:


15

Trên thực tế, Java 8 không giới thiệu nhiều điều sẽ gây bất lợi cho các ngôn ngữ JVM khác tương tác với Java. Công việc được thực hiện trên Lambdas đã giúp khắc phục một số vấn đề nhỏ xung quanh inv invocate, MethodHandles, MethodReferences, v.v. - nhưng ngoài ra nó vẫn tiếp tục như bình thường. Điều đó nói rằng, có một loạt các API hoàn toàn mới mà các ngôn ngữ JVM khác có thể có khả năng gọi vào bây giờ. Những cái họ sẽ sử dụng theo mặc định hay không là tùy thuộc vào họ.

Sự thay đổi tác động lớn nhất thực sự xuất hiện với Java 7 - với mã byte được kích hoạt cho phép các cuộc gọi ràng buộc động / trễ trong JVM - thứ được thiết kế ban đầu cho các ngôn ngữ khác trên JVM. Do đó, nó đã được điều chỉnh rất hữu ích cho Lamdbas, vì vậy kể từ Java 8, Java sẽ thực sự bắt đầu phát ra các mã byte này.

Một số ngôn ngữ (ví dụ như JRuby) đã sử dụng inv invocate rất nhiều, trong khi những ngôn ngữ khác (Scala, Groovy et al) vẫn đang điều tra việc sử dụng nó hoặc đang ở giai đoạn đầu của việc vá nó. Các cuộc gọi bất khả xâm phạm Java, trái ngược với vô số cách giải quyết chậm hơn mà họ buộc phải sử dụng trong quá khứ.

Java 9 sẽ mang lại nhiều thách thức hơn cho các ngôn ngữ JVM với dự án Jigsaw vào nền tảng, đây sẽ là khởi đầu cho sự kết thúc đối với việc tải lớp và các đường dẫn lớp truyền thống cho JVM. Những người sử dụng ngôn ngữ JVM khá nhận thức được điều này và tôi mong đợi một sự hợp tác hợp lý sẽ diễn ra.


1
Nhưng, theo như tôi biết, đóng cửa Scala là một đối tượng.
Giorgio

1
Vâng. Scala chỉ vừa mới bỏ hỗ trợ cho Java 1.5, sẽ còn rất lâu nữa cho đến khi họ giảm 1.6.
Jörg W Mittag

1
@Giorgio Các tính năng ngôn ngữ của Java là không quan trọng vì hầu hết các tính năng này tương đương với các thủ thuật mã byte khi được biên dịch bằng mọi cách. Nếu chúng tôi chấp nhận rằng JVM sẽ luôn tương thích ngược, ngay cả khi mã byte mới được giới thiệu, Scala sẽ không bị ảnh hưởng và có thể chọn tận dụng các tính năng JVM mới đó một cách thuận tiện.
maple_shaft

1
"Các tính năng ngôn ngữ của Java là không quan trọng vì hầu hết các tính năng này tương đương với các thủ thuật mã byte khi được biên dịch.": Nếu một ngôn ngữ khác muốn sử dụng cấu trúc Java, thì nó phải có khả năng nhận ra mã byte được tạo cho cấu trúc đó. Nếu Java giới thiệu một cấu trúc mới ánh xạ tới mã byte mới, thì ngôn ngữ máy chủ ít nhất nên triển khai một trình bao bọc / giao diện mới để nhận biết và sử dụng mã byte mới. Ví dụ: nếu lambda Java 8 không tạo đối tượng nhưng một số cấu trúc mới với mã byte mới, cụ thể cho nó, ngôn ngữ máy chủ phải được điều chỉnh để nhận ra nó.
Giorgio

2
@Giorgio: Chắc chắn, nhưng không có thay đổi nào như vậy được lên kế hoạch cho nền tảng Java 8. Trên thực tế, JVMS chỉ được mở rộng hai lần trong toàn bộ lịch sử của Nền tảng Java, vào năm 2003 và 2010 và lần thứ hai (giới thiệu invokedynamicmã byte) đặc biệt hỗ trợ các ngôn ngữ khác ngoài Java; thực tế, ngôn ngữ Java 7 không hỗ trợ hoặc sử dụng mã byte đó.
Jörg W Mittag

2

Scala sắp bị bỏ lại khi Java thêm lambdas vì lambdas Java được gán một loại theo bối cảnh chúng được sử dụng, trong khi Scala lambdas được gán một loại dựa trên mùi thơm, loại tham số và loại trả về của chúng, ví dụ:

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

từ Java 8 có thể được viết bằng Scala như:

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

trừ khi bạn sử dụng / ghi một số trình bao bọc chuyển đổi Scala's () => Đơn vị thành Runnable.


Cảm ơn câu trả lời và cũng đã giải quyết câu hỏi của tôi (+1). Nếu tôi hiểu chính xác, Scala sẽ phải tiếp tục sử dụng các lớp ẩn danh để khởi tạo các giao diện trong ngữ cảnh trong đó Java 8 sẽ sử dụng lambdas (vì lambdas Java 8 có ngữ nghĩa khác với Scala lambdas). Một điểm khác không rõ ràng với tôi là điều gì sẽ xảy ra nếu một phương thức Java trả về lambda Java. Điều gì xảy ra nếu một lớp Scala gọi phương thức đó? Điều gì sẽ là kiểu trở lại trong Scala?
Giorgio

1
@Giorgio Trong Java 8, một biểu thức lambda là một lối tắt cấp độ ngôn ngữ để tạo một thể hiện của giao diện khai báo một phương thức duy nhất và được trì hoãn theo ngữ cảnh. Vì vậy, khi một phương thức Java 8 trả về lambda, nó thực sự trả về một thể hiện của giao diện được khai báo là kiểu trả về của phương thức. Kể từ Scala 2.9.1, kiểu trả về sẽ chỉ đơn giản là một ví dụ của một số giao diện nói (Runnable hoặc so sánh) mà bạn không thể coi là Scala lambda, trừ khi bạn hoặc các phiên bản tương lai của Scala libary giới thiệu một chuyển đổi ngầm từ đó giao diện với loại lambda Scala.
hellodanylo

@SkyDan: Ok, vì vậy Scala sẽ xem Java lambdas như các đối tượng triển khai một số giao diện. Điểm này đối với tôi không rõ ràng: Tôi nghĩ Java sẽ tạo ra một số mã byte khác với đối tượng. Nhưng nó phải là một đối tượng dưới mui xe, nếu không nó sẽ không được công nhận là việc thực hiện giao diện. Tôi nghĩ rằng tôi đã nhận nó ngay bây giờ.
Giorgio

@Giorgio, nếu bạn muốn biết thêm về các thay đổi liên quan đến lambda trong Java 8 và buộc các thay đổi này, tôi khuyên bạn nên đọc tổng quan hấp dẫn và chi tiết này về dự án Lambda .
hellodanylo

@SkyDan: Đọc nó ngay bây giờ. Dường như với tôi rằng lambdas làm đại diện cho các đối tượng (mặc dù loại / Giao diện được suy ra từ bối cảnh trong đó chúng được định nghĩa). Vì vậy, thông tin được cung cấp tại mail.openjdk.java.net/pipermail/lambda-dev/2011-August/ trộm ("lambdas không phải là đối tượng") là không chính xác hoặc ít nhất là sai lệch.
Giorgio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.