สัญลักษณ์ที่อยู่ในตำแหน่งที่ไม่ใช่ฟังก์ชั่นถือเป็นชื่อของตัวแปร 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เป็นข้อยกเว้นที่สำคัญ)