- ใน Go 1.18 มีการเพิ่มแนวคิดใหม่คือ core type พร้อมกับการนำฟีเจอร์ generics เข้ามาใช้งาน แต่ได้มีการตัดสินใจว่า จะถอดออกใน 1.25
- core type เป็นแนวคิดเชิงนามธรรมเพื่อความสะดวกในการติดตั้งใช้งานคอมไพเลอร์ โดยใช้แทน underlying type เดิมเมื่อจัดการกับโอเปอแรนด์ของ generic type
- ในสเปกของภาษาก็มีการแทนที่คำว่า "underlying type" เดิมด้วย "core type" เช่นกัน
พารามิเตอร์ชนิดข้อมูลและข้อจำกัดของชนิดข้อมูล
- พารามิเตอร์ชนิดข้อมูลทำหน้าที่เป็นตัวแทนของชนิดข้อมูลที่ยังไม่ถูกกำหนด และจะถูกตัดสินในช่วงคอมไพล์
- ข้อจำกัดของชนิดข้อมูลเป็นตัวกำหนดว่าการดำเนินการใดบ้างที่สามารถทำได้กับชนิดข้อมูลพารามิเตอร์นั้น
- ใน Go มีการนิยามข้อจำกัดของชนิดข้อมูลด้วยการผสมข้อกำหนดของเมธอดและชนิดข้อมูลเข้าด้วยกัน ซึ่งทำให้เกิด type set
- type set หมายถึงกลุ่มของชนิดข้อมูลทั้งหมดที่สอดคล้องกับอินเทอร์เฟซหนึ่ง ๆ
type Constraint interface {
~[]byte | ~string
Hash() uint64
}
- แนวทางที่อิงกับ type set แบบนี้มีความยืดหยุ่นและทรงพลังอย่างมากสำหรับการนิยามการดำเนินการของ generic type
func at[bytestring Constraint](s bytestring, i int) byte {
return s[i]
}
การนำ core type มาใช้และข้อจำกัด
- core type ถูกนิยามเป็นกฎเพื่อทำให้การใช้ generic type ในบางการดำเนินการง่ายขึ้น
- วิธีนิยาม core type:
- หากเป็นชนิดข้อมูลทั่วไป core type จะเหมือนกับ underlying type ของชนิดข้อมูลนั้น
- หากเป็นพารามิเตอร์ชนิดข้อมูล จะมี core type ได้ก็ต่อเมื่อชนิดข้อมูลทั้งหมดใน type set มี underlying type เดียวกัน
- แต่วิธีนี้ก่อให้เกิดปัญหาดังต่อไปนี้:
- สเปกของภาษาซับซ้อนขึ้น ทำให้แม้แต่กฎที่เรียบง่ายก็เข้าใจได้ยาก
- มีการกล่าวถึงแนวคิด core type โดยไม่จำเป็นแม้ในโค้ดที่ไม่ใช่ generic
- การดำเนินการบางอย่างที่มีแนวคิด core type ทำให้ข้อจำกัดเข้มงวดเกินไป จนไม่อนุญาตแม้แต่การดำเนินการที่จริง ๆ แล้วปลอดภัย
- ความไม่สอดคล้องกับกฎอื่นที่ไม่ได้ใช้ core type ทำให้ความสม่ำเสมอของการออกแบบภาษาลดลง
การถอด core type ออกจาก Go 1.25
- ใน Go 1.25 (มีกำหนดในเดือนสิงหาคม 2025) ได้มีการตัดสินใจถอดแนวคิด core type ออกจากสเปกภาษา
- เปลี่ยนไปใช้วิธีอธิบายข้อจำกัดที่จำเป็นของแต่ละการดำเนินการด้วยข้อความที่ชัดเจนโดยตรง
- ผลสำคัญของการเปลี่ยนแปลง:
- ลดจำนวนแนวคิดลง ทำให้การเรียนรู้ภาษา Go ง่ายขึ้น
- โค้ดที่ไม่ใช่ generic ชัดเจนขึ้นโดยไม่ต้องพึ่งแนวคิดจาก generics
- สามารถออกแบบกฎให้ยืดหยุ่นมากขึ้นตามลักษณะของแต่ละการดำเนินการ
- วางรากฐานสำหรับการขยายฟีเจอร์ในอนาคต (เช่น การเข้าถึงฟิลด์ร่วม การเสริมความสามารถของ slice การปรับปรุง type inference เป็นต้น)
การปรับใช้หลักและผลที่คาดหวัง
- ข้อความทั้งหมดในสเปกที่เคยกล่าวถึง core type จะถูกลบออกหรือแทนที่ด้วยข้อความที่ชัดเจนโดยตรง
- ในข้อความ error ของคอมไพเลอร์ก็จะเลิกใช้คำว่า core type และให้คำอธิบายที่เฉพาะเจาะจงมากขึ้น
- ไม่ส่งผลต่อพฤติกรรมของโปรแกรม Go เดิม
- สเปกภาษาจะเรียบง่ายขึ้น และสำหรับผู้ใช้ ภาษา Go จะตรงไปตรงมาและชัดเจนยิ่งขึ้น
6 ความคิดเห็น
ความคิดเห็นบน Hacker News
ชอบที่ทีม Go จัดการกับการเปลี่ยนแปลงสเปกอย่างระมัดระวังมาก
10 ปีที่ผ่านมาของทีมพัฒนา Go คือกระบวนการหาสมดุลระหว่างฟีเจอร์กับความเรียบง่าย
Go 1.25 ไม่ได้เพิ่มฟีเจอร์ของภาษาโดยตรง
ติดตาม Go มาตั้งแต่ก่อนมี Windows build
เรื่องที่ว่าเมื่ออาร์กิวเมนต์ของ
closeเป็น type parameter แล้วทุก type ต้องเป็น channel ที่มี element type เดียวกันนั้นไม่เป็นความจริงcloseและยังคอมไพล์ได้ปกติแม้ใช้ type set ที่มี element type ต่างกันกำลังเรียนรู้ Go แบบค่อยเป็นค่อยไป และมีพื้นฐานจาก C++
[dead]
ตอนนี้ generative AI เขียนโค้ดได้แล้ว จึงสงสัยว่ายังจำเป็นต้องมี garbage collector อยู่หรือไม่
ตอนนี้ AI สร้างโค้ดเขียนโค้ดได้แล้ว เลยสงสัยว่ายังจำเป็นต้องมีตัวเก็บกวาดหน่วยความจำอยู่หรือไม่
> ชวนให้คิดเลยนะ...
โอ้โห.. ถ้า AI ไปถึงระดับที่เขียนโค้ดแบบนั้นได้ (โค้ดที่จัดการหน่วยความจำได้อย่างสมบูรณ์แบบ) นักพัฒนาที่เป็นมนุษย์ก็คงอยู่ในบทบาทแบบทุกวันนี้ได้ยากนะ
1+1=2 ก็อธิบายด้วยคณิตศาสตร์ได้อยู่แล้ว จะฝืนใช้ AI ไปแก้ทำไม..
ในแง่ของการลดโค้ดแบบบอยเลอร์เพลตที่คนต้องอ่านและลดบริบทของโค้ดที่ต้องคอยตาม GC ก็อาจมีความหมายเหมือนกันไม่ใช่หรือ?
ถ้ากำลังคาดการณ์กันว่าแทบจะไม่ต้องอ่านโค้ดอีกต่อไปเลย อันนั้นก็ไม่แน่เหมือนกันนะ
ดูจากที่คอมเมนต์ต้นฉบับก็ถูกทำให้จางไว้เหมือนกัน ก็คงไม่ได้มีคนเห็นด้วยมากนัก
ถ้าสามารถคำนวณช่วงเวลาของการจัดสรรและการคืนหน่วยความจำได้ตั้งแต่ตอนคอมไพล์ ก็สามารถตัดการนับจำนวนการอ้างอิงออกได้ไม่ใช่หรือ? ดูเหมือนว่าผู้เขียนคอมเมนต์ต้นฉบับบน Hacker News จะยังไม่เข้าใจปัญหาเรื่องการนำหน่วยความจำกลับมาใช้ใหม่