2016-07-13 2 views
0

In SICP Übung 1.37Kann nicht verstehen, wie wir eine Prozedur als Aktualparameter angeben können, wenn formale Parameter als Werte im Schema verwendet werden?

Section 1.3.3 in SICP Scrollen Sie bis zum Ende des Abschnitts (kurz vor 1.3.4), um die Übung [3. Übung im Abschnitt] zu finden.

Nach dem Problem, ich definiert cont-Frac als

(define (cont-frac n d k) 
    (if (= k 0) 
    0 
    (/ n (+ d (cont-frac n d (- k 1)))) 
    ) 
) 

Link to solution for the exercise

Nach der Lösung verknüpfen Sie den obigen Code konsistent zu sein scheint. Das Problem tritt im zweiten Teil der Lösung auf, wenn n und d als (lamda (i) 1.0) in Teil (a) der Lösung substituiert werden, was ein Verfahren ist.

Ich kann nicht verstehen, wie dies funktioniert, wenn in der Prozedur cont-frac ersetzt wird. Als ich versuchte, ist es der Fehler, der falsche Art von Argument sagt


Edit 1

Ich habe meine ganze Lösung gegeben. Es löst das Problem, erfasst aber nicht die Essenz des Abschnitts. Dies ist die Lösung für die Übungen 1.37, 1.38 und 1.39. Das Programm nicht nicht verwendet Verfahren als Allgemeines Verfahren, welche Lösungen der unten stehenden Links tun Solution to 1.37, Solution to 1.38 und Solution to 1.39

Im folgende Programm
in dem Verfahren phi und e-2-val ist k die Schritte nicht in Fortsetzung Fraktion
in dem Verfahren tan ist k Winkel im Bogenmaß (No von Schritten 1000 zum genauen Wert)

#!/usr/local/bin/guile \ 
-e main -s 
!# 
(define (finite-cont-frac n d k) 
    (if (= k 0) 
     0 
     (/ n (+ d (finite-cont-frac n d (- k 1)))))) 

(define (e-2 n d k1 c k) 
    (define (d-val) 
     (if (= (modulo k1 3) 1) 
      (+ c 2) 
      1)) 
    (define (c-val) 
     (if (= (d-val) 1) c (d-val))) 
    (if (= k 0) 
     0 
     (/ n (+ (d-val) (e-2 n (d-val) (+ k1 1) (c-val) (- k 1)))))) 

(define (tan-cf n k d k1) 
    (define (d-val) 
     (if (= k1 0) 1 (+ d 2))) 
    (if (= k 0) 
     0 
     (/ n (+ (d-val) (tan-cf n (- k 1) (d-val) (+ k1 1)))))) 

(define (tan-man x kk) 
    (let ((a (- (* x x)))) 
     (tan-cf a kk 1 0))) 
(define rrr 80.0) 
(define (main args) 
    (let* ((k (string->number (list-ref args 1))) 
      (phi (/ 1.0 (finite-cont-frac 1.0 1.0 k))) 
      (e-2-val (e-2 1.0 1 0.0 0 k)) 
      (tt (/ (tan-man k 1000) (- 0.0 k)))) 
     (display tt) 
     (newline))) 

+0

Beachten Sie, dass schließenden Klammern nicht auf ihre eigene Linie wie C Programmierung curlies sein sollte. Sie sollten in der Zeile oberhalb der letzten schließenden Klammer stehen. – Sylwester

+0

Ist es wie eine idiomatische Regel? Weil das keinen Fehler gibt. –

+1

* TL; DR Es ist ein Konsens. * Es ist wahr, dass es die Interpretationen nicht beeinflusst. Sie könnten ein Symbol oder eine Klammer in jeder Zeile haben, die Ihr Beispiel mehrere Seiten lange Zeile von unlesbarem, aber perfekt ausführbarem Code darstellt. Lisp hat sehr wenig Struktur in seinem Code, so wie Sie den Code stylen, ist wie Sie es lesbar machen. Es gibt [style guides] (http://mumble.net/~campbell/scheme/style.txt), die lispers zustimmen und Fragen dazu auf [PSE] (http://programmers.stackexchange.com/questions/99229/why-does-the-lisp-community-prefer-to-acum-um-all-the-parentheses-at-the-end) – Sylwester

Antwort

1

Die verknüpfte Antwort sieht falsch aus, Sie sollten Prozeduren übergeben, nicht Nummern als tatsächliche Parameter. Mit Hilfe eines Helfer Verfahren accumulate genannt:

(define (accumulate combiner null-value term1 term2 a next b) 
    (if (> a b) 
     null-value 
     (combiner (term1 a) 
       (term2 a) 
       (accumulate combiner 
          null-value 
          term1 
          term2 
          (next a) 
          next 
          b)))) 

(define (cont-frac n d k) 
    (accumulate (λ (x y rec) (/ x (+ y rec))) 
       0 n d 1 add1 k)) 

Jetzt können wir die Prozedur aufrufen, wie erwartet:

(cont-frac (lambda (i) 1.0) 
      (lambda (i) 1.0) 
      10) 
=> 0.6179775280898876 
+0

Ich habe gerade erkannt, welchen Fehler ich gemacht habe, und bin zum Stackoverflow zurückgekehrt, um die Frage zu löschen. Danke für die Lösung. –

+0

Die verknüpfte Antwort ist richtig. Meine Lösung ist für den Abschnitt nicht geeignet. Meine Lösung ist in gewisser Hinsicht nicht falsch, aber die Lösung in der Verbindung verwendet n und d als Prozeduren, die k als Parameter übergeben. Die Lösung in der Verbindung ist sehr verallgemeinert, ich musste eine Menge anderer Prozeduren schreiben, um n und d in den Übungen 1.38 und 1.39 zu definieren, aber unter Verwendung der verallgemeinerten Lösung der Verbindung war es ausreichend, λ-Funktionen zu übergeben. –

Verwandte Themen