- "The missing Standard Library for TypeScript"
- ออกแบบมาเพื่อให้สร้างโปรแกรมที่ซับซ้อนทั้งแบบ synchronous/asynchronous ได้ง่าย
- ทำให้โค้ดมีความเป็น Composable, Reusable, Testable มากยิ่งขึ้น
- Maximum Type-Safety (รวมถึงการจัดการข้อผิดพลาด)
- มีไลบรารีหลากหลายให้ใช้งาน
- รองรับ clustering และ workflow (เวอร์ชันอัลฟา)
- ความเข้ากันได้กว้างขวาง
- Node, Deno, Bun, Cloudflare Workers, Chrome
- React, Solid.JS, Vite, Next.JS, Tauri
- คุณสมบัติหลัก
- Concurrency: ด้วยโมเดล concurrency ที่อิงกับ Fiber จึงสามารถสร้างแอปพลิเคชันที่ขยายตัวได้สูงและมี latency ต่ำมาก
- Composability: ใช้องค์ประกอบขนาดเล็กที่นำกลับมาใช้ซ้ำได้ เพื่อสร้างซอฟต์แวร์ที่ดูแลรักษาง่าย อ่านง่าย และยืดหยุ่น
- Resource Safety: สามารถจัดการการได้มาและการคืนทรัพยากรได้อย่างปลอดภัย แม้โปรแกรมจะล้มเหลว
- Type Safety: ให้ความสำคัญกับ type inference และ type safety เพื่อใช้ประโยชน์จากระบบ type ของ TypeScript ได้อย่างเต็มที่
- Error Handling: ใช้ความสามารถด้านการจัดการข้อผิดพลาดที่มีมาในตัว เพื่อจัดการข้อผิดพลาดอย่างเป็นระบบและเชื่อถือได้
- Asynchronicity: เขียนโค้ดให้มีลักษณะเหมือนกันได้ ไม่ว่าจะเป็น synchronous หรือ asynchronous
- Observability: ด้วยความสามารถในการติดตามอย่างครบถ้วน จึงดีบักและมอนิเตอร์การทำงานของโปรแกรมได้ง่าย
ทำไมต้อง Effect?
- การเขียนโปรแกรมเป็นเรื่องยาก
- เวลาสร้างไลบรารีและแอป เราใช้เครื่องมือจำนวนมากเพื่อจัดการความซับซ้อน
- Effect นำเสนอวิธีคิดแบบใหม่สำหรับการเขียนโปรแกรมด้วย TypeScript
- ด้วยเครื่องมือในระบบนิเวศของ Effect คุณสามารถสร้างแอปพลิเคชันและไลบรารีที่ดีกว่าเดิมได้
- สิ่งนี้ช่วยให้เข้าใจภาษา TypeScript และระบบ type ได้ดีขึ้น พร้อมทำให้โปรแกรมมีความน่าเชื่อถือและดูแลรักษาง่ายขึ้น
แพตเทิร์นของ Effect
- ในโค้ด TypeScript ทั่วไป มักสมมติว่าฟังก์ชันจะสำเร็จหรือไม่ก็ throw exception
- ตัวอย่าง: ฟังก์ชัน
divide จะ throw exception เมื่อต้องหารด้วย 0
- ดูจาก type เพียงอย่างเดียว เราไม่สามารถรู้ได้ว่าฟังก์ชันนี้อาจ throw exception
- เมื่อใน codebase มีฟังก์ชันอยู่หลักร้อยหรือหลักพัน ปัญหานี้ยิ่งใหญ่ขึ้น
- จึงลืมจัดการ exception ได้ง่าย และจัดการได้ยาก
- คอมไพเลอร์ของ TypeScript คือแนวป้องกันชั้นแรกต่อบั๊ก ข้อผิดพลาดของโดเมน และความซับซ้อนทั่วไป
การนำแพตเทิร์นของ Effect ไปใช้
- แนวคิดสำคัญของ Effect คือ นอกจากค่าที่สำเร็จแล้ว ยังสามารถใช้ระบบ type เพื่อติดตามข้อผิดพลาดและ "context" ได้ด้วย
- ตัวอย่าง: ฟังก์ชัน
divide เวอร์ชันของ Effect จะไม่ throw exception แต่จะส่งต่อข้อผิดพลาดให้ผู้เรียก
- มีความสามารถสำหรับจัดการทั้งข้อผิดพลาดและค่าที่สำเร็จ
- การติดตาม context ทำให้สามารถส่งข้อมูลเพิ่มเติมให้ฟังก์ชันได้ โดยไม่ต้องส่งอาร์กิวเมนต์ทุกตัวไปตรงๆ
- ตัวอย่าง: ระหว่างทดสอบ สามารถแทนที่ implementation จริงของบริการภายนอกด้วย mock object ได้
import { Effect } from "effect"
const divide = (a: number, b: number): Effect.Effect<number, Error, never> =>
b === 0
? Effect.fail(new Error("Cannot divide by zero"))
: Effect.succeed(a / b)
ระบบนิเวศของ Effect
- การผสานกันระหว่างแนวคิดอันเป็นเอกลักษณ์ของ Effect กับเครื่องมืออื่น ๆ ก่อให้เกิดระบบนิเวศของไลบรารีที่อุดมสมบูรณ์ ซึ่งช่วยให้สร้างแอปพลิเคชันที่ซับซ้อนได้ง่าย
- สิ่งที่ในอดีตดูเหมือนเป็นไปไม่ได้ ตอนนี้กลายเป็นเรื่องปกติ
- ระบบนิเวศของ Effect กำลังเติบโตอย่างรวดเร็ว และสามารถดูได้บน GitHub ของ Effect
อย่าสร้างวงล้อขึ้นมาใหม่
- ในโค้ดแอปพลิเคชัน TypeScript มักต้องแก้ปัญหาเดิมซ้ำ ๆ
- การโต้ตอบกับบริการภายนอก ระบบไฟล์ และฐานข้อมูล เป็นปัญหาร่วมกันของนักพัฒนาแอปทุกคน
- Effect มีระบบนิเวศของไลบรารีที่หลากหลาย ซึ่งมอบโซลูชันมาตรฐานสำหรับปัญหาเหล่านี้
- โดยไม่ต้องติดตั้ง dependency หลายตัว Effect ช่วยแก้ปัญหาจำนวนมากได้ในคราวเดียว
การแก้ปัญหาเชิงปฏิบัติ
- Effect ได้แรงบันดาลใจจาก Scala และ Haskell
- แต่เป้าหมายของ Effect คือการมอบชุดเครื่องมือเชิงปฏิบัติ เพื่อแก้ปัญหาในชีวิตจริงที่ต้องเผชิญเมื่อสร้างแอปพลิเคชันและไลบรารีด้วย TypeScript
เรียนรู้ไปอย่างสนุก
- การเรียนรู้ Effect เป็นเรื่องสนุก
- นักพัฒนาจำนวนมากกำลังใช้ Effect ในงานจริงเพื่อแก้ปัญหาจริง
- คุณอาจเริ่มจากการใช้เพียงบางส่วนของระบบนิเวศ Effect แล้วค่อย ๆ ใช้เครื่องมือเพิ่มขึ้น
- ในช่วงแรก แนวคิดของ Effect อาจดูไม่คุ้นเคย แต่หากใช้เวลาอ่านเอกสารและทำความเข้าใจแนวคิดหลัก ก็จะช่วยได้มากเมื่อไปใช้เครื่องมือขั้นสูงในภายหลัง
- ชุมชนของ Effect พร้อมช่วยเรื่องการเรียนรู้และการเติบโตอยู่เสมอ ลองดูที่ Discord หรือ GitHub
3 ความคิดเห็น
ดูเหมือนว่าจะมีแนวทางคล้ายกับแก่นหลักที่
rustมีอยู่เลยนะครับคงต้องลองใช้อีกสักหน่อยถึงจะบอกได้ชัด แต่ถ้าเทียบกับ fp-ts แล้ว รู้สึกว่าใช้งานได้ลื่นกว่ามาก
fp-tsตัดสินใจว่าจะไม่พัฒนา 3.0 ต่อ และจะไปรวมกับeffectถ้าคุณใช้
fp-tsอยู่ ก็น่าลองพิจารณาeffectดูhttps://x.com/MichaelArnaldi/status/1626975031048773635
https://effect.website/docs/other/fp-ts