1

「コンピュータプログラムの構造と解釈」を行っていますが、演習の1つ(2.1)を実行するのに少し問題があります。R5RSモードのDrRacketでコーディングしています。

これが私のコードです:

(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)))

構文をめちゃくちゃにしたと思います。しかし、私はそれを修正する方法がわかりません。

4

3 に答える 3

4

変数宣言の周りに括弧のセットを追加しました。

また、cを使用してnとdを定義したので、letをlet *に変更して、正しく機能させる必要がありました。

私の修正コード:

(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)))
于 2010-09-08T03:16:58.253 に答える
3

編集が示すように、c識別子を時期尚早に使用しています。(これが、余分な括弧の構文の問題を修正した後、機能しない理由です。)「let」内の識別子は互いに見えません。2番目の3つのレットを最初のレットの下にネストする必要があります。

    (let ((c (gcd ...)))
      (let ((...))
        exps ...))

SICPが他のletフォームを導入した時期/場合は思い出せませんが、ネストされたletを多数使用している場合は、let*後続の各識別子が以前のすべての範囲内にあるものを使用できます。つまり、次の2つの定義は同等です。

(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形式のスコープ規則は、初心者にとっては少し難しい場合があります。

于 2010-09-08T13:11:21.917 に答える
2

これを試して:

(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)))
于 2010-09-08T03:14:25.283 に答える