2009-05-01 6 views
8

Ich bin gerade dabei, Scheme zu lernen. Ich habe kürzlich (zu viel!) Zeit damit verbracht, einen Fehler in einem Programm zu finden, bevor ich merkte, dass ich das 'else' Wort in einer cond-Klausel verpasste. Aber das Verhalten unter solchen Umständen scheint etwas seltsam zu sein. Beim Experimentieren mit den Bedingungen mit nur einem einfachen Programm (unten) wird das 'was auch immer' wie erwartet in der else-Klausel angezeigt, aber auch angezeigt, aber ohne das 'else' wird es mit den umgebenden doppelten Anführungszeichen und dem uninterpretierten neuen angezeigt Linie buchstäblich gedruckt. Kann mir jemand erklären, was passiert? TIA.Was passiert in einer Scheme 'cond' Klausel, wenn 'else' weggelassen wird?

(define (foo x) 
    (cond ((eq? x 0) (display "zero\n")) 
      (display "whatever\n"))) 

    (define (bar x) 
    (cond ((eq? x 0) (display "zero\n")) 
      (else (display "whatever\n")))) 

In the repl window: 
Welcome to DrScheme, version 4.1.5 [3m]. 
Language: Pretty Big; memory limit: 128 megabytes. 
> (foo 0) 
zero 
> (bar 0) 
zero 
> (foo 2) 
"whatever\n" 
> (bar 2) 
whatever 
> 

Antwort

16

"else" ist nur ein Synonym für "wahr". Die Art, Cond zu lesen, ist eine Testreihe, bei der der erste Test, der wahr ist, das zu evaluierende Formular verursacht.

(cond ((test) (do this)) 
     ((test) (do this))) 

Hier ist Ihre erste

(cond ((eq? x 0) (display "zero\n")) 
     (display "whatever\n"))) 

cond bei (eq? x 0) sieht und bestimmt das ist falsch. Die nächste Klausel lautet (display "whatever\n"). Es sieht display, und da display nicht nil ist, ist es wahr. Es wertet dann die Zeichenkette "whatever\n" aus, die sich einfach zu sich selbst auswertet. Also ist der Wert des Cond dann "whatever\n".

Jetzt ist hier, Sie zweite:

(cond ((eq? x 0) (display "zero\n")) 
     (else (display "whatever\n")))) 

Hier ist der erste Test falsch ist, und es geht auf die zweite, die else ist und die true ergibt. (Wenn Sie darüber nachdenken, ist das, was das "sonst" in einem normalen Wenn-dann-sonst bedeutet: "Wahr für alle Fälle, in denen keiner der vorherigen Tests wahr war.")

Jetzt das Formular, das darauf folgt ist (display "whatever\n"). Das ist eine Funktion, die das Zeichenfolgenargument an die Konsole sendet und nichts zurückgibt, weil das Display dies tut. In einem anderen Schema könnte es den Zeichenfolgenwert zurückgeben und es auch ausdrucken. In diesem Fall würden Sie

whatever 
"whatever\n" 
+1

Tatsächlich ist 'else' in R5RS Scheme zumindest kein Synonym von true. Es ist nur eine Kennung, die das Makro erkennt. –

+1

die operational noch ein Synonym für wahr ist. –

9

In der foo Funktion, die cond Anweisung wertet display als Bedingung zu testen. Da es tatsächlich ein Symbol gibt, das display genannt wird, wird es als wahr ausgewertet, so dass das "whatever\n" dann als das Ergebnis von (foo 2) ausgewertet wird.

+0

sehen. Ihre Antwort war wunderbar klar und ebenso verdient akzeptierte Antwort. Ich habe es Charlie für sein Tippen gegeben. Vielen Dank. – Leonard

+0

Keine Sorge, er verdient es! –

+0

Nun, ich habe dich trotzdem hochgestuft, Greg. –