From Opcodes to Algorithms - Day 12 to 15

เขียน visual assembly canvas มา 120 ชั่วโมงแล้ว รู้สึกได้เล่นอะไรเยอะมาก~

ตอนนี้แก้ logic ให้ทุกบล็อครันแบบ parallel กับแก้ message router และ actor ให้รับส่งข้อมูลกันได้ ชอบความเรียบง่ายของ actor model มาก ไม่ต้องใช้ library อะไรเลย รู้สึกว่าเขียนเทสต์ง่ายมากด้วย สร้าง inbox, outbox ไว้ แล้วให้ router ช่วยส่งหากัน

อีกอย่างที่ฟินมาก คือตอนนี้มี step visualizations แล้ว เรา scan source file แล้วนับดูว่า program counter เลขไหนจะอยู่ที่บรรทัดอะไร แล้วก็สร้าง mapping ออกมาให้เทียบ แล้วก็เขียน codemirror extension ให้ไปไฮไลท์บรรทัด แล้วให้ตัว machine ไปเรียก นอกจากนี้ก็ทำให้ step through เริ่มรันใหม่ได้เองหลังโปรแกรมรันจบแล้ว

งานที่ดูเหมือนจะถึกแต่สนุกมาก คือเราทำ error handling แบบดีๆ ทั้งใน runtime, parser, scanner, router และ compiler เพราะก่อนหน้านี้เราใช้ unwrap/panic แบบเถื่อนๆ เลย แต่พอมาได้เขียนจริงๆ รู้สึกว่า Rust จัดการ error ได้สวยที่สุดในทุกภาษาที่เคยเขียนมาเลย

ตอนแรกเราคิดว่าด้วยความที่ที่ error ใน Rust มันเป็น values มันจะต้องมา if err return แบบ Go หรือ pattern match ยุ่บยับหรือเปล่า แต่เจอว่า Rust มี construct เยอะมากให้เราจัดการ error แบบสวยงาม ไม่มี boilerplate และไม่กระทบต่อ flow การอ่านโค้ดเราเลย

จากที่ลองมา เราชอบ map_err, ok_or, ok_or_else คู่กับ ? operator มาก เวลาเขียนก็แค่เรียก map_err เพื่อทำให้ error มันเฉพาะเจาะจงขึ้น แล้ว early return เลย มัน communicate intent ได้ชัดมาก ว่าฉันกำลังจะ map error type นะ

ชอบ let else ที่เราสามารถ pattern match ของที่ต้องการ ถ้าไม่มีก็ else แล้ว return, break, continue ได้เลย รู้สึกว่าโค้ดสวยสุดๆ ตอนนี้ที่ยังไม่ได้ทำคือ parser panic mode & synchronization ให้มันยังรายงาน error ออกมาเรื่อยๆ พร้อมกันทีเดียว ไม่ได้ error แล้วจบเลย

เจอว่าเราเขียน parser/scanner ตอนแรกไม่ได้ครอบคลุมมาก มีบัคเพียบเลยที่ทำให้มัน crash เลยต้องมาจัดการดีๆ กับตัว runtime เองก็ไม่ได้ clear state เลย และ router ก็มี edge case เยอะมาก เช่น receive อยู่ท้ายสุด หรือ receive มาก่อน send เลยต้องใช้เวลามาทำให้มัน robust ขึ้น จัดการพวก panics, errors & edge cases ไปหลายชั่วโมง แต่ลองเล่นแล้วฟินมาก

พอมี unit tests & integration tests เยอะ แล้วจะแก้บัคอะไรก็ง่ายมาก ไม่ต้องคอยมาดักเคสในหัวเลย ชอบที่ Rust รัน 30 กว่าเทสต์ในไม่ถึง 10 ms ฟินมาก แล้วรู้เลยว่า tests ที่เขียนไปมันมีประโยชน์เพราะว่าเจอเคสที่นึกไม่ถึงเยอะมาก

นอกจากนั้นก็จัดการ state transitions ของ machine แต่ละตัว ตอนนี้ยังใช้วิธีบ้านๆ แบบเก็บ enum อยู่ ตอนแรกจะโมเดลเป็น state machine จะได้ visualize state space ได้ง่าย แต่รู้สึกว่าแบบที่ทำอยู่ก็ไม่แย่มาก พอเราโมเดล state ออกมาแล้วก็ทำพวก message routing, handling, cleanup ได้ง่ายขึ้น

ตอนนี้ใช้เวลาไป 15 วัน รวม 120 ชั่วโมง เขียนไป 360 commits แล้ว เดี๋ยวน่าจะได้ลองเขียนอะไรที่เป็น visual มากขึ้นแล้ว ใช้ความสามารถของ Reactflow ให้คุ้ม อยากทำพวก 3D rendering, canvas, synthesizers ใจจะขาดแล้ว น่าจะกระตุกจิตกระชากใจขึ้น

-- Day 12 - 15 of "From Opcodes to Algorithms" in Rust

October 27, 30, 31, to November 1. Post on Facebook.

#journal