مشكلة مع "دع" بناء الجملة في المخطط
سؤال
سأمر عبر "هيكل وتفسير برامج الكمبيوتر" وأواجه بعض المتاعب في القيام بأحد التمارين ( 2.1 ). أنا أرمز في drracket في وضع R5RS.
هذا هو الكود الخاص بي:
(define (make-rat n d)
(let (((c (gcd n d))
(neg (< (* n d) 0))
(n (/ (abs n) c))
(d (/ (abs d) c)))
(cons (if neg (- n) n) d))))
وإليك رسالة الخطأ التي تعطيني Drracket:
let: bad syntax (not an identifier and expression for a binding) in: ((c (gcd n d)) (neg (< (* n d) 0)) (pn (/ (abs n) c)) (pd (/ (abs d) c)))
أعتقد أنني أفسدت دعونا بناء الجملة. لكنني لست متأكدًا من كيفية إصلاحه.
المحلول
كما يشير التحرير الخاص بك ، فأنت تستخدم معرف C قبل الأوان. (وهذا هو السبب في أنه لا يعمل بعد إصلاح قضية بناء الجملة من الأقواس الإضافية.) معرفات "دع" لا ترى بعضها البعض. ستحتاج إلى أن تعشق الثلاثة الثانية ، دعنا ندعو تحت الأول.
(let ((c (gcd ...)))
(let ((...))
exps ...))
لا أتذكر متى/إذا قام SICP بتقديم نماذج أخرى للسماح ، ولكن إذا كنت عالقًا باستخدام الكثير من المتداخلة ، فيمكنك الاستخدام let*
حيث يكون كل معرف لاحق في نطاق كل ما سبق. أي أن التعارمين التاليين متكافئان:
(define foo
(let* ((a 1)
(b (+ 1 a))
(c (+ 1 b)))
(+ 1 c)))
(define foo
(let ((a 1))
(let ((b (+ 1 a)))
(let ((c (+ 1 b)))
(+ 1 c)))))
يمكن أن تكون قواعد النطاق الخاصة بأشكال LET المختلفة كثيرًا للمبتدئين ، لسوء الحظ.
نصائح أخرى
أضفت مجموعة إضافية من الأقواس حول الإعلانات المتغيرة ، يصيح.
أيضًا ، نظرًا لأنني اعتدت C لتعريف N و D ، كان عليّ أن أتغير إلى السماح للسماح* لجعله يعمل بشكل صحيح
الرمز الثابت الخاص بي:
(define (make-rat n d)
(let* ((c (gcd n d))
(neg (< (* n d) 0))
(n (/ (abs n) c))
(d (/ (abs d) c)))
(cons (if neg (- n) n) d)))
جرب هذا:
(define (make-rat n d)
(let ([c (gcd n d)]
[neg (< (* n d) 0)]
[n (/ (abs n) c)]
[d (/ (abs d) c)])
(cons (if neg
(- n)
n)
d)))