Saturday, February 04, 2006

define-syntax ใน scheme

เคยพูดถึง DSL (Domain Specific Language) ไปแล้ว
ซึ่ง RoR หยิบมา implement ในหลายๆส่วนใน ActiveRecord
เช่น
  • การ declare relationship ระหว่าง model
  • การ declare Validate rule ของ model


ใน scheme มี function define-syntaxที่อนุญาตให้เรา define syntax ของเราเองได้
ลองดูตัวอย่างง่ายๆ (ง่ายสุดๆ)

ปกติใน scheme, การ assign value ให้กับ variable จะใช้ syntax นี้
(define a 10)


วันดีคืนดี เกิดอยากเปลี่ยนรูปแบบ syntax ให้เป็นแบบนี้
(mylet a = 10)

Note: อยากใช้ let นะ จะได้เหมือน basic แต่ว่า scheme มี let ใช้แล้ว
เลยเปลี่ยนเป็น mylet แทน

วิธี define syntax ก็ง่ายๆ
เริ่มด้วย

(define-syntax mylet
(lambda (x)
(syntax-case x (=)
(
;;pattern to match
(mylet var = value)
;;transformer
(syntax (define var value))
)
)))


เริ่มด้วย (mylet a = 10) จะถูก pass เข้าไปในรูปตัวแปร x
จากนั้นก็จะถูก function syntax-case เอาไปใช้ในการทำ pattern matching

ประโยค syntax-case x (=) หมายความว่า
เครื่องหมาย = ใช้เป็น reserved word สำหรับ syntax นี้

ใน syntax-case จะประกอบด้วย
pattern mathcing กับ transformer

(mylet var = value) เป็น pattern matching
ซึ่งจะถูก match เข้ากับ (mylet a = 10)
ผลลัพท์ที่ได้ var => a, value => 10

(syntax (define var value)) เป็นส่วน transformer
ในที่นี้ (mylet a = 10) ก็จะถูกแปลงเป็น (define a 10)

อ่านตัวอย่างเพิ่มเติมในบทความ Metaprogramming using Scheme

Related link from Roti

No comments: