ฉันกำลังพยายามแทนที่ IF ในเครื่อง (จุดประสงค์คือการฝัง DSL)
พฤติกรรมทำให้ฉันสับสนจริงๆ ใน SBCL:
(macrolet ((if (x) x))
(if 'x)) ; => X
(macrolet ((if (x) x))
(let ((x 2))
(if 'x))) ; => Execution of a form compiled with errors.
(let ((x 2))
(macrolet ((if (x) x))
(if 'x))) ; => Execution of a form compiled with errors.
มีความคิดบ้างไหมว่าทำไมมันถึงมีพฤติกรรมแบบนั้น?
ฉันยังลองใช้สัญลักษณ์ฝึกงาน xxx::if
แต่ก็ไม่มีโชค SBCL ยังคงคิดว่ามันเป็นตัวดำเนินการพิเศษไม่ว่าจะอยู่ในแพ็คเกจใดก็ตาม
มีการแทนที่โอเปอเรเตอร์พิเศษในเครื่องอย่างถูกต้องหรือไม่? หรืออย่างน้อยก็แทนที่ตัวอักษร ซึ่งหมายความว่าเราสามารถพิมพ์ if
และขยายได้ (การใช้เวทย์มนตร์ของผู้อ่านอาจช่วยได้ แต่ฉันไม่คุ้นเคย)
อัปเดต (แก้ไขแล้ว): ข้อความแสดงข้อผิดพลาดที่แน่นอนในวันที่ 2 ที่ฉันได้รับ
Execution of a form compiled with errors.
Form:
(MACROLET ((IF (X)
X))
(IF 'X))
Compile-time error:
Lock on package COMMON-LISP violated when binding IF as a local macro while in
package COMMON-LISP-USER.
See also:
The SBCL Manual, Node "Package Locks"
The ANSI Standard, Section 11.1.2.1.2
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR]
อันที่ 3 ก็คล้ายๆ กัน
ปรากฎว่าการใช้ xxx::if
ทำให้ใช้งานได้ ฉันเพียงแต่ไม่ได้แชโดว์สัญลักษณ์อย่างถูกต้องในการทดลองครั้งก่อน
วิธีง่ายๆ ในการทำงาน:
(defpackage p)
(macrolet ((p::if (x) x))
(let ((x 2))
(p::if 'x))) ; => X
หากคุณต้องการสืบทอดตัวดำเนินการ CL ตามปกติอื่นๆ ใน P
ให้ทำ (defpackage p (:use :cl) (:shadow if))
p::if
ฉันไม่ได้รับข้อผิดพลาดจากเวอร์ชัน 2 และ 3 เพียงคำเตือนเกี่ยวกับตัวแปร X ที่ไม่ได้ใช้ ซึ่งเข้าใจได้เนื่องจากคุณกำลังอ้างอิงx
ในส่วนเนื้อความ ไม่ได้ใช้ตัวแปร - person Barmar   schedule 29.02.20202
โดยไม่มีคำเตือนหากฉันลบเครื่องหมายคำพูดก่อนx
- person Barmar   schedule 29.02.2020sb-ext:unlock-package :cl
อาจรบกวนการล็อคแพ็คเกจใช่ไหม ให้ฉันลองใช้ REPL ใหม่ - person BlueFlo0d   schedule 29.02.2020(let ((x 2)) (macrolet ((cl-user::if (x) x)) (cl-user::if 'x)))
ในการทำซ้ำครั้งใหม่ ฉันใช้ SBCL 1.5.1 การใช้งานนี้ขึ้นอยู่กับหรือไม่? - person BlueFlo0d   schedule 29.02.2020cl-user::if
สร้างแพ็คเกจของคุณเองและใช้mypackage::if
- person Barmar   schedule 29.02.2020(defpackage p (:use :cl) (:shadow if)) (macrolet ((p::if (x) x)) (p::if 'x))
ใช้งานได้สำหรับฉันตอนนี้ ขอบคุณมาก! - person BlueFlo0d   schedule 29.02.2020(make-package 'p)
จากนั้นฉันก็ใช้p::if
ไม่จำเป็นต้องสืบทอดหรือทำเงาอะไร - person Barmar   schedule 29.02.2020(defpackage p)
และ(make-package 'p)
นั้นไม่ได้ระบุไว้สำหรับ Common Lisp แบบพกพา ไม่ได้กำหนดว่าแพ็คเกจใด ใช้ SBCL ใช้ ฉาวโฉ่ไม่มีเลย - person Rainer Joswig   schedule 29.02.2020