1 คะแนน โดย GN⁺ 2024-11-14 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Raku เป็นเหมือน ห้องทดลองฟีเจอร์ภาษา ที่ทดลองไอเดียหลายอย่างโดยตรง มากกว่าจะเป็นการออกแบบหนึ่งเดียวที่ขัดเกลาจนสมบูรณ์ จึงทำให้เห็นการทดลองที่ภาษาอื่นอาจนำไปใช้ได้รวมอยู่ในที่เดียว
  • Junctions เผยแพร่การดำเนินการไปยังชุดของค่าที่เป็นไปได้ แล้วพับกลับด้วยตัวระบุปริมาณแบบบูลีนอย่าง all·any·one ทำให้เขียนเงื่อนไขซับซ้อนได้สั้นลง
  • * ของ Whatevers ใช้กับช่วงไม่สิ้นสุด, ฟังก์ชันนิรนาม และการทำดัชนีตามความยาวของลิสต์ ทำให้เกิดสไตล์โค้ดที่กระชับแต่ไม่คุ้นตา
  • Regex ของ Raku ยอมทิ้งความเข้ากันได้กับ PCRE เพื่อแลกกับฟีเจอร์อำนวยความสะดวก เช่น ไวยากรณ์ที่ประกอบกันได้, ตัวคั่นค่า, lookahead ที่อ่านง่าย และการละเว้นช่องว่างเป็นค่าเริ่มต้น
  • เมื่อดูตั้งแต่ Hyperoperators, Pair Syntax, Slangs, RakuAST ไปจนถึง Rakudo Star จะเห็นว่า Raku เป็นภาษาที่ทดลองอย่างกว้างขวาง ตั้งแต่ไวยากรณ์ไปจนถึงวิธีการจัดจำหน่าย

เหตุผลที่ Raku ดูเหมือนห้องทดลองฟีเจอร์ภาษา

  • หลังจากใช้งาน Raku จริงมานานกว่า 1 ปี Raku ดูเป็นภาษาที่ใกล้เคียงกับ “ห้องทดลองสำหรับฟีเจอร์ภาษา
  • โมเดล concurrency 5 แบบ และวิธีทำงานเดียวกันหลายวิธี แสดงให้เห็นลักษณะการทดลองแบบ “ดูว่าจะเกิดอะไรขึ้น”
  • เหตุผลที่หลายฟีเจอร์มีปฏิสัมพันธ์กันอย่างประหลาดและมี edge case มาก ก็เพราะการขัดเกลาฟีเจอร์เหล่านั้นให้ทำงานร่วมกันได้นั้นยากกว่าการรันการทดลอง 100 อย่างมาก
  • ฟีเจอร์ที่กล่าวถึงที่นี่คือการทดลองแบบ Raku ที่สักวันหนึ่งอาจเห็นได้ในภาษาโปรแกรมอื่นด้วย

Junctions: การซ้อนทับของค่าที่เป็นไปได้และตัวระบุปริมาณแบบบูลีน

  • Junctions แทน การซ้อนทับของค่าที่เป็นไปได้ และเมื่อใช้การดำเนินการกับ junction การดำเนินการเดียวกันจะถูกนำไปใช้กับค่าทั้งหมดภายใน
    • 2|10 กลายเป็น any(2, 10)
    • 2&10 + 3 กลายเป็น all(5, 13)
    • (1&2) + (10^20) ถูกประกอบเป็นแบบ all(one(11, 21), one(12, 22))
  • การใช้งานหลักของ Junctions คือการแสดง สูตรบูลีน อย่าง all, any
    • ไม่มีวิธีแยกโครงสร้าง junction
    • หากต้องการใช้งานจริง ต้องพับให้เป็นบูลีนก่อน
  • so บังคับแปลง junction ให้เป็นบูลีน
    • so (1&2) + (10^20) < 15 ได้ True
    • so (1&2) + (10^20) > 0 ได้ False
  • list.all ของ Raku ไม่ใช่เมธอดที่รับอาร์กิวเมนต์ แต่เป็น เมธอดไร้อาร์กิวเมนต์ ที่เปลี่ยนลิสต์ให้เป็น junction
    • <1 2 3>.all กลายเป็น all(1, 2, 3)
    • เมื่อใช้ is-prime($x) จะถูกนำไปใช้กับแต่ละค่า เช่น all(False, True, True)
  • เมื่อประกอบ Junctions เข้าด้วยกัน ก็สามารถสร้างพฤติกรรมแบบ unique ได้
    • สามารถแสดง “สมาชิกทุกตัวเท่ากับสมาชิกหนึ่งตัวพอดีหรือไม่” ด้วย {.all == .one}
    • <1 2 3 7> เป็นจริง และ <1 2 3 7 2> เป็นเท็จ

Whatevers: ช่วงไม่สิ้นสุดและฟังก์ชันนิรนามที่สร้างด้วย *

  • * ของ Whatevers คือ สัญลักษณ์ whatever ที่รับหลายบทบาทใน Raku
  • ในช่วงหรือซีเควนซ์ * หมายถึงไม่มีขอบเขต
    • 1..* คือ 1..Inf
    • (2,4,8...*)[17] คือ 262144
  • นิพจน์ที่มี * จะถูกยกขึ้นเป็นฟังก์ชันนิรนาม
    • พฤติกรรมนี้เรียกว่า whatever-priming
    • ผลลัพธ์คือ WhateverCode และนอกจากชนิดแล้วก็แยกไม่ออกจากฟังก์ชันอื่น
    • (* + 10)(2) ได้ 12
    • (^10).map(* % 2) สร้างแพตเทิร์น 0 1 0 1 ...
  • หากมี * สองตัวในนิพจน์ แต่ละตัวจะเป็นอาร์กิวเมนต์ตามตำแหน่งคนละตัว
    • (2, 30, 4, 50).map(* + *) คืนค่า (32, 54)
    • พฤติกรรมนี้มีประโยชน์กับการนิยาม Fibonacci ที่ซับซ้อน แต่ก็ไม่แน่ชัดว่าดีกว่าวิธีที่ให้ * แต่ละตัวเป็นค่าเดียวกันหรือไม่
  • เมธอดจำนวนมากของ Raku รับฟังก์ชันได้ ทำให้ priming ถูกใช้ได้กว้าง
    • l[*-1] ดูเหมือนดัชนีติดลบ แต่จริง ๆ แล้ว [] ส่งความยาวของลิสต์ให้ฟังก์ชันเพื่อคำนวณดัชนีที่จะเข้าถึง
    • หากความยาวลิสต์เป็น 10, l[*-1] จะเป็น l[10-1] หรือสมาชิกตัวสุดท้าย
    • l.head(2) หมายถึงสมาชิกสองตัวแรก ส่วน l.head(*-2) หมายถึงทั้งหมด ยกเว้นสมาชิกสองตัวสุดท้าย
  • หากส่งฟังก์ชันอื่นให้ [] ก็สามารถทำโครงสร้างอย่าง ring buffer ได้ง่าย
    • @x[95 % *]-- คำนวณตำแหน่งโดยใช้ความยาวของลิสต์

Regex: ไวยากรณ์ที่ประกอบกันได้โดยทิ้งความเข้ากันได้กับ PCRE

  • Raku ใช้ ไวยากรณ์ regex ใหม่ ที่ต่างจาก POSIX regex หรือ PCRE
    • POSIX regex เป็นโครงสร้างที่มี backslash และเครื่องหมายวรรคตอนจำนวนมาก
    • PCRE เข้ากันได้ย้อนหลังกับ POSIX และสืบทอดโครงสร้าง backslash·เครื่องหมายวรรคตอนที่ซับซ้อนกว่าเดิม
    • Perl 6 ตัดความเข้ากันได้ย้อนหลังและนำไวยากรณ์ regex ใหม่มาใช้
  • จุดปรับปรุงที่เด่นที่สุดคือ ความสามารถในการประกอบกัน
    • ในหลายภาษา การรวม regex ทำโดยนำสตริง regex มาต่อกัน
    • Raku สามารถแทรก regex อื่น เช่น /< foo >+/ เพื่อแมตช์ regex foo หนึ่งครั้งขึ้นไป โดยไม่ให้หลุดออกไปยัง regex ชั้นบน
  • สามารถแบ่ง regex ที่ซับซ้อนออกเป็นส่วนย่อยที่เล็กลงและอ่านง่ายขึ้นได้
  • เมื่อยอมตัดความเข้ากันได้ย้อนหลัง ก็มีการเพิ่ม ฟีเจอร์อำนวยความสะดวก หลายอย่าง
    • \d+ % ',' แมตช์ 1, 1,2, 1,1,4 แต่ไม่แมตช์ 1, หรือ 12
    • lookahead และ non-capturing group ไม่ใช่ชุดสัญลักษณ์ที่อ่านยาก
    • r1 && r2 แมตช์เฉพาะสตริงที่ตรงทั้ง r1 และ r2
    • สามารถหยุด backtracking ได้ด้วย :
    • โดยค่าเริ่มต้น ช่องว่างจะถูกละเว้น และต้องเปิดใช้อย่างชัดเจนในแพตเทิร์นการแมตช์
  • ไวยากรณ์ regex ของ Raku สามารถมองได้ว่าเป็นฟีเจอร์ที่อาจปรากฏในภาษาอื่นได้ โดยแยกจากความสามารถในการประมวลผลจริง

Hyperoperators: mapping แบบทั่วไปที่ลงไปถึงลิสต์ซ้อน

  • รูปแบบพื้นฐานของ Hyperoperators คือ l>>.method ซึ่งคล้ายกับ map แต่ ลงไปในลิสต์ย่อยแบบ recursive
    • [1, [2, 3], 4]>>.succ ได้ [2 [3 4] 5]
  • ใน Raku การเรียกฟังก์ชันรูปแบบ f(list, *args) สามารถเปลี่ยนเป็นรูปแบบเมธอด list.&f(* args) ได้
    • ดังนั้น >>. จึงทำงานเหมือนตัวดำเนินการ mapping แบบทั่วไป
    • สามารถใช้ร่วมกับ Whatever ได้ เช่น [1, [2, 3], 4]>>.&(*+1)
  • binary hyperoperator แบบ l1 << op >> l2 จะ นำ op ไปใช้กับแต่ละสมาชิก ของสองลิสต์
    • ลิสต์ที่สั้นกว่าจะวนซ้ำจนกว่าลิสต์ที่ยาวกว่าจะจบ
    • [1, 2, 3, 4, 5] <<+>> [10, 20] ได้ [11 22 13 24 15]
    • รูปแบบ << op<< หรือ >>op>> จะวนซ้ำเฉพาะจนกว่าลิสต์ด้านซ้ายหรือด้านขวาจะจบเท่านั้น
  • ใช้ได้กับค่าเดี่ยวและลิสต์ซ้อนด้วย
    • [1, 2, 3, 4, 5] <<+>> 10 ได้ [11 12 13 14 15]
    • [1, [2, 3], 4, 5] <<+>> [10, 20] ได้ [11 [22 23] 14 25]
  • hyperoperator สำหรับ hash สองตัว ยังมีพฤติกรรมแยกต่างหากที่นำ op ไปใช้กับ union, intersection และ hash difference
  • ชื่อ Hyperoperator มาจากการที่ทุกการดำเนินการถูก ประเมินแบบขนาน
    • ลูปแบบระบุชัดก็สามารถทำให้ขนานได้ด้วย prefix hyper

Pair Syntax: หน่วยพื้นฐานของ hash และการส่ง flag อย่างกระชับ

  • Pair คือหน่วยพื้นฐานที่ประกอบเป็น hash ของ Raku
    • hash คือกลุ่มของคู่ key => value
    • pair เป็น type พื้นฐาน และ hash คือคอลเลกชันของ pair
  • Raku มี colon syntax จำนวนมากสำหรับระบุ pair แบบสั้น
    • my $x = 3; :$x คือ x => 3
    • :a<$x> คือ a => "$x"
    • :a($x) คือ a => 3
    • :3a คือ a => 3
  • รูปย่อที่สำคัญที่สุดคือ :key และ :!key
    • แมปเป็น key => True และ key => False ตามลำดับ
    • ใช้เป็นวิธีที่กระชับในการใส่ flag ให้เมธอด
  • เมธอด match รับ colon pair หลายตัวเหมือน flag
    • ใช้รูปแบบอย่าง :continue(:$c), :pos(:$p), :global(:$g), :overlap(:$ov)
    • :f(:$foo) ใน signature จะนิยามพารามิเตอร์ $foo พร้อมสร้าง alias :f
    • ผู้เรียกสามารถตั้ง flag เดียวกันได้ด้วย :f หรือ :foo
  • อาร์กิวเมนต์ colon pair มีความยืดหยุ่นทั้งลำดับและตำแหน่ง
    • "abab".match(/../, :g) ทำการแมตช์แบบ global
    • "abab".match(/../, :g, :ov) ทำการแมตช์แบบ overlap
    • สามารถสลับลำดับและเขียนติดกันได้ เช่น "abab".match(:g:ov, /../)
    • สามารถวางอาร์กิวเมนต์คีย์เวิร์ดหลังการเรียกฟังก์ชันได้ เช่น "abab".match(:g, /../):ov:2nd
  • ไวยากรณ์แบบนี้ช่วยระบุตัวเลือกของเมธอดได้สั้นกว่า match(global=True, overlap=True) มาก

Slangs, RakuAST, Rakudo Star

  • Slangs คือฟีเจอร์สำหรับเปลี่ยนไวยากรณ์ของ Raku
    • ใช้ได้กับงานอย่างการแก้ไวยากรณ์ลูป, เปลี่ยน identifier, เพิ่ม actor, เพิ่มซีเควนซ์ DNA
    • ตัวอย่างที่ยกมาคือ Slang::Otherwise, Slang::Piersing, OO::Actors, BioInfo
  • RakuAST คือฟีเจอร์สำหรับพาร์สนิพจน์ Raku เป็น AST ภายใน Raku เอง
    • Q/my $x; $x++/.AST แสดงการประกาศตัวแปรและการดำเนินการเพิ่มค่าแบบ postfix ในรูป RakuAST::StatementList
    • มีตัวอย่างการส่งออกโค้ด Raku เป็นสัญกรณ์แบบภาษาอื่น เช่น Q/my $x; put $x/.AST.DEPARSE("NL")
  • Raku มีชุดติดตั้ง Rakudo Star
    • distribution นี้ติดตั้ง โมดูล third-party ที่คัดเลือกไว้ล่วงหน้าให้
    • เป็นเหมือนทางประนีประนอมระหว่างภาระในการดูแล standard library ขนาดใหญ่ กับภาระที่ผู้ใช้ต้องหาแพ็กเกจที่เหมาะสมจาก ecosystem เอง

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

 
GN⁺ 2024-11-14
ความคิดเห็นจาก Hacker News
  • ก่อนหน้านี้ผมเคยทำสิ่งที่คล้ายกับฟีเจอร์ regular expression แบบประกอบกันได้ ที่เคยพูดถึงกันที่นี่ เป็น implementation แยกต่างหากสำหรับ JavaScript และแม้จะผ่านมาหลายปีแล้ว มันก็ยังเป็นหนึ่งในไลบรารีที่ผมหยิบไปใช้ในโปรเจกต์อื่นบ่อยที่สุด
    มันทำให้รู้สึกใกล้เคียงขึ้นอีกนิดกับการมี parser เป็น first-class citizen อยู่ในภาษา และมีตัวอย่างการใช้สิ่งนี้ทำ parser สำหรับ media type ด้วย regular expression: https://runkit.com/tolmasky/media-type-parsing-with-template...
    บน npm คือ templated-regular-expression, GitHub: https://github.com/tolmasky/templated-regular-expression
    แน่นอนว่าภาษาโปรแกรมมิงควรมี parser ของจริง และไม่ควรใช้ regular expression เป็น parser แต่ถ้ายังไงก็ต้องใช้ regular expression อยู่แล้ว การแบ่งมันเป็นชิ้นเล็ก ๆ ได้ก็ยอดเยี่ยมจริง ๆ

    • “parser ของจริง” นั้น ไม่ทรงพลังพอจะ parse Raku
      regular expression ของ Raku เมื่อใช้ร่วมกับ grammar จะทรงพลังกว่ามาก และถ้าเขียนดี ๆ ก็เข้าใจง่ายกว่า “parser ของจริง” ใด ๆ ด้วยซ้ำ ถ้าจะ parse Raku ด้วย parser ทั่วไป จำเป็นต้องสามารถเพิ่มและลบรายการใน parser ระหว่างการ parse ได้ ซึ่ง parser ของ Raku จัดการเรื่องนี้โดย subclass grammar ปัจจุบัน เพื่อเพิ่ม·ลบรายการภายใน lexical scope ปัจจุบัน แล้วเมื่อ scope จบลงก็ย้อนกลับไปใช้ grammar เดิม
      ใน Raku regular expression คืออีก syntax หนึ่งสำหรับเขียนโค้ด และต่างจาก syntax หลักกับพฤติกรรมพื้นฐานเพียงเล็กน้อยเท่านั้น มันสามารถมีพารามิเตอร์และตัวแปรได้ ถ้างานใดไม่เหมาะกับ syntax ของ regular expression ก็สามารถแทรก syntax ปกติของ Raku เข้าไปทำสิ่งที่ต้องการ แล้วกลับมายัง syntax ของ regular expression ได้
      ตัวอย่างเช่น สามารถ match A หนึ่งตัวขึ้นไป ตามด้วย B จำนวนเท่ากัน และ C จำนวนเท่ากันได้ด้วย ใน syntax regular expression ส่วนใหญ่ ถ้าจะ match A กับ B ให้มีจำนวนเท่ากันต้องใช้ recursion ตรงกลาง แต่ถ้าทำแบบนั้นจะจัดการ C ในแบบเดียวกันได้ยาก และอ่านยากขึ้นมาก วิธีของ Raku ไม่ต้องใช้ backtracking หรือ recursion จึงอาจรันได้ค่อนข้างเร็ว
      ถ้าห่อด้วย grammar ก็จะได้ parse tree ที่สมบูรณ์ และแม้จะทำได้โดยไม่ใช้ grammar แต่ใช้ grammar จะง่ายกว่า ตัวอย่าง parser จริงที่มักแนะนำคือ JSON::TINY::Grammar: https://github.com/moritz/json/blob/master/lib/JSON/Tiny/Gra...
      พูดตามตรง ส่วนสำคัญไม่น้อยของการออกแบบ “parser ของจริง” ดูเหมือนเป็นผลพลอยได้จากข้อจำกัดด้าน RAM ของคอมพิวเตอร์ยุคแรก ๆ ขั้นตอน tokenization ที่แยกออกมาต่างหากมีไว้เพื่อลด RAM ที่ซอร์สโค้ดใช้ เพื่อเหลือหน่วยความจำไว้สำหรับการวิเคราะห์ความหมายและการคอมไพล์ในขั้นต่อไป และผมไม่คิดว่ามันทำให้ขั้นตอนถัด ๆ ไปง่ายขึ้นมากขนาดนั้น โมดูล JSON::Tiny ข้างต้นสร้างโครงสร้างข้อมูล native ของ Raku ด้วย action class ระหว่างที่ grammar กำลัง parse ดังนั้นจึงเหมือนกับ parse ไปพร้อมกับ compile ไปด้วย
  • ใช้ Raku ใน production อยู่ การประมวลผลข้อความ นี่เป็นภาษาที่ดีที่สุด และประสบการณ์ในการสร้าง parser ก็ดีมาก
    น่าแปลกใจที่มันไม่ได้เป็นภาษาระดับท็อปสำหรับสร้าง LLM text pipeline

    • มาช้าไปหน่อย แต่อยากรู้ว่ามีตัวอย่างดี ๆ ของการใช้ Raku เรียก HTTPS API แล้ว poll จนกว่าจะคืนค่าบางอย่างหรือไม่
    • อยากรู้ว่าคุณใช้ แพ็กเกจ LLM ของ Raku อยู่ไหม ถ้าใช้ ใช้ตัวไหน
  • ว้าว ผมอยากออกจากวงการก่อนถึงวันที่ต้องมาดูแล codebase ของ Raku เลย

    • ตลกดี พออ่านบล็อกโพสต์นั้นแล้ว ผมกลับอยากลาออกจากงานแล้วไปหาทีม Raku เพื่อทำงานด้วย ยังอาจจะไร้เดียงสาเกินไปก็ได้ :)
    • ถ้าไม่เคยเห็นโค้ด Raku ทั่วไป เห็นบทความแล้วจะมีปฏิกิริยาแบบนั้นก็เข้าใจได้
      ถ้าดูหนังสือ Raku สำหรับผู้เริ่มต้น จะมีหลายส่วนที่ให้ความรู้สึกเหมือน Python ที่ติด syntax ตระกูล C เข้าไป เป็น syntax ที่เน้นวงเล็บปีกกา แต่ทั้งความใช้งานง่าย โครงสร้างข้อมูล built-in และฟีเจอร์เชิงวัตถุล้วนอยู่ในระดับสูง
      ถ้ารู้จักภาษาสคริปต์ระดับสูงอื่น ๆ โค้ด Raku ของสคริปต์ที่คล้ายกันน่าจะอ่านได้ค่อนข้างง่าย ผมไม่คิดว่าคนส่วนใหญ่จะใช้ฟีเจอร์แปลกมาก ๆ ในโค้ดประจำวัน และ Raku แม้จะยืดหยุ่นกว่า แต่โดยปกติโค้ดก็ไม่ได้ดูเข้าใจยาก
    • คล้ายกับ Perl ไม่มีใครอยากดูแลมัน แต่การใช้มันสนุกจริง ๆ พลังในการสื่อความ สูงมาก
      ใน Raku จะเห็นจุดนั้นได้จากความสามารถในการนิยาม keyword argument แบบย่อ เช่น :global(:$g) หรือความสามารถในการเรียก global regex match อย่าง match(/foo/, :g) โดยถือว่าค่าเป็น True ใน Perl ก็มีอะไรแบบนี้เยอะ และทั้งหมดมีไว้เพื่อให้ใช้ได้เร็วขึ้นและสนุกขึ้น แต่สำหรับมือใหม่จะอ่านยากลง
    • แปลกดีที่ผู้คนพูดแบบคล้าย ๆ กันเกี่ยวกับการดูแล codebase ที่เขียนด้วยความช่วยเหลือจาก AI
      ต่อไปคงกลายเป็นช่องว่างระหว่างรุ่น โปรแกรมเมอร์รุ่นเก่าทั้งรุ่นอาจรู้สึกเหมือนถูกกันออกจากสภาพแวดล้อมการทำงานที่สำหรับคนรุ่นปัจจุบันถือเป็นเรื่องปกติ
    • ผมไม่คิดว่า Raku เป็นภาษาที่ตั้งใจทำมาเพื่อ “อุตสาหกรรม”
  • ฟีเจอร์บางอย่างคุ้น ๆ อยู่ครึ่งหนึ่ง Hyper ฟังดูเหมือนเป็นเวอร์ชันที่ทำแบบฉับพลันกว่าอะไรสักอย่างในสาย recursion-schemes และ * ที่เห็นตรงนี้ก็คล้ายกับ _ ของ Scala อยู่บ้าง
    _ ใช้กับ lambda ได้ดี จนอยากให้ทุกภาษารับสิ่งคล้าย ๆ กันไปใช้

  • > (2, 30, 4, 50).map(* + *) returns (32, 45) ไม่ควรเป็น returns (32, 54) เหรอ? เพราะพจน์ที่สองคือ 4+50
    หรือบางทีอาจเป็นผลจาก การแปลนำหน้า ที่มาจากบางประเทศที่พูดแบบ “four and fifty” เช่น vierenvijftig แทน fifty-four ในภาษาอังกฤษ

    • ลองเช็กใน rakudo แล้ว จริง ๆ มันคืนค่า (32 54) น่าจะเป็นคนเขียนเผลอพิมพ์ผิด
  • ถ้าอย่างนั้น ตอนนี้ Perl ก็เป็นเหมือนยาเริ่มต้นสำหรับไปสู่ ภาษาในตระกูล APL แล้วสินะ?

    • ใช่ แถมในบทความยังไม่ได้พูดถึง meta operator ด้วย
      ตัวอย่างเช่น สามารถใช้ reduce meta operator [ ] ร่วมกับ infix + เพื่อ “รวมทั้งหมด” ได้: [+] 1, 2, 3
  • Raku ยังมีปัญหาใหญ่เรื่อง ความเร็ว อยู่ การแยกวิเคราะห์ไฟล์ล็อกด้วย regex เป็นจุดแข็งของ Perl แต่แม้แต่ Raku รุ่นล่าสุด หากไม่นับเวลาเริ่มต้น ก็ยังใช้เวลานานกว่า Python 3.13 ถึง 6.5 เท่า

    • ควรยกตัวอย่างมาด้วย จากประสบการณ์ของผม Raku บางอย่างก็เร็วกว่า บางอย่างก็ช้ากว่า ดังนั้นถ้าพูดแค่ว่า “Raku ใช้เวลานานกว่า Python 3.13 ถึง 6.5 เท่า” โดยไม่ดูว่าช้าตรงไหน ก็แทบไม่มีความหมาย
  • น่าทึ่งจริง ๆ ที่ (2,4,8...*)[17] กลายเป็น 262144

    • ในหัวผมมีคำว่า “น่ากลัว” ผุดขึ้นมาทันที แล้วก็ตามมาด้วย “ผลลัพธ์อันน่ากลัว” และ ปัญหาการหยุดทำงาน แต่รสนิยมของแต่ละคนอาจไม่เหมือนกัน
    • การตรวจจับส่วนเพิ่มมีอยู่ใน Perl6 มานานแล้ว จึงไม่ใช่ฟีเจอร์ใหม่
      หากไม่นับ Whatever ความใหม่หลังจาก Perl6/Raku น่าจะอยู่ที่ lazy evaluation
    • ค่อนข้างสอดคล้องกันดี
      (1,3,9...*)[4,5] จะได้ (81 243) และ (1,3,9...*)[(1..3)] จะได้ (3 9 27)
      ยังซ้อนกันได้ด้วย เช่นนิพจน์อย่าง (1,2,4...*)[(1,2,4...*)[1,2,3]] ก็ทำได้
  • เป็นการคัดฟีเจอร์ที่น่าสนใจของ Raku มาพูดถึง
    ผมมองว่าฟีเจอร์สำคัญที่สุดของ Raku คือ อินเทอร์เฟซบรรทัดคำสั่ง และ grammar
    การรองรับอินเทอร์เฟซบรรทัดคำสั่งเป็นฟีเจอร์ที่พบได้ทั่วไป เช่นมีการใช้งานและกรณีนำ docopt มาใช้ แต่ใน Raku ฟีเจอร์นี้มีมาในตัวและใช้งานได้ดี
    ส่วน grammar เป็นฟีเจอร์ที่พบได้ยาก เพราะภาษาโปรแกรมมิงมี grammar เป็น องค์ประกอบชั้นหนึ่ง และทำให้สามารถสร้างและประกอบ grammar ด้วยการเขียนโปรแกรมเชิงวัตถุได้

  • ผมติดตามโปรเจกต์นี้มาหลายปีและก็คิดว่าน่าสนใจ แต่ก็น่าเสียดายจริง ๆ ที่ Perl 6 ดูเหมือนจะหลงทางไปไกลเกินไปใน การเดินทางสู่โลกหลังกระจก นี้

    • สงสัยว่า Patrick Michaud ช่วงนี้กำลังทำอะไร และเป็นอย่างไรบ้าง