การพัฒนาใหม่ของ Java จะมีผลต่อการทำงานร่วมกันกับภาษาเช่น Scala และ Clojure อย่างไร


11

เท่าที่ฉันเข้าใจทั้ง Scala และ Clojure ได้รับการออกแบบเป็นภาษาใหม่ที่

  1. ขึ้นอยู่กับ JVM และ
  2. รวมเข้ากับโค้ด Java ได้ง่ายในแง่ที่อนุญาตให้ใช้คลาส Java ภายในโค้ด Scala และ Clojure

เริ่มต้นด้วย Java 8 (และอาจรุนแรงยิ่งขึ้นกับ Java รุ่นถัดไป) จะมีการเปลี่ยนแปลงในความหมายของภาษา Java

ฉันต้องการถามว่าการเปลี่ยนแปลงเหล่านี้จะส่งผลกระทบต่อการทำงานร่วมกันระหว่าง Java และ Scala / Clojure อย่างไรและผลที่ตามมาจะเป็นอย่างไร ตัวอย่างเช่นเนื่องจาก lambdas ใน Java 8 ไม่ใช่วัตถุ (ดูเช่นที่นี่ ) Scala และ Clojure อาจต้องจัดการกับค่า Java ที่ไม่ใช่วัตถุ นี่จะเป็นปัญหาหรือไม่?

ฉันนึกถึงสถานการณ์ต่อไปนี้:

  1. ภาษา Scala หรือ Clojure จะถูกขยายเพื่อปรับให้เข้ากับความหมาย Java ใหม่ (เพื่อจัดการกับค่าที่ไม่ใช่วัตถุใหม่) และรองรับการทำงานร่วมกันกับ Java
  2. ภาษา Scala หรือ Clojure จะไม่ถูกขยาย สิ่งนี้จะเกิดขึ้นได้หากคุณลักษณะ Java ใหม่เช่นค่าฟังก์ชันสามารถแมปกับแนวคิดที่มีอยู่แล้วเท่านั้น เช่นใน Scala แม้ฟังก์ชั่นเป็นวัตถุดังนั้นฉันคิดว่าฟังก์ชั่น Java จะถูกห่อเป็นวัตถุบางอย่างอีกครั้งเมื่อพวกเขากลายเป็น Scala
  3. ภาษา Scala หรือ Clojure จะยังคงสนับสนุนการทำงานร่วมกันได้ถึง Java 6 หรือ 7 โดยไม่ต้องติดตามการพัฒนา Java ล่าสุด สิ่งนี้ต้องการให้ Java รุ่นเก่ายังคงได้รับการสนับสนุน (อย่างน้อยก็โดย OpenJDK หรือโครงการอื่น) เพื่อให้ภาษาเหล่านี้สามารถยึดตามสาขาจารีต / เสถียรของ Java ได้

สรุป: เราคาดหวังได้หรือไม่ว่าการพัฒนา Java ในอนาคตจะส่งผลกระทบต่อภาษาเช่น Scala และ Clojure เพื่อรักษาความสามารถในการทำงานร่วมกันกับ Java มีการอภิปราย (ลิงก์ไปยัง) ในหัวข้อนี้อย่างต่อเนื่องหรือไม่?

บันทึก

ฉันสามารถจินตนาการได้ว่า Scala, Clojure และภาษาที่ใช้ JVM อื่น ๆ จะไม่มีปัญหาสำคัญใด ๆ ในการอัปเดตการใช้งานเป็น JVM เวอร์ชันใหม่ (และฟีเจอร์ JVM ใหม่นี้จะทำให้การติดตั้งนี้ง่ายยิ่งขึ้น) คำถามของฉันมุ่งเน้นไปที่คุณสมบัติของ Java เป็นภาษาและ / ภาษาอื่น ๆ ของ JVM จะสามารถ "ดู" / ใช้คุณสมบัติใหม่เหล่านี้ได้หรือไม่ไม่ว่าภาษาที่ใช้ JVM จะทำงานกับ JVM ล่าสุดหรือไม่


6
มันไม่ชัดเจนที่จะบอกว่า Scala ฯลฯ ขึ้นอยู่กับ Java พวกเขาขึ้นอยู่กับรหัส JVM ไบต์ ฟีเจอร์การทำงานร่วมกันทั้งหมดนั้นเกี่ยวข้องกับ bytecode ไม่ใช่ซอร์สโค้ดภาษา Java ดังนั้นการเปลี่ยนแปลงใด ๆ ที่ทำกับ Java เองก็ไม่เป็นอันตราย เฉพาะการเปลี่ยนแปลงที่เกิดขึ้นกับ JVM เท่านั้นที่สามารถส่งผลกระทบต่อภาษาเหล่านี้และ JVM นั้นค่อนข้างอนุรักษ์นิยมอย่างยิ่ง - โดยทั่วไปจะไม่ลบการสนับสนุนอะไรเลย ในความเป็นจริงการเปลี่ยนแปลงส่วนใหญ่ใน JVM ในปัจจุบันมีวัตถุประสงค์เฉพาะสำหรับภาษาแบบไดนามิกที่ใหม่กว่า
Kilian Foth

@Kilian Foth: เท่าที่ผมรู้ Scala Stringเป็น StringJava Scala ใช้คลาสไลบรารี Java บางคลาส แต่ฉันสามารถเปลี่ยนสูตรได้ถ้าคุณคิดว่ามันแรงเกินไป
Giorgio

@Kilian Foth: ฉันได้ลบคำขึ้นอยู่กับเพราะความสำคัญของคำถามของฉันค่อนข้างจะทำงานร่วมกันระหว่าง Scala และ Java resp Clojure และ Java
Giorgio

@KilianFoth นี่ควรเป็นคำตอบเพราะมันเน้นความกังวลที่สำคัญของคำถาม เป้าหมายอันดับหนึ่งของ Java รุ่นใหม่คือความเข้ากันได้แบบย้อนหลัง
maple_shaft

3
@maple_shaft: ฉันได้แก้ไขคำถามของฉันและลบคำว่า "พึ่งพา" ตามที่ฉันได้ชี้ให้เห็นในความคิดเห็นอื่นปัญหาของฉันไม่ใช่วิธีที่ Scala หรือ Clojure ขึ้นอยู่กับคุณสมบัติของ Java หรือ JVM แต่วิธีที่ Scala / Clojure สามารถ "เห็น" คุณสมบัติของ Java เท่าที่ฉันรู้ว่าพวกเขาสามารถเห็นคุณสมบัติ Java 6 เช่นคลาส, อินเตอร์เฟส, วัตถุ, วิธีการ, ชนิดข้อมูลดั้งเดิม สิ่งนี้อนุญาตให้ใช้ Scala / Clojure (เรียก) โค้ด Java 6 คำถามของฉันคือภาษาเหล่านี้จะ "เห็น" (และสามารถใช้) ภาษา Java ในอนาคตได้หรือไม่หรือต้องใช้ส่วนขยายในภาษา Scala / Clojure หรือไม่
จอร์โจ

คำตอบ:


15

จริงๆแล้ว Java 8 ไม่ได้แนะนำอะไรมากมายที่จะเป็นอันตรายต่อภาษา JVM อื่น ๆ ที่ทำงานร่วมกับ Java งานที่ทำบน Lambdas ช่วยแก้ไขปัญหาเล็ก ๆ จำนวนหนึ่งเกี่ยวกับ invokedynamic, MethodHandles, MethodReferences เป็นต้น - แต่นอกเหนือจากนั้นมันยังดำเนินการตามปกติ ที่กล่าวว่ามี API ใหม่มากมายที่ภาษา JVM อื่น ๆ สามารถโทรเข้ามาได้ในตอนนี้ สิ่งที่พวกเขาจะใช้เป็นค่าเริ่มต้นหรือไม่ขึ้นอยู่กับพวกเขา

การเปลี่ยนแปลงที่ใหญ่ที่สุดที่ส่งผลกระทบต่อการทำงานร่วมกันระหว่างอินเทอร์แอคทีฟนั้นมาพร้อมกับ Java 7 โดยมีการเรียกใช้ bytecode ที่เรียกใช้แบบไดนามิก / การโทรล่าช้าภายใน JVM ซึ่งเป็นสิ่งแรก มันได้รับการดัดแปลงให้เป็นประโยชน์อย่างมากสำหรับ Lamdbas ดังนั้นสำหรับ Java 8, Java จะเริ่มต้นปล่อยออกมาเป็น bytecodes เหล่านี้

บางภาษา (เช่น JRuby) กำลังใช้ invokeynamic อยู่มากขณะที่ภาษาอื่น (Scala, Groovy et al) ยังคงตรวจสอบการใช้งานหรืออยู่ในช่วงเริ่มต้นของการปะแก้มันในทางทฤษฎีมันทำให้การเรียกแบบไดนามิกของพวกเขาเกือบจะเหมือนกับที่มีอยู่ การเรียกใช้ Java แบบไม่โต้ตอบเมื่อเทียบกับการแก้ไขปัญหาที่ช้ากว่ามากพวกเขาถูกบังคับให้ใช้ในอดีต

Java 9 จะนำความท้าทายมากขึ้นสำหรับภาษา JVM ด้วย Project Jigsaw เข้ามาในแพลตฟอร์มซึ่งจะเป็นจุดเริ่มต้นของจุดสิ้นสุดสำหรับการโหลดคลาสแบบดั้งเดิมและคลาสพา ธ สำหรับ JVM กลุ่มภาษา JVM ค่อนข้างตระหนักถึงเรื่องนี้และฉันคาดหวังว่าจะมีการร่วมมือกันที่เหมาะสม


1
แต่เท่าที่ฉันรู้การปิดสกาล่าเป็นวัตถุ
จอร์โจ

1
อ๋อ Scala เพิ่งลดการสนับสนุน Java 1.5 ไปเมื่อไม่นานมานี้จนกว่าจะลดลง 1.6
Jörg W Mittag

1
@Giorgio คุณสมบัติภาษาของ Java นั้นไม่สำคัญเท่าที่ควรจะเป็นเมื่อเทียบกับเทคนิคของ bytecode เมื่อทำการคอมไพล์แล้ว หากเรายอมรับว่า JVM จะสามารถใช้งานร่วมกันได้ตลอดเวลาแม้ว่าจะมีการแนะนำไบต์ใหม่แล้ว Scala จะไม่ได้รับผลกระทบใด ๆ และสามารถเลือกที่จะใช้ประโยชน์จากคุณสมบัติ JVM ใหม่ได้ตามความสะดวก
maple_shaft

1
"คุณสมบัติภาษาของ Java นั้นไม่สำคัญเท่าที่จะเป็นส่วนหนึ่งของกลวิธีของ bytecode เมื่อทำการคอมไพล์แล้ว": หากภาษาอื่นต้องการใช้โครงสร้าง Java ก็ต้องสามารถรับรู้ bytecode ที่สร้างขึ้นสำหรับการสร้างนั้น หาก Java แนะนำโครงสร้างใหม่ที่จับคู่กับไบต์ใหม่อย่างน้อยภาษาโฮสต์ควรใช้ wrapper / อินเตอร์เฟสใหม่เพื่อรับรู้และใช้ bytecode ใหม่ เช่นหากแลมบ์ดาของ Java 8 ไม่ได้สร้างวัตถุ แต่สร้างขึ้นใหม่ด้วยรหัสเฉพาะใหม่สำหรับมันจะต้องปรับภาษาโฮสต์ให้จดจำได้
Giorgio

2
@Giorgio: แน่นอน แต่ไม่มีการเปลี่ยนแปลงดังกล่าวสำหรับแพลตฟอร์ม Java 8 ในความเป็นจริง JVMS ขยายออกไปสองเท่าในประวัติศาสตร์ทั้งหมดของแพลตฟอร์ม Java ในปี 2003 และ 2010 และครั้งที่สอง (การแนะนำinvokedynamicbytecode) ได้รับการสนับสนุนโดยเฉพาะเพื่อรองรับภาษาอื่นที่ไม่ใช่ Java อันที่จริงภาษา Java 7 ไม่สนับสนุนหรือใช้ bytecode นั้น
Jörg W Mittag

2

Scala กำลังจะถูกทิ้งไว้ข้างหลังเมื่อ Java เพิ่ม lambdas เพราะ Java lambdas ได้รับการกำหนดประเภทตามบริบทที่พวกเขาใช้ในขณะที่ Scala lambdas ได้รับการกำหนดประเภทตาม arities ประเภทพารามิเตอร์และประเภทผลตอบแทนเช่น

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

จาก Java 8 สามารถเขียนใน Scala เป็น:

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

ยกเว้นว่าคุณใช้ / เขียนตัวแปลงบางส่วนที่แปลง Scala's () => หน่วยเป็น Runnable


ขอบคุณสำหรับคำตอบและสำหรับการตอบคำถามของฉัน (+1) ถ้าฉันเข้าใจถูกต้อง Scala จะต้องใช้คลาสที่ไม่ระบุชื่อเพื่อสร้างอินเทอร์เฟซอินเทอร์เฟซในบริบทที่ Java 8 จะใช้ lambdas (เนื่องจาก Java 8 lambdas มีความหมายที่แตกต่างจาก Scala lambdas) จุดที่ไม่ชัดเจนสำหรับฉันก็คือสิ่งที่จะเกิดขึ้นหากวิธีการ Java ส่งกลับ Java แลมบ์ดา จะเกิดอะไรขึ้นถ้าคลาสสกาล่าเรียกวิธีการนั้น ประเภทผลตอบแทนใน Scala คืออะไร
Giorgio

1
@Giorgio ใน Java 8 นิพจน์แลมบ์ดาเป็นช็อตคัตระดับภาษาเพื่อสร้างอินสแตนซ์ของอินเทอร์เฟซที่ประกาศวิธีการเดียวและถูกเลื่อนออกไปตามบริบท ดังนั้นเมื่อเมธอด Java 8 ส่งคืนแลมบ์ดามันจะส่งคืนอินสแตนซ์ของอินเทอร์เฟซซึ่งถูกประกาศว่าเป็นชนิดส่งคืนของเมธอด ในฐานะของ Scala 2.9.1 ประเภทการคืนจะเป็นเพียงอินสแตนซ์ของอินเตอร์เฟสบางตัวบอกว่า (Runnable or Comparator) ซึ่งคุณไม่สามารถถือเป็น Scala lambda ได้เว้นแต่ว่าคุณหรือ Scala libary ในอนาคตจะแนะนำการแปลงโดยนัยจากนั้น อินเตอร์เฟสกับชนิดของ Scala lambda
hellodanylo

@SkyDan: ตกลงดังนั้น Scala จะเห็น Java lambdas เป็นวัตถุที่ใช้อินเทอร์เฟซบางตัว จุดนี้ไม่ชัดเจนสำหรับฉัน: ฉันคิดว่า Java จะสร้างบางไบต์ที่แตกต่างจากที่ของวัตถุ แต่มันจะต้องเป็นวัตถุภายใต้ประทุนมิฉะนั้นจะไม่ได้รับการยอมรับว่าเป็นการใช้งานส่วนต่อประสาน ฉันคิดว่าฉันได้รับแล้ว
Giorgio

@Giorgio ยังถ้าคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงที่เกี่ยวข้องกับแลมบ์ดาในชวา 8 และกองกำลังที่ผลักดันการเปลี่ยนแปลงเหล่านี้ผมแนะนำให้คุณอ่านบทความนี้ภาพรวมที่น่าสนใจและมีรายละเอียดของโครงการแลมบ์ดา
hellodanylo

@SkyDan: อ่านตอนนี้ ดูเหมือนว่าฉันจะทำหน้าที่เป็นตัวแทนวัตถุ (แม้ว่าประเภท / ส่วนต่อประสานจะอนุมานจากบริบทที่กำหนดไว้) ดังนั้นข้อมูลที่ให้ไว้ที่mail.openjdk.java.net/pipermail/lambda-dev/2011-August/ … ("lambdas ไม่ใช่วัตถุ") นั้นไม่ถูกต้องหรืออย่างน้อยก็ทำให้เข้าใจผิด
จอร์โจ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.