سؤال

سأمر عبر "هيكل وتفسير برامج الكمبيوتر" وأواجه بعض المتاعب في القيام بأحد التمارين ( 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)))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top