1 คะแนน โดย GN⁺ 2025-10-17 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เวอร์ชัน 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 ความคิดเห็น

 
GN⁺ 2025-10-17
ความเห็นจาก Hacker News
  • มีการย้ำว่าการค่อย ๆ นำระบบตรวจสอบชนิดอัตโนมัติเข้ามาใน Elixir เป็นตัวอย่างการพัฒนาภาษาที่ยอดเยี่ยมซึ่งภาษาโปรแกรมอื่น ๆ ก็น่าศึกษา มีหลายภาษาที่ระบบนิเวศแตกออกเป็นสองฝั่งเพราะการเปลี่ยนแปลงครั้งใหญ่ แต่ในกรณีของ Elixir นั้น José เคยประกาศไว้อย่างชัดเจนตั้งแต่ปี 2018 แล้วว่าตัวภาษาเองเสร็จสมบูรณ์ จึงทำให้อุ่นใจได้ว่า language และ core จะไม่แตกหักอีกต่อไปและมีความเสถียรมาก พร้อมแนะนำวิดีโองานนำเสนอที่เกี่ยวข้อง และบอกว่าประทับใจกับการบริหารจัดการที่สม่ำเสมอและยอดเยี่ยม

    • ถ้าพูดถึงกรณีระบบนิเวศแตกเพราะการเปลี่ยนแปลงครั้งใหญ่ในภาษาหลัก ๆ ก็นึกออกแค่ Python 3 กับ Perl 6 สองกรณีนี้แรงมากจนทำให้การเปลี่ยนแปลงของภาษาอื่น ๆ ดูยิ่งใหญ่ตามไปด้วย
    • ใน Elixir ไม่เคยรู้สึกว่าต้องคอยวิ่งไล่อัปเกรดเวอร์ชันอยู่ตลอด แต่จะเป็นประสบการณ์แบบคอยดูว่ามีอะไรใหม่ ๆ เข้ามาแล้วอยากอัปเกรดเพราะฟีเจอร์นั้นใช้งานได้จริง มากกว่าจะรู้สึกกังวลหรือเครียดเหมือนถูกบังคับให้เปลี่ยนเวอร์ชัน
    • ใช้ Elixir ใน production มาตั้งแต่ปี 2017 และทุกครั้งที่อัปเกรดก็ราบรื่นกว่าที่คาดไว้มาก ตรงกันข้าม การอัปเกรด Erlang/OTP มักซับซ้อนกว่าเพราะปัญหาความเข้ากันได้ ดังนั้นจึงมักใช้ Elixir เวอร์ชันล่าสุด แต่รอ OTP อีกหนึ่งหรือสองเดือนให้ปัญหาความขัดแย้งต่าง ๆ ถูกจัดการก่อนแล้วค่อยอัปเกรด
    • Elixir ยังมีบางจุดที่ไม่สมบูรณ์และเรื่องความสะดวกก็ยังไม่พอ จึงยังต้องการแนวทางที่ชัดเจนในการไปถึงเป้าหมายและการทำให้ระบบนิเวศมีเสถียรภาพมากขึ้น รู้สึกว่าแพ็กเกจจำนวนมากถูกปล่อยทิ้งหรือมีเอกสารไม่เพียงพอจนตามความเปลี่ยนแปลงของระบบนิเวศ Phoenix ได้ยาก ผู้ใช้จำนวนมากก็ไม่ได้ต้องการ LiveViews หรือระบบคอมโพเนนต์บางแบบ และอุปสรรคในการเชื่อมต่อกับเครื่องมือหรือเทคโนโลยีอื่นก็สูง การย้ายจาก Python 2 ไป 3 เป็นสิ่งจำเป็นและทำได้ค่อนข้างดีด้วยเครื่องมือย้ายระบบแบบอัตโนมัติ แม้จะมีการลองผิดลองถูกมากอยู่บ้าง ขณะที่ Ruby 3 กลับสร้างความสับสนจากการนำไฟล์ชนิดภายนอกเข้ามาและการแตกย่อยของเครื่องมือ รวมถึงมีประสบการณ์ด้านลบเรื่อง boilerplate, governance และการยึด gem จนทำให้ไม่ค่อยอยากใช้ Ruby อีก ต่อให้ภาษาเยี่ยมแค่ไหน การบริหารจัดการที่ไม่ดีอาจทำลายทุกอย่างได้ จึงย้ำว่าความร่วมมือและการสื่อสารที่เป็นผู้ใหญ่ รวมถึงการจัดการการเปลี่ยนแปลงที่ดีเป็นเรื่องสำคัญ มองว่าการเปลี่ยนแปลงด้านการออกแบบภาษาควรผ่านการทดลองล่วงหน้าอย่างเพียงพอและทำอย่างระมัดระวัง พร้อมสื่อสารกับผู้ใช้ล่วงหน้าให้มากพอเพื่อลดความสับสนที่ไม่จำเป็น หวังว่า Elixir/Phoenix/OTP จะใช้งานง่ายขึ้น ทรงพลังขึ้น มีประสิทธิภาพในการพัฒนามากขึ้น และให้ประสิทธิภาพที่ดีจนผู้ใช้หลากหลายกลุ่มใช้งานได้อย่างมั่นใจ พร้อมแนะนำทรัพยากรอย่าง Livebook และ Exercism Elixir track
  • Elixir ยังคงออกฟีเจอร์และการปรับปรุงที่ยอดเยี่ยมอย่างต่อเนื่องและพัฒนาไปอย่างมั่นคง โครงสร้างของภาษาก็โดดเด่นมาก และผู้สร้างก็ยังคงวางทิศทางได้ถูกต้องอย่างต่อเนื่อง จนน่าประทับใจมาก เสียดายแค่ว่าในชีวิตประจำวันไม่ค่อยมีโอกาสได้ใช้ Elixir

    • ถึงขั้นลาออกจากงานแล้วไปก่อตั้งบริษัทเองเพื่อจะได้ใช้ Elixir
  • มีการแชร์ข้อมูลการทดลองเกี่ยวกับความเร็วในการคอมไพล์ dependency ของ Phoenix โดยบน Mac M1 Max กับแอปเล็ก ๆ ที่มีเพียง dependency พื้นฐานของ Phoenix พบเวลาในการคอมไพล์ตามค่าของตัวแปรสภาพแวดล้อม MIX_OS_DEPS_COMPILE_PARTITION_COUNT ดังนี้

    PARTITION_COUNT=1:  12.336초 (유저 32.30s, 시스템 7.23s, CPU 320%)
    PARTITION_COUNT=5:  6.970초 (유저 0.37s, 시스템 0.49s, CPU 12%)
    PARTITION_COUNT=10: 7.236초 (유저 0.38s, 시스템 0.50s, CPU 12%)
    

    มีการล้างแคชระหว่างรอบด้วยคำสั่ง rm -rf _build

    • ดูเหมือนว่าการรันหลังจากนั้นจะวัดในสภาพที่มีแคชถูกนำมาใช้แล้ว และอาจเป็นไปได้ว่ามีการคอมไพล์ native โดยตรงในโฟลเดอร์ dep เลยไม่ทิ้งร่องรอยไว้ใน _build
    • ไม่เข้าใจว่าทำไมผล benchmark ของฟีเจอร์ในรีลีสนี้ถึงโดนโหวตลบ อยากรู้ว่ามีใครช่วยอธิบายความเห็นได้ไหม
  • ช่วงไม่กี่เดือนที่ผ่านมาเริ่มชอบ Gleam มาก ระบบชนิดที่จะเข้ามาใน Elixir ก็เป็นเรื่องน่ายินดี แต่ก่อนหน้านี้นี่เป็นหนึ่งในปัจจัยหลักที่ทำให้ตัดสินใจรับ Elixir มาใช้ได้ยาก อยากกลับไปลอง Elixir อีกครั้งในสักวัน แต่ก็ยังกลัวว่าจะกลายเป็นแบบ TypeScript ใน JavaScript ที่ดูเหมือนมี type ภายนอก แต่ในความเป็นจริงหลาย lib หรือแพ็กเกจก็ยังจบลงด้วย dynamic/any อยู่ดี เลยสงสัยว่าความกังวลนี้เป็นเรื่องเกินไปหรือเปล่า Beam นั้นยอดเยี่ยมจริง ๆ

    • เงื่อนไขต่างจาก TypeScript เพราะด้วย pattern matching ทำให้แม้แต่โค้ดเบส Elixir เดิมก็น่าจะอนุมานชนิดได้อย่างน้อยราว 50% และเพราะ vanilla Elixir มี type ให้มาเป็นพื้นฐาน โค้ดที่ยังได้รับการดูแลก็น่าจะถูกทำให้มี type อย่างรวดเร็ว ฉันเองไม่ได้ชอบระบบชนิดและใช้แค่ JS แต่กับ Elixir การใส่ type เกิดขึ้นได้อย่างเป็นธรรมชาติ TypeScript เหมือนวิ่งย้อนขึ้นไปด้านบน ขณะที่ Elixir เหมือนแพร่ลงไปด้านล่างอย่างเป็นธรรมชาติ
    • Gleam ไม่สามารถใช้จุดแข็งที่แท้จริงของ OTP/BEAM ได้อย่างเต็มที่ นี่คือเสน่ห์ที่มีเฉพาะใน Elixir
    • Elixir มีแนวคิดเรื่องชนิดอยู่แล้วมาตั้งแต่ก่อน ทั้ง primitive type, struct และการ destructure ตาม shape รวมถึงมีเครื่องมืออย่าง Dialyzer และ TypedStruct สำหรับตรวจสอบชนิด จึงไม่ใช่ภาษาที่ไร้ type แบบสุดโต่งเหมือน JavaScript
    • Gleam ก็ดี แต่บน JVM ก็มี Kotlin ซึ่งเป็นภาษาที่มี type และไวยากรณ์คล้าย Ruby แถมยัง compile-to-JS ได้ด้วย
  • รู้สึกว่า 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" ในเชิงไวยากรณ์

    • Kotlin แทบจะเป็นความรู้สึกแบบ jruby ที่เราอยากได้จริง ๆ
  • กำลังใช้ Soketi ร่วมกับ pusher sdk เพื่อจัดการ broadcast event แอปมีโครงสร้างที่ผสมทั้ง real-time endpoint และ REST endpoint ภาระงานด้าน real-time ไม่ได้หนักมาก แต่ถ้าจำเป็นก็คิดจะแยกไปทำด้วย Go อีกทาง และกำลังจะเพิ่มฟีเจอร์ด้าน collaboration เร็ว ๆ นี้ จึงกำลังชั่งใจว่าในสถานการณ์แบบนี้ควรนำ Phoenix มาใช้หรือไม่