- เวอร์ชัน Elixir 1.19 ทำให้สามารถตรวจพบบั๊กได้มากขึ้นและเร็วขึ้น ด้วย การเสริมความแข็งแกร่งของระบบชนิดข้อมูล และ การปรับปรุงประสิทธิภาพการคอมไพล์
- การอนุมานชนิดข้อมูลได้ขยายไปถึง ฟังก์ชันนิรนามและโปรโตคอล ทำให้ตรวจสอบอัตโนมัติได้ครอบคลุมยิ่งขึ้นโดยไม่ต้องมีคำอธิบายชนิดข้อมูลจากผู้ใช้
- มอบ ความเร็วในการคอมไพล์ที่ดีขึ้นสูงสุด 4 เท่า สำหรับโปรเจ็กต์ขนาดใหญ่ พร้อมการคอมไพล์แบบขนานและการเพิ่มประสิทธิภาพการโหลดโค้ด
- มี การรองรับ Erlang/OTP 28 และการนำการรับรอง OpenChain มาใช้ ช่วยเสริมทั้งระบบนิเวศและ ความโปร่งใสของซัพพลายเชน
- นอกจากนี้ยังมีฟีเจอร์อีกหลายอย่าง เช่น การปรับปรุงการพาร์สออปชัน, ความสามารถในการดีบักของ ExUnit ที่ดีขึ้น, และการเข้าถึงเอกสารผ่าน shell ที่ดีขึ้น
การปรับปรุงหลักของ Elixir 1.19
การปรับปรุงระบบชนิดข้อมูล
การอนุมานชนิดข้อมูลสำหรับทุกองค์ประกอบ
- Type inference (การอนุมานชนิดข้อมูล) คือความสามารถในการ ตัดสินชนิดข้อมูลของนิพจน์โดยอัตโนมัติในช่วงคอมไพล์
- เดิมทีรองรับการอนุมานชนิดข้อมูลโดยเน้นที่ pattern, guard และค่าที่ส่งคืนเป็นหลัก แต่ในรีลีสนี้ได้เพิ่ม การอนุมานชนิดข้อมูลสำหรับทุกองค์ประกอบ (ยกเว้น guard)
- ระบบจะอนุมานชนิดข้อมูลโดยอ้างอิงทั้งภายในโมดูลและการเรียกใช้ฟังก์ชันในไลบรารีมาตรฐานของ Elixir ทำให้ฟังก์ชันที่เดิมอนุมานได้เพียง
dynamic() -> boolean() สามารถ อนุมานได้ชัดเจนขึ้นเป็น integer() -> boolean()
- การอนุมานชนิดข้อมูลมี trade-off หลายด้าน เช่น ความเร็วในการคอมไพล์, ความสามารถในการแสดงออก, การคอมไพล์แบบค่อยเป็นค่อยไป, และความชัดเจนของข้อผิดพลาด โดยในอนาคตมีแผนจะเพิ่มการอนุมานชนิดข้อมูลของ guard และข้อมูลชนิดข้อมูลของ dependency
- หากมีการระบุ type signature ให้กับฟังก์ชันไว้ ระบบจะทำงานเป็น การตรวจสอบชนิดข้อมูลตามที่ประกาศไว้อย่างชัดเจน แทนการอนุมาน และจะยอมรับเฉพาะชนิดข้อมูลที่ตรงกับคำอธิบายของผู้ใช้
การตรวจสอบชนิดข้อมูลตอน dispatch และ implement โปรโตคอล
- ตอนนี้ Elixir ใช้ การตรวจสอบชนิดข้อมูลทั้งตอนเรียกใช้โปรโตคอลและตอน implement
- ตัวอย่างเช่น หากส่งชนิดข้อมูลที่ไม่ได้ implement โปรโตคอล
String.Chars ไปยัง string interpolation ระบบจะขึ้น ข้อความเตือน
- ใน for comprehension หากส่ง ชนิดข้อมูลที่ไม่ตรงตามโปรโตคอล
Enumerable เป็น generator ก็จะมีคำเตือนเช่นกัน
- การตรวจสอบชนิดข้อมูลลักษณะนี้ช่วยป้องกันบั๊กได้มากขึ้นตั้งแต่ช่วงคอมไพล์
การอนุมานและตรวจสอบชนิดข้อมูลของฟังก์ชันนิรนาม
- Elixir 1.19 รองรับ การอนุมานและการตรวจสอบชนิดข้อมูลสำหรับฟังก์ชันนิรนาม
- ตัวอย่างเช่น หากส่งชนิดข้อมูลที่ไม่ถูกต้องอย่าง
"hello" ให้กับฟังก์ชันนิรนามที่คาดหวังชนิด %{} ระบบจะตรวจพบได้ทันทีเป็น คำเตือนในช่วงคอมไพล์
- การอนุมานชนิดข้อมูลยังใช้กับ function capture (
&String.to_integer/1 เป็นต้น) ด้วย ทำให้ ขอบเขตของการตรวจสอบชนิดข้อมูลอัตโนมัติขยายกว้างขึ้น
ข้อมูลอ้างอิงและพาร์ตเนอร์
- ระบบชนิดข้อมูลนี้พัฒนาขึ้นผ่านความร่วมมือระหว่าง CNRS และ Remote
- ได้รับการสนับสนุนจาก Fresha, *Starfish* *, Dashbit และรายอื่น ๆ
ความเร็วในการคอมไพล์ที่เร็วขึ้นในโปรเจ็กต์ขนาดใหญ่
ปรับปรุงคอขวดในการโหลดโค้ด
- เดิมทีระบบจะ โหลดทันทีเมื่อมีการประกาศโมดูล แต่ในรีลีสนี้ได้เปลี่ยนเป็นกลยุทธ์ lazy loading
- ผลคือ ลดภาระของ code server และเพิ่มประสิทธิภาพการคอมไพล์แบบขนาน ทำให้ความเร็วในการคอมไพล์ของโปรเจ็กต์ขนาดใหญ่ เพิ่มขึ้นมากกว่า 2 เท่า
- มีข้อควรระวังสำคัญ 2 ประการ
- หากสร้างโปรเซสแยกขึ้นมาระหว่างคอมไพล์แล้วเข้าถึงโมดูลในโปรเจ็กต์เดียวกัน อาจเกิดกรณีโหลดไม่ครบได้ วิธีหลีกเลี่ยงคือใช้
Kernel.ParallelCompiler.pmap/2 หรือ Code.ensure_compiled!/1 เป็นต้น
- หากเรียกโมดูลในโปรเจ็กต์เดียวกันภายใน callback ของ
@on_load อาจเกิดข้อผิดพลาดได้ และหากจำเป็นสามารถใช้ตัวเลือก @compile {:autoload, true}
- ทั้งสองกรณีนี้ในอดีตอาจทำให้เกิดข้อผิดพลาดระหว่างคอมไพล์แบบไม่กำหนดแน่ชัด แต่การปรับปรุงครั้งนี้ช่วยรับประกัน สภาพแวดล้อมการคอมไพล์ที่กำหนดแน่ชัด (ทำซ้ำได้)
การคอมไพล์ dependency แบบขนาน
- รองรับ การคอมไพล์ dependency แบบขนาน ผ่านตัวแปรสภาพแวดล้อม
MIX_OS_DEPS_COMPILE_PARTITION_COUNT
- โดยใช้หลาย OS process พร้อมกันเพื่อ คอมไพล์ dependency แบบขนาน ทำให้ขึ้นอยู่กับขนาดโปรเจ็กต์และจำนวนคอร์ CPU แล้ว ประสิทธิภาพการคอมไพล์อาจดีขึ้นได้สูงสุด 4 เท่า
- ในเชิงทดลอง การตั้งค่าเป็น ประมาณครึ่งหนึ่งของจำนวนคอร์ทั้งหมด ให้ประสิทธิภาพด้านการใช้ทรัพยากรที่ดี
- เนื่องจากการทำงานแบบขนานอาจทำให้ การใช้หน่วยความจำเพิ่มขึ้น จึงควรระวังเมื่อนำไปใช้กับ CI หรือ build server
การรองรับ Erlang/OTP 28
- Elixir 1.19 รองรับอย่างเป็นทางการกับ Erlang/OTP 28.1+
- จาก การเปลี่ยนแปลงวิธีแสดง regular expression ใน Erlang/OTP 28 ทำให้ไม่สามารถใช้ regular expression เป็นค่าเริ่มต้นของ struct ได้อีกต่อไป
- แต่ตอน initialize struct ยังสามารถ ใช้ regular expression ได้ตามปกติ
การนำการรับรอง OpenChain มาใช้
- รีลีสนี้เป็นเวอร์ชันแรกที่เริ่ม ปฏิบัติตามมาตรฐาน OpenChain
- แต่ละรีลีสจะมี SBoM (Source Bill of Materials) ในฟอร์แมต CycloneDX 1.6/SPDX 2.3 รวมอยู่ด้วย
- สิ่งนี้ช่วยเพิ่ม ความโปร่งใสของซัพพลายเชน ในด้านองค์ประกอบของรีลีสและไลเซนส์ และช่วยให้การจัดการมีความเข้มงวดยิ่งขึ้น
- งานส่วนนี้ดำเนินการโดย Jonatan Männchen และได้รับการสนับสนุนจาก Erlang Ecosystem Foundation
การปรับปรุงอื่น ๆ
- มีการเพิ่ม การปรับปรุงเครื่องมือและไลบรารี หลายด้าน เช่น การพาร์สออปชัน, การดีบักและประสิทธิภาพของ ExUnit, และการเข้าถึงเอกสารผ่าน shell
- สำหรับรายละเอียดรีลีสเพิ่มเติม โปรดดู CHANGELOG
1 ความคิดเห็น
ความเห็นจาก Hacker News
มีการย้ำว่าการค่อย ๆ นำระบบตรวจสอบชนิดอัตโนมัติเข้ามาใน Elixir เป็นตัวอย่างการพัฒนาภาษาที่ยอดเยี่ยมซึ่งภาษาโปรแกรมอื่น ๆ ก็น่าศึกษา มีหลายภาษาที่ระบบนิเวศแตกออกเป็นสองฝั่งเพราะการเปลี่ยนแปลงครั้งใหญ่ แต่ในกรณีของ Elixir นั้น José เคยประกาศไว้อย่างชัดเจนตั้งแต่ปี 2018 แล้วว่าตัวภาษาเองเสร็จสมบูรณ์ จึงทำให้อุ่นใจได้ว่า language และ core จะไม่แตกหักอีกต่อไปและมีความเสถียรมาก พร้อมแนะนำวิดีโองานนำเสนอที่เกี่ยวข้อง และบอกว่าประทับใจกับการบริหารจัดการที่สม่ำเสมอและยอดเยี่ยม
Elixir ยังคงออกฟีเจอร์และการปรับปรุงที่ยอดเยี่ยมอย่างต่อเนื่องและพัฒนาไปอย่างมั่นคง โครงสร้างของภาษาก็โดดเด่นมาก และผู้สร้างก็ยังคงวางทิศทางได้ถูกต้องอย่างต่อเนื่อง จนน่าประทับใจมาก เสียดายแค่ว่าในชีวิตประจำวันไม่ค่อยมีโอกาสได้ใช้ Elixir
มีการแชร์ข้อมูลการทดลองเกี่ยวกับความเร็วในการคอมไพล์ dependency ของ Phoenix โดยบน Mac M1 Max กับแอปเล็ก ๆ ที่มีเพียง dependency พื้นฐานของ Phoenix พบเวลาในการคอมไพล์ตามค่าของตัวแปรสภาพแวดล้อม
MIX_OS_DEPS_COMPILE_PARTITION_COUNTดังนี้มีการล้างแคชระหว่างรอบด้วยคำสั่ง
rm -rf _build_buildช่วงไม่กี่เดือนที่ผ่านมาเริ่มชอบ Gleam มาก ระบบชนิดที่จะเข้ามาใน Elixir ก็เป็นเรื่องน่ายินดี แต่ก่อนหน้านี้นี่เป็นหนึ่งในปัจจัยหลักที่ทำให้ตัดสินใจรับ Elixir มาใช้ได้ยาก อยากกลับไปลอง Elixir อีกครั้งในสักวัน แต่ก็ยังกลัวว่าจะกลายเป็นแบบ TypeScript ใน JavaScript ที่ดูเหมือนมี type ภายนอก แต่ในความเป็นจริงหลาย lib หรือแพ็กเกจก็ยังจบลงด้วย dynamic/any อยู่ดี เลยสงสัยว่าความกังวลนี้เป็นเรื่องเกินไปหรือเปล่า Beam นั้นยอดเยี่ยมจริง ๆ
รู้สึกว่า Elixir เป็นสภาพแวดล้อมสำหรับการพัฒนาเว็บที่มีอนาคตมากที่สุด ทุกครั้งที่เจอองค์กรหรือทีมที่ใช้ Elixir ในงานจริง ก็มักรู้สึกว่าระดับของทีมนั้นสูงกว่าค่าเฉลี่ยทั่วไป และมองว่า Elixir ยังคงนำเสนอทิศทางและมาตรฐานให้กับสภาพแวดล้อมที่ต้องพัฒนาอย่างต่อเนื่อง
มีการแนะนำว่ารีลีส Elixir นี้เริ่มรองรับฟอร์แมต Source SBoM ที่เป็น CycloneDX 1.6 ขึ้นไป และ SPDX 2.3 ขึ้นไป การมีการจัดการ SBOM ในระดับภาษานั้นน่าขอบคุณมาก น่าเสียดายที่บริษัทปัจจุบันไม่ได้ใช้ Elixir
ถ้าอยากมีส่วนร่วมกับโปรเจกต์โอเพนซอร์ส Elixir ที่ใช้งานจริง คอมโพเนนต์หลักของ Mozilla Hubs เดิมยังคงได้รับการพัฒนาด้วย Elixir ต่อในฐานะโปรเจกต์อิสระ ดูได้ที่ Hubs Foundation/reticulum
บนพื้นฐานของไลบรารีมาตรฐานของ Elixir สามารถทำ type inference ตอนคอมไพล์สำหรับสถานการณ์เฉพาะของแอปได้ เช่น การอนุมานจาก dynamic type เป็น boolean หรือจาก integer เป็น boolean
แม้จะไม่มีประสบการณ์พัฒนา Elixir โดยตรง แต่ก็เป็นแฟนมาก่อน สมัยก่อนชอบความใช้งานได้จริงและความสวยงามของ Ruby แต่เมื่อเริ่มสนใจระบบชนิดก็เปลี่ยนภาษา ทั้ง Elixir และ Ruby ต่างก็นำระบบชนิดเข้ามาแล้ว แต่ตอนนี้กลับใช้ Kotlin เป็นหลัก ซึ่งให้ความรู้สึกเหมือน "Ruby ที่มี type" ในเชิงไวยากรณ์
กำลังใช้ Soketi ร่วมกับ pusher sdk เพื่อจัดการ broadcast event แอปมีโครงสร้างที่ผสมทั้ง real-time endpoint และ REST endpoint ภาระงานด้าน real-time ไม่ได้หนักมาก แต่ถ้าจำเป็นก็คิดจะแยกไปทำด้วย Go อีกทาง และกำลังจะเพิ่มฟีเจอร์ด้าน collaboration เร็ว ๆ นี้ จึงกำลังชั่งใจว่าในสถานการณ์แบบนี้ควรนำ Phoenix มาใช้หรือไม่