1 คะแนน โดย GN⁺ 4 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เหตุผลที่ความนิยมของประเภทแบบสแตติกลดลงตั้งแต่ช่วงทศวรรษ 2000 ถึงต้นทศวรรษ 2010 ก่อนจะกลับมาเพิ่มขึ้นอีกครั้งในช่วงกลางถึงปลายทศวรรษ 2010 อธิบายได้ด้วยการที่ คุณภาพของระบบประเภทแบบสแตติกดีขึ้น
  • ระบบประเภทแบบไดนามิกเปรียบได้กับการ ขุดดินด้วยมือเปล่า เพราะมนุษย์ต้องเป็นผู้ตัดสินสถานะและเนื้อหาของตัวแปรกับฟิลด์เอง โดยคอมพิวเตอร์ไม่ได้ช่วยและไม่ได้ขัดขวาง
  • ระบบประเภทแบบสแตติกในอดีตอย่าง Java ยุคแรกหรือ C++98 เปรียบได้กับ พลั่วกระดาษ ที่ช่วยแยก nullable กับ non-nullable pointer ก็ไม่ได้ แถมยังบังคับให้เขียนชื่อประเภทซ้ำไปซ้ำมา
  • ระบบประเภทสมัยใหม่อย่าง TypeScript, Haskell, MyPy, Swift, Rust รองรับการจัดการ null, sum type·union type และ type inference เพื่อช่วยตรวจสอบข้อผิดพลาดของโปรแกรมและแสดงสถานะได้ดีขึ้น
  • เมื่อความสามารถของ IDE อย่างการเติมชื่อเมธอดอัตโนมัติแพร่หลาย ข้อมูลที่ใส่ไว้ในระบบประเภทแบบสแตติกก็ไม่เพียงช่วยตรวจข้อผิดพลาด แต่ยังต่อยอดเป็น ข้อได้เปรียบด้านประสิทธิภาพการทำงาน

ข้อถกเถียงหลัก

  • มุมมองนี้ชี้ว่าความนิยมของประเภทแบบสแตติกไม่ได้เป็นเพียงกระแส แต่กลับมาสูงขึ้นอีกครั้งเพราะคุณภาพของ ระบบประเภทแบบสแตติก ที่ใช้งานได้แพร่หลายดีขึ้น
  • มีการใช้อุปมาว่า ถ้ามีพลั่วดี การขุดดินด้วยพลั่วย่อมดีกว่ามือเปล่า แต่ถ้ามีแค่พลั่วที่ทำจากกระดาษ มือเปล่าจะดีกว่า
  • ระบบประเภทแบบไดนามิกทำให้มนุษย์ต้องคิดเองว่าตัวแปรและฟิลด์ในโปรแกรมมีสถานะและเนื้อหาแบบใด โดยคอมพิวเตอร์ไม่ได้ช่วยตัดสิน
  • ระบบประเภทแบบสแตติกที่แย่อาจสร้างภาระมากกว่าประโยชน์ และถูกเปรียบกับการขุดดินด้วยพลั่วกระดาษ

ข้อจำกัดของระบบประเภทแบบสแตติกในอดีต

  • ระบบประเภทแบบสแตติกของ Java ยุคแรกหรือ C++98 ที่ถูกใช้อย่างแพร่หลายในยุค 90 และต้นทศวรรษ 2000 แม้แต่งานพื้นฐานอย่างการแยก nullable pointer กับ non-nullable pointer ก็ยังช่วยได้ไม่ดี
  • ระบบประเภทแบบสแตติกในอดีตถูกอธิบายว่าเป็นโครงสร้างที่ไม่มี sum type และมีเพียง product type
  • ระบบประเภทแบบสแตติกในอดีตบังคับให้ต้องเขียนชื่อประเภทด้วยมือไว้ตามจุดต่าง ๆ
  • โค้ดอย่าง BufferedReader bufferedReader = new BufferedReader(new FileReader(filename)); ถูกบรรยายว่าเป็นหายนะขนาดย่อม

จุดที่ระบบประเภทสมัยใหม่พัฒนาขึ้น

  • ระบบประเภทสมัยใหม่อย่าง TypeScript, Haskell, MyPy, Swift, Rust มีวิธีแยก nullable type และ non-nullable type
  • ยกตัวอย่างเช่น Haskell ใช้ Maybe t, TypeScript ใช้ T | null, Swift ใช้ T?, Rust ใช้ Optional<T> ซึ่งทำให้ระบบประเภทสามารถบอกได้ว่าจุดใดต้องตรวจ null และจุดใดตกหล่นไป
  • มีคำอธิบายว่าในทางปฏิบัติ เราแทบไม่เห็นข้อผิดพลาด null pointer ในรันไทม์อีกแล้ว
  • ระบบประเภทสมัยใหม่มอบ sum type หรือ union type อย่างน้อยหนึ่งแบบ และทำให้สามารถปฏิบัติตามแนวคิด "Make invalid states unrepresentable" ได้
  • วิธีนี้ทำให้สามารถแสดงอ็อบเจ็กต์ที่เป็น state machine ได้โดยให้แต่ละฟิลด์มีอยู่เฉพาะเมื่ออยู่ในสถานะที่เกี่ยวข้องเท่านั้น
  • ระบบประเภทสมัยใหม่มี type inference ทำให้เมื่อคอมไพเลอร์ดู let x = 5; แล้วรู้ว่าเป็นตัวเลข ก็ไม่จำเป็นต้องเขียน let x: number = 5;

ความสามารถของ IDE และบทสรุป

  • เมื่อความสามารถของ IDE เช่นการเติมชื่อเมธอดอัตโนมัติแพร่หลาย ประโยชน์ของระบบประเภทแบบสแตติกก็เพิ่มขึ้นอีก
  • ในยุค 90 Intellisense เป็นความสามารถหลักของ Visual Studio แต่ในยุค 2020 ความสามารถคล้ายกันมีอยู่แทบทุก IDE และเอดิเตอร์
  • ข้อมูลที่ใส่ไว้ในระบบประเภทแบบสแตติกไม่ได้ใช้เพียงเพื่อตรวจสอบข้อผิดพลาดของโปรแกรม แต่ยังสร้าง ข้อได้เปรียบด้านประสิทธิภาพการทำงาน เพิ่มเติม
  • ระบบประเภทแบบไดนามิกที่ดีอาจดีกว่าระบบประเภทแบบสแตติกที่แย่ แต่ปัจจุบันเราสามารถใช้ระบบประเภทแบบสแตติกที่ดีกว่าอดีตมากได้แล้ว

1 ความคิดเห็น

 
GN⁺ 4 시간 전
ความคิดเห็นจาก Lobste.rs
  • บทความนี้ดี แต่ผมไม่ได้เห็นด้วยทั้งหมด แม้ว่าระบบชนิดแบบสถิตในช่วงต้นทศวรรษ 2000 จะไม่ได้ยอดเยี่ยม แต่ผมคิดว่ามันก็ดีกว่าการไม่มี static type เลยมาก
    แม้จะยังไม่มี closed sum type แต่ก็สามารถจำลองได้พอสมควรด้วย subtyping และแม้จะยังไม่มี non-nullable type แต่ C++ ก็มี reference กับ non-pointer type และ Java ก็มี primitive type ที่ช่วยรองรับบางส่วน ใน Ruby หรือ JavaScript ไม่เพียงแต่ทุก type จะเป็น nullable เท่านั้น แต่ยังถูกปฏิบัติได้ทั้งเหมือนสตริง เหมือนจำนวนเต็ม หรือเหมือนทุก type อื่นในโปรแกรมด้วย ซึ่งแย่กว่าเดิมอีก
    ผมคิดว่าเหตุผลใหญ่ที่กระแสเริ่มเปลี่ยนไปในมุมมองต่อ static type เป็นเพราะในยุคบูมของโซเชียลเน็ตเวิร์ก Web 2.0 นั้น first-mover advantage สำคัญกว่าทุกอย่าง ต่อให้สร้างหนี้ทางเทคนิคด้วย Ruby หรือ Python ก็ยังดีกว่าปล่อยของเร็ว ทำซ้ำเร็ว มากกว่าจะถูกทิ้งไว้ข้างหลังแบบ Friendster หรือ Digg และถ้าช้าก็แค่ซื้อเซิร์ฟเวอร์เพิ่มด้วยเงินทุนดอกเบี้ยต่ำที่หาได้ง่ายในตอนนั้น
    ต่อมาในยุคบูมของมือถือ ซอฟต์แวร์ต้องไปรันบนอุปกรณ์ผู้ใช้ที่มีข้อจำกัดและควบคุมไม่ได้ แอปแบบ dynamic type ที่ช้าก็คือช้าจริง และถ้าเกิด type error ก็ไม่สามารถกู้คืนอย่างสวยงามด้วย top-level response handler แบบฝั่งเซิร์ฟเวอร์ได้ ในสภาพแวดล้อมนั้น ความปลอดภัยและประสิทธิภาพของ static type จึงดูน่าเชื่อถือขึ้นมาก

    • มีงานวิจัยไม่น้อยที่เปรียบเทียบ Java และ C++ แบบยุค 90 กับโค้ดเบสภาษาที่เป็น dynamic type แล้วพบว่าอัตราบั๊กใกล้เคียงกัน ซึ่งคนที่ชอบภาษากลุ่ม dynamic language มักยกสิ่งนี้มาเป็นหลักฐานว่า static type ไม่ได้มีประโยชน์มากนัก
      ตอนต้นทศวรรษ 2000 ผมก็เห็นด้วย เพราะระบบ type ตอนนั้นมักบังคับใช้คุณสมบัติที่แทบไม่ค่อยผิดอยู่แล้ว แต่กลับเพิ่มข้อจำกัดที่ไม่ได้ช่วยให้จัดโครงสร้างโค้ดได้ดีขึ้น โดยเฉพาะวิธีที่ผูก subtyping เข้ากับ implementation inheritance ซึ่งไม่ยืดหยุ่น
      แต่พอได้ใช้ระบบ type ที่ทันสมัยขึ้น ผมก็เปลี่ยนความคิด ใน snmalloc นั้นใช้ระบบ type ของ C++ เพื่อบังคับ state machine ของการเป็นเจ้าของหน่วยความจำ และในโค้ดเบสอื่นก็ใช้ตรวจสอบพฤติกรรม overflow ที่ถูกต้องของตัวนับใน ring buffer ทั้งสองอย่างถ้าพลาดจะดีบักน่ารำคาญและเป็นสาเหตุของข้อผิดพลาดที่พบบ่อย แต่ระบบ type ทำให้โค้ดที่ผมคิดว่าเขียนถูกแต่จริง ๆ ผิด คอมไพล์ไม่ผ่าน จึงกันไม่ให้บั๊กเข้าไปอยู่ใน tree ได้
    • ผมมองว่าการพัฒนาด้วยภาษาแบบ dynamic type ช้ากว่าภาษาแบบ static type ผมเห็นข้อโต้แย้งตรงข้ามบ่อยมากแต่ไม่เข้าใจ
      ใน IDE แค่กด . แล้วพิมพ์ชื่อเมธอดไปนิดหน่อยก่อนกด Enter ที่ตัวเลือกที่ถูกต้อง ก็ประหยัดเวลาได้ทีละ 2 วินาทีทุก ๆ ไม่กี่วินาที และยังประหยัดเวลา 30 วินาทีที่ต้องไปเปิดดู class definition เวลาที่ไม่รู้ว่ามีเมธอดอะไรบ้าง หลักการนี้อธิบายไว้ดีใน https://grugbrain.dev/#grug-on-type-systems
      เพราะเราเขียนบรรทัดโค้ดที่เรียกใช้เมธอดบ่อยกว่าการเขียนชนิดของพารามิเตอร์ฟังก์ชันมาก การแลกเปลี่ยนนี้จึงเสียเปรียบฝั่ง dynamic type อย่างหนัก สิ่งที่มีค่าจริง ๆ ไม่ใช่การอนุญาตให้โค้ดเหลวไหลที่ควรล้มเหลวตอนรันไทม์ผ่านได้ แต่คือการละชนิดของตัวแปรโลคัลได้ และภาษา static type ก็ไม่จำเป็นต้องห้ามเรื่องนั้นตั้งแต่แรก
    • ระบบ type ที่ได้รับความนิยมในช่วงต้นทศวรรษ 2000 ไม่ใช่แค่ระดับ “ไม่ได้ยอดเยี่ยม” แต่แย่ และยัง verbose มาก
      โค้ดเบสหายากที่ใช้ระบบ type อย่างจริงจังมักเต็มไปด้วยโค้ดเป็นหน้าที่แทบไม่ได้สื่ออะไรเลย แต่ก็ยังมีเงื่อนไขตอนรันไทม์กองโต และถ้าเป็น Java โปรแกรมก็ช้าลงอย่างมีนัยสำคัญเมื่อ type hierarchy โตขึ้น โค้ดเบสส่วนใหญ่ใช้ type แบบกระจัดกระจายพร้อมเงื่อนไขตอนรันไทม์จำนวนมาก ซึ่งก็ไม่ได้ช่วยลดขอบเขตการทดสอบที่ต้องมีเมื่อเทียบกับระบบ dynamic type มากนัก
      ภาษากลุ่ม dynamic type แม้จะไม่ได้รางวัลแบบ static แต่มีข้อดีคือกระชับ อ่านและรีวิวง่าย และทดสอบง่ายกว่า โดยเฉพาะในสภาพแวดล้อมแบบ dependency injection framework ช่วงปลายยุค 90 ถึงต้นยุค 2000 ที่ทุกครั้งจะเพิ่ม service ใหม่ต้องไปแก้ XML หลายไฟล์ และยังทำงานได้โดยไม่ต้องใช้ IDE ที่กิน RAM ไปครึ่งเครื่อง
      ช่วงต้นอาชีพของผมก็เป็นแบบนี้เป๊ะ เลยเห็นด้วยกับบทความมาก ค่าใช้จ่ายเทียบประโยชน์ของ Java 1.4 ถึง Java 6 มันแย่มากจนเกือบทำให้ผมเลิกใช้ภาษาที่มี static type ไปเลย และกว่าจะมารู้ทีหลังจากลองเล่น Haskell เป็นงานอดิเรกว่า static type ก็สามารถมีความคุ้มค่าได้ และปัญหาที่แท้จริงคือ Java ต่างหาก บทความ “python is not java” ก็สะท้อนยุคมืดนั้นได้ดี
    • subtyping ที่อิงกับ inheritance นั้นยิ่งอ่อนกว่าอีก มันไม่ได้ให้ความสะดวกของ pattern matching ที่ตรวจสอบความครบถ้วนได้ และการ implement ก็แตกกระจายไปหลายที่
    • คำอธิบายที่ว่าการเปิดเว็บให้เร็วกว่าเจ้าอื่น เอาออกสู่ผู้ใช้ก่อน และล็อกข้อได้เปรียบจาก economies of scale ไว้ให้ได้ เป็นเรื่องสำคัญนั้น ฟังดูคุ้นกับสถานการณ์ปัจจุบันไม่น้อย
  • หลังจากที่ static typing กลายเป็นกระแสหลักของยุคสมัย ผมก็ยังสงสัยว่าเราได้เห็น ประโยชน์ด้านความน่าเชื่อถือ ของซอฟต์แวร์จริง ๆ มากแค่ไหน
    เดิมทีผมคิดว่าจุดเด่นของ static typing อยู่ที่ feedback ระหว่างพัฒนาที่ได้ทันทีและการลดความล้มเหลวร้ายแรงตอนรันไทม์มากกว่า แม้ในทางทฤษฎีความล้มเหลวแบบนั้นจะเกิดขึ้นได้เสมอ แต่ในทางปฏิบัติดูเหมือนมันไม่ได้เกิดบ่อยขนาดนั้น

    • เห็นนะ พอเราเริ่มตั้งเป้าให้โค้ดเบส TypeScript ที่ไม่เล็กมี TypeScript error เป็น 0 จำนวนครั้งที่พยายามเรียกเมธอดบน undefined และ null ก็ลดลงอย่างมาก
      ทั้งรุ่นน้องและบางคนที่เป็นซีเนียร์ตอนแรกก็มองโลกในแง่ร้าย คิดว่าจะมี @ts-ignore โผล่เต็มไปหมด แต่ในความเป็นจริงมีอยู่แค่ประมาณสามจุดเท่านั้น รวมถึงกรณีที่มาจาก type ของ dependency ที่พังด้วย เมื่อก่อนใน development branch แอปจะล่มเพราะสับสนเรื่อง type ราวสัปดาห์ละครั้งจนขัดขวางงานผม แต่ตอนนี้จำไม่ได้แล้วด้วยซ้ำว่าครั้งล่าสุดเกิดขึ้นเมื่อไร
      แค่ทำให้ tsc ผ่านก็ช่วยลด บั๊กที่เกี่ยวกับ type ได้ แม้ในกรณีที่ผมไม่ได้เป็นคนเขียนโค้ดเองด้วย ตรงกันข้าม linter สมัยนี้ขยันเกินเหตุ และการพยายามทำให้เครื่องมืออย่าง Sonar พอใจกลับทำให้เห็นความเสียหายจากการ refactor จริง ๆ คำเตือน 95% เป็นของปลอม 3% เป็นบั๊กของตัวเครื่องมือ และอีก 2% ที่พอช่วยได้ก็ไม่ใช่สาเหตุของบั๊กจริงอยู่ดี แทนที่จะใช้เวลา 1 สัปดาห์ปรับโค้ดเบสให้เข้ากับมันแล้วจับบั๊กได้ 1 ตัว ระหว่างทางกลับใส่บั๊กเพิ่มไปอีก 2 ตัว
      งานที่ทำเพื่อให้ tsc ผ่าน โดยเฉลี่ยแล้วทำให้เกิดการแก้บั๊กล้วน ๆ ราววันละ 2 จุด และ regression 1 จุด แต่ regression มักมีความรุนแรงต่ำกว่า ไม่ใช่การ crash ทั้งระบบ แค่เป็นพฤติกรรมที่ผิดไป
      ถ้าเพิ่ม property-based testing เข้าไปด้วย จะใช้เวลาเฉลี่ย 2–4 ชั่วโมง และเปิดเผยบั๊กได้อย่างน้อย 1 ตัวทุกครั้ง ถ้าโค้ดของคุณสามารถทำ property-based testing ได้ ก็ควรทำ
      ผมใช้ DeepSeek V4 Flash ซึ่งเป็นโมเดลราคาถูกเพื่อเพิ่มขอบเขตการทดสอบ โดยระวังไม่ให้เกิดเทสต์ขยะ สุดท้ายก็แก้บั๊กเชิงตรรกะได้ราววันละ 2–3 ตัว และไม่มี crash แต่ชุดทดสอบก็อยู่ในระดับที่แทบจะพอบำรุงรักษาไหวเท่านั้น
      ตอนให้รุ่นน้องใช้ Sonnet กับสาย Opus 4.5 และ 4.6 สร้างเทสต์แบบคร่าว ๆ โมเดลเหล่านั้นกลับสร้างแต่เทสต์ที่ “บันทึกพฤติกรรมปัจจุบัน” ทำให้ผลของการแก้ไขมีน้อย และชุดทดสอบก็ดูแลต่อไม่ได้จนต้องทิ้ง
      การทดสอบที่อิงโมเดลนั้นยอดเยี่ยมมากในการจับบั๊ก แต่การตั้งค่ายุ่งยาก และการชี้นำให้มันขุดคุ้ยตามมุมต่าง ๆ โดยไม่เผาผลาญรอบการทำงานไปกับฟีเจอร์ผิวเผินนั้นยุ่งมาก ถ้ามีอะไรอย่าง profile-based model-based fuzzer ก็น่าจะน่าสนใจ
      สรุปคือ type checker จับความล้มเหลวร้ายแรงและความสับสนหลายแบบได้ดี ส่วน property-based testing ยอดเยี่ยมมาก สำหรับการทดสอบทั่วไปนั้น ต้องมีวินัยสูงพอสมควรถึงจะได้ผลตอบแทนอย่างสม่ำเสมอ
    • สำหรับผมถือว่าใช่ บั๊กแบบ null pointer ใน JavaScript ที่ผมใช้แทบกลายเป็นเรื่องเล็กน้อยจนมองข้ามได้หลังย้ายไป TypeScript และเพื่อนร่วมงานก็รู้สึกคล้ายกัน
  • ตรงที่เอา TypeScript ไปรวมเป็นพวกเดียวกับ type system ที่ดี อันนี้ผมเห็นด้วยได้ยากที่สุด

    • ใช่ TypeScript ไม่ sound และโดยเฉพาะวิธีที่มันทำ type narrowing ข้าม await นี่กัดผมมาหลายรอบแล้ว ถึงอย่างนั้นก็เป็นความจริงว่ามันทำให้สถานการณ์ดีขึ้นอย่างมาก
      พูดตามตรง ผมเองสุดท้ายก็ยอมรับ structural typing ได้ และคิดว่ามันจะส่งผลบวกต่อการออกแบบภาษาในอนาคต
  • ข้ออ้างนี้ฟังไม่ค่อยน่าเชื่อถือ ภาษาโปรแกรมที่ใช้การได้และมี algebraic data types กับ type inference ก็มีมาตั้งแต่กลางยุค 90 แล้ว
    type system ของ Java และ C++ นั้นอ่อนมาก แต่ SML, OCaml และ Haskell มีอยู่แล้ว และให้ความรู้สึกไม่ต่างจากปัจจุบันมากนัก ถ้าผู้คนไม่ใช้ภาษาเหล่านั้น ปัญหาก็น่าจะอยู่ที่วัฒนธรรม การยอมรับใช้ และข้อกำหนดที่ไม่ได้ถูกพูดออกมา มากกว่าจะอธิบายได้ด้วยแค่ว่า “type system ที่ใช้งานได้ยังดีไม่พอ”
    หรือถ้าจะบอกว่า “type system ของภาษายอดนิยมในตอนนั้นแย่ แต่ type system ของภาษายอดนิยมในวันนี้ดีขึ้น เลยทำให้ type system ได้รับความนิยมมากขึ้น” แบบนั้นก็ฟังดูเป็นตรรกะแบบวนกลับ
    อีกทั้งยังมีความต่างเชิงนัยสำคัญมากระหว่างภาษาที่ถูกออกแบบมาพร้อมกับ type system ตั้งแต่ต้น กับภาษาที่เดิมทีออกแบบมาแบบไม่มี type แล้วค่อยเอา type system มาครอบทีหลัง

  • ต่อให้เดิมผมจะชอบ dynamic typing มากกว่า ผมก็ยังคิดว่าบทความนี้ยุติธรรมพอสมควร ทุกวันนี้ผมทำงานด้วย C# งานอดิเรกใช้ Lisp และเมื่อก่อนก็เคยใช้ Python
    ตอนที่ต้องใช้ Java 5 ผมมักต้องสู้กับ type system อยู่ตลอด ซึ่งโดยมากเป็นผลจากการตัดสินใจแย่ ๆ ของคนทำไลบรารี พอย้ายมา C# ราวปี 2010 type system ก็ไม่ได้เป็นโทษแบบเชิงรุก แต่มักซ้ำซ้อนเสียมากกว่า และยังกัน null pointer exception ซึ่งเป็นความสับสนเรื่อง type ที่พบบ่อยที่สุดใน Python ไม่ได้ด้วย
    type system ของ C# เริ่มช่วยได้จริง ๆ ก็ราวปี 2020 ตอนมี non-nullable reference types เข้ามา ปีนี้ก็จะมี native union types เข้ามาด้วย แต่ไลบรารี union types ที่บังคับความครบถ้วนได้นั้นมีให้ใช้ได้มาตั้งแต่ปี 2016 เป็นอย่างน้อย และผมเริ่มใช้ตั้งแต่ปี 2020
    ผมคิดว่าเรื่องกระแสก็ยังมีบทบาทอยู่ แต่บางส่วนก็ไม่ใช่เรื่องแย่ ภาษาที่กำลังนิยมและมี type system ที่แสดงออกได้มากกว่าก็นำพาการปรับปรุงมาสู่ภาษาทั่วไปที่พวกเราใช้ทำงานหาเงินกันด้วย

  • Haskell และระบบ type ของมันมีอยู่แล้วตั้งแต่ยุค 2000s แม้จะยังไม่ได้ถูกใช้อย่างแพร่หลายเหมือนตอนนี้ แต่ก็มีอยู่จริง ดังนั้นข้ออ้างนี้ควรเสริมส่วนนี้ด้วย
    โดยส่วนตัวผมคิดว่า TypeScript เป็นปัจจัยสำคัญที่ทำให้ผู้ใช้ภาษากระแสหลักคุ้นเคยกับระบบ type ที่ดีกว่า นอกจากคุณภาพและการสนับสนุนจาก Microsoft แล้ว มันยังมีข้อได้เปรียบตรงที่ใช้กับ JavaScript ได้ และ JavaScript ก็ต้องการ type มากกว่า Python ด้วยซ้ำ เพราะ “Undefined is not a function.” และ “The good parts.”

    • อยากให้มีหนังสือ “good parts” ที่อิงกับ JavaScript รุ่นปัจจุบันและยังคงความกระชับไว้
      “Real World Haskell” ออกมาในปี 2008 และมีเป้าหมายจะทำให้ Haskell ดูน่าสนใจขึ้นสำหรับโปรแกรมเมอร์กระแสหลัก แต่ไม่แน่ใจว่ามันช่วยเผยแพร่ข่าวดีได้มากแค่ไหน
      ในโลก Java มี Scala ที่นำ type เจ๋ง ๆ เข้ามาตั้งแต่ปี 2004 และฝั่ง .NET ก็มี F# ในปี 2005 Scala อาจเป็นภาษาที่ได้ผู้ใช้ที่โดดเด่นอย่าง Twitter มากที่สุด แต่ก็ไม่ได้อยู่ในตำแหน่งที่จะดึงผู้ใช้บนแพลตฟอร์มนั้นมาได้ในสัดส่วนมากแบบ TypeScript และก็ไม่ได้ดึงดูดผู้ใช้จากภาษาอื่นได้เป็นจำนวนมากแบบ Rust หรือ Go
    • บทความพูดถึงประเด็นนี้ไว้แล้ว โดยเปรียบ ระบบ static type ที่อ่อนแอ อย่าง Java ยุคแรกหรือ C++98 ซึ่งเคยได้รับความนิยมในยุค 90s และต้นยุค 2000s ว่าเป็นเหมือนพลั่วกระดาษ
      ในย่อหน้าถัดไปบทความก็พูดถึง Haskell ว่าเป็น “ระบบ type สมัยใหม่” แต่คนที่มีประสบการณ์กับ Haskell ในช่วงปลายยุค 90s ถึงต้นยุค 2000s นั้นแทบจะใกล้เคียง 0% แม้นับรวมคนที่แค่เคยลองจับเล่นส่วนตัวด้วยก็ตาม บทความกำลังพูดถึงว่าตอนนั้นนักพัฒนาส่วนใหญ่สัมผัสกับภาษา static type กันอย่างไร และทำไมคนส่วนใหญ่เหล่านั้นถึงพร้อมใจกันหลีกเลี่ยงภาษา static type
    • ผมมองว่า Haskell กับ OCaml ค่อนข้างลำบากเพราะ ecosystem ของเครื่องมือ ยังอ่อนอยู่บ้าง ตัวภาษาเองยอดเยี่ยม แต่โดนบั่นทอนการยอมรับจากปัญหาเล็ก ๆ น้อย ๆ ฝั่งเครื่องมือที่เหมือนโดนกระดาษบาดไม่รู้จบ
      ตัวอย่างเช่น ถ้าจะใช้ dune ใน OCaml คุณต้องเข้าใจไฟล์ opam, ไฟล์ dune, ไวยากรณ์ ocaml module และไวยากรณ์ ocaml Haskell เองก็มี compiler extension แบบเลือกใช้ที่ให้ความรู้สึกน่ากลัวพอ ๆ กัน
      ซึ่งต่างจาก cargo ที่แค่รู้ toml กับ Rust ก็พอ