สัญลักษณ์ที่อยู่ในตำแหน่งที่ไม่ใช่ฟังก์ชั่นถือเป็นชื่อของตัวแปร In (function variable)
function
อยู่ในตำแหน่งฟังก์ชั่น (หลังจากวงเล็บเปิด) และvariable
ไม่ใช่ ตัวแปรที่ยกมาอย่างชัดเจนนอกจากจะถูกแทนที่ด้วยค่าของพวกเขา
หากคุณกำลังจะเขียน(boundp my-variable)
นั่นจะหมายถึง "เป็นสัญลักษณ์ที่ถูกเก็บไว้ในค่าของตัวแปรที่my-variable
ถูกผูกไว้เป็นตัวแปร" และไม่ได้ "เป็นสัญลักษณ์ที่my-variable
ถูกผูกไว้เป็นตัวแปร
เหตุใดจึงมีbound-and-truep
พฤติกรรมแตกต่างกัน
นี่เป็นมาโครและกฎการประเมิน (ฟังก์ชั่น) ปกติไม่ได้ใช้ที่นี่มาโครมีอิสระในการตัดสินใจว่าจะประเมินอาร์กิวเมนต์เมื่อใดและเมื่อใด มาโครที่ทำจริง ๆ จะเปลี่ยนอาร์กิวเมนต์และส่งคืนผลลัพธ์เป็นรายการซึ่งจะถูกประเมินผล การเปลี่ยนแปลงและการประเมินผลขั้นสุดท้ายเกิดขึ้นในเวลาที่ต่างกันเรียกว่าการขยายตัวของเวลามหภาคและการประเมินผลเวลา
นี่คือbound-and-true-p
ลักษณะของคำจำกัดความของลักษณะ:
(defmacro bound-and-true-p (var)
"Return the value of symbol VAR if it is bound, else nil."
`(and (boundp (quote ,var)) ,var))
ใช้มาโครของเครื่องอ่านซึ่งแตกต่างจากมาโคร lisp (เพิ่มเติมจากด้านล่าง) หากต้องการไม่ทำให้ซับซ้อนมากขึ้นอีกโปรดอย่าใช้มาโครของเครื่องอ่าน:
(defmacro bound-and-true-p (var)
"Return the value of symbol VAR if it is bound, else nil."
(list 'and (list 'boundp (list 'quote var)) var))
ถ้าคุณเขียน
(bound-and-true-p my-variable)
นั่นคือ "แปล" เป็นครั้งแรก
(and (boundp 'my-variable) my-variable)
และนั่นคือการประเมินผลตอบแทนnil
ถ้าmy-variable
ไม่ใช่boundp
หรือมิฉะนั้นมูลค่าของmy-variable
(ซึ่งแน่นอนว่าสามารถเป็นได้nil
)
คุณอาจสังเกตเห็นว่าการขยายตัวไม่ใช่
(and (boundp (quote my-variable)) my-variable)
อย่างที่เราคาดหวัง quote
เป็นรูปแบบพิเศษไม่ใช่แมโครหรือฟังก์ชัน เช่นเดียวกับมาโครรูปแบบพิเศษสามารถทำอะไรก็ได้กับข้อโต้แย้งของพวกเขา รูปแบบพิเศษนี้จะคืนค่าอาร์กิวเมนต์ของมันที่นี่เป็นสัญลักษณ์แทนค่าตัวแปรของสัญลักษณ์ นั่นคือจุดประสงค์เดียวของรูปแบบพิเศษนี้: การป้องกันการประเมิน! มาโครไม่สามารถทำได้ด้วยตนเองพวกเขาจำเป็นต้องใช้quote
เพื่อทำเช่นนั้น
ดังนั้นสิ่งที่เกิดขึ้นด้วย'
? มันเป็นแมโครผู้อ่านซึ่งเป็นที่กล่าวถึงข้างต้นไม่ได้เช่นเดียวกับแมโครกระเพื่อม แม้ว่าแมโครจะใช้ในการแปลงรหัส / ข้อมูล แต่แมโครของเครื่องอ่านจะใช้ก่อนหน้านี้เมื่ออ่านข้อความเพื่อแปลงข้อความนั้นเป็นรหัส / ข้อมูล
'something
เป็นรูปแบบย่อสำหรับ
(quote something)
`
ใช้ในความหมายที่แท้จริงของbound-and-true-p
ยังเป็นมาโครอ่าน หากเครื่องหมายคำพูดเป็นสัญลักษณ์ใน`symbol
นั้นเทียบเท่ากับ'symbol
แต่เมื่อใช้ในการอ้างอิงรายการตามที่`(foo bar ,baz)
มันทำงานแตกต่างกันในรูปแบบที่จะนำหน้าด้วย,
จะถูกประเมิน
`(constant ,variable)
เทียบเท่ากับ
(list (quote constant) variable))
สิ่งนี้ควรตอบคำถามที่ว่าทำไมบางครั้งสัญลักษณ์ที่ไม่ได้อ้างอิงถูกประเมิน (แทนที่ด้วยค่า) และบางครั้งก็ไม่ แมโครสามารถใช้quote
เพื่อป้องกันไม่ให้มีการประเมินสัญลักษณ์
แต่ทำไมbound-and-true-p
มาโครถึงboundp
ไม่ได้? เราจะต้องสามารถตรวจสอบว่าสัญลักษณ์ใด ๆ ที่ไม่รู้จักจนถึงเวลาทำงานนั้นถูกผูกไว้เป็นสัญลักษณ์หรือไม่ สิ่งนี้จะเป็นไปไม่ได้หากboundp
มีการเสนอราคาโดยอัตโนมัติ
bound-and-true-p
ใช้เพื่อตรวจสอบว่ามีการกำหนดตัวแปรที่รู้จักและใช้ค่าของมัน สิ่งนี้มีประโยชน์หากไลบรารีมีการอ้างอิงเพิ่มเติมในไลบรารีบุคคลที่สามเช่นเดียวกับใน:
(defun foo-get-value ()
(or (bound-and-true-p bar-value)
;; we have to calculate the value ourselves
(our own inefficient or otherwise undesirable variant)))
bound-and-true-p
อาจจะหมายถึงฟังก์ชั่นและต้องมีการโต้แย้งที่จะยกมา '
แต่เพราะมันมีไว้สำหรับกรณีที่คุณรู้ล่วงหน้าสิ่งที่ตัวแปรคุณดูแลเกี่ยวกับแมโครถูกใช้ในการช่วยให้คุณประหยัดจากที่มีการพิมพ์
setq
ย่อมาset quoted
และ(set 'some-variable "less")
แต่เดิมเป็นแมโครที่ขยายตัวใน โดยทั่วไปแล้ว Elisp ไม่สอดคล้องกันอย่างมากกับข้อโต้แย้งที่ยกมาและไม่มีข้อโต้แย้ง แต่ฟังก์ชั่นใด ๆ (ไม่ใช่มาโคร) ที่จำเป็นต้องมีปฏิสัมพันธ์กับตัวแปรแทนค่าจะใช้อาร์กิวเมนต์ที่ยกมา (setq
เป็นข้อยกเว้นที่สำคัญ)