diff options
-rw-r--r-- | doc/r5rs/Makefile.am | 4 | ||||
-rw-r--r-- | doc/r5rs/r5rs.de.texi | 8805 | ||||
-rw-r--r-- | doc/translation-rationale-de | 263 |
3 files changed, 9071 insertions, 1 deletions
diff --git a/doc/r5rs/Makefile.am b/doc/r5rs/Makefile.am index c64e4ffb1..8f33c47f5 100644 --- a/doc/r5rs/Makefile.am +++ b/doc/r5rs/Makefile.am @@ -21,6 +21,8 @@ AUTOMAKE_OPTIONS = gnu -info_TEXINFOS = r5rs.texi +info_TEXINFOS = \ + r5rs.texi \ + r5rs.de.texi EXTRA_DIST = ChangeLog-2008 diff --git a/doc/r5rs/r5rs.de.texi b/doc/r5rs/r5rs.de.texi new file mode 100644 index 000000000..d5b8a1246 --- /dev/null +++ b/doc/r5rs/r5rs.de.texi @@ -0,0 +1,8805 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename r5rs.de.info +@documentlanguage de +@documentencoding UTF-8 +@settitle Revised(5) Scheme + +@c Translation of Guile's copy of r5rs.texi, see doc/r5rs/r5rs.texi. + +@c \documentclass[twoside]{algol60} + +@c \pagestyle{headings} +@c \showboxdepth=0 + + + +@c \def\headertitle{Revised$^{5}$ Scheme} +@c \def\integerversion{5} + +@c Sizes and dimensions + +@c \topmargin -.375in % Nominal distance from top of page to top of + +@c box containing running head. +@c \headsep 15pt % Space between running head and text. + +@c \textheight 663pt % Height of text (including footnotes and figures, + +@c excluding running head and foot). + +@c \textwidth 523pt % Width of text line. +@c \columnsep 15pt % Space between columns +@c \columnseprule 0pt % Width of rule between columns. + +@c \parskip 5pt plus 2pt minus 2pt % Extra vertical space between paragraphs. +@c \parindent 0pt % Width of paragraph indentation. +@c \topsep 0pt plus 2pt % Extra vertical space, in addition to + +@c \parskip, added above and below list and + +@c paragraphing environments. + +@c \oddsidemargin -.5in % Left margin on odd-numbered pages. +@c \evensidemargin -.5in % Left margin on even-numbered pages. + +@c % End of sizes and dimensions + +@paragraphindent 0 +@c %**end of header +@c syncodeindex fn cp + +@ifinfo +@dircategory Die Algorithmische Sprache Scheme +@direntry +* R5RS-de: (r5rs-de). Der Revised(5) Report on Scheme (deutsch). +@end direntry +@end ifinfo + + +@c \parindent 0pt %!! 15pt % Width of paragraph indentation. + + @b{20. Februar 1998} +@c \hfil \today{} + +@c @include{first} +@titlepage + +@c HTML first page +@title Scheme +@subtitle Revised(5) Report on the Algorithmic Language Scheme +@c First page + +@c \thispagestyle{empty} + +@c \todo{"another" report?} + +@quotation +Überarbeiteter^5 Bericht über die Algorithmische Sprache Scheme. +@end quotation + + +@author R@sc{ICHARD} K@sc{ELSEY}, W@sc{ILLIAM} C@sc{LINGER} +@author @sc{UND} J@sc{ONATHAN} R@sc{EES} (@i{Herausgeber}) +@author H. A@sc{BELSON} +@author R. K. D@sc{YBVIG} +@author C. T. H@sc{AYNES} +@author G. J. R@sc{OZAS} +@author N. I. A@sc{DAMS IV} +@author D. P. F@sc{RIEDMAN} +@author E. K@sc{OHLBECKER} +@author G. L. S@sc{TEELE} J@sc{R}. +@author D. H. B@sc{ARTLEY} +@author R. H@sc{ALSTEAD} +@author D. O@sc{XLEY} +@author G. J. S@sc{USSMAN} +@author G. B@sc{ROOKS} +@author C. H@sc{ANSON} +@author K. M. P@sc{ITMAN} +@author M. W@sc{AND} + + +@c {\it Dedicated to the Memory of ALGOL 60} +@i{Der Erinnerung an Robert Hieb gewidmet} +@c [For the macros in R5RS -RK] + + + + +@majorheading Zusammenfassung + + +[Der englische Originaltext dieses Berichts] enthält eine normative +Beschreibung der Programmiersprache Scheme. Scheme ist ein Dialekt der +Lisp-Programmiersprache mit statischen Sichtbarkeitsbereichen und echter +Endrekursion, der von Guy Lewis Steele Jr.@: und Gerald Jay Sussman +erfunden wurde. Er wurde mit einem Augenmerk auf besonders klarer und +einfacher Semantik entworfen mit nur wenigen verschiedenen Arten, +Ausdrücke zu bilden. Eine große Vielfalt von Programmierparadigmen, +unter ihnen imperative, funktionale und nachrichtenübermitteltende +Stile, finden in Scheme eine gelegene Ausdrucksweise. + +Diese Einleitung bietet eine kurze Geschichte der Sprache und des +Berichts. + +Die ersten drei Kapitel zeigen die grundlegenden Ideen der Sprache und +beschreiben die Konventionen der Notation, mit der die Sprache +beschrieben und Programme in der Sprache geschrieben werden. + +Die Kapitel @ref{Ausdrücke} und @ref{Programmstruktur} beschreiben +Syntax und Semantik von Ausdrücken, Programmen und Definitionen. + +Das Kapitel @ref{Standardprozeduren} beschreibt die in Scheme +eingebauten Prozeduren, wozu alle Grundbausteine der Sprache zur +Datenmanipulation und zur Ein- und Ausgabe gehören. + +Das Kapitel @ref{Formale Syntax und Semantik} bietet eine formale Syntax +für Scheme, geschrieben in erweiterter BNF, zusammen mit einer formalen +denotationellen Semantik. Auf die formale Syntax und Semantik folgt ein +Beispiel der Nutzung der Sprache. + +Der Bericht endet mit einer Liste von Verweisen und einem alphabetischen +Register. + +@ignore todo +expand the summary so that it fills up the column. +@end ignore + + +@c \vfill +@c \begin{center} +@c {\large \bf +@c *** DRAFT*** \\ +@c %August 31, 1989 +@c \today +@c }\end{center} + + + + + +@c \addvspace{3.5pt} % don't shrink this gap +@c \renewcommand{\tocshrink}{-3.5pt} % value determined experimentally + + + + + + +@page + +@end titlepage + +@c INFO first page +@ifnottex + +@c First page + +@c \thispagestyle{empty} + +@c \todo{"another" report?} + + +@node top, Einleitung, (dir), (dir) +@top Revised(5) Report on the Algorithmic Language Scheme + +@sp 1 + + +@quotation +Überarbeiteter^5 Bericht über die Algorithmische Sprache Scheme. + +R@sc{ichard} K@sc{elsey}, W@sc{illiam} C@sc{linger und} J@sc{onathan} R@sc{ees} (@i{Herausgeber}) +@sp 1 +@multitable @columnfractions 0.25 0.25 0.25 0.25 +@item H. A@sc{belson} @tab R. K. D@sc{ybvig} @tab C. T. H@sc{aynes} @tab G. J. R@sc{ozas} +@item N. I. A@sc{dams IV} @tab D. P. F@sc{riedman} @tab E. K@sc{ohlbecker} @tab G. L. S@sc{teele} J@sc{r}. +@item D. H. B@sc{artley} @tab R. H@sc{alstead} @tab D. O@sc{xley} @tab G. J. S@sc{ussman} +@item G. B@sc{rooks} @tab C. H@sc{anson} @tab K. M. P@sc{itman} @tab M. W@sc{and} +@item +@end multitable +@end quotation + + +@sp 2 + +@c {\it Dedicated to the Memory of ALGOL 60} +@i{Der Erinnerung an Robert Hieb gewidmet} +@c [For the macros in R5RS -RK] + +@sp 3 + + + + +@majorheading Zusammenfassung + + +[Der englische Originaltext dieses Berichts] enthält eine normative +Beschreibung der Programmiersprache Scheme. Scheme ist ein Dialekt der +Lisp-Programmiersprache mit statischen Sichtbarkeitsbereichen und echter +Endrekursion, der von Guy Lewis Steele Jr.@: und Gerald Jay Sussman +erfunden wurde. Er wurde mit einem Augenmerk auf besonders klarer und +einfacher Semantik entworfen mit nur wenigen verschiedenen Arten, +Ausdrücke zu bilden. Eine große Vielfalt von Programmierparadigmen, +unter ihnen imperative, funktionale und nachrichtenübermitteltende +Stile, finden in Scheme eine gelegene Ausdrucksweise. + +Diese Einleitung bietet eine kurze Geschichte der Sprache und des +Berichts. + +Die ersten drei Kapitel zeigen die grundlegenden Ideen der Sprache und +beschreiben die Konventionen der Notation, mit der die Sprache +beschrieben und Programme in der Sprache geschrieben werden. + +Die Kapitel @ref{Ausdrücke} und @ref{Programmstruktur} beschreiben +Syntax und Semantik von Ausdrücken, Programmen und Definitionen. + +Das Kapitel @ref{Standardprozeduren} beschreibt die in Scheme +eingebauten Prozeduren, wozu alle Grundbausteine der Sprache zur +Datenmanipulation und zur Ein- und Ausgabe gehören. + +Das Kapitel @ref{Formale Syntax und Semantik} bietet eine formale Syntax +für Scheme, geschrieben in erweiterter BNF, zusammen mit einer formalen +denotationellen Semantik. Auf die formale Syntax und Semantik folgt ein +Beispiel der Nutzung der Sprache. + +Der Bericht endet mit einer Liste von Verweisen und einem alphabetischen +Register. + +@ignore todo +expand the summary so that it fills up the column. +@end ignore + + +@c \vfill +@c \begin{center} +@c {\large \bf +@c *** DRAFT*** \\ +@c %August 31, 1989 +@c \today +@c }\end{center} + + + + + +@c \addvspace{3.5pt} % don't shrink this gap +@c \renewcommand{\tocshrink}{-3.5pt} % value determined experimentally + +@unnumbered Inhalt + +@menu +* Einleitung:: +* Übersicht von Scheme:: +* Schreibkonventionen:: +* Grundkonzepte:: +* Ausdrücke:: +* Programmstruktur:: +* Standardprozeduren:: +* Formale Syntax und Semantik:: +* Bemerkungen:: +* Weiteres Material:: +* Beispiel:: +* Bibliographie:: +* Register:: +@end menu + + + + + +@page + +@end ifnottex + + +@c @include{intro} +@node Einleitung, Übersicht von Scheme, top, top +@unnumbered Einleitung + +@menu +* Hintergrund:: +* Anerkennungen:: +@end menu + + + + +Programmiersprachen sollten nicht entworfen werden, indem man +Funktionalitäten über Funktionalitäten schichtet, sondern indem man +Schwächen und Einschränkungen entfernt, die es so erscheinen lassen, +als wären weitere Funktionalitäten nötig. Scheme demonstriert, dass +eine sehr kleine Zahl von Regeln, wie Ausdrücke gebildet werden, ohne +Einschränkungen, wie man sie zusammenfügt, genügen, um eine praktische +und effiziente Programmiersprache zu bilden, die flexibel genug ist, +die meisten größeren Programmierparadigmen, die heute genutzt werden, +zu bedienen. + +@c Scheme hat die Entwicklung von Lisp beeinflusst. +Scheme +war eine der ersten Programmiersprachen, die Prozeduren erster Klasse +wie im Lambda-Kalkül enthält, und hat so bewiesen, wie nützlich +statische Sichtbarkeitsregeln und eine Blockstruktur in einer dynamisch +typisierten Sprache sind. Scheme war der erste größere Dialekt von +Lisp, der Prozeduren von Lambda-Ausdrücken und Symbolen unterscheidet, +der eine einzelne lexikalische Umgebung für alle Variablen benutzt und +der die Operatorposition eines Prozeduraufrufs auf gleiche Weise +auswertet wie eine Operandenposition. Indem Scheme Iterationen allein +mit Prozeduraufrufen ausdrückt, betonte Scheme, dass endrekursive +Prozeduraufrufe im Kern goto-Ausdrücke, die Argumente übergeben, sind. +Scheme war die erste weit verbreitete Programmiersprache, die +Ausstiegsprozeduren erster Klasse, aus denen alle anderen +Programmflussstrukturen synthetisiert werden können, rückhaltlos +unterstützte. Eine spätere Fassung von Scheme führte das Konzept +exakter und inexakter Zahlen ein, eine Erweiterung der generischen +Arithmetik von Common Lisp. Vor weniger langer Zeit wurde Scheme zur +ersten Programmiersprache, die hygienische Makros unterstützt, welche +Syntaxerweiterungen von in Blöcken strukturierten Sprachen auf +konsistente und zuverlässige Weise zulassen. + + +@node Hintergrund, Anerkennungen, Einleitung, Einleitung +@unnumberedsec Hintergrund + + +Die erste Beschreibung von Scheme wurde im Jahr 1975 [Scheme75] +geschrieben. Ein überarbeiteter Bericht („revised report``) [Scheme78] +@ignore todo +italicize or not? +@end ignore +erschien 1978. Er beschrieb die Entwicklung der Sprache, als seine +MIT-Implementierung ausgebaut wurde, um einen innovativen Übersetzer +(Compiler) [Rabbit]. Drei separate Projekte begannen 1981 und 1982, um +Varianten von Scheme für Kurse am MIT, Yale und der Indiana University +zu benutzen [Rees82], [MITScheme], [Scheme311]. Ein einführendes +Informatiklehrbuch, das Scheme benutzt, wurde 1984 veröffentlicht +[SICP]. + + +Als sich Scheme weiter verbreitete, +fingen lokale Dialekte an, auseinanderzugehen, bis Studenten und +Forscher Probleme bekamen, den an anderen Orten geschriebenen Code zu +verstehen. +Fünfzehn Repräsentanten der größeren Implementierungen von Scheme +versammelten sich deshalb im Oktober 1984, um an einem besseren und von +mehr Leuten anerkannten Standard für Scheme zu arbeiten. + +Ihr Bericht [RRRS] wurde am MIT und der Indiana University im Sommer +1985 veröffentlicht. Weitere Revisionen fanden im Frühling 1986 [R3RS] +und im Frühling 1988 [R4RS] statt. Der vorliegende Bericht entspricht +weiteren Revisionen, auf die man sich in einer Besprechung bei Xerox +PARC im Juni 1992 geeinigt hat. + + +@sp 3 + +Wir beabsichtigen, dass dieser Bericht der gesamten Scheme-Gemeinschaft +gehören soll, und erteilen damit die Erlaubnis, ihn gänzlich oder in +Teilen ohne Gebühr zu kopieren. Insbesondere ermutigen wir +Implementierer von Scheme, diesen Bericht als Ausgangspunkt für +Handbücher und andere Dokumentation zu benutzen und nach Bedarf zu +verändern. + + + + +@node Anerkennungen, , Hintergrund, Einleitung +@unnumberedsec Anerkennungen + + +Wir möchten den folgenden Leuten für ihre Hilfe danken: Alan Bawden, Michael +Blair, George Carrette, Andy Cromarty, Pavel Curtis, Jeff Dalton, Olivier Danvy, +Ken Dickey, Bruce Duba, Marc Feeley, +Andy Freeman, Richard Gabriel, Yekta G"ursel, Ken Haase, Robert +Hieb, Paul Hudak, Morry Katz, Chris Lindblad, Mark Meyer, Jim Miller, Jim Philbin, +John Ramsdell, Mike Shaff, Jonathan Shapiro, Julie Sussman, +Perry Wagle, Daniel Weise, Henry Wu und Ozan Yigit. +Wir danken Carol Fessenden, Daniel +Friedman und Christopher Haynes für die Erlaubnis, Text aus dem +Referenzhandbuch von Scheme 311 Version 4 zu verwenden. Wir danken +Texas Instruments, Inc. für die Erlaubnis, Text aus dem @emph{TI Scheme +Language Reference Manual}[TImanual85] zu verwenden. Wir erkennen gerne +den Einfluss der Handbücher für MIT Scheme[MITScheme], T[Rees84], Scheme +84[Scheme84], Common Lisp[CLtL] und Algol 60[Naur63] an. + +Wir danken auch Betty Dexter für die enorme Mühe, mit der sie diesen +Bericht in @TeX{} gesetzt hat, und Donald Knuth für den Entwurf des +Programms, dass ihr Ärger bereitet hat. + +Das Artificial Intelligence Laboratory des Massachusetts Institute of +Technology, das Computer Science Department der Indiana University, das +Computer and Information Sciences Department der University of Oregon +und das NEC Research Institute haben die Vorbereitung dieses Berichts +unterstützt. Unterstützung für die Arbeit des MIT kam in Teilen von der +Advanced Research Projects Agency des Department of Defense unter dem +Vertrag N00014-80-C-0505 des Office of Naval Research. Unterstützung +für die Arbeit der Indiana University gab es durch NSF-Förderungen NCS +83-04567 und NCS 83-03325. + + + + +@sp 2 + +@c \clearchapterstar{Description of the language} %\unskip\vskip -2ex +@c @include{struct} + +@c 1. Structure of the language + +@node Übersicht von Scheme, Schreibkonventionen, Einleitung, top +@chapter Übersicht von Scheme + +@menu +* Semantik:: +* Syntax:: +* Notation und Terminologie:: +@end menu + + +@node Semantik, Syntax, Übersicht von Scheme, Übersicht von Scheme +@section Semantik + + + +Dieser Abschnitt vermittelt eine Übersicht über die Semantik von Scheme. +Eine detaillierte informelle Semantik ist Thema der Kapitel +@ref{Grundkonzepte} bis @ref{Standardprozeduren}. Als Referenz bietet +der Abschnitt @ref{Formale Semantik} eine formale Semantik von Scheme. + +Scheme folgt Algol darin, dass es eine Programmiersprache mit statischen +Sichtbarkeitsbereichen ist. Jede Nutzung einer Variable wird mit einer +lexikalisch offenbaren Bindung dieser Variablen assoziiert. + +Scheme benutzt latente statt ausdrücklicher Typisierung. Typen werden +mit Werten (auch Objekte genannt) assoziiert +@cindex @w{Objekt} +statt mit Variablen. (Manche Autoren nennen latent typisierte Sprachen +auch schwach typisierte oder dynamisch typisierte Sprachen.) Andere +Sprachen mit latenten Typen sind APL, Snobol und andere Lisp-Dialekte. +Sprachen mit ausdrücklichen Typen (manchmal stark typisierte oder +statisch typisierte Sprachen genannt) sind unter Anderem Algol 60, +Pascal und C. + +Alle Objekte, die im Laufe einer Scheme-Berechnung erzeugt werden, +einschließlich Prozeduren und Fortsetzungen, haben einen +unbeschränkten Gültigkeitsbereich. Kein Scheme-Objekt wird jemals +zerstört. Der Grund dafür, dass Scheme-Implementierungen (meistens!) +nicht der Speicher ausgeht, ist, dass sie sich den von einem Objekt +belegten Speicher zurückholen dürfen, wenn sie beweisen können, dass +das Objekt keinen Einfluss auf jegliche zukünftige Berechnung haben +kann. Andere Sprachen, in denen die meisten Objekte einen +unbeschränkten Gültigkeitsbereich haben, sind unter Anderem APL und +andere Lisp-Dialekte. + +Scheme-Implementierungen sind verpflichtet, echt endrekursiv zu sein. +Dadurch kann die Ausführung einer iterativen Berechnung mit konstantem +Speicher auskommen, selbst wenn die iterative Berechnung syntaktisch +durch eine rekursive Prozedur beschrieben wird. Somit kann mit einer +echt endrekursiven Implementierung die Iteration mit der herkömmlichen +Mechanik von Prozeduraufrufen ausgedrückt werden, so dass besondere +Konstrukte für die Iteration nur als syntaktischer Zucker nützlich sind. +Siehe den Abschnitt @ref{Echte Endrekursion}. + +Scheme-Prozeduren sind selbst auch Objekte. Prozeduren können dynamisch +erstellt werden, in Datenstrukturen gespeichert werden, als Ergebnisse +von Prozeduren zurückgegeben werden und so weiter. Andere Sprachen mit +diesen Eigenschaften sind unter Anderem Common Lisp und ML. +@ignore todo +Rozas: Scheme had them first. +@end ignore + + +Eine Scheme auszeichnende Funktionalität ist, dass Fortsetzungen +(Continuations), welche in den meisten anderen Sprachen nur im +Hintergrund bestehen, auch als Objekte „erster Klasse`` gelten. +Fortsetzungen sind nützlich bei der Implementierung einer großen +Vielzahl von fortgeschrittenen Programmflussstrukturen, einschließlich +nicht-lokaler Sprünge, Rücksetzverfahren (@abbr{engl.} Backtracking) und +Ko-Routinen. Siehe den Abschnitt @ref{Programmflussfunktionalitäten}. + +Argumente an Scheme-Prozeduren werden immer als Wertparameter übergeben. +Das bedeutet, die eigentlichen Argument-Ausdrücke werden zuerst +ausgewertet, bevor die Prozedur ausgeführt wird, egal ob die Prozedur +die Ergebnisse der Auswertung überhaupt benutzt. ML, C und APL sind +drei andere Sprachen, die auch Argumente immer als Wertparameter +übergeben. Dies unterscheidet sich von Haskells verzögerter Auswertung +oder den Namensparametern von Algol 60, bei denen ein Argument-Ausdruck +erst dann ausgewertet wird, wenn sein Wert von der Prozedur gebraucht +wird. + +@ignore todo +Lisp's call by value should be explained more +accurately. What's funny is that all values are references. +@end ignore + + +Schemes Modell der Arithmetik wurde so gestaltet, dass es möglichst +unabhängig davon ist, welche bestimmten Zahlendarstellungen ein Rechner +benutzt. In Scheme ist jede ganze Zahl eine rationale Zahl, jede +rationale Zahl ist eine reelle Zahl und jede reelle Zahl ist eine +komplexe Zahl. Daher besteht in Scheme kein Unterschied zwischen +ganzzahliger und reeller Arithmetik, welcher für andere Sprachen so +wichtig ist. Stattdessen unterscheidet Scheme zwischen exakter +Arithmetik, welche dem mathematischen Ideal entspricht, und nicht +exakter Arithmetik, die Annäherungen macht. Wie in Common Lisp ist +exakte Arithmetik nicht auf ganze Zahlen beschränkt. + +@node Syntax, Notation und Terminologie, Semantik, Übersicht von Scheme +@section Syntax + + +Scheme benutzt wie die meisten Lisp-Dialekte eine vollständig +geklammerte Präfix-Notation für Programme und (andere) Daten; die +Grammatik von Scheme erzeugt eine Untersprache der für Daten benutzten +Sprache. Eine wichtige Folge dieser einfachen, einheitlichen +Darstellung ist, dass Scheme-Programme und Daten von anderen +Scheme-Programmen oft gleich behandelt werden. Zum Beispiel wertet die +@samp{Eval}-Prozedur ein als Daten ausgedrücktes Scheme-Programm aus. + +Die @samp{Read}-Prozedur führt syntaktische sowie lexikalische +Aufgliederung der von ihr gelesenen Daten durch. Die +@samp{Read}-Prozedur versteht ihre Eingabe als Daten (Abschnitt +@pxref{Externe Darstellung}) und nicht als Programm. + +Die formale Syntax von Scheme ist im Abschnitt @ref{Formale Syntax} +beschrieben. + + +@node Notation und Terminologie, , Syntax, Übersicht von Scheme +@section Notation und Terminologie + +@menu +* Grundlegende; Bibliotheks- und optionale Funktionalitäten:: +* Fehlersituationen und unbestimmtes Verhalten:: +* Eintragsformat:: +* Auswertungsbeispiele:: +* Namenskonventionen:: +@end menu + + + +@node Grundlegende; Bibliotheks- und optionale Funktionalitäten, Fehlersituationen und unbestimmtes Verhalten, Notation und Terminologie, Notation und Terminologie +@subsection Grundlegende; Bibliotheks- und optionale Funktionalitäten + + + +Jede Implementierung von Scheme muss alle nicht als @dfn{optional} +markierten Funktionalitäten von Scheme unterstützen. Implementierungen +steht es +@cindex @w{optional} +frei, optionale Funktionalitäten von Scheme wegzulassen oder +Erweiterungen anzubieten, solange diese Erweiterungen nicht im Konflikt +mit der Sprache steht, über die hier berichtet wird. Insbesondere +müssen Implementierungen portablen Code unterstützen, indem sie einen +syntaktischen Modus anbieten, der keinen Schreibkonventionen dieses +Berichts zuvorkommt. + +Um das Verständnis und die Implementierung von Scheme zu erleichtern, +sind manche Funktionalitäten als @dfn{Bibliothek}sfunktionalitäten +markiert. Diese können leicht unter Benutzung der anderen, +@cindex @w{Bibliothek} +grundlegenden, Funktionalitäten implementiert werden. Streng genommen +sind sie überflüssig, aber sie fassen übliche Muster, wie Scheme benutzt +wird, und werden daher als bequeme Kurzschreibweisen angeboten. + +@node Fehlersituationen und unbestimmtes Verhalten, Eintragsformat, Grundlegende; Bibliotheks- und optionale Funktionalitäten, Notation und Terminologie +@subsection Fehlersituationen und unbestimmtes Verhalten + + + +@cindex @w{Fehler} +Wenn dieser Bericht von einer Fehlersituation spricht, zeigt der Bericht +mit „ein Fehler wird signalisiert`` an, dass Implementierungen den +Fehler feststellen und melden müssen. Wenn in der Diskussion eines +Fehlers keine solche Formulierung auftaucht, dann müssen +Implementierungen den Fehler nicht feststellen oder melden, sind aber +dazu angehalten. Eine Fehlersituation, die Implementierungen nicht +feststellen müssen, wird in der Regel einfach als „ein Fehler`` +bezeichnet. + +Zum Beispiel ist es ein Fehler, wenn einer Prozedur ein Argument +übergeben wird, für das nicht spezifiziert wurde, dass die Prozedur +damit umgehen kann, selbst wenn solche Definitionsbereichsfehler in +diesem Bericht nur selten erwähnt werden. Implementierungen dürfen den +Definitionsbereich einer Prozedur erweitern, so dass er solche Argumente +auch einschließt. + +Dieser Bericht verwendet die Formulierung „darf eine Verletzung einer +Implementierungseinschränkung melden``, um Umstände anzuzeigen, unter +denen eine Implementierung melden darf, dass sie die Ausführung eines +korrekten Programms wegen einer von der Implementierung geforderten +Einschränkung nicht fortführen kann. Von +Implementierungseinschränkungen wird selbstverständlich abgeraten, aber +Implementierungen werden ermutigt, Verletzungen solcher +Implementierungseinschränkungen zu melden. +@cindex @w{Implementierungseinschränkung} + +Zum Beispiel darf eine Implementierung eine Verletzung einer +Implementierungseinschränkung melden, wenn sie nicht genug +Speicherkapazität hat, um ein Programm auszuführen. + +Wenn der Wert eines Ausdrucks als „unbestimmt`` angegeben wird, dann +muss dieser Ausdruck zu irgendeinem Objekt ausgewertet werden, ohne +einen Fehler zu signalisieren, aber zu welchem Wert hängt von der +Implementierung ab; dieser Bericht schreibt ausdrücklich nicht vor, +welcher Wert zurückgegeben werden sollte. +@cindex @w{unbestimmt} + +@ignore todo +Talk about unspecified behavior vs. unspecified values. +@end ignore + + +@ignore todo +Look at KMP's situations paper. +@end ignore + + + +@node Eintragsformat, Auswertungsbeispiele, Fehlersituationen und unbestimmtes Verhalten, Notation und Terminologie +@subsection Eintragsformat + + +Die Kapitel @ref{Ausdrücke} und @ref{Standardprozeduren} sind in +Einträge unterteilt. Jeder Eintrag beschreibt eine Funktionalität der +Sprache oder eine Gruppe zusammengehöriger Funktionalitäten, wobei eine +Funktionalität entweder ein syntaktisches Konstrukt oder eine eingebaute +Prozedur ist. Ein Eintrag beginnt mit einer oder mehreren Kopfzeilen +der Form + + +@noindent +@deffn {@var{Kategorie}} @var{Schablone} + +@end deffn + +für verpflichtende, grundlegende Funktionalitäten oder + + +@noindent +@deffn {@var{Qualifikator} @var{Kategorie}} @var{Schablone} + +@end deffn + +wobei @var{Qualifikator} entweder „Bibliotheks`` oder „optionale`` sein +kann gemäß der Definition im Abschnitt @ref{Grundlegende; Bibliotheks- +und optionale Funktionalitäten}. + +Wenn die @var{Kategorie} als „Syntax`` angegeben ist, beschreibt der +Eintrag einen Ausdruckstyp und die Schablone gibt die Syntax des +Ausdruckstyps an. Bestandteile von Ausdrücken werden als syntaktische +Variablen ausgezeichnet, welche mit spitzen Klammern geschrieben werden, +zum Beispiel @r{<Ausdruck>} oder @r{<Variable>}. Syntaktische Variable +sollten verstanden werden als etwas, was Programmtextsegmente +bezeichnet; zum Beispiel steht @r{<Ausdruck>} für eine beliebige +Zeichenkette, die einen syntaktisch gültigen Ausdruck darstellt. Die +Notation + +@format + @r{<Ding1>} @dots{} +@end format + +zeigt null oder mehr Vorkommen eines @r{<Ding>} an, wogegen + +@format + @r{<Ding1>} @r{<Ding2>} @dots{} +@end format + +eines oder mehr Vorkommen eines @r{<Ding>} anzeigt. + +Wenn @var{Kategorie} „Prozedur`` ist, dann beschreibt der Eintrag eine +Prozedur und die Kopfzeile gibt eine Schablone eines Aufrufs der +Prozedur an. Argumentnamen in der Schablone sind @var{kursiv}. Somit +zeigt die Kopfzeile + + +@noindent +@deffn {Prozedur} vector-ref @var{vector} @var{k} + +@end deffn + +an, dass die eingebaute Prozedur @t{vector-ref} zwei Argumente nimmt, +einen Vektor @var{Vector} und eine exakte nicht negative ganze Zahl +@var{k} (siehe unten). Die Kopfzeilen + + +@noindent + +@deffn {Prozedur} make-vector @var{k} + + +@deffnx {Prozedur} make-vector @var{k} @var{fill} + +@end deffn + +zeigen an, dass die Prozedur @t{Make-vector} so definiert werden muss, +dass sie entweder ein oder zwei Argumente nimmt. + + +Es ist ein Fehler, wenn einer Operation ein Argument vorgelegt wird, +wofür nicht spezifiziert wurde, dass sie damit umgehen kann. Der Kürze +wegen folgen wir der Konvention, dass wenn ein Argumentname auch der +Name eines im Abschnitt @ref{Typfremdheit} aufgeführten Typs ist, dieses +Argument vom genannten Typen sein muss. Zum Beispiel schreibt obige +Kopfzeile für @t{Vector-ref} vor, dass das erste Argument an +@t{Vector-ref} ein Vektor sein muss. Die folgenden Namenskonventionen +implizieren ebenfalls Typeinschränkungen: +@c \newcommand{\foo}[1]{\vr{#1}, \vri{#1}, $\ldots$ \vrj{#1}, $\ldots$} + + +@c @center @c begin-tabular +@quotation +@table @asis +@item @var{Objekt} +ein beliebiges Objekt +@item @var{Liste}, @var{Liste1}, @dots{} @var{Listej}, @dots{} +Liste (siehe Abschnitt @pxref{Paare und Listen}) +@item @var{z}, @var{z1}, @dots{} @var{zj}, @dots{} +komplexe Zahl +@item @var{x}, @var{x1}, @dots{} @var{xj}, @dots{} +reelle Zahl +@item @var{y}, @var{y1}, @dots{} @var{yj}, @dots{} +reelle Zahl +@item @var{q}, @var{q1}, @dots{} @var{qj}, @dots{} +rationale Zahl +@item @var{n}, @var{n1}, @dots{} @var{nj}, @dots{} +ganze Zahl +@item @var{k}, @var{k1}, @dots{} @var{kj}, @dots{} +exakte, nicht negative ganze Zahl +@c @item +@end table +@end quotation + + + + +@ignore todo +Provide an example entry?? +@end ignore + + + +@node Auswertungsbeispiele, Namenskonventionen, Eintragsformat, Notation und Terminologie +@subsection Auswertungsbeispiele + + +Das in Programmbeispielen benutzte Symbol „@result{}`` sollte als +„wird ausgewertet zu`` gelesen werden. Zum Beispiel bedeutet + + +@example + +(* 5 8) ==> 40 + +@end example + + +dass der Ausdruck @t{(* 5 8)} zum Objekt @t{40} ausgewertet wird. Oder +genauer gesagt: Der Ausdruck, der sich aus der Zeichenfolge „@t{(* 5 +8)}`` ergibt, wird, in der Anfangsumgebung, ausgewertet zu einem Objekt, +das durch die Zeichenfolge „@t{40}`` extern dargestellt werden kann. +Siehe den Abschnitt @ref{Externe Darstellung} für eine Diskussion der +externen Darstellungen eines Objekts. + +@node Namenskonventionen, , Auswertungsbeispiele, Notation und Terminologie +@subsection Namenskonventionen + + +Nach Konvention enden die Namen von Prozeduren, die immer einen +booleschen Wert zurückgeben, gewöhnlich auf „@code{?}``. Solche +Prozeduren werden Prädikate genannt. +@vindex @w{?} + +Nach Konvention enden die Namen von Prozeduren, die Werte in bereits +zugeteilte Speicherstellen einspeichern (siehe den Abschnitt +@pxref{Speichermodell}), gewöhnlich auf „@code{!}``. +@vindex @w{!} +Solche Prozeduren werden Veränderungsprozeduren genannt. Nach +Konvention ist der von einer Veränderungsprozedur zurückgegebene Wert +unbestimmt. + +Nach Konvention erscheint „@code{->}`` im Namen von Prozeduren, die +@vindex @w{->} +ein Objekt einen Typs nehmen und ein entsprechendes Objekt eines anderen +Typs zurückgeben. Zum Beispiel nimmt @samp{List->vector} eine Liste und +gibt einen Vektor zurück, dessen Elemente dieselben sind wie die der +Liste. + + + +@ignore todo +Terms that need defining: thunk, command (what else?). +@end ignore + + +@c @include{lex} + +@c Lexical structure + +@c %\vfill\eject +@node Schreibkonventionen, Grundkonzepte, Übersicht von Scheme, top +@chapter Schreibkonventionen + +@menu +* Bezeichner:: +* Leerraum und Kommentare:: +* Andere Notationen:: +@end menu + + +Dieser Abschnitt berichtet informell über einige der beim Schreiben von +Scheme-Programmen benutzten Schreibkonventionen. Eine formale Syntax +von Scheme finden Sie im Abschnitt @ref{Formale Syntax}. + +Groß- und kleingeschriebene Formen eines Buchstabens werden nie +unterschieden außer innerhalb von Zeichen- und Zeichenketten-Konstanten. +Zum Beispiel ist @samp{Foo} derselbe Bezeichner wie @samp{FOO} und +@t{#x1AB} ist dieselbe Zahl wie @t{#X1ab}. + +@node Bezeichner, Leerraum und Kommentare, Schreibkonventionen, Schreibkonventionen +@section Bezeichner + + + +Die meisten Bezeichner, die in anderen Programmiersprachen zugelassen +sind, +@cindex @w{Bezeichner} +sind auch in Scheme zulässig. Die genauen Regeln für das Bilden von +Bezeichnern unterscheiden sich je nach Scheme-Implementierung, aber in +allen Implementierungen ist eine Folge von Zeichen, Ziffern und +„erweiterten Buchstabenzeichen``, die mit einem Zeichen beginnt, das +keine Zahl beginnen kann, ein Bezeichner. Außerdem sind @code{+}, +@code{-} und @code{...} auch Bezeichner. +@vindex @w{...} +@vindex @w{-} +@vindex @w{+} +Hier sind einige Beispiele von Bezeichnern: + + +@example + +lambda q +list->vector soup ++ V17a +<=? a34kTMNs +Das-Wort-Rekursion-hat-viele-Bedeutungen + +@end example + + +Erweiterte Buchstabenzeichen dürfen innerhalb von Bezeichnern benutzt +werden, als wären sie Buchstaben. Die folgenden Zeichen sind erweiterte +Buchstabenzeichen: + + +@example + +! $ % & * + - . / : < = > ? @@ ^ _ ~ +@end example + + +Siehe den Abschnitt @ref{Lexikalische Struktur} für eine formale Syntax +von Bezeichnern. + +Bezeichner haben in Scheme-Programmen zwei Zwecke: + + +@itemize @bullet + +@item +Jeder Bezeichner darf als Variable oder als syntaktisches Schlüsselwort +benutzt werden +(siehe die Abschnitte @pxref{Variable; syntaktische Schlüsselwörter; und +Regionen} und @pxref{Makros}). + +@item +Wenn ein Bezeichner als Literal oder innerhalb eines Literals auftaucht +(siehe den Abschnitt @pxref{Literale Ausdrücke}), wird er benutzt, um +ein @emph{Symbol} zu bezeichnen (siehe den Abschnitt @pxref{Symbole}). + + +@end itemize + +@cindex @w{syntaktisches Schlüsselwort} +@cindex @w{Variable} + +@c \label{keywordsection} +@c The following identifiers are syntactic keywords, and should not be used +@c as variables: + +@c \begin{scheme} +@c => do or +@c and else quasiquote +@c begin if quote +@c case lambda set! +@c cond let unquote +@c define let* unquote-splicing +@c delay letrec% +@c \end{scheme} + +@c Some implementations allow all identifiers, including syntactic +@c keywords, to be used as variables. This is a compatible extension to +@c the language, but ambiguities in the language result when the +@c restriction is relaxed, and the ways in which these ambiguities are +@c resolved vary between implementations. + + +@node Leerraum und Kommentare, Andere Notationen, Bezeichner, Schreibkonventionen +@section Leerraum und Kommentare + + +@dfn{Leerraum}-Zeichen sind Leerzeichen und Zeilenvorschübe. +@cindex @w{Leerraum} +(Implementierungen bieten typischerweise zusätzliche Leerraum-Zeichen +wie Tabulatorzeichen oder Seitenvorschübe.) Leerraum wird zur besseren +Lesbarkeit benutzt und um Tokens voneinander zu trennen, wobei ein Token +eine unteilbare lexikalische Einheit wie zum Beispiel ein Bezeichner +oder eine Zahl ist; dort hat der Leerraum sonst keine Auswirkung. +Leerraum darf zwischen jeglichen zwei Tokens auftreten, aber nicht +innerhalb eines Tokens. Leerraum darf auch innerhalb einer Zeichenkette +auftreten, wo er aber Auswirkungen hat. + +Ein Semikolon (@t{;}) zeigt den Anfang eines Kommentars an. Der +Kommentar geht weiter bis zum +@cindex @w{;} +@cindex @w{Kommentar} +Ende der Zeile, auf der das Semikolon steht. Kommentare sind gegenüber +Scheme unsichtbar, aber das Ende der Zeile ist als Leerraum sichtbar. +Dies verhindert, dass ein Kommentar in der Mitte eines Bezeichners oder +einer Zahl steht. + + +@example + +;;; Die FACT-Prozedur berechnet die Fakultät +;;; einer nicht negativen ganzen Zahl. +(define fact + (lambda (n) + (if (= n 0) + 1 ;Rekursionsanfang: Rückgabe 1 + (* n (fact (- n 1)))))) + +@end example + + + +@node Andere Notationen, , Leerraum und Kommentare, Schreibkonventionen +@section Andere Notationen + + +@ignore todo +Rewrite? +@end ignore + + +Für eine Beschreibung der Notationen, die für Zahlen benutzt werden, +siehe den Abschnitt @ref{Zahlen}. + + +@table @t + + +@item @t{.@: + -} +Diese werden in Zahlen benutzt und können auch sonst irgendwo in einem +Bezeichner auftauchen, außer als deren erstes Zeichen. Ein abgegrenztes +Plus- oder Minuszeichen für sich alleine ist auch ein Bezeichner. Ein +abgegrenzter Punkt (der nicht innerhalb einer Zahl oder eines +Bezeichners auftritt) wird in der Notation für Paare benutzt (Abschnitt +@pxref{Paare und Listen}) und um den Rest-Parameter in einer formalen +Parameterliste anzuzeigen (Abschnitt @pxref{Prozeduren}). Eine +abgegrenzte Folge von drei Punkten nacheinander ist auch ein Bezeichner. + +@item @t{( )} +Runde Klammern werden zur Gruppierung und zum Kennzeichnen von Listen +(section @pxref{Paare und Listen}). + +@item @t{'} +Ein halbes Anführungszeichen wird benutzt, um literale Daten anzuzeigen +(Abschnitt @pxref{Literale Ausdrücke}). + +@item @t{`} +Das Backquote-Zeichen wird benutzt, um fast-konstante Daten anzuzeigen +(Abschnitt @pxref{Quasimaskierung}). + +@item @t{, ,@@} +Das Kommazeichen und die Folge aus Komma und At-Zeichen werden zusammen +mit dem Backquote benutzt (Abschnitt @pxref{Quasimaskierung}). + +@item @t{"} +Das doppelte Anführungszeichen wird zum Abgrenzen von Zeichenketten +benutzt (Abschnitt @pxref{Zeichenketten}). + +@item \ +Der Backslash wird in der Syntax für Zeichen-Konstante benutzt +(Abschnitt @pxref{Zeichen}) und als ein Maskierungszeichen innerhalb von +Zeichenketten-Konstanten (Abschnitt @pxref{Zeichenketten}). + +@c A box used because \verb is not allowed in command arguments. + +@item @w{@t{[ ] @{ @} |}} +Linke und rechte eckige und geschweifte Klammern sowie der vertikale +Strich sind reserviert für mögliche spätere Erweiterungen der Sprache. + +@item # +Das Rautezeichen wird für eine Vielfalt von Zwecken benutzt, je nachdem, +welches Zeichen direkt darauf folgt: + +@item @t{#t} @t{#f} +Dies sind die booleschen Konstanten (Abschnitt @pxref{Boolesche Werte}). + +@item #\ +Dies leitet eine Zeichen-Konstante ein (Abschnitt @pxref{Zeichen}). + +@item #@t{(} +Dies leitet eine Vektor-Konstante ein (Abschnitt @pxref{Vektoren}). +Vektor-Konstante werden beendet mir @t{)} . + +@item @t{#e #i #b #o #d #x} +Diese werden zur Notation von Zahlen benutzt (Abschnitt @pxref{Syntax +numerischer Konstanter}). + +@end table + + +@c @include{basic} + +@c \vfill\eject +@node Grundkonzepte, Ausdrücke, Schreibkonventionen, top +@chapter Grundkonzepte + +@menu +* Variable; syntaktische Schlüsselwörter; und Regionen:: +* Typfremdheit:: +* Externe Darstellungen:: +* Speichermodell:: +* Echte Endrekursion:: +@end menu + + + +@node Variable; syntaktische Schlüsselwörter; und Regionen, Typfremdheit, Grundkonzepte, Grundkonzepte +@section Variable; syntaktische Schlüsselwörter; und Regionen + + + + +Ein Bezeichner darf einen Syntaxtyp benennen oder er darf +@cindex @w{Bezeichner} +eine Stelle benennen, an der ein Wert gespeichert werden kann. Ein +Bezeichner, der einen Syntaxtyp benennt, heißt ein @emph{syntaktisches +Schlüsselwort} +@cindex @w{syntaktisches Schlüsselwort} +und wird als an diese Syntax @emph{gebunden} bezeichnet. Ein +Bezeichner, der eine Stelle benennt, heißt eine @emph{Variable} und wird +als an diese Stelle +@cindex @w{Variable} +@emph{gebunden} bezeichnet. Die Menge aller sichtbaren Bindungen, die +an einem Punkt eines Programms gelten, sind +@cindex @w{Bindung} +bekannt als die an diesem Punkt geltende @emph{Umgebung}. Der Wert, der +an der Stelle, an die die Variable gebunden ist, gespeichert ist, heißt +der Wert der Variablen. Manchmal wird, die Terminologie missbrauchend, +gesagt, die Variable benenne den Wert oder sei an den Wert gebunden. +Das ist nicht ganz zutreffend, aber diese Praxis führt selten zu +Verwirrung. + +@ignore todo +Define ``assigned'' and ``unassigned'' perhaps? +@end ignore + + +@ignore todo +In programs without side effects, one can safely pretend that the +variables are bound directly to the arguments. Or: +In programs without @code{set!}, one can safely pretend that the +@vindex @w{set!} +variable is bound directly to the value. +@end ignore + + +Bestimmte Ausdruckstypen werden benutzt, um neue Arten von Syntax zu +erzeugen und um syntaktische Schlüsselwörter an diese neuen Syntaxen zu +binden, während andere Ausdruckstypen neue Stellen erzeugen und Variable +an diese Stellen binden. Diese Ausdruckstypen werden +@emph{Bindungskonstrukte} genannt. + +@cindex @w{Bindungskonstrukt} +Jene, die syntaktische Schlüsselwörter binden, werden im Abschnitt +@ref{Makros} aufgeführt. Das grundlegendste Variablenbindungskonstrukt +ist der @samp{Lambda}-Ausdruck, weil alle anderen +Variablenbindungskonstrukte als @samp{Lambda}-Ausdrücke beschrieben +werden können. Die anderen Variablenbindungskonstrukte sind die +Ausdrücke @samp{Let}, @samp{Let*}, @samp{Letrec} und @samp{Do} (siehe +die Abschnitte @pxref{Prozeduren}, @pxref{Bindungskonstrukte} und +@pxref{Iteration}). + +@c Note: internal definitions not mentioned here. + +Wie Algol und Pascal und anders als die meisten anderen Dialekte von +Lisp außer Common Lisp ist Scheme eine Sprache mit statischen +Sichtbarkeitsbereichen und einer Block-Struktur. Für jeden Ort, wo ein +Bezeichner in einem Programm gebunden wird, gibt es eine zugehörige +@dfn{Region} des Programmtexts, in der +@cindex @w{Region} +die Bindung sichtbar ist. Die Region wird durch die jeweiligen +Bindungskonstrukte bestimmt, die die Bindung herstellen; wenn die +Bindung zum Beispiel durch einen @samp{Lambda}-Ausdruck hergestellt +wird, ist ihre Region der gesamte @samp{Lambda}-Ausdruck. Jede +Erwähnung eines Bezeichners bezieht sich auf diejenige Bindung dieses +Bezeichners, die die am weitesten innen liegende diese Erwähnung +enthaltende Region hergestellt hat. Wenn keine der Regionen, in denen +diese Benutzung des Bezeichners vorkommt, eine Bindung für diesen +Bezeichner enthält, dann bezieht sich diese Benutzung auf die Bindung +der Variablen in der Umgebung auf oberster Ebene, falls vorhanden +(Kapitel @pxref{Ausdrücke} und @pxref{Standardprozeduren}); ist keine +solche Bindung des Bezeichners vorhanden, nennt man ihn +@dfn{ungebunden}. +@cindex @w{oberste Ebene} +@cindex @w{gebunden} +@cindex @w{ungebunden} + +@ignore todo +Mention that some implementations have multiple top level environments? +@end ignore + + +@ignore todo +Pitman sez: needs elaboration in case of @t{(let ...)} +@end ignore + + +@ignore todo +Pitman asks: say something about vars created after scheme starts? +@t{(define x 3) (define (f) x) (define (g) y) (define y 4)} +Clinger replies: The language was explicitly +designed to permit a view in which no variables are created after +Scheme starts. In files, you can scan out the definitions beforehand. +I think we're agreed on the principle that interactive use should +approximate that behavior as closely as possible, though we don't yet +agree on which programming environment provides the best approximation. +@end ignore + + +@node Typfremdheit, Externe Darstellung, Variable; syntaktische Schlüsselwörter; und Regionen, Grundkonzepte +@section Typfremdheit + + + +Kein Objekt erfüllt mehr als eines der folgenden Prädikate: + + +@example + +boolean? pair? +symbol? number? +char? string? +vector? port? +procedure? + +@end example + + +Diese Prädikaten definieren die Typen @emph{Boolean} (boolescher Typ), +@emph{Pair} (Paar), @emph{Symbol} (Symbol), @emph{Number} (Zahl), +@emph{Char} (oder @emph{Character}, deutsch Zeichen), @emph{String} +(Zeichenkette), @emph{Vector} (Vektor), @emph{Port} (Port) und +@emph{Procedure} (Prozedur). Die leere Liste ist ein besonderes Objekt +und hat ihren eigenen Typ; sie erfüllt keines der obigen Prädikate. + +@vindex symbol? +@vindex pair? +@vindex boolean? +@cindex @w{Typ} + +@vindex vector? +@vindex string? +@vindex char? +@vindex number? + +@cindex @w{leere Liste} +@vindex procedure? +@vindex port? + +Obwohl es einen gesonderten booleschen Typ gibt, kann jeder Scheme-Wert +als ein boolescher Wert zum Prüfen einer Bedingung benutzt werden. Wie +im Abschnitt @ref{Boolesche Werte} erklärt wird, gelten alle Werte beim +Prüfen als wahr außer @t{#f}. +@c and possibly the empty list. +@c The only value that is guaranteed to count as +@c false is \schfalse{}. It is explicitly unspecified whether the empty list +@c counts as true or as false. +Dieser Bericht benutzt das Wort „wahr`` für einen beliebigen +Scheme-Wert außer @t{#f} und der Bericht benutzt das Wort „falsch`` für +@t{#f}. +@cindex @w{falsch} +@cindex @w{wahr} + +@node Externe Darstellungen, Speichermodell, Typfremdheit, Grundkonzepte +@section Externe Darstellungen + + + +Ein wichtiges Konzept in Scheme (und Lisp) ist das der @emph{externen +Darstellung} eines Objekts als eine Folge von Zeichen. Zum Beispiel ist +eine externe Darstellung der ganzen Zahl 28 die Zeichenfolge „@t{28}`` +und eine externe Darstellung einer Liste bestehend aus den ganzen Zahlen +8 und 13 ist die Zeichenfolge „@t{(8 13)}``. + +Die externe Darstellung eines Objekts muss nicht eindeutig sein. Die +ganze Zahl 28 hat auch die Darstellungen „@t{#e28.000}`` und +„@t{#x1c}``, die Liste im vorherigen Absatz hat auch die Darstellungen +„@t{( 08 13 )}`` und „@t{(8 .@: (13 .@: ()))}`` (siehe den Abschnitt +@pxref{Paare und Listen}). + +Viele Objekte haben Standarddarstellungen als externe Darstellung, aber +manche, wie Prozeduren, haben keine Standarddarstellungen (auch wenn +bestimmte Implementierungen für sie Darstellungen festlegen dürfen). + +Eine externe Darstellung darf in ein Programm geschrieben werden, um das +zugehörige Objekt zu erhalten (siehe @samp{Quote}, Abschnitt +@pxref{Literale Ausdrücke}). + +Externe Darstellungen können auch zur Eingabe und Ausgabe benutzt +werden. Die Prozedur @samp{Read} (Abschnitt @pxref{Eingabe}) wandelt +externe Darstellungen um und die Prozedur @samp{Write} (Abschnitt +@pxref{Ausgabe}) erzeugt solche. Zusammen bieten sie ein elegantes und +mächtiges Mittel zur Ein- und Ausgabe. + +Beachten Sie, dass die Zeichenfolge „@t{(+ 2 6)}`` @emph{keine} externe +Darstellung für die ganze Zahl 8 ist, wenn sie auch ein Ausdruck +@emph{ist}, der zu der ganzen Zahl 8 ausgewertet wird; stattdessen ist +sie eine externe Darstellung einer dreielementigen Liste, deren Elemente +das Symbol @t{+} und die ganzen Zahlen 2 und 6 sind. Die Syntax von +Scheme hat die Eigenschaft, dass eine beliebige Zeichenfolge, die ein +Ausdruck ist, auch die externe Darstellung irgendeines Objekts ist. +Dies kann zu Verwirrung führen, da es ohne Kontext nicht offensichtlich +sein kann, ob eine bestimmte Zeichenfolge Daten oder Programm bezeichnen +soll, es ist aber auch eine Quelle der Macht, da so das Schreiben von +Programmen wie Interpretern und Übersetzern erleichtert wird, die +Programme als Daten behandeln (oder umgekehrt). + +Die Syntax externer Darstellungen verschiedener Arten von Objekten +begleitet die Beschreibungen der Grundoperationen, um die Objekte zu +manipulieren, welche in den jeweiligen Abschnitten des Kapitels +@ref{Standardprozeduren} zu finden sind. + +@node Speichermodell, Echte Endrekursion, Externe Darstellungen, Grundkonzepte +@section Speichermodell + + + +Variable und Objekte wie Paare, Vektoren und Zeichenketten bezeichnen +implizit Speicherstellen oder Folgen von Speicherstellen. Zum Beispiel +bezeichnet eine Zeichenkette +@cindex @w{Stelle} +so viele Stellen, wie es Zeichen in der Zeichenkette gibt. (Diese +Stellen müssen keinem ganzen Maschinenwort entsprechen.) Ein neuer Wert +darf mit der Prozedur @t{String-set!} in einer dieser Stellen +gespeichert werden, aber die Zeichenkette bezeichnet dann noch immer +dieselben Stellen wie vorher. + +Ein von einer Stelle geholtes Objekt, durch Variablenreferenz oder durch +eine Prozedur wie @samp{Car}, @samp{Vector-ref} oder @samp{String-ref} +ist im Sinne von @code{Eqv?} gleichwertig +@c and \ide{eq?} ?? +(Abschnitt @pxref{Äquivalenzprädikate}) +@vindex @w{eqv?} +zum Objekt, was vor dem Holen zuletzt an der Stelle gespeichert war. + +Jede Stelle wird markiert, um anzuzeigen, ob sie in Benutzung ist. +Keine Variable und kein Objekt bezieht sich je auf eine Stelle, die +nicht in Benutzung ist. Wann immer dieser Bericht davon spricht, dass +Speicher für eine Variable oder ein Objekt zugeteilt wird, ist damit +gemeint, dass eine entsprechende Anzahl von Stellen aus der Menge +unbenutzer Stellen gewählt wird und die ausgewählten Stellen markiert +werden, um anzuzeigen, dass sie nun benutzt sind, bevor die Variable +oder das Objekt dazu gebracht wird, diese Stellen zu bezeichnen. + +In vielen Systemen ist es wünschenswert, dass sich Konstante (@abbr{d.h.} die +Werte von +@cindex @w{Konstante} +literalen Ausdrücken) in Nur-Lese-Speicher befinden. Um dies +auszudrücken, ist es gelegen sich vorzustellen, dass jedes Objekt, +welches Stellen bezeichnet, mit einer Markierung assoziiert ist, die +angibt, ob das Objekt veränderlich +@cindex @w{veränderlich} +oder unveränderlich ist. In solchen Systemen sind literale Konstante +und die Zeichenketten, +@cindex @w{unveränderlich} +die @code{symbol->string} zurückgibt, unveränderliche Objekte, während +alle Objekte, +@vindex @w{Symbol->string} +die durch andere in diesem Bericht angegebene Prozeduren erzeugt wurden, +veränderlich sind. Es ist ein Fehler zu versuchen, einen neuen Wert an +eine Stelle zu speichern, die von einem unveränderlichen Objekt +bezeichnet wird. + +@node Echte Endrekursion, , Speichermodell, Grundkonzepte +@section Echte Endrekursion + + + +Implementierungen von Scheme müssen +@emph{echt endrekursiv}. +@cindex @w{echte Endrekursion} +sein. Prozeduraufrufe, die in den unten beschriebenen bestimmten +syntaktischen Kontexten vorkommen, sind ,endständige Aufrufe`. Eine +Scheme-Implementierung ist echt endrekursiv, wenn sie eine unbeschränkte +Anzahl von aktiven endständigen Aufrufen unterstützt. Ein Aufruf ist +@emph{aktiv}, wenn die aufgerufene Prozedur noch immer einen Rücksprung +durchführen, @abbr{d.h.} einen Wert zurückgeben, kann. Beachten Sie, +dass dies alle Aufrufe einschließt, die entweder von der aktuellen +Fortsetzung oder von zuvor mit @samp{Call-with-current-continuation} +gefangenen Fortsetzungen, die später aufgerufen werden, einschließt. +Ohne gefangene Fortsetzungen könnten Aufrufe höchstens einen Rücksprung +durchführen und aktive Aufrufe wären diejenigen, die noch keinen +Rücksprung durchgeführt haben. Eine formale Definition von echter +Endrekursion ist in [propertailrecursion] zu finden. + + +@quotation +@emph{Begründung:} + +Intuitiv wird kein Speicher für einen aktiven endständigen Aufruf +benötigt, weil die Fortsetzung, die im endständigen Aufruf benutzt wird, +dieselbe Semantik hat wie die Fortsetzung, die der den Aufruf +enthaltenden Prozedur übergeben wurde. Obwohl eine nicht richtige +Implementierung in diesem Aufruf eine neue Fortsetzung benutzen könnte, +würde ein Rücksprung zu dieser neuen Fortsetzung einen sofortigen +Rücksprung zu der der Prozedur übergebenen Fortsetzung nach sich ziehen. +Eine echt endrekursive Implementierung springt direkt zu dieser +übergebenen Fortsetzung zurück. + +Echte Endrekursion war eine der zentralen Ideen in Steeles und Sussmans +ursprünglicher Fassung von Scheme. Ihr erster Scheme-Interpreter +implementierte sowohl Funktionen als auch Akteure. Programmfluss wurde +über Akteure ausgedrückt, welche sich darin von Funktionen +unterschieden, dass sie ihre Ergebnisse einem anderen Akteur übergaben +statt an den Aufrufer. In der Terminologie dieses Abschnitts endete +jeder Akteur mit einem endständigen Aufruf an einen anderen Akteur. + +Steele und Sussman beobachteten später, dass der Code in ihrem +Interpreter, der mit Akteuren umging, identisch war mit dem für +Funktionen und es daher keinen Grund dafür gab, beide in die Sprache +aufzunehmen. + +@end quotation + + +Ein @emph{endständiger Aufruf} ist ein Prozeduraufruf, der +@cindex @w{endständiger Aufruf} +@emph{endständig} auftritt. Endständigkeit ist induktiv definiert. +Beachten Sie, dass Endständigkeit immer in Bezug auf einen bestimmten +Lambda-Ausdruck bestimmt wird. + + + +@itemize @bullet + +@item +Der letzte Ausdruck im Rumpf eines Lambda-Ausdrucks, unten dargestellt +als @r{<endständiger Ausdruck>} tritt endständig auf. + +@format +@t{(lambda <Formale> + <Definition>* <Ausdruck>* <endständiger Ausdruck>) +} + +@end format + + + +@item +Wenn einer der folgenden Ausdrücke endständig ist, sind die als +<endständiger Ausdruck> dargestellten Unterausdrücke endständig. Diese +wurden über die Regeln der im Kapitel @ref{Formale Syntax und Semantik} +angegebenen Grammatik abgeleitet, durch Ersetzung der Vorkommen von +<Ausdruck> durch <endständiger Ausdruck>. Hier sind nur die Regeln +dargestellt, die Endständigkeit enthalten. + + +@format +@t{(if <Ausdruck> <endständiger Ausdruck> <endständiger Ausdruck>) +(if <Ausdruck> <endständiger Ausdruck>) + +(cond <cond-Klausel>+) +(cond <cond-Klausel>* (else <endständige Folge>)) + +(case <Ausdruck> + <case-Klausel>+) +(case <Ausdruck> + <case-Klausel>* + (else <endständige Folge>)) + +(and <Ausdruck>* <endständiger Ausdruck>) +(or <Ausdruck>* <endständiger Ausdruck>) + +(let (<Bindungsspezifikation>*) <endständiger Rumpf>) +(let <Variable> (<Bindungsspezifikation>*) <endständiger Rumpf>) +(let* (<Bindungsspezifikation>*) <endständiger Rumpf>) +(letrec (<Bindungsspezifikation>*) <endständiger Rumpf>) + +(let-syntax (<Syntaxspezifikation>*) <endständiger Rumpf>) +(letrec-syntax (<Syntaxspezifikation>*) <endständiger Rumpf>) + +(begin <endständige Folge>) + +(do (<Iterationsspezifikation>*) + (<Test> <endständige Folge>) + <Ausdruck>*) + +@r{where} + +<cond-Klausel> --> (<Test> <endständige Folge>) +<case-Klausel> --> ((<Datenelement>*) <endständige Folge>) + +<endständiger Rumpf> --> <Definition>* <endständige Folge> +<endständige Folge> --> <Ausdruck>* <endständiger Ausdruck> +} + +@end format + + + +@item +Wenn ein @samp{Cond}-Ausdruck entständig auftritt und eine Klausel der +Form @samp{(@r{<Ausdruck1>} => @r{<Ausdruck2>})} enthält, dann ist der +(implizite) Aufruf der Prozedur, die sich aus der Auswertung von +@r{<Ausdruck2>} ergibt, endständig. @r{<Ausdruck2>} selbst ist nicht +endständig. + + +@end itemize + + +Bestimmte eingebaute Prozeduren müssen auch endrekursive Aufrufe +durchführen. Das erste an @code{apply} und an +@vindex @w{apply} +@code{call-with-current-continuation} übergebene Argument sowie das +zweite an +@vindex @w{call-with-current-continuation} +@code{call-with-values} übergebene Argument muss endrekursiv aufgerufen +werden. +@vindex @w{call-with-values} +Ebenso muss @code{eval} sein Argument so auswerten, als wäre es +@vindex @w{eval} +innerhalb der @code{eval}-Prozedur endständig. +@vindex @w{eval} + +Im folgenden Beispiel ist der einzige endrekursive Aufruf der Aufruf von +@samp{f}. Keiner der Aufrufe von @samp{g} oder @samp{h} sind +endrekursive Aufrufe. Die Referenz auf @samp{x} ist endständig, aber +sie ist kein Aufruf und daher nicht endrekursiv. + +@example + +(lambda () + (if (g) + (let ((x (h))) + x) + (and (g) (f)))) + +@end example + + + +@quotation +@emph{Anmerkung:} +Implementierungen dürfen, sie müssen aber nicht, erkennen, dass einige +der nicht endrekursiven Aufrufe, wie oben der Aufruf von @samp{h}, +ausgewertet werden können, als wären sie endrekursiv. Im obigen +Beispiel könnte der @samp{Let}-Ausdruck zu einem endrekursiven Aufruf +von @samp{h} übersetzt werden. (Die Möglichkeit, dass @samp{h} eine +unerwartete Anzahl von Werten zurückgibt, kann ignoriert werden, weil +dann die Wirkung des @samp{Let} ausdrücklich unbestimmt und +implementierungsabhängig ist.) +@end quotation + + + +@c @include{expr} + +@c \vfill\eject +@node Ausdrücke, Programmstruktur, Grundkonzepte, top +@chapter Ausdrücke + +@menu +* Grundlegende Ausdruckstypen:: +* Abgeleitete Ausdruckstypen:: +* Makros:: +@end menu + + + +@c \newcommand{\syntax}{{\em Syntax: }} +@c \newcommand{\semantics}{{\em Semantics: }} + +@c [Deleted for R5RS because of multiple-value returns. -RK] +@c A Scheme expression is a construct that returns a value, such as a +@c variable reference, literal, procedure call, or conditional. + +Ausdruckstypen werden eingeteilt in @emph{grundlegende} oder in +@emph{abgeleitete} Ausdruckstypen. Grundlegende Ausdruckstypen +schließen Variable und Prozeduraufrufe ein. Abgeleitete Ausdrückstypen +sind nicht semantisch grundlegend, sondern können stattdessen als Makros +definiert werden. Mit Ausnahme von @samp{Quasiquote} zur +Quasimaskierung, dessen Makrodefinition komplex ist, werden die +abgeleiteten Ausdrücke zu den Bibliotheksfunktionalitäten gezählt. +Angemessene Definitionen werden im Abschnitt @ref{Abgeleitete +Ausdruckstypen} vorgestellt. + +@node Grundlegende Ausdruckstypen, Abgeleitete Ausdruckstypen, Ausdrücke, Ausdrücke +@section Grundlegende Ausdruckstypen + +@menu +* Variablenreferenzen:: +* Literale Ausdrücke:: +* Prozeduraufrufe:: +* Prozeduren:: +* Bedingungen:: +* Zuweisungen:: +@end menu + + + +@node Variablenreferenzen, Literale Ausdrücke, Grundlegende Ausdruckstypen, Grundlegende Ausdruckstypen +@subsection Variablenreferenzen + + + +@deffn {Syntax} @r{<Variable>} + + +Ein Ausdruck, der aus einer Variablen +@cindex @w{Variable} +(Abschnitt @pxref{Variable; syntaktische Schlüsselwörter; und Regionen}) +besteht, ist eine Variablenreferenz. Der Wert der Variablenreferenz ist +der an der Stelle, an die die Variable gebunden ist, gespeicherte Wert. +Es ist ein Fehler, eine ungebundene Variable zu referenzieren. +@cindex @w{ungebunden} + + +@format +@t{(define x 28) +x ==> 28 +} +@end format + +@end deffn + +@node Literale Ausdrücke, Prozeduraufrufe, Variablenreferenzen, Grundlegende Ausdruckstypen +@subsection Literale Ausdrücke + + + + +@deffn {Syntax} quote @r{<Datenelement>} + +@deffnx {Syntax} @t{'}@r{<Datenelement>} + + +@deffnx {Syntax} @r{<Konstante>} + + +@samp{(quote @r{<Datenelement>})} wird ausgewertet zu @r{<Datenelement>}. +Durch @samp{Quote} wird das @r{<Datenelement>} @emph{maskiert}. +@cindex @w{'} +@r{<Datenelement>} darf eine beliebige externe Darstellung eines +Scheme-Objekts sein (siehe den Abschnitt @pxref{Externe Darstellungen}). +Diese Notation wird zum Einfügen literaler Konstanter in Scheme-Code +benutzt. + + +@format +@t{ +(quote a) ==> a +(quote #(a b c)) ==> #(a b c) +(quote (+ 1 2)) ==> (+ 1 2) +} +@end format + + +@samp{(quote @r{<Datenelement>})} darf abgekürzt werden als +@t{'}@r{<Datenelement>}. Die beiden Notationen sind in allen Bezügen +äquivalent. + + +@format +@t{'a ==> a +'#(a b c) ==> #(a b c) +'() ==> () +'(+ 1 2) ==> (+ 1 2) +'(quote a) ==> (quote a) +''a ==> (quote a) +} +@end format + + +Numerische Konstante, Zeichenkettenkonstante, Zeichenkonstante und +boolesche Konstante werden „zu sich selbst`` ausgewertet; sie müssen +nicht mit @samp{Quote} maskiert werden. + + +@format +@t{'"abc" ==> "abc" +"abc" ==> "abc" +'145932 ==> 145932 +145932 ==> 145932 +'#t ==> #t +#t ==> #t +} +@end format + + +Wie im Abschnitt @ref{Speichermodell} angemerkt ist es ein Fehler, eine +Konstante (@abbr{d.h.} den Wert eines literalen Ausdrucks) mit einer +Veränderungsprozedur wie @samp{Set-car!} oder @samp{String-set!} +abzuändern. + +@end deffn + + +@node Prozeduraufrufe, Prozeduren, Literale Ausdrücke, Grundlegende Ausdruckstypen +@subsection Prozeduraufrufe + + + +@deffn {Syntax} @r{<Operator>} @r{<Operand1>} @dots{}, + + +Ein Prozeduraufruf wird geschrieben, indem man einfach die Ausdrücke für +die aufzurufende Prozedur und die ihr zu übergebenden Argumente mit +runden Klammern umschließt. Die Operator- und Operand-Ausdrücke werden +(in unbestimmter Reihenfolge) ausgewertet und der daraus hervorgehenden +Prozedur werden die sich ergebenden Argumente übergeben. +@cindex @w{Prozeduraufruf} +@cindex @w{Aufruf} + +@format +@t{ +(+ 3 4) ==> 7 +((if #f + *) 3 4) ==> 12 +} +@end format + + +Eine Menge von Prozeduren sind schon als die Werte von Variablen in der +Anfangsumgebung verfügbar; zum Beispiel sind die Prozeduren für die +Addition und Multiplikation in obigen Beispielen die Werte der Variablen +@samp{+} und @samp{*}. Neue Prozeduren entstehen durch das Auswerten +von Lambda-Ausdrücken (siehe den Abschnitt @pxref{Prozeduren}). +@ignore todo +At Friedman's request, flushed mention of other ways. +@end ignore + +@c or definitions (see section~\ref{define}). + +Prozeduraufrufe dürfen eine beliebige Anzahl von Werten zurückgeben +(siehe @code{values} im +@vindex @w{values} +Abschnitt @pxref{Programmflussfunktionalitäten}). Mit Ausnahme von +@samp{Values} geben die in der Anfangsumgebung verfügbaren Prozeduren +einen Wert oder, bei Prozeduren wie @samp{Apply}, genau die Werte, die +ein Aufruf eines ihrer Argumente zurückgibt, zurück. . + +Prozeduraufrufe werden auch @emph{Kombinationen} genannt. + +@cindex @w{Kombination} + + +@quotation +@emph{Anmerkung:} Anders als bei anderen Dialekten von Lisp ist die +Auswertungsreihenfolge unbestimmt und die Ausdrücke für den Operator und +die Operanden werden immer nach denselben Auswertungsregeln ausgewertet. +@end quotation + + + +@quotation +@emph{Anmerkung:} +Obwohl die Auswertungsreihenfolge ansonsten unbestimmt ist, ist die +Wirkung einer beliebigen nebenläufigen Auswertung von Operator- und +Operandausdrücken so weit eingeschränkt, dass sie mit der Wirkung bei +einer beliebigen sequentiellen Auswertungsreihenfolge übereinstimmen +muss. Die Auswertungsreihenfolge darf für jeden Prozeduraufruf +unterschiedlich gewählt werden. +@end quotation + + + +@quotation +@emph{Anmerkung:} +In vielen Dialekten von Lisp ist die leere Kombination @t{()} ein +zulässiger Ausdruck. In Scheme müssen Kombinationen mindestens einen +Unterausdruck haben, so dass @t{()} kein syntaktisch gültiger Ausdruck +ist. +@ignore todo +Dybvig: ``it should be obvious from the syntax.'' +@end ignore + +@end quotation + + +@ignore todo +Freeman: +I think an explanation as to why evaluation order is not specified +should be included. It should not include any reference to parallel +evaluation. Does any existing compiler generate better code because +the evaluation order is unspecified? Clinger: yes: T3, MacScheme v2, +probably MIT Scheme and Chez Scheme. But that's not the main reason +for leaving the order unspecified. +@end ignore + + +@end deffn + + +@node Prozeduren, Bedingungen, Prozeduraufrufe, Grundlegende Ausdruckstypen +@subsection Prozeduren + + + + +@deffn {Syntax} lambda @r{<Formale>} @r{<Rumpf>} + +@emph{Syntax:} +@r{<Formale>} sollte eine Liste formaler Argumente sein, wie sie unten +beschrieben ist, und @r{<Rumpf>} sollte eine Folge von einem oder mehr +Ausdrücken sein. + +@emph{Semantik:} +Ein Lambda-Ausdruck wird immer zu einer Prozedur ausgewertet. Die +Umgebung, die bestand, während der Lambda-Ausdruck ausgewertet wurde, +wird als Teil der Prozedur gespeichert. Wird die Prozedur später mit +tatsächlichen Argumenten aufgerufen, wird die Umgebung, in der der +Lambda-Ausdruck ausgewertet wurde, erweitert, indem die Variablen in der +Liste formaler Argumente an neue Stellen gebunden werden, dann werden +die entssprechenden tatsächlichen Argumentwerte an diese Stellen +gespeichert und die Ausdrücke im Rumpf des Lambda-Ausdrucks werden der +Reihe nach in der erweiterten Umgebung ausgewertet. Das oder die +Ergebnisse des letzten Ausdrucks im Rumpf wird @abbr{bzw.} werden als +das oder die Ergebnisse des Prozeduraufrufs zurückgegeben. + + +@format +@t{(lambda (x) (+ x x)) ==> @emph{}eine Prozedur +((lambda (x) (+ x x)) 4) ==> 8 + +(define reverse-subtract ; rückwärts subtrahieren + (lambda (x y) (- y x))) +(reverse-subtract 7 10) ==> 3 + +(define add4 + (let ((x 4)) + (lambda (y) (+ x y)))) +(add4 6) ==> 10 +} +@end format + + +@r{<Formale>} sollte eine der folgenden Formen haben: + + + +@itemize @bullet + +@item +@t{(@r{<Variable1>} @dots{},)}: +Die Prozedur nimmt eine feste Anzahl von Argumenten; wenn die Prozedur +aufgerufen wird, werden die Argumente in den Bindungen der +entsprechenden Variablen gespeichert. + +@item +@r{<Variable>}: +Die Prozedur nimmt eine beliebige Anzahl von Argumenten entgegen; wird +die Prozedur aufgerufen, wird die Folge aus den tatsächlichen Argumenten +in eine neu angeforderte Liste umgewandelt und diese Liste in der +Bindung von @r{<Variable>} gespeichert. + +@item +@t{(@r{<Variable1>} @dots{}, @r{<Variable_n>} @b{.} +@r{<Variable_n+1>})}: +Wenn ein durch ein Leerzeichen abgetrennter Punkt vor der letzten +Variablen steht, dann nimmt die Prozedur n oder mehr Argumente, wobei n +die Anzahl formaler Argumente vor dem Punkt ist (es muss mindestens +eines geben). Der Wert, der in der Bindung der letzten Variablen +gespeichert wird, wird der einer neu angeforderten Liste derjenigen +tatsächlichen Argumente sein, die nach Verteilung aller anderen +tatsächlichen Argumente auf die anderen formalen Argumenten übrig +bleiben. + +@end itemize + + +Es ist ein Fehler, wenn eine @r{<Variable>} mehr als einmal in +@r{<Formale>} vorkommt. + + +@format +@t{((lambda x x) 3 4 5 6) ==> (3 4 5 6) +((lambda (x y . z) z) + 3 4 5 6) ==> (5 6) +} +@end format + + +Jede Prozedur, die durch das Auswerten eines Lambda-Ausdrucks entsteht, +wird (konzeptionell) mit einer Speicherstelle beschriftet, damit +@code{eqv?} und +@vindex @w{eqv?} +@code{eq?} mit Prozeduren umgehen können (siehe den Abschnitt +@pxref{Äquivalenzprädikate}). +@vindex @w{eq?} + +@end deffn + + +@node Bedingungen, Zuweisungen, Prozeduren, Grundlegende Ausdruckstypen +@subsection Bedingungen + + + +@deffn {Syntax} if @r{<Test>} @r{<Folgerung>} @r{<Alternative>} +@deffnx {Syntax} if @r{<Test>} @r{<Folgerung>} +@c \/ if hyper = italic + +@emph{Syntax:} @r{<Test>}, @r{<Folgerung>} und @r{<Alternative>} dürfen +beliebige Ausdrücke sein. + +@emph{Semantik:} +Ein @samp{If}-Ausdruck wird wie folgt ausgewertet: Zuerst wird +@r{<Test>} ausgewertet. Wenn er einen wahren Wert liefert (siehe +@cindex @w{wahr} +den Abschnitt @pxref{Boolesche Werte}), dann wird @r{<Folgerung>} +ausgewertet und ihr(e) Wert(e) zurückgegeben. Ansonsten wird +@r{<Alternative>} ausgewertet und ihr(e) Wert(e) zurückgegeben. Wenn +@r{<Test>} einen falschen Wert liefert und keine @r{<Alternative>} +angegeben wurde, ist das Ergebnis des Ausdrucks unbestimmt. + + +@format +@t{(if (> 3 2) 'ja 'nein) ==> ja +(if (> 2 3) 'ja 'nein) ==> nein +(if (> 3 2) + (- 3 2) + (+ 3 2)) ==> 1 +} +@end format + + +@end deffn + + +@node Zuweisungen, , Bedingungen, Grundlegende Ausdruckstypen +@subsection Zuweisungen + + + + +@deffn {Syntax} set! @r{<Variable>} @r{<Ausdruck>} + +@r{<Ausdruck>} wird ausgewertet und der sich ergebende Wert an der +Stelle gespeichert, an die @r{<Variable>} gebunden ist. @r{<Variable>} +muss entweder in einer Region gebunden sein, die den +@samp{Set!}-Ausdruck einschließt, +@cindex @w{Region} +oder auf oberster Ebene gebunden sein. Das Ergebnis des +@samp{Set!}-Ausdrucks ist unbestimmt. + + +@format +@t{(define x 2) +(+ x 1) ==> 3 +(set! x 4) ==> @emph{unbestimmt} +(+ x 1) ==> 5 +} +@end format + + +@end deffn + + +@node Abgeleitete Ausdruckstypen, Makros, Grundlegende Ausdruckstypen, Ausdrücke +@section Abgeleitete Ausdruckstypen + +@menu +* Bedingung:: +* Bindungskonstrukte:: +* Sequenzierung:: +* Iteration:: +* Verzögerte Auswertung:: +* Quasimaskierung:: +@end menu + + + +Die Konstrukte in diesem Abschnitt sind hygienisch, wie im Abschnitt +@ref{Makros} diskuttiert. +Als Referenz sind im Abschnitt @ref{Abgeleitete Ausdruckstypen} +Makrodefinitionen zu finden, die die meisten hier beschriebenen +Konstrukte in grundlegende Konstrukte, die im vorherigen Abschnitt +beschrieben wurden, umwandeln. + +@ignore todo +Mention that no definition of backquote is provided? +@end ignore + + +@node Bedingung, Bindungskonstrukte, Abgeleitete Ausdruckstypen, Abgeleitete Ausdruckstypen +@subsection Bedingungen + + + +@deffn {Bibliothekssyntax} cond <Klausel1> <Klausel2> @dots{}, + +@emph{Syntax:} +Jede @r{<Klausel>} sollte entweder folgende Form haben: + +@format +@t{(@r{<Test>} @r{<Ausdruck1>} @dots{},) +} +@end format + +wobei @r{<Test>} ein beliebiger Ausdruck ist, oder die @r{<Klausel>} hat +alternativ diese Form: + +@format +@t{(@r{<Test>} => @r{<Ausdruck>}) +} +@end format + +Die letzte @r{<Klausel>} darf auch eine „else-Klausel`` sein, welche +die folgende Form hat: + +@format +@t{(else @r{<Ausdruck1>} @r{<Ausdruck2>} @dots{},)@r{.} +} +@end format + + +@cindex @w{Else} + +@cindex @w{=>} + +@emph{Semantik:} +Ein @samp{Cond}-Ausdruck wird ausgewertet, indem man der Reihe nach die +@r{<Test>}-Ausdrücke der aufeinanderfolgenden @r{<Klausel>}n auswertet, +bis eine von ihnen zu einem wahren Wert ausgewertet wird (siehe +@cindex @w{wahr} +den Abschnitt @pxref{Boolesche Werte}). Sobald ein @r{<Test>} zu einem +wahren Wert ausgewertet wird, werden die verbleibenden in seiner +@r{<Klausel>} stehenden Vorkommen eines @r{<Ausdruck>}s der Reihe nach +ausgewertet und das Ergebnis @abbr{bzw.} die Ergebnisse des letzten +@r{<Ausdruck>}s in der @r{<Klausel>} wird(werden) als Ergebnis(se) des +gesamten @samp{Cond}-Ausdrucks zurückgegeben. Wenn die gewählte +@r{<Klausel>} nur den @r{<Test>} und keine Vorkommen von @r{<Ausdruck>} +enthält, dann wird der Wert vom @r{<Test>} als Ergebnis zurückgegeben. +Wenn die gewählte @r{<Klausel>} die alternative Form mit @code{=>} +benutzt, dann wird der @r{<Ausdruck>} ausgewertet. +@vindex @w{=>} +Sein Wert muss eine Prozedur sein, die ein Argument annimmt; diese +Prozedur wird dann mit dem Wert vom @r{<Test>} aufgerufen und der von +dieser Prozedur zurückgegebene Wert @abbr{bzw.} die von ihr +zurückgegebenen Werte werden dann auch vom @samp{Cond}-Ausdruck +zurückgegeben. Wenn jeder @r{<Test>} zu falschen Werten ausgewertet +wird und es keine else-Klausel gibt, dann ist das Ergebnis des bedingten +Ausdrucks unbestimmt; gibt es eine else-Klausel, dann werden seine +@r{<Ausdruck>}-Vorkommen ausgewertet und der Wert @abbr{bzw.} die Werte +des letzten Ausdrucks zurückgegeben + + +Das folgende Beispiel nimmt an, dass die benutzte Scheme-Implementierung +die Umlaute und das scharfe S (ß) auch als Buchstabenzeichen ansieht, +als Erweiterung zur in diesem Bericht spezifizierten Syntax: + +@format +@t{(cond ((> 3 2) 'größer) + ((< 3 2) 'kleiner)) ==> größer + +(cond ((> 3 3) 'größer) + ((< 3 3) 'kleiner) + (else 'gleich)) ==> gleich + +(cond ((assv 'b '((a 1) (b 2))) => cadr) + (else #f)) ==> 2 +} +@end format + + + +@end deffn + + + +@deffn {Bibliothekssyntax} case @r{<Schlüssel>} <Klausel1> <Klausel2> @dots{}, + +@emph{Syntax:} +@r{<Schlüssel>} darf ein beliebiger Ausdruck sein. Jede @r{<Klausel>} +sollte die folgende Form haben: + +@format +@t{((@r{<Datenelement1>} @dots{},) @r{<Ausdruck1>} @r{<Ausdruck2>} @dots{},)@r{,} +} +@end format + +wobei jedes @r{<Datenelement>} eine externe Darstellung irgendeines +Objekts ist. Alle @r{<Datenelement>}e müssen verschieden sein. Die +letzte @r{<Klausel>} darf eine „else-Klausel`` sein, welche die folgende +Form hat: + +@format +@t{(else @r{<Ausdruck1>} @r{<Ausdruck2>} @dots{},)@r{.} +} +@end format + + +@vindex else + +@emph{Semantik:} +Ein @samp{Case}-Ausdruck wird wie folgt ausgewertet. @r{<Schlüssel>} +wird ausgewertet und sein Ergebnis mit jedem @r{<Datenelement>} +verglichen. Wenn das Ergebnis der Auswertung von @r{<Schlüssel>} +gleichwertig ist (im Sinne von @samp{Eqv?}; siehe den Abschnitt +@pxref{Äquivalenzprädikate}) mit einem @r{<Datenelement>}, dann werden +die Ausdrücke in der entsprechenden @r{<Klausel>} von links nach rechts +ausgewertet und das Ergebnis @abbr{bzw.} die Ergebnisse des letzten +Ausdrucks in der @r{<Klausel>} werden als Ergebnis(se) des +@samp{Case}-Ausdrucks zurückgegeben. Wenn die Auswertung von +@r{<Schlüssel>} zu einem anderen Ergebnis als jedes @r{<Datenelement>} +führt, dann werden, wenn es eine else-Klausel gibt, ihre Ausdrücke +ausgewertet und das Ergebnis @abbr{bzw.} die Ergebnisse des letzten +davon ist das Ergebnis @abbr{bzw.} sind die Ergebnisse des +@samp{Case}-Ausdrucks; andernfalls ist das Ergebnis des +@samp{Case}-Ausdrucks unbestimmt. + + +@format +@t{(case (* 2 3) + ((2 3 5 7) 'prim) + ((1 4 6 8 9) 'zusammengesetzt)) ==> zusammengesetzt +(case (car '(c d)) + ((a) 'a) + ((b) 'b)) ==> @emph{unbestimmt} +(case (car '(c d)) + ((a e i o u) 'Vokal) + ((j) 'Halbvokal) + (else 'Konsonant)) ==> Konsonant +} +@end format + + +@end deffn + + + +@deffn {Bibliothekssyntax} and <Test1> @dots{}, + +Die @r{<Test>}-Ausdrücke werden von links nach rechts ausgewertet und +der Wert des ersten Ausdrucks, der zu einem falschen Wert ausgewertet +wird (siehe den Abschnitt @pxref{Boolesche Werte}) wird zurückgegeben. +Jegliche verbleibenden Ausdrücke werden nicht ausgewertet. Wenn alle +Ausdrücke zu wahren Werten ausgewertet werden, wird der Wert des letzten +Ausdrucks zurückgegeben. Gibt es keine Ausdrücke, so wird @t{#t} +zurückgegeben. + + +@format +@t{(and (= 2 2) (> 2 1)) ==> #t +(and (= 2 2) (< 2 1)) ==> #f +(and 1 2 'c '(f g)) ==> (f g) +(and) ==> #t +} +@end format + + +@end deffn + + + +@deffn {Bibliothekssyntax} or <Test1> @dots{}, + +Die @r{<Test>}-Ausdrücke werden von links nach rechts ausgewertet und +der Wert des ersten Ausdrucks, der zu einem wahren Wert ausgewertet wird +(siehe den Abschnitt @pxref{Boolesche Werte}) wird zurückgegeben. +Jegliche verbleibenden Ausdrücke werden nicht ausgewertet. Wenn alle +Ausdrücke zu falschen Werten ausgewertet werden, wird der Wert des +letzten Ausdrucks zurückgegeben. Gibt es keine Ausdrücke, so wird +@t{#f} zurückgegeben. + + +@format +@t{(or (= 2 2) (> 2 1)) ==> #t +(or (= 2 2) (< 2 1)) ==> #t +(or #f #f #f) ==> #f +(or (memq 'b '(a b c)) + (/ 3 0)) ==> (b c) +} +@end format + + +@end deffn + + +@node Bindungskonstrukte, Sequenzierung, Bedingungen, Abgeleitete Ausdruckstypen +@subsection Bindungskonstrukte + + +Die drei Bindungskonstrukte @samp{Let}, @samp{Let*} und @samp{Letrec} +verleihen Scheme eine Block-Struktur wie bei Algol 60. [Auf Deutsch +heißt „Let ...`` soviel wie „Sei ...``.] Die Syntax der drei Konstrukte +ist identisch, aber sie unterscheiden sich in den Regionen, die sie für +ihre Variablenbindungen herstellen +@cindex @w{Region} +In einem @samp{Let}-Ausdruck werden die Anfangswerte berechnet, bevor +ihre Variablen gebunden werden; in einem @samp{Let*}-Ausdruck werden die +Bindungen und Auswertungen eine nach der anderen der Reihe nach +durchgeführt, während in einem @samp{Letrec}-Ausdruck alle Bindungen +bereits gelten, während ihre Anfangswerte berechnet werden, wodurch +wechselseitig rekursive Definitionen ermöglicht werden. + + +@deffn {Bibliothekssyntax} let @r{<Bindungen>} @r{<Rumpf>} + +@emph{Syntax:} +@r{<Bindungen>} sollte die folgende Form haben: + +@format +@t{((@r{<Variable1>} @r{<Anfang1>}) @dots{},)@r{,} +} +@end format + +wobei jeder @r{<Anfang>} ein Ausdruck ist und der @r{<Rumpf>} eine Folge +von einem oder mehr Ausdrücken sein sollte. Es ist ein Fehler, wenn +eine @r{<Variable>} mehr als einmal in der Liste der zu bindenden +Variablen vorkommt. + +@emph{Semantik:} +Jeder @r{<Anfang>} wird in der aktuellen Umgebung ausgewertet (in +unbestimmter Reihenfolge), dann werden die @r{<Variable>}n an neue +Stellen gebunden, die die Ergebnisse enthalten, woraufhin der +@r{<Rumpf>} in der so erweiterten Umgebung ausgewertet wird und der Wert +@abbr{bzw.} die Werte des letzten Ausdrucks im @r{<Rumpf>} zurückgegeben +wird(werden). Jede Bindung einer @r{<Variable>}n hat den @r{<Rumpf>} +als ihre Region. +@cindex @w{Region} + + +@format +@t{(let ((x 2) (y 3)) + (* x y)) ==> 6 + +(let ((x 2) (y 3)) + (let ((x 7) + (z (+ x y))) + (* z x))) ==> 35 +} +@end format + + +Siehe auch das benannte @samp{Let}, Abschnitt @ref{Iteration}. + +@end deffn + + + +@deffn {Bibliothekssyntax} let* @r{<Bindungen>} @r{<Rumpf>} + + +@emph{Syntax:} +@r{<Bindungen>} sollte die folgende Form haben: + +@format +@t{((@r{<Variable1>} @r{<Anfang1>}) @dots{},)@r{,} +} +@end format + +und der @r{<Rumpf>} sollte eine Folge von einem oder mehr Ausdrücken +sein. + +@emph{Semantik:} +@samp{Let*} ist ähnlich wie @samp{Let}, aber die Bindungen werden der +Reihe nach von links nach rechts durchgeführt und die Region einer +Bindung, die +@cindex @w{Region} +durch @samp{(@r{<Variable>} @r{<Anfang>})} angezeigt wird, ist der Teil +des @samp{Let*}-Ausdrucks rechts von der Bindung. Dadurch wird die +zweite Bindung in einer Umgebung ausgeführt, in der die erste Bindung +bereits sichtbar ist, und so weiter. + + +@format +@t{(let ((x 2) (y 3)) + (let* ((x 7) + (z (+ x y))) + (* z x))) ==> 70 +} +@end format + + +@end deffn + + + +@deffn {Bibliothekssyntax} letrec @r{<Bindungen>} @r{<Rumpf>} + +@emph{Syntax:} +@r{<Bindungen>} folgende Form haben sollte: + +@format +@t{((@r{<Variable1>} @r{<Anfang1>}) @dots{},)@r{,} +} +@end format + +und @r{<Rumpf>} eine Folge von einem oder mehreren Ausdrücken sein +sollte. Es ist ein Fehler, wenn eine @r{<Variable>} mehr als einmal in +der Liste der zu bindenden Variablen vorkommt. + +@emph{Semantik:} +Die @r{<Variable>}n werden an neue Stellen gebunden, die noch unfertige +Werte enthalten, jeder @r{<Anfang>} wird (in unbestimmter Reihenfolge) +ausgewertet, jeder Variablen das Ergebnis des zugehörigen @r{<Anfang>}s +zugewiesen und der @r{<Rumpf>} in der daraus hervorgehenden Umgebung +ausgewertet und der Wert @abbr{bzw.} die Werte des letzten Ausdrucks im +@r{<Rumpf>} zurückgegeben. Jede Bindung einer @r{<Variable>}n hat den +gesamten @samp{Letrec}-Ausdruck als ihre Reguibm was es ermöglicht, +@cindex @w{Region} +wechselseitig rekursive Prozeduren zu definieren. + + +@format +@t{(letrec ((even? ; gerade? + (lambda (n) + (if (zero? n) + #t + (odd? (- n 1))))) + (odd? ; ungerade? + (lambda (n) + (if (zero? n) + #f + (even? (- n 1)))))) + (even? 88)) + ==> #t +} +@end format + + +Eine Einschränkung von @samp{Letrec} ist sehr wichtig: es muss möglich +sein, jeden @r{<Anfang>} auszuwerten, ohne dass ein Wert irgendeiner +@r{<Variable>}n zugewiesen oder referenziert wird. Wird diese +Einschränkung verletzt, ist es ein Fehler. Die Einschränkung ist +notwendig, weil Scheme Argumente als Wertparameter und nicht als +Namensparameter übergibt. In den üblichsten Nutzungen von @samp{Letrec} +ist jeder @r{<Anfang>} ein Lambda-Ausdruck und die Einschränkung gilt +automatisch. + +@c \todo{use or uses? --- Jinx.} + +@end deffn + + +@node Sequenzierung, Iteration, Bindungskonstrukte, Abgeleitete Ausdruckstypen +@subsection Sequenzierung + + + +@deffn {Bibliothekssyntax} begin <Ausdruck1> <Ausdruck2> @dots{}, + +Jeder @r{<Ausdruck>} wird der Reihe nach von links nach rechts +ausgewertet und der Wert @abbr{bzw.} die Werte des letzten +@r{<Ausdruck>}s zurückgegeben. Dieser Ausdruckstyp wird für +Wirkungen wie Ein- und Ausgabe benutzt. + + +@format +@t{(define x 0) + +(begin (set! x 5) + (+ x 1)) ==> 6 + +(begin (display "4 plus 1 ist gleich ") + (display (+ 4 1))) ==> @emph{unbestimmt} + @emph{und gibt aus} 4 plus 1 ist gleich 5 +} +@end format + + +@end deffn + + +@node Iteration, Verzögerte Auswertung, Sequenzierung, Abgeleitete Ausdruckstypen +@subsection Iteration + +@c \unsection + + +@noindent + +@deffn {Bibliothekssyntax} do ((@r{<Variable1>} @r{<Anfang1>} @r{<Schritt1>}) @dots{}) (@r{<Test>} @r{<Ausdruck>} @dots{}) @r{<Befehl>} @dots{} +@cindex @w{Do} + +@samp{Do} (deutsch „tu``) ist ein Iterationskonstrukt. Es gibt eine +Menge von Variablen an, die zu binden sind, welchen Wert sie anfänglich +haben sollen und wie sie in jeder Iteration aktualisiert werden sollen. +Wird eine Terminierungsbedingung erfüllt, dann wird die Schleife nach +der Auswertung jedes @r{<Ausdruck>}s verlassen. + +@samp{Do}-Ausdrücke werden wie folgt ausgewertet: Die +@r{<Anfang>}sausdrücke werden ausgewertet (in einer unbestimmten +Reihenfolge), die @r{<Variable>}n werden an neue Stellen gebunden, die +Ergebnisse der @r{<Anfang>}sausdrücke in den Bindungen der +@r{<Variable>}n gespeichert und dann beginnt die Iterationsphase. + +Jede Iteration beginnt mit dem Auswerten vom @r{<Test>}; wenn das +Ergebnis falsch ist (siehe den Abschnitt @pxref{Boolesche Werte}), dann +werden der Reihe nach die Ausdrücke des @r{<Befehl>}s für ihre Wirkung +ausgewertet, die @r{<Schritt>}-Ausdrücke in einer unbestimmten +Reihenfolge ausgewertet, die @r{<Variable>}n an neue Stellen gebunden, +die Ergebnisse der @r{<Schritt>}e in den Bindungen der @r{<Variable>}n +gespeichert und die nächste Iteration fängt an. + +Wenn der @r{<Test>} zu einem wahren Wert ausgewertet wird, dann wird von +rechts nach links jeder @r{<Ausdruck>} ausgewertet und der Wert +@abbr{bzw.} die Werte des letzten @r{<Ausdruck>}s zurückgegeben. Gibt +es keinen @r{<Ausdruck>}, ist der Wert des @samp{Do}-Ausdrucks +unbestimmt. + +Die Region der Bindung einer @r{<Variable>}n +@cindex @w{Region} +besteht aus dem gesamten @samp{Do}-Ausdruck außer jedem @r{<Anfang>}. +Es ist ein Fehler, wenn eine @r{<Variable>} mehr als einmal in der Liste +der @samp{Do}-Variablen vorkommt. + +Ein @r{<Schritt>} darf weggelassen werden. In diesem Fall ist die +Wirkung dieselbe, wie wenn @samp{(@r{<Variable>} @r{<Anfang>} +@r{<Variable>})} statt @samp{(@r{<Variable>} @r{<Anfang>})} geschrieben +worden wäre. + + +@format +@t{(do ((vec (make-vector 5)) + (i 0 (+ i 1))) + ((= i 5) vec) + (vector-set! vec i i)) ==> #(0 1 2 3 4) + +(let ((x '(1 3 5 7 9))) + (do ((x x (cdr x)) + (Summe 0 (+ Summe (car x)))) + ((null? x) Summe))) ==> 25 +} +@end format + + +@c \end{entry} +@end deffn + + +@deffn {Bibliothekssyntax} let @r{<Variable>} @r{<Bindungen>} @r{<Rumpf>} + + +„Benanntes @samp{Let}`` ist eine Variante der Syntax von @code{Let}, die +@vindex @w{Let} +ein allgemeineres Schleifenkonstrukt als @samp{Do} bietet und auch zum +Ausdrücken von Rekursion benutzt werden kann. +Es hat dieselbe Syntax und Semantik wie das herkömmliche @samp{Let}, +außer dass @r{<Variable>} im @r{<Rumpf>} an eine Prozedur gebunden wird, +deren formale Argumente die gebundenen Variablen und deren Rumpf der +@r{<Rumpf>} ist. Daher kann durch einen Aufruf der durch die +@r{<Variable>} benannten Prozedur die Ausführung des @r{<Rumpf>}s +wiederholt werden. + +@c | <-- right margin + +@format +@t{(let loop ((Zahlen '(3 -2 1 6 -5)) + (nichtneg '()) + (neg '())) + (cond ((null? Zahlen) (list nichtneg neg)) + ((>= (car Zahlen) 0) + (loop (cdr Zahlen) + (cons (car Zahlen) nichtneg) + neg)) + ((< (car Zahlen) 0) + (loop (cdr Zahlen) + nichtneg + (cons (car Zahlen) neg))))) + ==> ((6 1 3) (-5 -2)) +} +@end format + + +@end deffn + + +@node Verzögerte Auswertung, Quasimaskierung, Iteration, Abgeleitete Ausdruckstypen +@subsection Verzögerte Auswertung + + + +@deffn {Bibliothekssyntax} delay @r{<Ausdruck>} + +@ignore todo +Fix. +@end ignore + + +Das @samp{Delay}-Konstrukt (deutsch „verzögern``) wird zusammen mit der +Prozedur @code{Force} (deutsch „erzwingen``) benutzt, um +@vindex @w{Force} +@dfn{verzögerte Auswertung} (Lazy evaluation) oder +@dfn{Bedarfsparameter} (Call by need) zu implementieren. +@cindex @w{Bedarfsparameter} +@cindex @w{Call by need} +@cindex @w{verzögerte Auswertung} +@cindex @w{Lazy evaluation} +@t{(delay @r{<Ausdruck>})} gibt ein Objekt zurück, was +@dfn{Versprechen} (Promise) genannt wird, welches zu einem zukünftigen +Zeitpunkt (durch +@cindex @w{Versprechen} +die @samp{Force}-Prozedur) +@ignore todo +Bartley's white lie; OK? +@end ignore + um die Auswertung des @r{<Ausdruck>}s gebeten werden kann und dann den +sich daraus ergebenden Wert liefert. Wenn der @r{<Ausdruck>} mehrere +Werte zurückgibt, ist die Wirkung davon unbestimmt. + +Siehe die Beschreibung von @samp{Force} (im Abschnitt +@pxref{Programmflussfunktionalitäten}) für eine vollständigere +Beschreibung von @samp{Delay}. + +@end deffn + + +@node Quasimaskierung, , Verzögerte Auswertung, Abgeleitete Ausdruckstypen +@subsection Quasimaskierung + + + + +@deffn {Syntax} quasiquote @r{<qq-Schablone>} + +@deffnx {Syntax} @t{`}@r{<qq-Schablone>} + + +„Backquote`` oder „Quasiquote``-Ausdrücke zur Quasimaskierung nützen +@cindex @w{Backquote} +beim Erstellen einer Liste oder Vektorstruktur, wenn die meisten aber +nicht alle Bestandteile der gewünschten Struktur im Voraus bekannt sind. +Wenn kein Komma innerhalb der @r{<qq-Schablone>} vorkommt, ist das +Ergebnis der +@cindex @w{Komma} +Auswertung von @t{`}@r{<qq-Schablone>} äquivalent zum Ergebnis der +Auswertung von @t{'}@r{<qq-Schablone>}. Kommt jedoch ein Komma +innerhalb der +@cindex @w{,} +@r{<qq-Schablone>} vor, so wird der auf das Komma folgende Ausdruck +ausgewertet („demaskiert``) und sein Ergebnis in die Struktur an Stelle +des Kommas und des Ausdrucks eingefügt. Kommt ein Komma direkt gefolgt +von einem At-Zeichen (@@) vor, muss der folgende +@cindex @w{,@@} +Ausdruck zu einer Liste ausgewertet werden; die öffnenden und +schließenden runden Klammern der Liste werden dann weggenommen und die +Elemente der Liste an Stelle der Komma-At-Zeichen-Ausdrucksfolge +eingefügt. Ein Komma-At-Zeichen sollte nur innerhalb einer Listen- oder +Vektor-@r{<qq-Schablone>} vorkommen. + +@c struck: "(in the sense of {\cf equal?})" after "equivalent" + + +@format +@t{`(list ,(+ 1 2) 4) ==> (list 3 4) +(let ((Name 'a)) `(list ,Name ',Name)) + ==> (list a (quote a)) +`(a ,(+ 1 2) ,@@(map abs '(4 -5 6)) b) + ==> (a 3 4 5 6 b) +`((@samp{foo} ,(- 10 3)) ,@@(cdr '(c)) . ,(car '(cons))) + ==> ((foo 7) . cons) +`#(10 5 ,(sqrt 4) ,@@(map sqrt '(16 9)) 8) + ==> #(10 5 2 4 3 8) +} +@end format + + +Quasimaskierungsformen dürfen verschachtelt werden. Ersetzungen werden +nur für demaskierte Bestandteile durchgeführt, die auf derselben +Verschachtelungsstufe wie das äußerste Backquote-Zeichen stehen. Die +Verschachtelungsstufe erhöht sich um eins für jede folgende +Quasimaskierung und sinkt ums eins in jeder Demaskierung. + + +@format +@t{`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f) + ==> (a `(b ,(+ 1 2) ,(foo 4 d) e) f) +(let ((Name1 'x) + (Name2 'y)) + `(a `(b „Name1 ,',Name2 d) e)) + ==> (a `(b ,x ,'y d) e) +} +@end format + + +Die beiden Notationen + @t{`}@r{<qq-Schablone>} und @t{(quasiquote @r{<qq-Schablone>})} + sind in allen Bezügen identisch. + @samp{,@r{<Ausdruck>}} ist identisch mit @samp{(unquote @r{<Ausdruck>})}, + und + @samp{,@@@r{<Ausdruck>}} ist identisch mit + @samp{(unquote-splicing @r{<Ausdruck>})}. +Welche externe Syntax @code{Write} für zweielementige Listen, deren +@vindex @w{Write} +Car eines dieser Symbole ist, erzeugt, darf je nach Implementierung +abweichen. + +@cindex @w{`} + + +@format +@t{(quasiquote (list (unquote (+ 1 2)) 4)) + ==> (list 3 4) +'(quasiquote (list (unquote (+ 1 2)) 4)) + ==> `(list ,(+ 1 2) 4) + @emph{}d.h. (quasiquote (list (unquote (+ 1 2)) 4)) +} +@end format + + +Unvorhersehbares Verhalten darf auftreten, wenn eines der Symbole +@code{Quasiquote}, @code{Unquote} oder @code{Unquote-splicing} in einer +@vindex @w{Unquote-splicing} +@vindex @w{Unquote} +@vindex @w{Quasiquote} +Positions innerhalb einer @r{<qq-Schablone>} auf andere Weise als oben +beschrieben vorkommt. + +@end deffn + +@node Makros, , Abgeleitete Ausdruckstypen, Ausdrücke +@section Makros + +@menu +* Bindungskonstrukte für syntaktische Schlüsselwörter:: +* Mustersprache:: +@end menu + + + +Scheme-Programme können neue abgeleitete Ausdruckstypen definieren und +benutzen. Diese nennt man @emph{Makros}. +@cindex @w{Makro} +Vom Programm definierte Ausdruckstypen haben die Syntax + +@example + +(@r{<Schlüsselwort>} @r{<Datenelement>} ...) + +@end example + +wobei @r{<Schlüsselwort>} ein Bezeichner ist, der den Ausdruckstyp +eindeutig festlegt. Dieser Bezeichner wird das @emph{syntaktische +Schlüsselwort} oder einfach @emph{Schlüsselwort} des Makros genannt. +Die +@cindex @w{Makro-Schlüsselwort} +@cindex @w{Schlüsselwort} +@cindex @w{syntaktisches Schlüsselwort} +Anzahl der @r{<Datenelement>}e und ihre Syntax hängt vom Ausdruckstyp +ab. + +Jede Instanz eines Makros als eine @emph{Benutzung} +@cindex @w{Makro-Benutzung} +des Makros bezeichnet. Die Menge an Regeln, die festlegen, wie eine +Makro-Benutzung zu einem grundlegenderen Ausdruck umgeschrieben wird, +heißt der @emph{Umwandler} +@cindex @w{Makroumwandler} +des Makros. + +Die Mittel zur Makro-Definition setzen sich aus zwei Teilen zusammen: + + + +@itemize @bullet + +@item +Eine Menge von Ausdrücken, um bestimmte Bezeichner als Makroausdrücke zu +kennzeichnen, sie mit Makroumwandlern zu verknüpfen und den +Sichtbarkeitsbereich, in dem ein Makro definiert ist, zu steuern, sowie + +@item +eine Mustersprache zum Angeben von Makroumwandlern. + +@end itemize + + +Das syntaktische Schlüsselwort eines Makros darf Variablenbindungen +überdecken und lokale Variablenbindungen dürfen Schlüsselwortbindungen +überdecken. Alle Makros, +@cindex @w{Schlüsselwort} +die mit der Mustersprache definiert wurden, sind „hygienisch`` und +„referenziell transparent``, also bleibt Schemes lexikalische Bindung +intakt [Kohlbecker86], [ hygienic], [Bawden88], [macrosthatwork], +[syntacticabstraction]: + +@cindex @w{hygienisch} + +@cindex @w{referenziell transparent} + + + + +@itemize @bullet + + +@item +Wenn ein Makroumwandler eine Bindung für einen Bezeichner (Variable oder +Schlüsselwort) einfügt, verhält sich diese, als würde der Bezeichner in +seinem gesamten Sichtbarkeitsbereich umbenannt, um Konflikte mit anderen +gleichnamigen Bezeichnern zu vermeiden. Beachten Sie, dass ein +@code{define} auf oberster Ebene eine Bindung einführen darf oder nicht, +siehe den Abschnitt @ref{Definitionen}. + +@item +Wenn ein Makroumwandler eine freie Referenz auf einen Bezeichner +einfügt, bezieht sich die Referenz auf die Bindung, die sichtbar war, +als der Makroumwandler festgelegt wurde, ohne Berücksichtigung jeglicher +lokaler Bindungen, die die Makro-Benutzung umgeben könnten. + + +@end itemize + +@vindex @w{Define} + +@c The low-level facility permits non-hygienic macros to be written, +@c and may be used to implement the high-level pattern language. + +@c The fourth section describes some features that would make the +@c low-level macro facility easier to use directly. + +@node Bindungskonstrukte für syntaktische Schlüsselwörter, Mustersprache, Makros, Makros +@subsection Bindungskonstrukte für syntaktische Schlüsselwörter + + + +@samp{Let-syntax} und @samp{Letrec-syntax} sind analog zu @samp{Let} und +@samp{Letrec}, aber sie binden syntaktische Schlüsselwörter an +Makrosumwandler statt Variable an Stellen zu binden, die Werte +enthalten. Syntaktische Schlüsselwörter dürfen auch auf oberster Ebene +gebunden werden; siehe den Abschnitt @ref{Syntaxdefinitionen}. + + +@deffn {Syntax} let-syntax @r{<Bindingungen>} @r{<Rumpf>} + +@emph{Syntax:} +@r{<Bindungen>} sollte folgende Form haben: + +@format +@t{((@r{<Schlüsselwort>} @r{<Umwandlerspezifikation>}) @dots{},) +} +@end format + +Jedes @r{<Schlüsselwort>} ist ein Bezeichner, jede +@r{<Umwandlerspezifikation>} ist eine Instanz von @samp{Syntax-rules} +und @r{<Rumpf>} sollte eine Folge von einem oder mehreren Ausdrücken +sein. Es ist ein Fehler, wenn ein @r{<Schlüsselwort>} mehr als einmal +in der Liste der Schlüsselwörter auftaucht, die gebunden werden. + +@emph{Semantik:} +Der @r{<Rumpf>} wird in der syntaktischen Umgebung umgeschrieben, die +entsteht, wenn die syntaktische Umgebung des @samp{Let-syntax}-Ausdrucks +um Makros, deren Schlüsselwörter die aus den +@r{<Schlüsselwort>}-Vorkommen sind, gebunden an die angegebenen +Umwandler, erweitert wird. Jede Bindung eines @r{<Schlüsselwort>}s hat +den @r{<Rumpf>} als ihre Region. + + +Das folgende Beispiel nimmt an, dass die benutzte Scheme-Implementierung +das scharfe S (ß) auch als Buchstabenzeichen ansieht, als Erweiterung +zur in diesem Bericht spezifizierten Syntax: + +@format +@t{(let-syntax ((when (syntax-rules () + ((when Test Anweisung1 Anweisung2 ...) + (if Test + (begin Anweisung1 + Anweisung2 ...)))))) + (let ((if #t)) + (when if (set! if 'jetzt)) + if)) ==> jetzt + +(let ((x 'außen)) + (let-syntax ((m (syntax-rules () ((m) x)))) + (let ((x 'innen)) + (m)))) ==> außen +} +@end format + + +@end deffn + + +@deffn {Syntax} letrec-syntax @r{<Bindungen>} @r{<Rumpf>} + +@emph{Syntax:} +Dieselbe wie bei @samp{Let-syntax}. + +@emph{Semantik:} +Der @r{<Rumpf>} wird in der syntaktischen Umgebung umgeschrieben, die +entsteht, wenn die syntaktische Umgebung des +@samp{Letrec-syntax}-Ausdrucks um die Makros, deren Schlüsselwörter die +aus den @r{<Schlüsselwort>}-Vorkommen sind, gebunden an die angegebenen +Umwandler, erweitert wird. +Jede Bindung eines @r{<Schlüsselwort>}s hat die @r{<Bindungen>} sowie +den @r{<Rumpf>} in ihrer Region, so dass die Umwandler Ausdrücke zu +Benutzungen der Makros umschreiben können, die durch den +@samp{Letrec-syntax}-Ausdruck eingeführt wurden. + + +@format +@t{(letrec-syntax + ((mein-or (syntax-rules () + ((mein-or) #f) + ((mein-or e) e) + ((mein-or e1 e2 ...) + (let ((temp e1)) + (if temp + temp + (mein-or e2 ...))))))) + (let ((x #f) + (y 7) + (temp 8) + (let odd?) + (if even?)) + (mein-or x + (let temp) + (if y) + y))) ==> 7 +} +@end format + + +@end deffn + +@node Mustersprache, , Bindungskonstrukte für syntaktische Schlüsselwörter, Makros +@subsection Mustersprache + + + +Eine @r{<Umwandlerspezifikation>} hat folgende Form: + + +@deffn {} syntax-rules @r{<Literale>} @r{<Syntaxregel>} @dots{}, + +@emph{Syntax:} +@r{<Literale>} sind eine Liste von Bezeichnern, und jede +@r{<Syntaxregel>} sollten die folgende Form haben + +@format +@t{(@r{<Muster>} @r{<Schablone>}) +} +@end format + +Das @r{<Muster>} in einer @r{<Syntaxregel>} ist ein listenförmiges +@r{<Muster>}, dessen Listenform mit dem Schlüsselwort für das Makro +beginnt. + +Allgemein ist ein @r{<Muster>} entweder ein Bezeichner, eine Konstante +oder eines der Folgenden + +@format +@t{(@r{<Muster>} @dots{}) +(@r{<Muster>} @r{<Muster>} @dots{} . @r{<Muster>}) +(@r{<Muster>} @dots{} @r{<Muster>} @r{<Auslassungspunkte>}) +#(@r{<Muster>} @dots{}) +#(@r{<Muster>} @dots{} @r{<Muster>} @r{<Auslassungspunkte>}) +} +@end format + +und eine Schablone ist ein Bezeichner, eine Konstante oder eines der +Folgenden + +@format +@t{(@r{<Element>} @dots{}) +(@r{<Element>} @r{<Element>} @dots{} . @r{<Schablone>}) +#(@r{<Element>} @dots{}) +} +@end format + +wobei ein @r{<Element>} eine @r{<Schablone>} ist, auf die optional +@r{<Auslassungspunkte>} folgen, wobei @r{<Auslassungspunkte>} der +Bezeichner „@samp{...}`` ist (welcher nicht als Bezeichner in einer +Schablone oder einem Muster benutzt werden darf). +@vindex ... + +@emph{Semantik:} Eine Instanz von @samp{Syntax-rules} erstellt einen +neuen Makroumwandler, indem eine Folge hygienischer Umschreiberegeln +angegeben wird. Eine Benutzung eines Makros, deren Schlüsselwort mit +einem über @samp{Syntax-rules} festgelegten Umwandler verknüpft ist, +wird mit den Mustern abgeglichen, die in @r{<Syntaxregel>} vorkommen, +angefangen mit der am weisten links stehenden @r{<Syntaxregel>}. Wenn +ein passendes Muster gefunden wurde, wird die Makrobenutzung hygienisch +entsprechend der Schablone umgeschrieben. + +Ein Bezeichner, der im Muster einer @r{<Syntaxregel>} steht, ist eine +@emph{Mustervariable}, außer wenn sie das Schlüsselwort ist, das das +Muster beginnt, unter den @r{<Literale>}n vorkommt oder der Bezeichner +„@samp{...}`` ist. Mustervariable werden beliebigen Eingabeelementen +zugeordnet und benutzt, um Elemente der Eingabe in der Schablone zu +bezeichnen. Es ist ein Fehler, wenn dieselbe Mustervariable mehr als +einmal in einem @r{<Muster>} auftaucht. + +Das Schlüsselwort am Anfang des Musters in einer @r{<Syntaxregel>} ist +nicht an dem Abgleich beteiligt und wird nicht als eine Mustervariable +oder als Literalbezeichner angesehen. + + +@quotation +@emph{Begründung:} +Der Bereich, auf den sich das Schlüsselwort auswirkt, wird anhand des +Ausdrucks oder der Syntaxdefinition festgelegt, die das Schlüsselwort +an den verknüpften Makroumwandler bindet. Wenn das Schlüsselwort eine +Mustervariable oder ein Literalbezeichner wäre, dann wäre die auf das +Muster folgende Schablone selbst im Bereich, auf den sich das +Schlüsselwort auswirkt, unabhängig davon, ob das Schlüsselwort durch +@samp{Let-syntax} oder @samp{Letrec-syntax} gebunden wurde. +@end quotation + + +Bezeichner, die unter den @r{<Literale>}n vorkommen, werden als +Literalbezeichner ausgelegt, die mit den entsprechenden Unterformen +der Eingabe abgeglichen werden. +Eine Unterform in der Eingabe passt zu einem Literalbezeichner genau +dann, wenn sie ein Bezeichner ist und entweder sowohl ihr Vorkommen im +Makroausdruck als auch ihr Vorkommen in der Makrodefinition dieselbe +lexikalische Bindung haben oder die beiden Bezeichner gleich sind und +beide keine lexikalische Bindung haben. + +@c [Bill Rozas suggested the term "noise word" for these literal +@c identifiers, but in their most interesting uses, such as a setf +@c macro, they aren't noise words at all. -- Will] + +Ein Untermuster gefolgt von @samp{...} kann zu null oder mehr +Elementen der Eingabe passen. Es ist ein Fehler, wenn @samp{...} +unter den @r{<Literale>}n vorkommt. Innerhalb eines Musters muss der +Bezeichner @samp{...} auf das letzte Element einer nichtleeren Folge +von Untermustern folgen. + +Formaler ausgedrückt passt eine Eingabeform F zu einem Muster M genau +dann, wenn: + + + +@itemize @bullet + +@item +M ein nichtliteraler Bezeichner ist, oder + +@item +M ein literaler Bezeichner ist und F ein Bezeichner mit derselben +Bindung ist, oder + +@item +M eine Liste @samp{(M_1 @dots{} M_n)} und F eine +Liste aus n +Formen ist, welche jeweils zu M_1 bis M_n passen, oder + +@item +M eine unechte Liste +@samp{(M_1 M_2 @dots{} M_n . M_n+1)} ist +und F eine Liste oder +unechte Liste von n oder mehr Formen ist, die jeweils zu M_1 bis M_n, +passen und deren n-ter „Cdr`` zu M_n+1 passt, oder + +@item +M von der Form +@samp{(M_1 @dots{} M_n M_n+1 <Auslassungspunkte>)} ist, +wobei <Auslassungspunkte> der Bezeichner @samp{...} ist +und F eine +echte Liste aus mindestens n Formen ist, deren erste n Formen jeweils zu +M_1 bis M_n passen, und jedes verbleibende Element von F +zu M_n+1 passt, oder + +@item +M ein Vektor von der Form @samp{#(M_1 @dots{} M_n)} +und F ein Vektor aus +n Formen ist, die zu M_1 bis M_n passen, oder + +@item +M von der Form +@samp{#(M_1 @dots{} M_n M_n+1 <Auslassungspunkte>)} ist, +wobei <Auslassungspunkte> der Bezeichner @samp{...} +und F ein Vektor aus n +oder mehr Formen ist, deren erste n jeweils zu +M_1 bis M_n passen und wobei jedes verbleibende Element von F +zu M_n+1 passt, oder + +@item +M ein Datenelement und F gleich M ist, in dem Sinne der +@samp{Equal?}-Prozedur. + +@end itemize + + +Es ist ein Fehler, ein Makroschlüsselwort in dem Bereich, auf den es +sich auswirkt, in einem Ausdruck zu benutzen, der zu keinem seiner +Muster passt. + +Wenn eine Makro-Benutzung anhand der Schablone der passenden +@r{<Syntaxregel>} umgeschrieben wird, werden Mustervariable, die in der +Schablone vorkommen, durch die Subformen ersetzt, zu denen sie in der +Eingabe passen. Mustervariable, die in Untermustern gefolgt von einer +oder mehr Instanzen des Bezeichners @samp{...} vorkommen, dürfen nur in +Unterschablonen vorkommen, auf die ebenso viele Instanzen von @samp{...} +folgen. Sie werden in der Ausgabe durch all die Subformen ersetzt, die +zur Eingabe passen, so verteilt, wie sie vorkommen. Es ist ein Fehler, +wenn die Ausgabe nicht wie festgelegt aufgebaut werden kann. + +@c %% This description of output construction is very vague. It should +@c %% probably be formalized, but that is not easy... + +Bezeichner, die in der Schablone vorkommen, aber keine Mustervariablen +oder der Bezeichner @samp{...} sind, werden wörtlich als literale +Bezeichner eingefügt. Wenn ein literaler Bezeichner als freier +Bezeichner eingefügt wird, referenziert er diejenige Bindung dieses +Bezeichners, in dessen Bereich die Instanz von @samp{Syntax-rules} +vorkommt. Wenn ein literaler Bezeichner als gebundener Bezeichner +eingefügt wird, dann verhält er sich, als würde er umbenannt, so wird +unerwünschtes Fangen freier Bezeichner verhindert. + +Wenn zum Beispiel @code{Let} und @code{Cond} wie im Abschnitt +@vindex @w{Cond} +@vindex @w{Let} +@ref{Abgeleitete Ausdruckstypen} definiert sind, dann sind sie +hygienisch (wie vorgeschrieben) und das Folgende ist kein Fehler. + + +@format +@t{(let ((=> #f)) + (cond (#t => 'ok))) ==> ok +} +@end format + + +Der Makroumwandler für @samp{Cond} erkennt @samp{=>} als eine lokale +Variable und daher als Ausdruck und nicht als den Bezeichner auf +oberster Ebene @samp{=>}, den der Makroumwandler als ein syntaktisches +Schlüsselwort behandelt. Daher wird das Beispiel umgeschrieben zu + + +@format +@t{(let ((=> #f)) + (if #t (begin => 'ok))) +} +@end format + + +statt zu + + +@format +@t{(let ((=> #f)) + (let ((temp #t)) + (if temp ('ok temp)))) +} +@end format + + +was zu einem ungültigen Prozeduraufruf führen würde. + +@end deffn + + +@page + +@c @include{prog} +@node Programmstruktur, Standardprozeduren, Ausdrücke, top +@chapter Programmstruktur + +@menu +* Programme:: +* Definitionen:: +* Syntaxdefinitionen:: +@end menu + + + +@node Programme, Definitionen, Programmstruktur, Programmstruktur +@section Programme + + +Ein Scheme-Programm besteht aus einer Folge von Ausdrücken, Definitionen +und Syntaxdefinitionen. Ausdrücke werden im Kapitel @ref{Ausdrücke} +beschrieben, Definitionen und Syntaxdefinitionen sind Thema im Rest des +momentanen Kapitels. + +Programme werden typischerweise in Dateien gespeichert oder interaktiv +in ein laufenden Scheme-System eingegeben, wobei auch andere Paradigmen +möglich sind; Fragen der Benutzerschnittstelle gehören dabei nicht zum +in diesem Bericht behandelten Stoff. (Tatsächlich könnte Scheme auch +als eine Notation zum Ausdrücken von Berechnungsmethoden von Nutzen +sein, selbst ohne jegliche mechanische Implementierung.) + +Definitionen und Syntaxdefinitionen, die auf der obersten Ebene eines +Programms stehen, können deklarativ interpretiert werden. Sie führen +dazu, dass Bindungen in der Umgebung auf oberster Ebene erzeugt werden +oder sie ändern den Wert einer bestehenden Bindung auf oberster Ebene. +Ausdrücke, die auf der obersten Ebene eines Programms vorkommen, werden +imperativ interpretiert; sie werden der Reihe nach ausgeführt, wenn das +Programm aufgerufen oder geladen wird und führen typischerweise +irgendeine Art von Initialisierung des Programms durch. + +Auf der obersten Ebene eines Programms ist ein @t{(begin @r{<Form1>} +@dots{},)} äquivalent zur Folge von Ausdrücken, Definitionen und +Syntaxdefinitionen, die den Rumpf des @code{Begin} bilden. +@vindex @w{Begin} + +@ignore todo +Cromarty, etc.: disclaimer about top level? +@end ignore + + +@node Definitionen, Syntaxdefinitionen, Programme, Programmstruktur +@section Definitionen + +@menu +* Definitionen auf oberster Ebene:: +* Interne Definitionen:: +@end menu + + + +Definitionen sind in manchen, aber nicht in jedem Kontext gültig, in dem +Ausdrücke stehen dürfen. Sie sind nur auf der obersten Ebene eines +@r{<Programm>}s gültig und am Anfang eines @r{<Rumpf>}s. + +@cindex @w{Definition} + +Eine Definition sollte eine der folgenden Formen haben: +@cindex @w{Define} + + + +@itemize @bullet + + +@item @t{(define @r{<Variable>} @r{<Ausdruck>})} + +@item @t{(define (@r{<Variable>} @r{<Formale>}) @r{<Rumpf>})} + +@r{<Formale>} sollten entweder eine Folge von null oder mehr Variablen +sein oder eine Folge von einer oder mehr Variablen, gefolgt von einem +durch Leerzeichen begrenzten Punkt und einer weiteren Variablen (wie in +einem Lambda-Ausdruck). Diese Form ist äquivalent zu + +@example + +(define @r{<Variable>} + (lambda (@r{<Formale>}) @r{<Rumpf>}))@r{.} + +@end example + + +@item @t{(define (@r{<Variable>} .@: @r{<Formale>}) @r{<Rumpf>})} + +@r{<Formale>} sollte eine einzelne Variable sein. Diese Form ist +äquivalent zu + +@example + +(define @r{<Variable>} + (lambda @r{<Formale>} @r{<Rumpf>}))@r{.} + +@end example + + + +@end itemize + + +@node Definitionen auf oberster Ebene, Interne Definitionen, Definitionen, Definitionen +@subsection Definitionen auf oberster Ebene + + +Auf der obersten Ebene eines Programms hat eine Definition + +@example + +(define @r{<Variable>} @r{<Ausdruck>}) + +@end example + +grundlegend dieselbe Wirkung wie ein Zuweisungsausdruck + +@example + +(set! @r{<Variable>} @r{<Ausdruck>}) + +@end example + +wenn @r{<Variable>} gebunden ist. Wenn @r{<Variable>} jedoch nicht +gebunden ist, dann wird die Definition die @r{<Variable>} an eine neue +Stelle binden, bevor sie die Zuweisung durchführt, wohingegen es ein +Fehler wäre, @samp{Set!} auf einer ungebundenen Variablen durchzuführen. +@cindex @w{ungebunden} + + +@example + +(define add3 + (lambda (x) (+ x 3))) +(add3 3) ==> 6 +(define first car) +(first '(1 2)) ==> 1 + +@end example + + +Manche Implementierungen von Scheme benutzen eine Anfangsumgebung, in +der alle möglichen Variablen schon vorab an Stellen gebunden sind, von +denen die meisten undefinierte Werte enthalten. Definitionen auf +oberster Ebene sind in einer solchen Implementierung wirklich +gleichbedeutend mit Zuweisungen. + +@ignore todo +Rozas: equal time for opposition semantics? +@end ignore + + + +@node Interne Definitionen, , Definitionen auf oberster Ebene, Definitionen +@subsection Interne Definitionen + + + +Definitionen dürfen am Anfang eines @r{<Rumpf>}s vorkommen (das heißt, +vom Rumpf eines @code{Lambda}-, +@vindex @w{Lambda} +@code{Let}-, @code{Let*}-, @code{Letrec}-, @code{Let-syntax} oder @code{Letrec-syntax}- +@vindex @w{Letrec-syntax} +@vindex @w{Let-syntax} +@vindex @w{Letrec} +@vindex @w{Let*} +@vindex @w{Let} +oder dem einer Definition in angemessener Form). Solche +Definitionen sind bekannt als @emph{interne Definitionen} im Gegensatz +zur Umgebung auf oberster Ebene, was oben beschrieben ist. +@cindex @w{Interne Definitionen} +Die durch eine interne Definition definierte Variable gilt lokal für den +@r{<Rumpf>}. Das heißt, die @r{<Variable>} wird gebunden statt +zugewiesen und die Region der Bindung ist der gesamte @r{<Rumpf>}. Zum +Beispiel + + +@example + +(let ((x 5)) + (define foo (lambda (y) (bar x y))) + (define bar (lambda (a b) (+ (* a b) a))) + (foo (+ x 3))) ==> 45 + +@end example + + +Ein @r{<Rumpf>}, der interne Definitionen enthält, kann immer in einen +völlig gleichbedeutenden @samp{Letrec}-Ausdruck umgewandelt werden. Zum +Beispiel ist der @samp{Let}-Ausdruck im obigen Beispiel gleichbedeutend +mit + + +@example + +(let ((x 5)) + (letrec ((foo (lambda (y) (bar x y))) + (bar (lambda (a b) (+ (* a b) a)))) + (foo (+ x 3)))) + +@end example + + +Genau wie bei dem gleichbedeutenden @samp{Letrec}-Ausdruck muss es +möglich sein, jeden @r{<Ausdruck>} jeder internen Definition in einem +@r{<Rumpf>} auszuwerten, ohne den Wert irgendeiner der @r{<Variable>}n, +die definiert werden, zuzuweisen oder sich darauf zu beziehen. + +Wann immer eine interne Definition vorkommen darf, ist @t{(begin +@r{<Definition1>} @dots{},)} gleichbedeutend mit der Folge von +Definitionen, die den Rumpf des @code{Begin} bilden. +@vindex @w{Begin} + +@node Syntaxdefinitionen, , Definitionen, Programmstruktur +@section Syntaxdefinitionen + + +Syntaxdefinitionen sind nur auf der obersten Ebene eines @r{<Programm>}s +gültig. + +@cindex @w{Syntaxdefinition} +Sie haben die folgende Form: +@cindex @w{Define-syntax} + +@t{(define-syntax @r{<Schlüsselwort>} @r{<Umwandlerspezifikation>})} + +@r{<Schlüsselwort>} ist ein Bezeichner und +die @r{<Umwandlerspezifikation>} sollte eine Instanz von +@code{Syntax-rules} sein. +@vindex @w{Syntax-rules} +Die syntaktische Umgebung auf oberster Ebene wird erweitert durch +Bindung des @r{<Schlüsselwort>}s an den angegebenen Umwandler. + +Es gibt keine Entsprechung von @samp{Define-syntax} für interne +Definitionen. + +@c [Rationale flushed because it may or may not be true and isn't the +@c real rationale anyway. -RK] +@c \begin{rationale} +@c As discussed below, the syntax and scope rules for syntax definitions +@c can give rise to syntactic ambiguities when syntactic keywords are +@c shadowed. +@c Further ambiguities would arise if {\cf define-syntax} +@c were permitted at the beginning of a \meta{body}, with scope +@c rules analogous to those for internal definitions. +@c \end{rationale} + +@c It is an error for a program to contain more than one top-level +@c \meta{definition} or \meta{syntax definition} of any identifier. + +@c [I flushed this because it isn't an error for a program to +@c contain more than one top-level definition of an identifier, +@c and I didn't want to introduce any gratuitous incompatibilities +@c with the existing Scheme language. -- Will] + +Obwohl Makros in jedem Kontext, der sie zulässt, zu Definitionen und +Syntaxdefinitionen umgeschrieben werden können, ist es ein Fehler, wenn +eine Definition oder eine Syntaxdefinition ein syntaktisches +Schlüsselwort überschattet, dessen Bedeutung nötig ist, um zu bestimmen, +ob eine Form aus der Gruppe von Formen, die die überschattende +Definition enthält, tatsächlich eine Definition ist oder, für interne +Definitionen, nötig ist, um die Grenze zwischen der Gruppe und den auf +die Gruppe folgenden Ausdrücken zu bestimmen. Zum Beispiel sind die +folgenden Code-Stücke Fehler: + +@example + +(define define 3) + +(begin (define begin list)) + +(let-syntax + ((foo (syntax-rules () + ((foo (Proz Args ...) Rumpf ...) + (define Proz + (lambda (Args ...) + Rumpf ...)))))) + (let ((x 3)) + (foo (plus x y) (+ x y)) + (define foo x) + (plus foo x))) + +@end example + + + + +@c @include{procs} + +@c Initial environment + +@c \vfill\eject +@node Standardprozeduren, Formale Syntax und Semantik, Programmstruktur, top +@chapter Standardprozeduren + +@menu +* Äquivalenzprädikate:: +* Zahlen:: +* Andere Datentypen:: +* Programmflussfunktionalitäten:: +* Eval:: +* Ein- und Ausgabe:: +@end menu + + + + + +@cindex @w{Anfangsumgebung} + +@cindex @w{oberste Ebene} + +@cindex @w{Bibliotheksprozedur} + +Dieses Kapitel beschreibt die eingebauten Prozeduren von Scheme. Die +anfängliche Scheme-Umgebung (@abbr{bzw.} die Scheme-Umgebung auf +„oberster Ebene``) enthält von Anfang an eine Reihe von Variablen, +die an Stellen mit nützlichen Werten gebunden sind, von denen die +meisten grundlegende Prozeduren sind, die Daten manipulieren. Zum +Beispiel ist die Variable @samp{Abs} gebunden an eine (Stelle mit +einer) Prozedur mit einem einzelnen Argument, die den Absolutbetrag +einer Zahl berechnet, und die Variable @samp{+} ist an eine Prozedur +gebunden, die Summen berechnet. Eingebaute Prozeduren, die leicht +über andere eingebaute Prozeduren ausgedrückt werden könnten, werden +als „Bibliotheksprozeduren`` ausgewiesen. + +Ein Programm darf eine Definition auf oberster Ebene benutzen, um eine +beliebige Variable zu binden. Es darf daraufhin eine jede solche +Bindung durch eine Zuweisung (siehe @pxref{Zuweisungen}) wieder +ändern. Diese Operationen verändern das Verhalten der in Scheme +eingebauten Prozeduren nicht. Das Ändern einer beliebigen Bindung auf +oberster Ebene, die nicht durch eine Definition eingeführt wurde, hat +allerdings eine unbestimmte Wirkung auf das Verhalten der eingebauten +Prozeduren. + +@node Äquivalenzprädikate, Zahlen, Standardprozeduren, Standardprozeduren +@section Äquivalenzprädikate + + + +Ein @dfn{Prädikat} ist eine Prozedur, die immer einen booleschen +@cindex @w{Prädikat} +Wert (@t{#t} oder @t{#f}) zurückgibt. Ein @dfn{Äquivalenzprädikat} ist +@cindex @w{Äquivalenzprädikat} +die berechnende Entsprechung der mathematischen Äquivalenzrelation (es +ist symmetrisch, reflexiv und transitiv). Von den in diesem Abschnitt +beschriebenen Äquivalenzprädikaten ist @samp{Eq?} das feinste oder am +stärksten unterscheidende und @samp{Equal?} ist das gröbste. +@samp{Eqv?} unterscheidet etwas weniger als @samp{Eq?}. +@ignore todo +Pitman doesn't like +this paragraph. Lift the discussion from the Maclisp manual. Explain +why there's more than one predicate. +@end ignore + + + + +@deffn {Prozedur} eqv? obj1 obj2 + +Die Prozedur @samp{Eqv?} definiert eine nützliche Äquivalenzrelation auf +Objekten. Kurz gesagt gibt sie @t{#t} zurück, wenn @var{Obj1} und +@var{Obj2} unter normalen Umständen als dasselbe Objekt angesehen werden +sollte. Die Bedeutung der Relation lässt ein wenig +Interpretationsspielraum, aber die folgende teilweise Spezifikation von +@samp{Eqv?} gilt für alle Implementierungen von Scheme. + +Die @samp{eqv?}-Prozedur gibt @t{#t} zurück, wenn: + + + +@itemize @bullet + +@item +@var{Obj1} und @var{Obj2} beide @t{#t} oder beide @t{#f} sind. + +@item +@var{Obj1} und @var{Obj2} beide Symbole sind und + + +@format +@t{(string=? (symbol->string obj1) + (symbol->string obj2)) + ==> #t +} +@end format + + + +@quotation +@emph{Anmerkung:} +Die Annahme ist, dass weder @var{Obj1} noch @var{Obj2} ein „nicht +interniertes Symbol`` ist, wie im Abschnitt @ref{Symbole} angedeutet. +Dieser Bericht versucht nicht, das Verhalten von @samp{Eqv?} für +implementierungsabhängige Erweiterungen festzulegen. +@end quotation + + +@item +@var{Obj1} und @var{Obj2} beide Zahlen und numerisch gleich sind (siehe +@samp{=} im Abschnitt @pxref{Zahlen}) und außerdem entweder beide exakt +oder beide inexakt sind. + +@item +@var{Obj1} und @var{Obj2} beide Zeichen sind und laut der Prozedur +@samp{Char=?} dasselbe Zeichen sind (siehe den Abschnitt +@pxref{Zeichen}). + +@item +@var{Obj1} und @var{Obj2} beide die leere Liste sind. + +@item +@var{Obj1} und @var{Obj2} Paare, Vektoren oder Zeichenketten sind, die +dieselben Stellen im Speicher bezeichnen (siehe den Abschnitt +@pxref{Speichermodell}). + +@item +@var{Obj1} und @var{Obj2} Prozeduren sind, deren Stellenbeschriftungen +gleich sind (siehe den Abschnitt @pxref{Prozeduren}). + +@end itemize + +@cindex @w{inexakt} +@cindex @w{exakt} + +Die Prozedur @samp{Eqv?} gibt @t{#f} zurück, wenn: + + + +@itemize @bullet + +@item +@var{Obj1} und @var{Obj2} verschiedene Typen sind (Abschnitt +@pxref{Typfremdheit}). + +@item +eines der @var{Obj1} und @var{Obj2} ein @t{#t} ist, aber das andere ein +@t{#f} ist. + +@item +@var{Obj1} und @var{Obj2} Symbole sind, aber + + +@format +@t{(string=? (symbol->string @var{obj1}) + (symbol->string @var{obj2})) + ==> #f +} +@end format + + +@item +eines von @var{Obj1} und @var{Obj2} eine exakte Zahl ist, aber die +andere eine inexakte Zahl ist. + +@item +@var{Obj1} und @var{Obj2} Zahlen sind, für die die Prozedur @samp{=} den +Wert @t{#f} zurückgibt. + +@item +@var{Obj1} und @var{Obj2} Zeichen sind, für die die Prozedur +@samp{Char=?} den Wert @t{#f} zurückgibt. + +@item +eines von @var{Obj1} und @var{Obj2} die leere Liste ist, aber das andere +nicht. + +@item +@var{Obj1} und @var{Obj2} Paare, Vektoren und Zeichenketten sind, die +unterschiedliche Stellen bezeichnen. + +@item +@var{Obj1} und @var{Obj2} Prozeduren sind, die sich für manche Argumente +unterschiedlich verhalten würden (verschiedene Werte zurückgeben oder +verschiedene Wirkungen haben würden). + + +@end itemize + + + +@format +@t{(eqv? 'a 'a) ==> #t +(eqv? 'a 'b) ==> #f +(eqv? 2 2) ==> #t +(eqv? '() '()) ==> #t +(eqv? 100000000 100000000) ==> #t +(eqv? (cons 1 2) (cons 1 2)) ==> #f +(eqv? (lambda () 1) + (lambda () 2)) ==> #f +(eqv? #f 'nil) ==> #f +(let ((p (lambda (x) x))) + (eqv? p p)) ==> #t +} +@end format + + +Die folgenden Beispiele veranschaulichen Fälle, für die die obigen +Regeln das Verhalten von @samp{Eqv?} nicht vollständig angeben. Alles, +was sich über solche Fälle sagen lässt, ist, dass der von @samp{Eqv?} +zurückgegebene Wert ein boolescher Wert sein muss. + + +@format +@t{(eqv? "" "") ==> @emph{unbestimmt} +(eqv? '#() '#()) ==> @emph{unbestimmt} +(eqv? (lambda (x) x) + (lambda (x) x)) ==> @emph{unbestimmt} +(eqv? (lambda (x) x) + (lambda (y) y)) ==> @emph{unbestimmt} +} +@end format + + +Der nächste Satz von Beispielen zeigt die Nutzung von @samp{Eqv?} mit +Prozeduren, die lokalen Zustand haben. Die Beispiele nehmen an, dass +die benutzte Scheme-Implementierung die Umlaute auch als +Buchstabenzeichen ansieht, als Erweiterung zur in diesem Bericht +spezifizierten Syntax. @samp{Gen-Zähler} muss jedes Mal eine andere +Prozedur zurückgeben, denn jede Prozedur hat ihren eigenen internen +Zähler. @samp{Gen-Verlierer} gibt jedoch jedes Mal gleichwertige +Prozeduren zurück, denn der lokale Zustand beeinflusst die Werte oder +Wirkungen der Prozeduren nicht. + + +@format +@t{(define gen-Zähler + (lambda () + (let ((n 0)) + (lambda () (set! n (+ n 1)) n)))) +(let ((g (gen-Zähler))) + (eqv? g g)) ==> #t +(eqv? (gen-Zähler) (gen-Zähler)) + ==> #f +(define gen-Verlierer + (lambda () + (let ((n 0)) + (lambda () (set! n (+ n 1)) 27)))) +(let ((g (gen-Verlierer))) + (eqv? g g)) ==> #t +(eqv? (gen-Verlierer) (gen-Verlierer)) + ==> @emph{unbestimmt} + +(letrec ((f (lambda () (if (eqv? f g) 'beide 'f))) + (g (lambda () (if (eqv? f g) 'beide 'g)))) + (eqv? f g)) + ==> @emph{unbestimmt} + +(letrec ((f (lambda () (if (eqv? f g) 'f 'beide))) + (g (lambda () (if (eqv? f g) 'g 'beide)))) + (eqv? f g)) + ==> #f +} +@end format + + +@c Objects of distinct types must never be regarded as the same object, +@c except that \schfalse{} and the empty list\index{empty list} are permitted to +@c be identical. + +@c \begin{scheme} +@c (eqv? '() \schfalse) \ev \unspecified% +@c \end{scheme} + +Weil es ein Fehler ist, konstante Objekte zu verändern (die, die von +literalen Ausdrücken zurückgegeben werden), dürfen Implementierungen die +Struktur zwischen Konstanten teilen, müssen aber nicht. Daher ist der +Wert von @samp{Eqv?} für Konstante manchmal implementierungsabhängig. + + +@format +@t{(eqv? '(a) '(a)) ==> @emph{unbestimmt} +(eqv? "a" "a") ==> @emph{unbestimmt} +(eqv? '(b) (cdr '(a b))) ==> @emph{unbestimmt} +(let ((x '(a))) + (eqv? x x)) ==> #t +} +@end format + + + +@quotation +@emph{Begründung:} +Obige Definition von @samp{Eqv?} gestattet Implementierungen Freiraum +bei der Behandlung von Prozeduren und Literalen: Implementierungen steht +es frei, entweder die Gleichheit zweier Prozeduren oder zweier Literale +zu bestätigen oder nicht bestätigen zu können, ob sie gleich sind, so +dass sie selbst entscheiden können, ob Darstellungen äquivalenter +Objekte durch Nutzung desselben Zeigers oder Bit-Musters verschmolzen +werden sollen, um eine Darstellung für beide zu sein. +@end quotation + + +@end deffn + + + +@deffn {Prozedur} eq? obj1 obj2 + +@samp{Eq?} ist ähnlich wie @samp{Eqv?}, außer dass es in manchen Fällen +in der Lage ist, feinere Unterschiede zu erkennen als @samp{Eqv?}. + +Es wird garantiert, dass sich @samp{Eq?} und @samp{Eqv?} auf Symbolen, +booleschen Werten, der leeren Liste, Paaren, Prozeduren und nicht leeren +Zeichenketten und Vektoren gleich verhalten. Das Verhalten von +@samp{Eq?} für Zahlen und Zeichen ist implementierungsabhängig, aber es +wird immer entweder wahr oder falsch zurückgeben und wird nur dann wahr +zurückgeben, wenn @samp{Eqv?} auch wahr zurückgeben würde. @samp{Eq?} +darf sich für leere Vektoren und leere Zeichenketten auch anders als +@samp{Eqv?} verhalten. + + +@format +@t{(eq? 'a 'a) ==> #t +(eq? '(a) '(a)) ==> @emph{unbestimmt} +(eq? (list 'a) (list 'a)) ==> #f +(eq? "a" "a") ==> @emph{unbestimmt} +(eq? "" "") ==> @emph{unbestimmt} +(eq? '() '()) ==> #t +(eq? 2 2) ==> @emph{unbestimmt} +(eq? #\A #\A) ==> @emph{unbestimmt} +(eq? car car) ==> #t +(let ((n (+ 2 3))) + (eq? n n)) ==> @emph{unbestimmt} +(let ((x '(a))) + (eq? x x)) ==> #t +(let ((x '#())) + (eq? x x)) ==> #t +(let ((p (lambda (x) x))) + (eq? p p)) ==> #t +} +@end format + + +@ignore todo +Needs to be explained better above. How can this be made to be +not confusing? A table maybe? +@end ignore + + + +@quotation +@emph{Begründung:} Gewöhnlich wird man @samp{Eq?} deutlich effizienter +implementieren können als @samp{Eqv?}, zum Beispiel als einfacher +Vergleich von Zeigern statt einer komplizierteren Operation. Ein Grund +ist, dass es unmöglich sein kann, @samp{Eqv?} für zwei Zahlen in +konstanter Zeit zu berechnen, während @samp{Eq?}, als Zeigervergleich +implementiert, immer in konstanter Zeit abgeschlossen sein wird. +@samp{Eq?} darf wie @samp{Eqv?} benutzt werden, wenn in einer Anwendung +Prozeduren benutzt werden, um zustandsbehaftete Objekte zu +implementieren, da es denselben Einschränkungen wie @samp{Eqv?} genügt. +@end quotation + + +@end deffn + + + +@deffn {Bibliotheksprozedur} equal? obj1 obj2 + +@samp{Equal?} vergleicht den Inhalt von Paaren, Vektoren und +Zeichenketten rekursiv, indem es auf andere Objekte wie Zahlen und +Symbole @samp{Eqv?} anwendet. Eine Daumenregel ist, dass Objekte im +Allgemeinen @samp{Equal?} sind, wenn sie gleich ausgegeben werden. +@samp{Equal?} muss nicht terminieren, wenn seine Argumente zirkuläre +Datenstrukturen sind. + + +@format +@t{(equal? 'a 'a) ==> #t +(equal? '(a) '(a)) ==> #t +(equal? '(a (b) c) + '(a (b) c)) ==> #t +(equal? "abc" "abc") ==> #t +(equal? 2 2) ==> #t +(equal? (make-vector 5 'a) + (make-vector 5 'a)) ==> #t +(equal? (lambda (x) x) + (lambda (y) y)) ==> @emph{unbestimmt} +} +@end format + + +@end deffn + + +@node Zahlen, Andere Datentypen, Äquivalenzprädikate, Standardprozeduren +@section Zahlen + +@menu +* Numerische Typen:: +* Exaktheit:: +* Implementierungseinschränkungen:: +* Syntax numerischer Konstanter:: +* Numerische Operationen:: +* Numerische Ein- und Ausgabe:: +@end menu + + + +@cindex @w{Zahl} + +@c %R4%% The excessive use of the code font in this section was +@c confusing, somewhat obnoxious, and inconsistent with the rest +@c of the report and with parts of the section itself. I added +@c a \tupe no-op, and changed most old uses of \type to \tupe, +@c to make it easier to change the fonts back if people object +@c to the change. + +@c \newcommand{\type}[1]{{\it#1}} +@c \newcommand{\tupe}[1]{{#1}} + +Numerische Berechnung wurde traditionell von der Lisp-Gemeinschaft +vernachlässigt. Bis Common Lisp gab es keine vorsichtig durchdachte +Strategie zum Organisieren numerischer Berechnungen und abgesehen vom +MacLisp-System [Pitman83] wurden kaum Anstrengungen unternommen, +numerischen Code effizient auszuführen. Dieser Bericht erkennt die +exzellente Arbeit des Common-Lisp-Komitees an und akzeptiert viele ihrer +Empfehlungen. Auf manche Art vereinfacht und verallgemeinert dieser +Bericht deren Vorschläge auf eine Art, die mit den Zwecken von Scheme im +Einklang steht. + +Es ist wichtig, zwischen mathematischen Zahlen, den Scheme-Zahlen, +welche diese zu modellieren versuchen, und Notationen zum Aufschreiben +von Zahlen zu unterscheiden. Dieser Bericht benutzt die Typen Zahl +(@i{number}), komplexe Zahl (@i{complex}), reelle Zahl (@i{real}), +rationale Zahl (@i{rational}) und ganze Zahl (@i{integer}), um sowohl +die mathematischen Zahlen als auch die Scheme-Zahlen zu bezeichnen. +Maschinendarstellungen wie Festkomma (fixed point) und Gleitkomma +(floating point) werden [im englischsprachigen Scheme-Standard] durch +Namen wie @i{fixnum} und @i{flonum} bezeichnet. + +@c %R4%% I did some reorganizing here to move the discussion of mathematical +@c numbers before the discussion of the Scheme numbers, hoping that this +@c would help to motivate the discussion of representation independence. + +@node Numerische Typen, Exaktheit, Zahlen, Zahlen +@subsection Numerische Typen + + + +@cindex @w{numerische Typen} + +@c %R4%% A Scheme system provides data of type \type{number}, which is the most +@c general numerical type supported by that system. +@c \type{Number} is +@c likely to be a complicated union type implemented in terms of +@c \type{fixnum}s, \type{bignum}s, \type{flonum}s, and so forth, but this +@c should not be apparent to a naive user. What the user should see is +@c that the usual operations on numbers produce the mathematically +@c expected results, within the limits of the implementation. + +@c %R4%% I rewrote the following paragraph to make the various levels of +@c the tower into subsets of each other, instead of relating them by +@c injections. I think the injections tended to put people in the frame +@c of mind of thinking about coercions between non-overlapping numeric +@c types in mainstream programming languages. + +Mathematisch können Zahlen in einem Turm von Subtypen angeordnet werden, +@c %R4%% with injections relating adjacent levels of the tower: +in dem jede Stufe eine Teilmenge der darüberliegenden Stufe ist: + +@format + @r{number} (Zahl) + @r{complex} (komplexe Zahl) + @r{real} (reelle Zahl) + @r{rational} (rationale Zahl) + @r{integer} (ganze Zahl) +@end format + + +Zum Beispiel ist 3 eine ganze Zahl. Daher ist 3 auch eine rationale, +reelle und komplexe Zahl. Dasselbe gilt für die Scheme-Zahlen, die die +3 modellieren. Für Scheme-Zahlen sind diese Typen durch die Prädikate +@code{Number?}, @code{Complex?}, @code{Real?}, @code{Rational?}, +@vindex @w{Rational?} +@vindex @w{Real?} +@vindex @w{Complex?} +@vindex @w{Number?} +und @code{Integer?} definiert. +@vindex @w{Integer?} + +Es gibt keine einfache Beziehung zwischen dem Typ einer Zahl und ihrer +Darstellung in einem Rechner. Obwohl die meisten Implementierungen von +Scheme zumindest zwei verschiedene Darstellungen von 3 anbieten werden, +bezeichnen diese unterschiedlichen Darstellungen dieselbe ganze Zahl. + +@c %R4%% I moved "Implementations of Scheme are not required to implement +@c the whole tower..." to the subsection on implementation restrictions. + +Schemes numerische Operationen behandeln Zahlen als abstrakte Daten, die +so unabhängig wie möglich von ihrer Darstellung sind. Obwohl eine +Implementierung von Scheme Festkomma (fixnum), Gleitkomma (flonum) und +unter Umständen andere Repräsentationen benutzen darf, sollte dies +gegenüber dem Gelegenheitsprogrammierer, der einfache Programme +schreibt, unauffällig sein. + +Es ist allerdings notwendig, zwischen Zahlen zu unterscheiden, die exakt +dargestellt werden, und denen, deren Darstellung inexakt sein darf. Zum +Beispiel müssen Indizes auf Datenstrukturen exakt bekannt sein, genau +wie manche Polynomialkoeffizienten eines Systems für symbolische Algebra +exakt bekannt sein müssen. Andererseits sind Messergebnisse an sich +schon inexakt und irrationale Zahlen können durch rationale Zahlen und +somit inexakt angenähert werden. Damit abgefangen werden kann, wenn +inexakte Zahlen benutzt werden, wo exakte Zahlen benötigt werden, +unterscheidet Scheme ausdrücklich zwischen exakten und inexakten Zahlen. +Diese Unterscheidung ist unabhängig von der Größendimension des +Datentyps. + +@node Exaktheit, Implementierungseinschränkungen, Numerische Typen, Zahlen +@subsection Exaktheit + + +@c %R4%% I tried to direct the following paragraph away from philosophizing +@c about the exactness of mathematical numbers, and toward philosophizing +@c about the exactness of Scheme numbers. + + +@cindex @w{Exaktheit} +Scheme-Zahlen sind entweder @i{exakt} oder @i{inexakt}. Eine Zahl ist +@r{exakt}, wenn sie als exakte Konstante geschrieben wurde oder sich aus +@r{exakt}en Zahlen nur durch @r{exakte} Operationen ergeben hat. Eine +Zahl ist @r{inexakt}, wenn sie als inexakte Konstante geschrieben wurde, +@c %R4%% models a quantity (e.g., a measurement) known only approximately, +sich aus @r{inexakten} Zutaten ergeben hat oder sich unter Benutzung +@r{inexakter} Operationen ergeben hat. Daher ist @r{Inexakt}heit eine +ansteckende Eigenschaft einer Zahl. +@c %R4%% The rest of this paragraph (from R3RS) has been dropped. + +Wenn zwei Implementierungen @r{exakte} Ergebnisse für eine Berechnung +liefern, die keine @r{inexakten} Zwischenergebnisse verwendet hat, +werden die beiden Endergebnisse mathematisch äquivalent sein. Dies ist +im Allgemeinen unwahr für Berechnungen, die @r{inexakte} Zahlen +verwenden, denn dort dürfen Näherungsverfahren wie Gleitkommaarithmetik +verwendet werden, aber es ist die Pflicht der jeweiligen +Implementierung, die Ergebnisse so nah ans mathematische Ideal zu +bringen, wie es praktikabel ist. + +Rationale Operationen wie @samp{+} sollten immer @r{exakte} Ergebnisse +liefern, wenn ihnen @r{exakte} Argumente übergeben werden. +@c %R4%%If an implementation is +@c unable to represent an \tupe{exact} result (for example, if it does not +@c support infinite precision integers and rationals) +Wenn die Operation keine @r{exakten} Ergebnisse liefern kann, darf sie +entweder die Verletzung einer Implementierungseinschränkung melden, oder +dem Ergebnis stillschweigend einen @r{inexakten} Wert aufzwingen. +@c %R4%%Such a coercion may cause an error later. +Siehe den Abschnitt @ref{Implementierungseinschränkungen}. + +Mit Ausnahme von @code{inexact->exact} müssen die in diesem Abschnitt +beschriebenen Operationen +@vindex @w{inexact->exact} +im Allgemeinen inexakte Ergebnisse liefern, wenn ihnen auch beliebige +inexakte Argumente gegeben wurden. Eine Operation darf allerdings ein +@r{exaktes} Ergebnis liefern, wenn sie beweisen kann, dass der Wert des +Ergebnisses nicht von der Inexaktheit ihrer Argumente betroffen ist. +Zum Beispiel liefert die Multiplikation einer beliebigen Zahl mit einer +@r{exakten} Null eine @r{exakte} Null als Ergebnis, selbst wenn das +andere Argument @r{inexakt} ist. + +@node Implementierungseinschränkungen, Syntax numerischer Konstanter, Exaktheit, Zahlen +@subsection Implementierungseinschränkungen + + + +@cindex @w{Implementierungseinschränkung} + +Implementierungen von Scheme müssen nicht den gesamten Turm von +Untertypen, die im Abschnitt @ref{Numerische Typen} angegeben wurden, +implementieren, aber sie müssen eine widerspruchsfreie Teilmenge davon +implementieren, die sowohl mit den Zwecken der Implementierung als auch +dem Geist der Scheme-Sprache konsistent ist. Zum Beispiel kann selbst +eine Implementierung, in der alle Zahlen @r{real} (reell) sind, dennoch +ziemlich nützlich sein. + +Implementierungen dürfen auch bloß einen eingeschränkten Wertebereich +eines beliebigen Typs unterstützen, wenn er die Anforderungen dieses +Abschnitts erfüllt. Der unterstützte Bereich @r{exakter} Zahlen eines +beliebigen Typs darf sich von dem unterstützten Bereich @r{inexakter} +Zahlen dieses Typs unterscheiden. Zum Beispiel darf eine +Implementierung, die Gleitkommazahlen zur Darstellung all ihrer +@r{inexakten} @r{reellen} Zahlen verwendet, einen praktisch +unbeschränkten Wertebereich für @r{exakte} @r{ganze} und @r{rationale} +Zahlen unterstützen, während sie den Wertebereich für @r{inexakte} +@r{reelle} (und deswegen auch den Wertebereich für @r{inexakte} +@r{ganze} und @r{rationale} Zahlen) auf den dynamischen Wertebereich des +Gleitkommaformats einschränkt. Desweiteren sind die Lücken zwischen +darstellbaren @r{inexakten} @r{ganzen} und @r{rationalen} Zahlen in +einer solchen Implementierung wahrscheinlich sehr groß, wenn sich die +Zahlen den Grenzen des Wertebereichs annähern. + +Eine Implementierung von Scheme muss exakte ganze Zahlen in dem +Wertebereich unterstützen, der als Index für Listen, Vektoren und +Zeichenketten verwendet werden kann, oder der das Ergebnis der +Berechnung der Länge einer Liste, eines Vektors oder eine Zeichenkette +sein kann. Die Prozeduren @code{Length}, @code{Vector-length}, +@vindex @w{Vector-length} +@vindex @w{Length} +und @code{String-length} müssen eine exakte +@vindex @w{String-length} +ganze Zahl zurückgeben und es ist ein Fehler, etwas anderes als eine +exakte ganze Zahl als Index zu benutzen. Desweiteren wird jede +ganzzahlige Konstante, wenn sie durch eine exakte Syntax für ganze +Zahlen ausgedrückt wurde, tatsächlich auch als eine exakte ganze Zahl +eingelesen, ohne Rücksicht auf jegliche Implementierungseinschränkungen, +die außerhalb dieses Bereichs gelten. Zuletzt werden die unten +angeführten Prozeduren immer eine exakte ganze Zahl als Ergebnis +zurückgeben, sofern all ihre Argumente exakte ganze Zahlen sind und das +mathematisch erwartete Ergebnis als exakte ganze Zahl innerhalb der +Implementierung darstellbar ist: + + +@example + ++ - * +quotient remainder modulo +max min abs +numerator denominator gcd +lcm floor ceiling +truncate round rationalize +expt + +@end example + + +Implementierungen werden ermutigt, sind aber nicht verpflichtet, +@r{exakte} @r{ganze} und @r{exakte} @r{rationale} Zahlen praktisch +unbeschränkter Größe und Genauigkeit zu unterstützen, und die oben +genannten Prozeduren und die Prozedur @samp{/} auf eine Art zu +implementieren, so dass sie immer @r{exakte} Ergebnisse liefern, wenn +ihnen @r{exakte} Argumente gegeben werden. Wenn eine dieser Prozeduren +kein @r{exaktes} Ergebnis liefern kann, obwohl ihr @r{exakte} Argumente +übergeben wurden, dann darf sie entweder eine Verletzung einer +Implementierungseinschränkung melden oder sie darf stillschweigend dem +Ergebnis einen @r{inexakten} Wert aufzwingen. Ein solches Aufzwingen +darf später zu einem Fehler führen. + +@c %R4%% I moved this stuff here. +@c It seems to me that the only thing that this requires is that +@c implementations that support inexact numbers have to have both +@c exact and inexact representations for the integers 0 through 15. +@c If that's what it's saying, I'd rather say it that way. +@c On the other hand, letting the limit be as small as 15 sounds a +@c tad silly, though I think I understand how that number was arrived at. +@c (Or is 35 the number?) + +@c Implementations are encouraged, but not required, to support \tupe{inexact} +@c numbers. For any implementation that supports \tupe{inexact} numbers, +@c there is a subset of the integers for which there are both \tupe{exact} and +@c \tupe{inexact} representations. This subset must include all non-negative +@c integers up to some limit specified by the implementation. This limit +@c must be 16 or greater. The +@c \ide{exact\coerce{}inexact} and \ide{inexact\coerce{}exact} +@c procedures implement the natural one-to-one correspondence between +@c the \tupe{inexact} and \tupe{exact} integers within this range. + +Eine Implementierung darf Gleitkommazahlen und andere näherungsweise +Darstellungsstrategien für @r{inexakte} Zahlen benutzen. +@c %R4%% The following sentence seemed a bit condescending as well as +@c awkward. It didn't seem to be very enforceable, so I flushed it. + +@c This is not to +@c say that implementors need not use the best known algorithms for +@c \tupe{inexact} computations---only that approximate methods of high +@c quality are allowed. + +Dieser Bericht empfiehlt, setzt aber nicht voraus, dass +Implementierungen, die Gleitkommadarstellungen benutzen, den +IEEE-Standards für 32-Bit- und 64-Bit-Gleitkommazahlen folgen, und dass +Implementierungen, die andere Darstellungen benutzen, dieselbe oder eine +höhere Genauigkeit bieten, wie sie unter Benutzung dieser +Gleitkommastandards erreicht werden kann [IEEE]. + +Insbesondere müssen Implementierungen, die eine Gleitkommadarstellung +verwenden, diesen Regeln folgen: Ein Gleitkommaergebnis muss mit +mindestens soviel Genauigkeit dargestellt werden, wie Genauigkeit +benutzt wurde, um ein beliebiges Argument der Operation auszudrücken. +Es ist wünschenswert (aber nicht notwendig), dass womöglich inexakte +Operationen wie @samp{Sqrt}, wenn sie auf @r{exakte} Argumente angewandt +werden, @r{exakte} Antworten liefern, wann immer das möglich ist (zum +Beispiel sollte die Quadratwurzel einer @r{exakten} 4 eine @r{exakte} 2 +sein). Wenn eine Operation jedoch anhand einer @r{exakten} Zahl ein +@r{inexaktes} Ergebnis liefert (wie durch @samp{Sqrt}), und wenn das +Ergebnis als eine Gleitkommazahl dargestellt wird, dann muss dafür das +verfügbare Gleitkommaformat mit der höchsten Genauigkeit benutzt werden, +aber wenn das Ergebnis auf andere Art dargestellt wird, muss die +Darstellung mindestens soviel Genauigkeit wie das genaueste verfügbare +Gleitkommaformat haben. + +Obwohl Scheme eine Vielfalt geschriebener +@c %R4%% representations of +Notationen für Zahlen unterstützt, darf eine Implementierung auch nur +manche davon unterstützen. +@c %R4%% +Zum Beispiel muss eine Implementierung nicht die kartesische und polare +Notation für komplexe Zahlen unterstützen. Wenn eine Implementierung +eine @r{exakte} numerische Konstante vorfindet, die sie nicht als eine +@r{exakte} Zahl darstellen kann, darf sie entweder eine Verletzung einer +Implementierungseinschränkung melden oder stillschweigend die Konstante +durch eine @r{inexakte} Zahl darstellen. + + +@node Syntax numerischer Konstanter, Numerische Operationen, Implementierungseinschränkungen, Zahlen +@subsection Syntax numerischer Konstanter + + + +@c @@@@LOSE@@@@ + +@c %R4%% I removed the following paragraph in an attempt to tighten up +@c this subsection. Except for its first sentence, which I moved to +@c the subsection on implementation restrictions, I think its content +@c is implied by the rest of the section. + +@c Although Scheme allows a variety of written representations of numbers, +@c any particular implementation may support only some of them. +@c These syntaxes are intended to be purely notational; any kind of number +@c may be written in any form that the user deems convenient. Of course, +@c writing 1/7 as a limited-precision decimal fraction will not express the +@c number exactly, but this approximate form of expression may be just what +@c the user wants to see. + +Die Syntax der geschriebenen Darstellungen für Zahlen wird formal im +Abschnitt @ref{Lexikalische Struktur} beschrieben. Beachten Sie, dass +Groß- und Kleinschreibung für numerische Konstante nicht unterschieden +wird. + +@c %R4%% See section~\ref{numberformats} for many examples. + +Eine Zahl darf binär, oktal, dezimal oder hexadezimal durch Nutzung +eines Radix-Präfixes geschrieben werden. Die Radix-Präfixe sind +@samp{#b} (binär), @samp{#o} (oktal), @samp{#d} (dezimal) und @samp{#x} +(hexadezimal). Ohne +@vindex #x +@vindex #d +@vindex #o +@vindex #b +ein Radix-Präfix wird eine Zahl als dezimal angenommen. + +Eine +@c %R4%% +@c simple +numerische Konstante darf durch ein Präfix als entweder @r{exakt} oder +@r{inexakt} festgelegt werden. Die Präfixe sind @samp{#e} +@vindex #e +für @r{exakt} und @samp{#i} für @r{inexakt}. Ein Exaktheitspräfix +@vindex #i +darf vor oder nach einem beliebigen benutzten Radix-Präfix stehen. Wenn +die geschriebene Darstellung einer Zahl kein Exaktheitspräfix hat, kann +die Konstante entweder @r{inexakt} oder @r{exakt} sein. Sie ist +@r{inexakt}, wenn sie einen Punkt als Dezimaltrennzeichen, einen +Exponenten oder ein „#``-Zeichen anstelle einer Ziffer, andernfalls ist +sie @r{exakt}. +@c %R4%% With our new syntax, the following sentence is redundant: + +@c The written representation of a +@c compound number, such as a ratio or a complex, is exact if and only if +@c all of its constituents are exact. + +In Systemen mit @r{inexakten} Zahlen verschiedener Genauigkeiten kann es +nützlich sein, die Genauigkeit einer Konstanten anzugeben. Zu diesem +Zweck dürfen numerische Konstante mit einer Exponentenmarkierung +geschrieben werden, die die gewünschte Genauigkeit der @r{inexakten} +Darstellung anzeigt. Die Buchstaben @samp{s}, @samp{f}, @samp{d} und +@samp{l} legen jeweils die Nutzung von kleiner („@var{short}``), +einfacher („@var{single}``), doppelter („@var{double}``) und großer +(„@var{long}``) Genauigkeit fest. (Wenn weniger als vier interne +@c %R4%%\tupe{flonum} +@r{inexakte} Darstellungen existieren, werden die vier spezifizierten +Größen auf die verfügbaren abgebildet. Zum Beispiel darf eine +Implementierung mit zwei internen Darstellungen „short`` und „single`` +zusammenlegen und „long`` und „double`` zusammenlegen.) Zusätzlich +steht die Exponentenmarkierung @samp{e} für die standardmäßige +Genauigkeit der Implementierung. Die standardmäßige Genauigkeit ist +mindestens so genau wie @var{double}, aber Implementierungen dürfen es +der Nutzerin erlauben, den Standard festzusetzen. + + +@example + +3.14159265358979F0 + @r{Runden auf single ---} 3.141593 +0.6L0 + @r{Erweitern auf long ---} .600000000000000 + +@end example + + + +@node Numerische Operationen, Numerische Ein- und Ausgabe, Syntax numerischer Konstanter, Zahlen +@subsection Numerische Operationen + + +Der Leser sei verwiesen auf den Abschnitt @ref{Eintragsformat} für eine +Zusammenfassung der Namenskonventionen, mit denen Einschränkungen der +Argumenttypen numerischer Routinen angegeben werden. +@c %R4%% The following sentence has already been said twice, and the +@c term "exactness-preserving" is no longer defined by the Report. + +@c Remember that +@c an exactness-preserving operation may coerce its result to inexact if the +@c implementation is unable to represent it exactly. +Die in diesem Abschnitt benutzten Beispiele gehen davon aus, dass jede +mit @r{exakter} Notation angegebene numerische Konstante tatsächlich als +eine @r{exakte} Zahl dargestellt wird. Manche Beispiele gehen auch +davon aus, dass bestimmte numerische Konstante, die mit @r{inexakter} +Notation geschrieben wurden, ohne Verlust von Genauigkeit dargestellt +werden können; die @r{inexakten} Konstanten wurden so gewählt, dass dies +in Implementierungen, die Gleitkommazahlen benutzen, um inexakte Zahlen +darzustellen, wahrscheinlich der Fall ist. + +@ignore todo +Scheme provides the usual set of operations for manipulating +numbers, etc. +@end ignore + + + +@deffn {Prozedur} number? obj +@deffnx {Prozedur} complex? obj +@deffnx {Prozedur} real? obj +@deffnx {Prozedur} rational? obj +@deffnx {Prozedur} integer? obj + +Diese numerischen Typprädikate können auf jede Art von Argument +angewandt werden, auch auf Nichtzahlen. Sie geben @t{#t} zurück, wenn +das Objekt den genannten Typ hat, und sonst geben sie @t{#f} zurück. +Im Allgemeinen ist, wenn ein Typprädikat für eine Zahl wahr ist, auch +jedes höhere Typprädikat für diese Zahl wahr. Umgekehrt sind, wenn ein +Typprädikat für eine Zahl falsch ist, alle niedrigeren Typprädikate für +diese Zahl auch falsch. +@c %R4%% The new section on implementation restrictions subsumes: +@c Not every system +@c supports all of these types; for example, it is entirely possible to have a +@c Scheme system that has only \tupe{integer}s. Nonetheless every implementation +@c of Scheme must have all of these predicates. + +Wenn @var{z} eine inexakte komplexe Zahl ist, dann ist @samp{(real? +@var{z})} genau dann wahr, wenn @samp{(zero? (imag-part @var{z}))} wahr +ist. Wenn @var{x} eine inexakte reelle Zahl ist, dann ist +@samp{(integer? @var{x})} genau dann wahr, wenn @samp{(= @var{x} (round +@var{x}))}. + + +@format +@t{(complex? 3+4i) ==> #t +(complex? 3) ==> #t +(real? 3) ==> #t +(real? -2.5+0.0i) ==> #t +(real? #e1e10) ==> #t +(rational? 6/10) ==> #t +(rational? 6/3) ==> #t +(integer? 3+0i) ==> #t +(integer? 3.0) ==> #t +(integer? 8/4) ==> #t +} +@end format + + + +@quotation +@emph{Anmerkung:} +Das Verhalten dieser Typprädikate ist auf @r{inexakten} Zahlen +unverlässlich, denn jede Ungenauigkeit kann das Ergebnis beeinflussen. +@end quotation + + + +@quotation +@emph{Anmerkung:} +In vielen Implementierung wird die Prozedur @code{Rational?} dieselbe +sein wie +@vindex @w{Rational?} +@code{Real?} und die Prozedur @code{Complex?} wird dieselbe sein wie +@vindex @w{Complex?} +@vindex @w{Real?} +@code{Number?}, aber ungewöhnliche Implementierungen könnten nur in der +Lage sein, +@vindex @w{Number?} +manche irrationale Zahlen exakt darzustellen, oder das Zahlensystem +erweitern, so dass es auch eine Art nicht komplexer Zahlen unterstützt. +@end quotation + + +@end deffn + + +@deffn {Prozedur} exact? @var{z} +@deffnx {Prozedur} inexact? @var{z} + +Diese numerischen Prädikate bieten Exaktheitheitsprüfungen einer Größe +an. Für jede beliebige Scheme-Zahl ist genau eines dieser Prädikate +wahr. + +@end deffn + + + +@deffn {Prozedur} = z1 z2 z3 @dots{}, +@deffnx {Prozedur} < x1 x2 x3 @dots{}, +@deffnx {Prozedur} > x1 x2 x3 @dots{}, +@deffnx {Prozedur} <= x1 x2 x3 @dots{}, +@deffnx {Prozedur} >= x1 x2 x3 @dots{}, + +@c - Some implementations allow these procedures to take many arguments, to +@c - facilitate range checks. +Diese Prozeduren geben @t{#t} zurück, wenn ihre Argumente (jeweils) +gleich, monoton steigend, monoton fallend, monoton nicht fallend oder +monoton nicht steigend sind. + +Diese Prädikate müssen transitiv sein. + + +@quotation +@emph{Anmerkung:} +Die traditionelle Implementierung dieser Prädikate in Lisp-artigen +Sprachen ist nicht transitiv. +@end quotation + + + +@quotation +@emph{Anmerkung:} +Auch wenn es kein Fehler ist, @r{inexakte} Zahlen mit diesen Prädikaten +zu vergleichen, können die Ergebnisse unverlässlich sein, weil eine +kleine Ungenauigkeit das Ergebnis beeinflussen kann; dies gilt besonders +für @code{=} und @code{Zero?}. +@vindex @w{Zero?} +@vindex @w{=} +Fragen Sie im Zweifel einen Numeriker um Rat. +@end quotation + + +@end deffn + + +@deffn {Bibliotheksprozedur} zero? @var{z} +@deffnx {Bibliotheksprozedur} positive? @var{x} +@deffnx {Bibliotheksprozedur} negative? @var{x} +@deffnx {Bibliotheksprozedur} odd? @var{n} +@deffnx {Bibliotheksprozedur} even? @var{n} + +Diese numerischen Prädikate prüfen, ob eine bestimmte Eigenschaft für +eine Zahl gilt, und geben @t{#t} oder @t{#f} zurück. Siehe obige +Anmerkung. + +@end deffn + + +@deffn {Bibliotheksprozedur} max x1 x2 @dots{}, +@deffnx {Bibliotheksprozedur} min x1 x2 @dots{}, + +Diese Prozeduren geben das Maximum oder Minimum ihrer Argumente zurück. + + +@format +@t{(max 3 4) ==> 4 ; exakt +(max 3.9 4) ==> 4.0 ; inexakt +} +@end format + + + +@quotation +@emph{Anmerkung:} +Solange ein beliebiges Argument inexakt ist, wird auch das Ergebnis +inexakt sein (außer die Prozedur kann beweisen, dass die Ungenauigkeit +nicht groß genug ist, um das Ergebnis zu beeinflussen, was nur in +ungewöhnlichen Implementierungen möglich ist). Wenn @samp{Min} oder +@samp{Max} zum Vergleich von Zahlen unterschiedlicher Exaktheit benutzt +wird und der numerische Wert des Ergebnisses nicht als eine inexakte +Zahl dargestellt werden kann, ohne Genauigkeit zu verlieren, dann darf +die Prozedur eine Verletzung einer Implementierungseinschränkung melden. +@end quotation + + +@end deffn + + + +@deffn {Prozedur} + z1 @dots{}, +@deffnx {Prozedur} * z1 @dots{}, + +Diese Proceduren geben die Summe oder das Produkt ihrer Argumente +zurück. +@c - These procedures are exactness preserving. + + +@format +@t{(+ 3 4) ==> 7 +(+ 3) ==> 3 +(+) ==> 0 +(* 4) ==> 4 +(*) ==> 1 +} +@end format + + +@end deffn + + + +@deffn {Prozedur} - z1 z2 +@deffnx {Prozedur} - @var{z} +@deffnx {optionale Prozedur} - z1 z2 @dots{}, +@deffnx {Prozedur} / z1 z2 +@deffnx {Prozedur} / @var{z} +@deffnx {optionale Prozedur} / z1 z2 @dots{}, + +Für zwei oder mehr Argumente geben diese Prozeduren die Differenz oder +den Quotienten ihrer Argumente zurück, linksassoziativ. Mit einem +Argument geben sie jedoch das additiv oder multiplikativ Inverse ihres +Arguments zurück. +@c - These procedures are exactness preserving, except that division may +@c - coerce its result to inexact in implementations that do not support +@c - \tupe{ratnum}s. + + +@format +@t{(- 3 4) ==> -1 +(- 3 4 5) ==> -6 +(- 3) ==> -3 +(/ 3 4 5) ==> 3/20 +(/ 3) ==> 1/3 +} +@end format + + +@end deffn + + + +@deffn {Bibliotheksprozedur} abs x + +@samp{Abs} gibt den Absolutbetrag ihres Arguments zurück. +@c - {\cf Abs} is exactness preserving when its argument is real. + +@format +@t{(abs -7) ==> 7 +} +@end format + +@end deffn + + + +@deffn {Prozedur} quotient n1 n2 +@deffnx {Prozedur} remainder n1 n2 +@deffnx {Prozedur} modulo n1 n2 + +Diese Prozeduren implementieren zahlentheoretische (ganzzahlige) +Division. @var{n2} sollte nicht null sein. Alle drei Prozeduren geben +ganze Zahlen zurück. Wenn @var{n1}/@var{n2} eine ganze Zahl ist: + +@format +@t{ (quotient @var{n1} @var{n2}) ==> @var{n1}/@var{n2} + (remainder @var{n1} @var{n2}) ==> 0 + (modulo @var{n1} @var{n2}) ==> 0 +} +@end format + +Wenn @var{n1}/@var{n2} keine ganze Zahl ist: + +@format +@t{ (quotient @var{n1} @var{n2}) ==> @var{n_q} + (remainder @var{n1} @var{n2}) ==> @var{n_r} + (modulo @var{n1} @var{n2}) ==> @var{n_m} +} +@end format + +wobei @var{n_q} der Wert von @var{n1}/@var{n2} gegen null gerundet ist, +0 < |@var{n_r}| < |@var{n2}|, 0 < |@var{n_m}| < |@var{n2}|, @var{n_r} +und @var{n_m} sich von @var{n1} um ein Vielfaches von @var{n2} +unterscheidet, @var{n_r} dasselbe Vorzeichen wie @var{n1} hat und +@var{n_m} dasselbe Vorzeichen wie @var{n2} hat. + +Daraus können wir schließen, dass für ganze Zahlen @var{n1} und @var{n2} +mit @var{n2} ungleich 0 gilt, dass + +@format +@t{ (= @var{n1} (+ (* @var{n2} (quotient @var{n1} @var{n2})) + (remainder @var{n1} @var{n2}))) + ==> #t +} +@end format + +sofern alle in der Berechnung vorkommenden Zahlen exakt sind. + + +@format +@t{(modulo 13 4) ==> 1 +(remainder 13 4) ==> 1 + +(modulo -13 4) ==> 3 +(remainder -13 4) ==> -1 + +(modulo 13 -4) ==> -3 +(remainder 13 -4) ==> 1 + +(modulo -13 -4) ==> -1 +(remainder -13 -4) ==> -1 + +(remainder -13 -4.0) ==> -1.0 ; inexakt +} +@end format + +@end deffn + + +@deffn {Bibliotheksprozedur} gcd n1 @dots{}, +@deffnx {Bibliotheksprozedur} lcm n1 @dots{}, + +Diese Prozeduren geben den größten gemeinsamen Teilrt („greatest common +divisor``) oder das kleinste gemeinsame Vielfache („least common +multiple``) ihrer Argumente zurück. Das Ergebnis ist nie negativ. +@c - These procedures are exactness preserving. + +@c %R4%% I added the inexact example. + +@format +@t{(gcd 32 -36) ==> 4 +(gcd) ==> 0 +(lcm 32 -36) ==> 288 +(lcm 32.0 -36) ==> 288.0 ; inexakt +(lcm) ==> 1 +} +@end format + + +@end deffn + + + +@deffn {Prozedur} numerator @var{q} +@deffnx {Prozedur} denominator @var{q} + +Diese Prozeduren geben den Zähler („numerator``) oder den Nenner +(„denominator``) ihres Arguments zurück; das Ergebnis wird berechnet, +als wäre das Argument als unkürzbarer Bruch dargestellt. Der Nenner ist +immer positiv. Der Nenner von 0 ist auf 1 festgelegt. +@c - The remarks about denominators are new. +@c - Clearly, they are exactness-preserving procedures. + +@ignore todo +More description and examples needed. +@end ignore + + +@format +@t{(numerator (/ 6 4)) ==> 3 +(denominator (/ 6 4)) ==> 2 +(denominator + (exact->inexact (/ 6 4))) ==> 2.0 +} +@end format + + +@end deffn + + + +@deffn {Prozedur} floor x +@deffnx {Prozedur} ceiling x +@deffnx {Prozedur} truncate x +@deffnx {Prozedur} round x + + +Diese Prozeduren geben ganze Zahlen zurück. +@samp{Floor} („abrunden``) gibt die größte ganze Zahl zurück, die nicht +größer als @var{x} ist. +@samp{Ceiling} („aufrunden``) gibt die kleinste ganze Zahl zurück, die +nicht kleiner als @var{x} ist. +@samp{Truncate} („abschneiden``) gibt die am nächsten bei @var{x} +liegende ganze Zahl zurück, deren Absolutbetrag nicht größer als der +Absolutbetrag von @var{x} ist. @samp{Round} („runden``) gibt die am +nächsten bei @var{x} liegende ganze Zahl zurück; sie rundet auf die +nächste gerade ganze Zahl, wenn @var{x} genau in der Mitte zwischen zwei +ganzen Zahlen liegt. + + +@quotation +@emph{Begründung:} +@samp{Round} rundet auf gerade Zahlen, um mit dem standardmäßigen +Rundungsmodus, der vom IEEE-Gleitkommastandard festgelegt wurde, +übereinzustimmen. +@end quotation + + + +@quotation +@emph{Anmerkung:} +Wenn das Argument einer dieser Prozeduren inexakt ist, dann wird das +Ergebnis auch inexakt sein. Wird ein exakter Wert benötigt, sollte das +Ergebnis an die Prozedur @samp{Inexact->exact} weitergereicht werden. +@end quotation + + + +@format +@t{(floor -4.3) ==> -5.0 +(ceiling -4.3) ==> -4.0 +(truncate -4.3) ==> -4.0 +(round -4.3) ==> -4.0 + +(floor 3.5) ==> 3.0 +(ceiling 3.5) ==> 4.0 +(truncate 3.5) ==> 3.0 +(round 3.5) ==> 4.0 ; inexakt + +(round 7/2) ==> 4 ; exakt +(round 7) ==> 7 +} +@end format + + +@end deffn + + +@deffn {Bibliotheksprozedur} rationalize x y +@c - \proto{rationalize}{ x}{Prozedur} + + +@samp{Rationalize} gibt die @emph{einfachste} rationale Zahl zurück, die +sich von @var{x} nicht um mehr als @var{y} unterscheidet. Eine +rationale Zahl r_1 ist @emph{einfacher} als eine andere rationale Zahl +@cindex @w{einfachste rationale Zahl} +r_2, wenn r_1 = p_1/q_1 und r_2 = p_2/q_2 (unkürzbare Brüche) und +|p_1|<= |p_2| und |q_1| <= |q_2|. Somit ist 3/5 einfacher als 4/7. +Obwohl nicht alle rationalen Zahlen in dieser Ordnung vergleichbar sind +(betrachten Sie 2/7 und 3/5), enthält jedes beliebige Intervall eine +rationale Zahl, die einfacher ist als jede andere rationale Zahl in +diesem Intervall (die einfachere 2/5 liegt zwischen 2/7 und 3/5). +Beachten Sie, dass 0 = 0/1 die einfachste rationale Zahl von allen ist. + + +@format +@t{(rationalize + (inexact->exact .3) 1/10) ==> 1/3 ; exakt +(rationalize .3 1/10) ==> #i1/3 ; inexakt +} +@end format + + +@end deffn + + +@deffn {Prozedur} exp @var{z} +@deffnx {Prozedur} log @var{z} +@deffnx {Prozedur} sin @var{z} +@deffnx {Prozedur} cos @var{z} +@deffnx {Prozedur} tan @var{z} +@deffnx {Prozedur} asin @var{z} +@deffnx {Prozedur} acos @var{z} +@deffnx {Prozedur} atan @var{z} +@deffnx {Prozedur} atan @var{y} @var{x} + +Diese Prozeduren sind Teil jeder Implementierung, die +@c %R4%% +allgemeine +reelle Zahlen unterstützt; sie berechnen die üblichen transzendenten +Funktionen. @samp{Log} berechnet den natürlichen Logarithmus von +@var{z} (nicht den Logarithmus zur Basis 10). @samp{Asin}, @samp{Acos} +und @samp{Atan} berechnen jeweils den Arkussinus (sin^-1), Arkuskosinus +(cos^-1) und Arkustangens (tan^-1). Die Variante mit zwei Argumenten +von @samp{Atan} berechnet @t{(angle (make-rectangular @var{x} @var{y}))} +(siehe unten), selbst in Implementierungen, die komplexe Zahlen nicht +allgemein unterstützen. + +Im Allgemeinen sind die mathematischen Funktionen log, arcsine, +arccosine und arctangent verschiedenartig definiert. +Der Wert von log z ist definiert als diejenige Zahl, deren Imaginärteil +im Bereich von -Pi (nicht einschließlich) bis Pi (einschließlich) liegt. +log 0 ist undefiniert. +Mit dem so definierten log ergeben sich die Werte von sin^-1 z, cos^-1 z +und tan^-1 z anhand der folgenden Formeln: + + +@center sin^-1 z = -i log (i z + sqrt(1 - z^2)) + + + +@center cos^-1 z = pi / 2 - sin^-1 z + + + +@center tan^-1 z = (log (1 + i z) - log (1 - i z)) / (2 i) + + +Die obige Spezifikation folgt [CLtL], wo wiederum [Penfield81] zitiert +wird; konsultieren Sie diese Quellen für detailliertere Diskussionen von +Verzweigungsschnitten, Randbedingungen und die Implementierung dieser +Funktionen. Wenn möglich liefern diese Prozeduren ein reelles Ergebnis +für ein reelles Argument. + +@c %R4%% + +@ignore todo +The cited references are likely to change their branch cuts +soon to allow for the possibility of distinct positive and negative +zeroes, as in IEEE floating point. We may not want to follow those +changes, since we may want a complex number with zero imaginary part +(whether positive or negative zero) to be treated as a real. I don't +think there are any better standards for complex arithmetic than the +ones cited, so we're really on our own here. +@end ignore + + +@end deffn + + + +@deffn {Prozedur} sqrt @var{z} + +Gibt die Haupt-Quadratwurzel von @var{z} zurück. Das Ergebnis wird +entweder einen positiven Realteil oder haben, oder null Realteil und +nicht-negativen Imaginärteil haben. +@end deffn + + + +@deffn {Prozedur} expt z1 z2 + +Gibt @var{z1} zur Potenz @var{z2} zurück. Für z_1 ~= 0 + + +@center z_1^z_2 = e^z_2 log z_1 + +0^z ist 1 wenn z = 0, und 0 sonst. +@end deffn + +@c - \begin{entry}{%- +@c - \proto{approximate}{ z x}{Prozedur}} +@c - +@c - Returns an approximation to \vr{z} in a representation whose precision is +@c - the same as that +@c - of the representation of \vr{x}, which must be an inexact number. The +@c - result is always inexact. +@c - +@c - \begin{scheme} +@c - (approximate 3.1415926535 1F10) +@c - \ev 3.14159F0 +@c - (approximate 3.1415926535 \#I65535) +@c - \ev \#I3 +@c - (approximate 3.14F0 1L8) +@c - \ev 3.14L0 +@c - (approximate 3.1415926535F0 1L8) +@c - \ev 3.14159L0 +@c - \end{scheme} +@c - \end{entry} + + + + +@deffn {Prozedur} make-rectangular x1 x2 +@deffnx {Prozedur} make-polar x3 x4 +@deffnx {Prozedur} real-part @var{z} +@deffnx {Prozedur} imag-part @var{z} +@deffnx {Prozedur} magnitude @var{z} +@deffnx {Prozedur} angle @var{z} + +Diese Prozeduren sind Teil jeder Implementierung, die +@c %R4%% +allgemeine +komplexe Zahlen unterstützt. Angenommen @var{x1}, @var{x2}, @var{x3} +und @var{x4} sind reelle Zahlen und @var{z} ist eine komplexe Zahl, so +dass + + +@center @var{z} = @var{x1} + @var{x2}@w{i} = @var{x3} . e^@w{i} @var{x4} + +Dann + +@format +@t{(make-rectangular @var{x1} @var{x2}) ==> @var{z} +(make-polar @var{x3} @var{x4}) ==> @var{z} +(real-part @var{z}) ==> @var{x1} +(imag-part @var{z}) ==> @var{x2} +(magnitude @var{z}) ==> |@var{x3}| +(angle @var{z}) ==> x_Winkel +} +@end format + +wobei -Pi < x_Winkel <= Pi mit x_Winkel = @var{x4} + 2Pi n +für eine ganze Zahl n. + + +@quotation +@emph{Begründung:} +@samp{Magnitude} ist dasselbe wie @code{Abs} für ein reelles Argument, +@vindex @w{Abs} +aber @samp{Abs} muss in allen Implementierungen vorhanden sein, während +@samp{Magnitude} nur in Implementierungen vorhanden sein muss, die +allgemeine komplexe Zahlen unterstützen. +@end quotation + + +@end deffn + + + +@deffn {Prozedur} exact->inexact @var{z} +@deffnx {Prozedur} inexact->exact @var{z} + +@samp{Exact->inexact} gibt eine @r{inexakte} Darstellung von @var{z} +zurück. Der zurückgegebene Wert ist die @r{inexakte} Zahl, die +numerisch dem Argument am nächsten liegen. +@c %R4%%For +@c \tupe{exact} arguments which have no reasonably close \tupe{inexact} equivalent, +@c it is permissible to signal an error. +Wenn ein @r{exaktes} Argument kein @r{inexaktes} Gegenstück in +vernünftiger Nähe hat, dann darf eine Verletzung einer +Implementierungseinschränkung gemeldet werden. + +@samp{Inexact->exact} gibt eine @r{exakte} Darstellung von @var{z} +zurück. Der zurückgegebene Wert ist die @r{exakte} Zahl, die numerisch +dem Argument am nächsten liegt. +@c %R4%% For \tupe{inexact} arguments which have no +@c reasonably close \tupe{exact} equivalent, it is permissible to signal +@c an error. +Wenn ein @r{inexaktes} Argument kein @r{exaktes} Gegenstück in +vernünftiger Nähe hat, dann darf eine Verletzung einer +Implementierungseinschränkung gemeldet werden. + +@c %R%% I moved this to the section on implementation restrictions. +@c For any implementation that supports \tupe{inexact} quantities, +@c there is a subset of the integers for which there are both \tupe{exact} and +@c \tupe{inexact} representations. This subset must include the non-negative +@c integers up to a limit specified by the implementation. The limit +@c must be big enough to represent all digits in reasonable radices, and +@c may correspond to some natural word size for the implementation. For +@c such integers, these procedures implement the natural one-to-one +@c correspondence between the representations. + +Diese Prozeduren implementieren die natürliche +Eins-zu-eins-Korrespondenz zwischen @r{exakten} und @r{inexakten} ganzen +Zahlen innerhalb eines implementierungsabhängigen Wertebereichs. Siehe +den Abschnitt @ref{Implementierungseinschränkungen}. + +@end deffn + +@sp 3 + +@node Numerische Ein- und Ausgabe, , Numerische Operationen, Zahlen +@subsection Numerische Ein- und Ausgabe + + + +@deffn {Prozedur} number->string z +@deffnx {Prozedur} number->string z radix + +@var{Radix} muss eine exakte ganze Zahl sein, entweder 2, 8, 10 oder 16. +Wenn er nicht angegeben wird, nimmt @var{Radix} standardmäßig den Wert +10 an. +Die Prozedur @samp{Number->string} nimmt eine Zahl und eine Radix und +gibt als String eine externe Darstellung der gegebenen Zahl zur +angegebenen Basis (die Radix) zurück, so dass + +@format +@t{(let ((number @var{Zahl}) + (radix @var{Radix})) + (eqv? Zahl + (string->number (number->string Zahl + Radix) + Radix))) +} +@end format + +wahr ist. Es ist ein Fehler, wenn kein mögliches Ergebnis diesen +Ausdruck wahr macht. + +Wenn @var{z} inexakt ist, die Radix 10 beträgt und obiger Ausdruck durch +ein Ergebnis erfüllt werden kann, das ein Dezimaltrennzeichen enthält, +dann enthält das Ergebnis einen Dezimalpunkt als Dezimaltrennzeichen und +wird mit der geringstmöglichen Anzahl Ziffern ausgedrückt (den +Exponenten und folgende Nullen nicht eingeschlossen), die nötig sind, um +obigen Ausdruck wahr zu machen [howtoprint], [howtoread], andernfalls +ist das Format des Ergebnisses unbestimmt. + +Das von @samp{Number->string} zurückgegebene Ergebnis enthält niemals +ein explizites Radix-Präfix. + + +@quotation +@emph{Anmerkung:} +Der Fehlerfall kann nur eintreten, wenn @var{z} keine komplexe Zahl oder +eine komplexe Zahl mit nicht-rationalem reellem oder imaginären Anteil +ist. +@end quotation + + + +@quotation +@emph{Begründung:} +Wenn @var{z} eine inexakte Zahl ist, die mit Gleitkommazahlen +dargestellt ist, und die Radix 10 ist, dann wird obiger Ausdruck +normalerweise von einem Ergebnis mit Dezimaltrennzeichen erfüllt. Der +unbestimmte Fall erlaubt Unendlichkeiten, NaNs und +Nichtgleitkommadarstellungen. +@end quotation + + +@end deffn + + + +@deffn {Prozedur} string->number string +@deffnx {Prozedur} string->number string radix + +@c %R4%% I didn't include the (string->number string radix exactness) +@c case, since I haven't heard any resolution of the coding to be used +@c for the third argument. + +Gibt eine Zahl mit der genauestmöglichen Darstellung zurück, die von der +gegebenen Zeichenkette @var{String} ausgedrückt wird. @var{Radix} muss +eine exakte ganze Zahl, entweder 2, 8, 10 oder 16, sein. Wenn +angegeben, ist @var{Radix} eine Standardbasis, gegenüber der ein +ausdrücklich angegebenes Radix-Präfix in @var{String} Vorrang hat +(@abbr{z.B.} @t{"#o177"}). Wenn @var{Radix} nicht angegeben wird, ist +die Standardbasis 10. Wenn @var{String} keine syntaktisch gültige +Notation einer Zahl ist, dann gibt @samp{String->number} den Wert @t{#f} +zurück. + + +@format +@t{(string->number "100") ==> 100 +(string->number "100" 16) ==> 256 +(string->number "1e2") ==> 100.0 +(string->number "15##") ==> 1500.0 +} +@end format + + + +@quotation +@emph{Anmerkung:} +Die Definitionsmenge von @samp{String->number} darf auf folgende Arten +von Implementierungen eingeschränkt werden. @samp{String->number} darf +@t{#f} zurückgeben, wann immer @var{String} ein ausdrückliches +Radix-Präfix enthält. Wenn alle von einer Implementierung unterstützten +Zahlen reell sind, dann darf @samp{String->number} den Wert @t{#f} +zurückgeben, wann immer @var{String} polare oder kartesische Notationen +für komplexe Zahlen benutzt. Wenn alle Zahlen ganze Zahlen sind, darf +@samp{String->number} den Wert @t{#f} zurückgeben, wann immer die +Bruchdarstellung benutzt wird. Wenn alle Zahlen exakt sind, dann darf +@samp{String->number} den Wert @t{#f} zurückgeben, wann immer eine +Exponentenmarkierung oder ein ausdrückliches Exaktheitspräfix benutzt +wird, oder wenn ein @t{#} anstelle einer Ziffer vorkommt. Wenn alle +inexakten Zahlen ganze Zahlen sind, dann darf @samp{String->number} den +Wert @t{#f} zurückgeben, wann immer ein Dezimaltrennzeichen benutzt +wird. +@end quotation + + +@end deffn + +@node Andere Datentypen, Programmflussfunktionalitäten, Zahlen, Standardprozeduren +@section Andere Datentypen + +@menu +* Boolesche Werte:: +* Paare und Listen:: +* Symbole:: +* Zeichen:: +* Zeichenketten:: +* Vektoren:: +@end menu + + +Dieser Abschnitt beschreibt Operationen auf manchen von Schemes +nicht-numerischen Datentypen: booleschen Werten („booleans``), Paaren +(„pairs``), Listen („lists``), Symbolen („symbols``), Zeichen +(„characters``), Zeichenketten („strings``) und Vektoren +(„vectors``). + +@node Boolesche Werte, Paare und Listen, Andere Datentypen, Andere Datentypen +@subsection Boolesche Werte + + + +Die standardmäßigen booleschen Objekte für wahr und falsch werden +geschrieben als @t{#t} und @t{#f}. Was aber wirklich +@vindex #f +@vindex #t +wichtig ist, sind die Objekte, die die bedingten Ausdrücke von Scheme +(@samp{If}, @samp{Cond}, @samp{And}, @samp{Or}, @samp{Do}) als wahr oder +falsch behandeln. Die Formulierung „ein wahrer Wert`` +@cindex @w{falsch} +@cindex @w{wahr} +(oder manchmal kurz „wahr``) bedeutet ein beliebiges Objekt, das von +den bedingten Ausdrücken als wahr behandelt wird, und die Formulierung +„ein falscher Wert`` (oder +@cindex @w{falsch} +„falsch``) bedeutet ein beliebiges Objekt, das von den bedingten +Ausdrücken als falsch behandelt wird. + +Von allen Standard-Scheme-Werten zählt nur @t{#f} +@c is guaranteed to count +als falsch in bedingten Ausdrücken. +@c It is not +@c specified whether the empty list\index{empty list} counts as false +@c or as true in conditional expressions. +Außer @t{#f} +@c and possibly the empty list, +zählen alle Standard-Scheme-Werte, einschließlich @t{#t}, Paaren, der +leeren Liste, Symbolen, Zahlen, Zeichenketten, Vektoren und Prozeduren +als wahr. + +@c \begin{note} +@c In some implementations the empty list counts as false, contrary +@c to the above. +@c Nonetheless a few examples in this report assume that the +@c empty list counts as true, as in \cite{IEEEScheme}. +@c \end{note} + +@c \begin{rationale} +@c For historical reasons some implementations regard \schfalse{} and the +@c empty list as the same object. These implementations therefore cannot +@c make the empty list count as true in conditional expressions. +@c \end{rationale} + + +@quotation +@emph{Anmerkung:} +Programmierer, die an andere Dialekte von Lisp gewöhnt sind, sollten +beachten, dass Scheme sowohl @t{#f} als auch die leere Liste +@cindex @w{leere Liste} +vom Symbol @code{nil} unterscheidet. +@vindex @w{nil} +@end quotation + + +Boolesche Konstante werden zu sich selbst ausgewertet, also müssen sie +in Programmen nicht maskiert werden. + + +@example + +#t ==> #t +#f ==> #f +'#f ==> #f + +@end example + + + + +@deffn {Bibliotheksprozedur} not obj + +@samp{Not} gibt @t{#t} zurück, wenn @var{Obj} falsch ist, und gibt sonst +@t{#f} zurück. + + +@format +@t{(not #t) ==> #f +(not 3) ==> #f +(not (list 3)) ==> #f +(not #f) ==> #t +(not '()) ==> #f +(not (list)) ==> #f +(not 'nil) ==> #f +} +@end format + + +@end deffn + + + +@deffn {Bibliotheksprozedur} boolean? obj + +@samp{Boolean?} gibt @t{#t} zurück, wenn @var{Obj} entweder @t{#t} oder +@t{#f} ist, und gibt sonst @t{#f} zurück. + + +@format +@t{(boolean? #f) ==> #t +(boolean? 0) ==> #f +(boolean? '()) ==> #f +} +@end format + + +@end deffn + + +@node Paare und Listen, Symbole, Boolesche Werte, Andere Datentypen +@subsection Paare und Listen + + + +Ein @dfn{Paar} (manchmal auch ein @dfn{gepunktetes Paar}, „dotted +pair``) ist eine +@cindex @w{gepunktetes Paar} +@cindex @w{dotted pair} +@cindex @w{Paar} +Verbundsstruktur mit zwei Komponenten, die als die Car- und +Cdr-Komponenten bezeichnet werden (aus historischen Gründen). Paare +werden durch die Prozedur @samp{Cons} erzeugt. Auf die Car- und +Cdr-Komponenten wird durch die Prozeduren @samp{Car} und @samp{Cdr} +zugegriffen. Die Car- und Cdr-Komponenten werden durch die Prozeduren +@samp{Set-car!} und @samp{Set-cdr!} zugewiesen. + +Paare werden vorrangig benutzt, um Listen darzustellen. Eine Liste kann +rekursiv als entweder die leere Liste oder ein Paar, dessen +@cindex @w{leere Liste} +Cdr eine Liste ist, definiert werden. Genauer ist die Menge der Listen +definiert als die kleinste Menge @var{X}, so dass gilt: + + + +@itemize @bullet + +@item +Die leere Liste ist in @var{X}. +@item +Wenn @var{Liste} in @var{X} ist, ist auch jedes Paar in @var{X}, dessen +Cdr-Komponente @var{Liste} enthält. + +@end itemize + + +Die Objekte in den Car-Komponenten aufeinanderfolgender Paare einer +Liste sind die Elemente der Liste. Zum Beispiel ist eine zweielementige +Liste ein Paar, deren Car das erste Element ist und deren Cdr ein Paar +ist, deren Car das zweite Element und deren Cdr die leere Liste ist. +Die Länge einer Liste ist die Anzahl der Elemente, was dasselbe ist wie +die Anzahl der Paare. + +Die leere Liste ist ein besonderes Objekt mit seinem eigenen Typ +@cindex @w{leere Liste} +(sie ist kein Paar); sie hat keine Elemente und ihre Länge ist null. + + +@quotation +@emph{Anmerkung:} +Die obigen Definitionen haben zur Folge, dass alle Listen eine endliche +Länge haben und auf die leere Liste enden. +@end quotation + + +Die allgemeinste Notation (externe Darstellung) für Scheme-Paare ist die +„gepunktete`` Notation @w{@samp{(@var{c1} .@: @var{c2})}}, wobei +@var{c1} der Wert der Car-Komponente und @var{c2} der Wert der +Cdr-Komponente ist. Zum Beispiel ist @samp{(4 .@: 5)} ein Paar, deren +Car 4 ist und deren Cdr 5 ist. Beachten Sie, dass @samp{(4 .@: 5)} die +externe Darstellung eines Paares ist, nicht ein Ausdruck, der zu einem +Paar ausgewertet wird. + +Eine optimiertere Notation kann für Listen benutzt werden: Die Elemente +der Liste werden einfach von runden Klammern umschlossen und durch +Leerzeichen getrennt. Die leere Liste wird als @t{()} geschrieben. Zum +Beispiel sind +@cindex @w{leere Liste} + + +@example + +(a b c d e) + +@end example + + +und + + +@example + +(a . (b . (c . (d . (e . ()))))) + +@end example + + +äquivalente Notationen für eine Liste von Symbolen. + +Eine Kette aus Paaren, die nicht auf die leere Liste endet, wird +@dfn{unechte Liste} genannt. Beachten Sie, dass eine unechte Liste +keine Liste ist. +@cindex @w{unechte Liste} +Die Listennotation und die gepunktete Notation können zur Darstellung +unechter Listen kombiniert werden: + + +@example + +(a b c . d) + +@end example + + +ist äquivalent zu + + +@example + +(a . (b . (c . d))) + +@end example + + +Ob ein bestimmtes Paar eine Liste ist, hängt davon ab, was in der +Cdr-Komponente gespeichert ist. Wenn die Prozedur @code{Set-cdr!} +benutzt wird, kann ein Objekt im einen Moment eine Liste sein +@vindex @w{Set-cdr!} +und im nächsten nicht mehr: + + +@example + +(define x (list 'a 'b 'c)) +(define y x) +y ==> (a b c) +(list? y) ==> #t +(set-cdr! x 4) ==> @emph{unbestimmt} +x ==> (a . 4) +(eqv? x y) ==> #t +y ==> (a . 4) +(list? y) ==> #f +(set-cdr! x x) ==> @emph{unbestimmt} +(list? x) ==> #f + +@end example + + +@c It is often convenient to speak of a homogeneous list of objects +@c of some particular data type, as for example \hbox{\cf (1 2 3)} is a list of +@c integers. To be more precise, suppose \var{D} is some data type. (Any +@c predicate defines a data type consisting of those objects of which the +@c predicate is true.) Then + +@c \begin{itemize} +@c \item The empty list is a list of \var{D}. +@c \item If \var{list} is a list of \var{D}, then any pair whose cdr is +@c \var{list} and whose car is an element of the data type \var{D} is also a +@c list of \var{D}. +@c \item There are no other lists of \var{D}. +@c \end{itemize} + +Innerhalb literaler Ausdrücke und in Darstellungen von mit der Prozedur +@code{Read} gelesenen Objekten bezeichnen die Formen +@t{'}@r{<Datenelement>}, +@vindex ' +@vindex @w{Read} +@t{`}@r{<Datenelement>}, @t{,}@r{<Datenelement>} und +@vindex , +@t{,@@}@r{<Datenelement>} zweielementige Listen, deren erstes Element +jeweils die Symbole @code{Quote}, @code{Quasiquote}, @w{@code{Unquote}} +und +@vindex @w{Unquote} +@vindex @w{Quasiquote} +@vindex @w{Quote} +@code{Unquote-splicing} sind. Das zweite Element ist in allen Fällen +@vindex @w{Unquote-splicing} +@r{<Datenelement>}. Diese Konvention wird unterstützt, damit beliebige +Scheme-Programme als Listen dargestellt werden können. +@ignore todo +Can or need this be stated +more carefully? +@end ignore + Das heißt, dass laut der Grammatik von Scheme jeder <Ausdruck> auch ein +<Datenelement> ist (siehe den Abschnitt @pxref{Externe Darstellung}). +Dies erlaubt unter Anderem, die Prozedur @samp{Read} zu benutzen, um +Scheme-Programme zu verarbeiten. Siehe den Abschnitt @ref{Externe +Darstellungen}. + + + +@deffn {Prozedur} pair? obj + +@samp{Pair?} gibt @t{#t} zurück, wenn @var{Obj} ein Paar ist, und gibt +andernfalls @t{#f} zurück. + + +@format +@t{(pair? '(a . b)) ==> #t +(pair? '(a b c)) ==> #t +(pair? '()) ==> #f +(pair? '#(a b)) ==> #f +} +@end format + +@end deffn + + + +@deffn {Prozedur} cons obj1 obj2 + +Gibt ein neu zugeteiltes Paar zurück, deren Car @var{Obj1} ist und deren +Cdr @var{Obj2} ist. Es wird garantiert, dass das Paar sich (im Sinn von +@samp{Eqv?}) von jedem existierenden Objekt unterscheidet. + + +@format +@t{(cons 'a '()) ==> (a) +(cons '(a) '(b c d)) ==> ((a) b c d) +(cons "a" '(b c)) ==> ("a" b c) +(cons 'a 3) ==> (a . 3) +(cons '(a b) 'c) ==> ((a b) . c) +} +@end format + +@end deffn + + + +@deffn {Prozedur} car paar + +@ignore nodomain +@var{Pair} must be a pair. +@end ignore + +Gibt den Inhalt der Car-Komponente von @var{Paar} zurück. Beachten Sie, +dass es ein Fehler ist, das Car der leeren Liste zu nehmen. +@cindex @w{leere Liste} + + +@format +@t{(car '(a b c)) ==> a +(car '((a) b c d)) ==> (a) +(car '(1 . 2)) ==> 1 +(car '()) ==> @emph{Fehler} +} +@end format + + +@end deffn + + + +@deffn {Prozedur} cdr paar + +@ignore nodomain +@var{Pair} must be a pair. +@end ignore + +Gibt den Inhalt der Cdr-Komponente von @var{Paar} zurück. Beachten Sie, +dass es ein Fehler ist, den Cdr der leeren Liste zu nehmen. + + +@format +@t{(cdr '((a) b c d)) ==> (b c d) +(cdr '(1 . 2)) ==> 2 +(cdr '()) ==> @emph{Fehler} +} +@end format + + +@end deffn + + + +@deffn {Prozedur} set-car! paar obj + +@ignore nodomain +@var{Pair} must be a pair. +@end ignore + +Speichert @var{Obj} in der Car-Komponente von @var{Paar}. Der durch +@samp{Set-car!} zurückgegebene Wert ist unbestimmt. +@c <!> +@c This procedure can be very confusing if used indiscriminately. + + +@format +@t{(define (f) (list 'keine-konstante-Liste)) +(define (g) '(konstante-Liste)) +(set-car! (f) 3) ==> @emph{unbestimmt} +(set-car! (g) 3) ==> @emph{Fehler} +} +@end format + + +@end deffn + + + +@deffn {Prozedur} set-cdr! paar obj + +@ignore nodomain +@var{Pair} must be a pair. +@end ignore + +Speichert @var{Obj} in der Cdr-Komponente von @var{Paar}. Der durch +@samp{Set-cdr!} zurückgegebene Wert ist unbestimmt. +@c <!> +@c This procedure can be very confusing if used indiscriminately. + +@end deffn + + + + + + +@deffn {Bibliotheksprozedur} caar paar +@deffnx {Bibliotheksprozedur} cadr paar + +@deffnx { @w{ @dots{}}} @w{ @dots{}} + +@deffnx {Bibliotheksprozedur} cdddar paar +@deffnx {Bibliotheksprozedur} cddddr paar + +Diese Prozeduren sind Zusammensetzungen von @samp{Car} und @samp{Cdr}, +wobei zum Beispiel @samp{Caddr} definiert werden könnte als + + +@format +@t{(define caddr (lambda (x) (car (cdr (cdr x)))))@r{.} +} +@end format + + +Beliebige Zusammensetzungen, bis zur Tiefe vier, werden angeboten. Es +gibt insgesamt achtundzwanzig solche Prozeduren. + +@end deffn + + + +@deffn {Bibliotheksprozedur} null? obj + +Gibt @t{#t} zurück, wenn @var{Obj} die leere Liste ist, +@cindex @w{leere Liste} +und gibt sonst @t{#f} zurück. + +@c \begin{note} +@c In implementations in which the empty +@c list is the same as \schfalse{}, {\cf null?} will return \schtrue{} +@c if \var{obj} is \schfalse{}. +@c \end{note} + +@end deffn + + +@deffn {Bibliotheksprozedur} list? obj + +Gibt @t{#t} zurück, wenn @var{Obj} eine Liste ist, und gibt sonst @t{#f} +zurück. Per Definition haben alle Listen endliche Länge und enden auf +die leere Liste. + + +@format +@t{ (list? '(a b c)) ==> #t + (list? '()) ==> #t + (list? '(a . b)) ==> #f + (let ((x (list 'a))) + (set-cdr! x x) + (list? x)) ==> #f +} +@end format + +@end deffn + + + +@deffn {Bibliotheksprozedur} list @var{obj} @dots{}, + +Gibt eine neu zugeteilte Liste ihrer Argumente zurück. + + +@format +@t{(list 'a (+ 3 4) 'c) ==> (a 7 c) +(list) ==> () +} +@end format + +@end deffn + + + +@deffn {Bibliotheksprozedur} length liste + +@ignore nodomain +@var{List} must be a list. +@end ignore + +Gibt die Länge von @var{Liste} zurück. + + +@format +@t{(length '(a b c)) ==> 3 +(length '(a (b) (c d e))) ==> 3 +(length '()) ==> 0 +} +@end format + +@end deffn + + + +@deffn {Bibliotheksprozedur} append liste @dots{}, + +@ignore nodomain +All @var{list}s should be lists. +@end ignore + +Gibt eine Liste zurück, die aus den Elementen der ersten @var{Liste}, +gefolgt von den Elementen der anderen @var{Liste}n, besteht. + + +@format +@t{(append '(x) '(y)) ==> (x y) +(append '(a) '(b c d)) ==> (a b c d) +(append '(a (b)) '((c))) ==> (a (b) (c)) +} +@end format + + +Die sich so ergebende Liste wird immer neu zugeteilt, außer dass sie +ihre Struktur mit dem letzten @var{Liste}nargument teilt. Das letzte +Argument darf tatsächlich ein beliebiges Objekt sein; eine unechte Liste +ergibt sich, wenn das letzte Argument keine echte Liste ist. +@ignore todo +This is pretty awkward. I should get Bartley to fix this. +@end ignore + + + +@format +@t{(append '(a b) '(c . d)) ==> (a b c . d) +(append '() 'a) ==> a +} +@end format + +@end deffn + + + +@deffn {Bibliotheksprozedur} reverse liste + +@ignore nodomain +@var{List} must be a list. +@end ignore + +Gibt eine neu zugeteilte Liste zurück, die aus den Elementen der +@var{Liste} in umgekehrter Reihenfolge besteht. + + +@format +@t{(reverse '(a b c)) ==> (c b a) +(reverse '(a (b c) d (e (f)))) + ==> ((e (f)) d (b c) a) +} +@end format + +@end deffn + + + +@deffn {Bibliotheksprozedur} list-tail liste @var{k} + +Gibt die Teilliste von @var{Liste} zurück, die man durch Weglassen der +ersten @var{k} Elemente erhält. Es ist ein Fehler, wenn @var{Liste} +weniger als @var{k} Elemente hat. @samp{List-tail} könnte definiert +werden als + + +@format +@t{(define list-tail + (lambda (x k) + (if (zero? k) + x + (list-tail (cdr x) (- k 1))))) +} +@end format + +@end deffn + + + +@deffn {Bibliotheksprozedur} list-ref liste @var{k} + +Gibt das Element @var{k} der @var{Liste} zurück. (Dieses ist +dasselbe wie das Car von @t{(list-tail @var{list} @var{k})}.) Es ist +ein Fehler, wenn die @var{Liste} weniger als @var{k} Elemente hat. + + +@format +@t{(list-ref '(a b c d) 2) ==> c +(list-ref '(a b c d) + (inexact->exact (round 1.8))) + ==> c +} +@end format + +@end deffn + + +@c \begin{entry}{% +@c \proto{last-pair}{ list}{Bibliotheksprozedur}} + +@c Returns the last pair in the nonempty, possibly improper, list \var{list}. +@c {\cf Last-pair} could be defined by + +@c \begin{scheme} +@c (define last-pair +@c (lambda (x) +@c (if (pair? (cdr x)) +@c (last-pair (cdr x)) +@c x)))% +@c \end{scheme} + +@c \end{entry} + + + +@deffn {Bibliotheksprozedur} memq obj liste +@deffnx {Bibliotheksprozedur} memv obj liste +@deffnx {Bibliotheksprozedur} member obj liste + +Diese Prozeduren geben die erste Teilliste der @var{Liste} zurück, deren +Car @var{Obj} ist, wobei die Teillisten der @var{Liste} die von +@t{(list-tail @var{Liste} @var{k})} zurückgegebenen nicht-leeren Listen +für @var{k} kleiner als die Länge der Liste sind. Wenn @var{Obj} in +@var{Liste} nicht vorkommt, dann wird @t{#f} (nicht die leere Liste) +zurückgegeben. @samp{Memq} benutzt @samp{Eq?} zum Vergleichen von +@var{Obj} mit den Elementen der @var{Liste}, während @samp{Memv} die +Prozedur @samp{Eqv?} und @samp{Member} die Prozedur @samp{Equal?} +benutzt. + + +@format +@t{(memq 'a '(a b c)) ==> (a b c) +(memq 'b '(a b c)) ==> (b c) +(memq 'a '(b c d)) ==> #f +(memq (list 'a) '(b (a) c)) ==> #f +(member (list 'a) + '(b (a) c)) ==> ((a) c) +(memq 101 '(100 101 102)) ==> @emph{unbestimmt} +(memv 101 '(100 101 102)) ==> (101 102) +} +@end format + + +@end deffn + + + +@deffn {Bibliotheksprozedur} assq obj aliste +@deffnx {Bibliotheksprozedur} assv obj aliste +@deffnx {Bibliotheksprozedur} assoc obj aliste + +@var{Aliste} (für „assoziative Liste``) muss eine Liste von Paaren +sein. Diese Prozeduren finden das erste Paar in @var{Aliste}, dessen +Car-Komponente @var{Obj} ist, und geben dieses Paar zurück. Wenn kein +Paar in @var{Aliste} das @var{Obj} als sein Car hat, dann wird @t{#f} +zurückgegeben (nicht die leere Liste). @samp{Assq} benutzt @samp{Eq?} +zum Vergleich von @var{Obj} mit den Car-Komponenten der Paare in der +@var{Aliste}, während @samp{Assv} die Prozedur @samp{Eqv?} und +@samp{Assoc} die Prozedur @samp{Equal?} benutzt. + + +@format +@t{(define e '((a 1) (b 2) (c 3))) +(assq 'a e) ==> (a 1) +(assq 'b e) ==> (b 2) +(assq 'd e) ==> #f +(assq (list 'a) '(((a)) ((b)) ((c)))) + ==> #f +(assoc (list 'a) '(((a)) ((b)) ((c)))) + ==> ((a)) +(assq 5 '((2 3) (5 7) (11 13))) + ==> @emph{unbestimmt} +(assv 5 '((2 3) (5 7) (11 13))) + ==> (5 7) +} +@end format + + + + +@quotation +@emph{Begründung:} +Obwohl sie normalerweise als Prädikate benutzt werden, haben +@samp{Memq}, @samp{Memv}, @samp{Member}, @samp{Assq}, @samp{Assv} und +@samp{Assoc} keine Fragezeichen in ihren Namen, weil sie nützliche Werte +statt bloß @t{#t} oder @t{#f} zurückgeben. +@end quotation + +@end deffn + + +@node Symbole, Zeichen, Paare und Listen, Andere Datentypen +@subsection Symbole + + + +Symbole sind Objekte, deren Nützlichkeit auf der Tatsache beruht, dass +zwei Symbole genau dann identisch sind (im Sinn von @samp{Eqv?}), wenn +ihre Namen auf gleiche Weise geschrieben werden. Dies ist genau die +Eigenschaft, die gebraucht wird, um Bezeichner in Programmen +darzustellen, daher benutzen die meisten +@cindex @w{Bezeichner} +Implementierungen von Scheme intern Symbole als Bezeichner. Symbole +sind nützlich für viele andere Anwendungen, zum Beispiel können sie so +wie Aufzählungswerte in Pascal benutzt werden. + +Die Regeln, wie ein Symbol geschrieben wird, sind genau die gleichen wie +die Regeln, wie ein Bezeichner geschrieben wird, siehe die Abschnitte +@ref{Bezeichner} und @ref{Lexikalische Struktur}. + +Es wird garantiert, dass jedes Symbol, was als Teil eines literalen +Ausdrucks zurückgegeben wurde oder was von der Prozedur @samp{Read} +gelesen und anschließend durch die Prozedur @samp{Write} geschrieben +wurde, wieder als dasselbe Symbol einlesbar ist (im Sinne von +@samp{Eqv?}). Die Prozedur @samp{String->symbol} kann jedoch Symbole +erstellen, für die diese Schreib-/Lese-Invarianz nicht gelten könnte, +weil ihre Namen Sonderzeichen oder Buchstaben in nicht standardmäßiger +Groß- und Kleinschreibung enthalten. + + +@quotation +@emph{Anmerkung:} +Manche Implementierungen von Scheme haben eine Funktionalität, die als +Slashifizierung („slashification``) bekannt ist, um +Schreib-/Lese-Invarianz für alle Symbole zu garantieren, aber historisch +war die wichtigste Anwendung dieser Funktionalität, das Fehlen eines +Datentyps für Zeichenketten auszugleichen. + +Manche Implementierungen haben auch „nicht internierte Symbole``, +welche Schreib-/Lese-Invarianz unmöglich machen, selbst in +Implementierungen mit Slashifizierung, und auch Ausnahmen zu der Regel +bilden, dass zwei Symbole genau dann dasselbe sind, wenn ihre Namen +gleich geschrieben werden. +@end quotation + + + + +@deffn {Prozedur} symbol? obj + +Gibt @t{#t} zurück, wenn @var{Obj} ein Symbol ist, und gibt sonst @t{#f} +zurück. + + +@format +@t{(symbol? 'foo) ==> #t +(symbol? (car '(a b))) ==> #t +(symbol? "bar") ==> #f +(symbol? 'nil) ==> #t +(symbol? '()) ==> #f +(symbol? #f) ==> #f +} +@end format + +@end deffn + + + +@deffn {Prozedur} symbol->string symbol + +Gibt den Namen des @var{Symbol}s als eine Zeichenkette zurück. Wenn das +Symbol ein Teil eines Objekts war, das als der Wert eines literalen +Ausdrucks zurückgegeben wurde (Abschnitt @pxref{Literale Ausdrücke}) +oder von einem Aufruf der Prozedur @samp{Read} zurückgegeben wurde, und +sein Name Buchstabenzeichen enthält, dann wird die zurückgegebene +Zeichenkette Zeichen in der von der Implementierung bevorzugten Groß- +und Kleinschreibung enthalten---manche Implementierungen werden +Großbuchstaben bevorzugen, andere Kleinschreibung. Wenn das Symbol von +@samp{String->symbol} zurückgegeben wurde, wird die Groß- und +Kleinschreibung der Zeichen der zurückgegebenen Zeichenkette dieselbe +sein wie die, die an @samp{String->symbol} übergeben wurde. Es ist ein +Fehler, Veränderungsprozeduren wie @code{String-set!} auf von +@vindex @w{String-set!} +dieser Prozedur zurückgegebene Zeichenketten anzuwenden. + +Die folgenden Beispiele nehmen an, dass die standardmäßige +Groß-und-Kleinschreibung der Implementierung Kleinschreibung ist: + + +@format +@t{(symbol->string 'fliegende-Fische) + ==> "fliegende-fische" +(symbol->string 'Martin) ==> "martin" +(symbol->string + (string->symbol "Malvina")) + ==> "Malvina" +} +@end format + +@end deffn + + + +@deffn {Prozedur} string->symbol string + +Gibt das Symbol zurück, dessen Name @var{String} ist. Diese Prozedur +kann Symbole erzeugen, deren Namen Sonderzeichen enthalten oder +Buchstaben in nicht standardmäßiger Groß- und Kleinschreibung enthalten, +aber es ist meistens eine schlechte Idee, solche Symbole zu erzeugen, +denn in manchen Implementierungen von Scheme können sie nicht als sie +selbst eingelesen werden. Siehe @samp{Symbol->string}. + +Die folgenden Beispiele nehmen an, dass die standardmäßige Groß- und +Kleinschreibung der Implementierung Kleinschreibung ist: + + +@format +@t{(eq? 'mISSISSIppi 'mississippi) + ==> #t +(string->symbol "mISSISSIppi") + ==> + @r{}das Symbol namens "mISSISSIppi" +(eq? 'bitBlt (string->symbol "bitBlt")) + ==> #f +(eq? 'JollyWog + (string->symbol + (symbol->string 'JollyWog))) + ==> #t +(string=? "K. Harper, M.D." + (symbol->string + (string->symbol "K. Harper, M.D."))) + ==> #t +} +@end format + + +@end deffn + + +@node Zeichen, Zeichenketten, Symbole, Andere Datentypen +@subsection Zeichen + + + +Zeichen sind Objekte, die gedruckte Zeichen wie Buchstaben und Ziffern +darstellen. +@c There is no requirement that the data type of +@c characters be disjoint from other data types; implementations are +@c encouraged to have a separate character data type, but may choose to +@c represent characters as integers, strings, or some other type. +Zeichen werden mit der Notation #\@r{<Zeichen>} oder #\@r{<Zeichenname>} +geschrieben. Zum Beispiel: + + + +@c @center @c begin-tabular +@quotation +@table @asis +@item @t{#\a} +; Kleinbuchstabe +@item @t{#\A} +; Großbuchstabe +@item @t{#\(} +; linke runde Klammer +@item @t{#\ } +; das Leerzeichen +@item @t{#\space} +; die bevorzugte Art, ein Leerzeichen zu schreiben +@item @t{#\newline} +; das Zeilenvorschubs-Zeichen („newline``) +@c @item +@end table +@end quotation + + + + +Groß- und Kleinschreibung hat Auswirkungen in #\@r{<Zeichen>}, aber +nicht in #\@r{<Zeichenname>}. +@c \hyper doesn't + +@c allow a linebreak +Wenn @r{<Zeichen>} in +#\@r{<Zeichen>} ein Buchstabe ist, dann muss das auf @r{<Zeichen>} +folgende Zeichen ein Trennzeichen wie ein Leerzeichen oder eine runde +Klammer sein. Diese Regel löst den mehrdeutigen Fall auf, dass zum +Beispiel die Folge von Zeichen „@t{#\space}`` als entweder eine +Darstellung des Leerzeichens oder als eine Darstellung des Zeichens +„@t{#\s}`` gefolgt von einer Darstellung des Symbols „@t{pace}`` +verstanden werden könnte. + +@ignore todo +Fix +@end ignore + +Zeichen, die in der Notation #\ geschrieben werden, sind +selbtauswertend. Das heißt, sie müssen in Programmen nicht maskiert +werden. +@c The \sharpsign\backwhack{} +@c notation is not an essential part of Scheme, however. Even implementations +@c that support the \sharpsign\backwhack{} notation for input do not have to +@c support it for output. + +Manche der Prozeduren, die auf Zeichen arbeiten, ignorieren den +Unterschied zwischen Groß- und Kleinschreibung. Die Prozeduren, die +Groß- und Kleinschreibung ignorieren, haben @w{``@t{-ci}''} (für „case +insensitive``) in ihre Namen eingebettet. + + + +@deffn {Prozedur} char? obj + +Gibt @t{#t} zurück, wenn @var{Obj} ein Zeichen ist, sonst gibt sie +@t{#f} zurück. + +@end deffn + + + +@deffn {Prozedur} char=? char1 char2 +@deffnx {Prozedur} char<? char1 char2 +@deffnx {Prozedur} char>? char1 char2 +@deffnx {Prozedur} char<=? char1 char2 +@deffnx {Prozedur} char>=? char1 char2 + + +@ignore nodomain +Both @var{char1} and @var{char2} must be characters. +@end ignore + +Durch diese Prozeduren wird der Menge der Zeichen eine totale Ordnung +auferlegt. Es wird garantiert, dass gemäß dieser Ordnung gilt: + + + +@itemize @bullet + +@item +Die Großbuchstaben sind in der richtigen Reihenfolge. Zum Beispiel gibt +@samp{(char<? #\A #\B)} den Wert @t{#t} zurück. +@item +Die Kleinbuchstaben sind in der richtigen Reihenfolge. Zum Beispiel +gibt @samp{(char<? #\a #\b)} den Wert @t{#t} zurück. +@item +Die Ziffern sind in der richtigen Reihenfolge. Zum Beispiel gibt +@samp{(char<? #\0 #\9)} den Wert @t{#t} zurück. +@item +Entweder kommen alle Ziffern vor allen Großbuchstaben, oder umgekehrt. +@item +Entweder kommen alle Ziffern nach allen Großbuchstaben, oder umgekehrt. + +@end itemize + + +Manche Implementierungen können diese Prozeduren so verallgemeinern, +dass sie mehr als zwei Argumente nehmen, genau wie bei den +entsprechenden numerischen Prädikaten. + +@end deffn + + + +@deffn {Bibliotheksprozedur} char-ci=? char1 char2 +@deffnx {Bibliotheksprozedur} char-ci<? char1 char2 +@deffnx {Bibliotheksprozedur} char-ci>? char1 char2 +@deffnx {Bibliotheksprozedur} char-ci<=? char1 char2 +@deffnx {Bibliotheksprozedur} char-ci>=? char1 char2 + +@ignore nodomain +Both @var{char1} and @var{char2} must be characters. +@end ignore + +Diese Prozeduren sind ähnlich wie @samp{Char=?} et cetera, aber sie +behandeln Groß- und Kleinbuchstaben, als wären sie dasselbe. Zum +Beispiel gibt @samp{(char-ci=? #\A #\a)} den Wert @t{#t} zurück. Manche +Implementierungen können diese Prozeduren so verallgemeinern, dass sie +mehr als zwei Argumente nehmen, genau wie bei den entsprechenden +numerischen Prädikaten. + +@end deffn + + + +@deffn {Bibliotheksprozedur} char-alphabetic? char +@deffnx {Bibliotheksprozedur} char-numeric? char +@deffnx {Bibliotheksprozedur} char-whitespace? char +@deffnx {Bibliotheksprozedur} char-upper-case? letter +@deffnx {Bibliotheksprozedur} char-lower-case? letter + +Diese Prozeduren geben @t{#t} zurück, wenn ihre Argumente jeweils +Buchstaben, Zahlen, Leerraum, Großbuchstaben oder Kleinbuchstaben sind, +sonst geben sie @t{#f} zurück. Die folgenden Anmerkungen, welche +speziell für den ASCII-Zeichensatz gelten, sind nur als Orientierung +gedacht: Die Buchstabenzeichen sind die 52 Groß- und Kleinbuchstaben. +Die Ziffernzeichen sind die zehn Dezimalziffern. Die Leerraumzeichen +sind das Leerzeichen, das Tabulatorzeichen, der Zeilenvorschub, der +Seitenvorschub und der Wagenrücklauf. +@end deffn + + +@c %R4%%\begin{entry}{% +@c \proto{char-upper-case?}{ letter}{Prozedur} +@c \proto{char-lower-case?}{ letter}{Prozedur}} + +@c \domain{\var{Letter} must be an alphabetic character.} +@c These procedures return \schtrue{} if their arguments are upper case or +@c lower case characters, respectively, otherwise they return \schfalse. +@c \end{entry} + + + +@deffn {Prozedur} char->integer char +@deffnx {Prozedur} integer->char @var{n} + +Gegeben ein Zeichen gibt @samp{Char->integer} eine exakte ganzzahlige +Darstellung des Zeichens zurück. Gegeben eine exakte ganze Zahl, die +das Bild eines Zeichens unter @samp{Char->integer} ist, gibt +@samp{Integer->char} dieses Zeichen zurück. Diese Prozeduren +implementieren ordnungserhaltende Isomorphismen zwischen der Menge an +Zeichen unter der Ordnung von @code{Char<=?} und einer der +@vindex @w{Char<=?} +Teilmengen der ganzen Zahlen unter der Ordnung von @samp{<=}. Das +heißt, wenn + + +@format +@t{(char<=? @var{a} @var{b}) @result{} #t @r{}und (<= @var{x} @var{y}) @result{} #t +} +@end format + + + +@noindent + und @var{x} und @var{y} in der Definitionsmenge von +@samp{Integer->char} sind, dann + + +@format +@t{(<= (char->integer @var{a}) + (char->integer @var{b})) ==> #t + +(char<=? (integer->char @var{x}) + (integer->char @var{y})) ==> #t +} +@end format + + +@end deffn + + + +@deffn {Bibliotheksprozedur} char-upcase char +@deffnx {Bibliotheksprozedur} char-downcase char + +@ignore nodomain +@var{Char} must be a character. +@end ignore + +Diese Prozeduren geben ein Zeichen @var{Char2} zurück, für das +@samp{(char-ci=? @var{char} @var{char2})} gilt. Zudem ist, wenn +@var{Char} ein Buchstabe ist, das Ergebnis von @samp{Char-upcase} ein +Großbuchstabe und das Ergebnis von @samp{Char-downcase} ein +Kleinbuchstabe. + +@end deffn + + +@node Zeichenketten, Vektoren, Zeichen, Andere Datentypen +@subsection Zeichenketten + + + +Zeichenketten sind Folgen von Zeichen. +@c In some implementations of Scheme +@c they are immutable; other implementations provide destructive procedures +@c such as {\cf string-set!}\ that alter string objects. +Zeichenketten werden als Folge von Zeichen geschrieben, die in doppelte +Anführungszeichen eingeschlossen sind (@samp{"}). Doppelte +Anführungszeichen können nur in eine Zeichenkette geschrieben werden, +indem man sie mit einem Backslash (\) maskiert, wie hier: + + +@example + +"Das Wort \"Rekursion\" hat viele Bedeutungen." + +@end example + + +Ein Backslash kann nur in einer Zeichenkette geschrieben werden, indem +man ihn mit einem anderen Backslash maskiert. Scheme legt die Wirkung +eines Backslashs innerhalb eines Strings, auf den keine doppelten +Anführungszeichen oder ein Backslash folgt, nicht fest. + +Eine konstante Zeichenkette darf sich von einer Zeile bis auf die +nächste erstrecken, aber der genaue Inhalt einer solchen Zeichenkette +ist unbestimmt. +@c this is +@c usually a bad idea because +@c the exact effect may vary from one computer +@c system to another. + +Die @emph{Länge} einer Zeichenkette ist die Anzahl der Zeichen, die sie +enthält. Diese Anzahl ist eine exakte, nicht negative ganze Zahl, die +von der Erstellung einer Zeichenkette an fest ist. Die @dfn{gültigen +Indizes} einer Zeichenkette sind die +@cindex @w{gültige Indizes} +exakten, nicht negativen ganzen Zahlen, die kleiner als die Länge der +Zeichenkette ist. Das erste Zeichen einer Zeichenkette hat den Index 0, +das zweite hat den Index 1, und so weiter. + +In Formulierungen wie „die Zeichen von @var{String} vom Index +@var{Anfang} bis zum Index @var{Ende}`` ist damit gemeint, dass der +Index @var{Anfang} dazugehört und der Index @var{Ende} nicht mehr +dazugehört. Wenn also @var{Anfang} und @var{Ende} derselbe Index sind, +wird auf eine leere Teilzeichenkette Bezug genommen, und wenn +@var{Anfang} null und @var{Ende} die Länge von @var{String} ist, dann +wird auf die gesamte Zeichenkette Bezug genommen. + +Manche der Prozeduren, die auf Zeichenketten arbeiten, ignorieren den +Unterschied zwischen Groß- und Kleinschreibung. Die Prozeduren, die +Groß- und Kleinschreibung ignorieren, haben @w{„@samp{-ci}``} (für +``case insensitive'') in ihre Namen eingebettet. + + + +@deffn {Prozedur} string? obj + +Gibt @t{#t} zurück, wenn @var{Obj} eine Zeichenkette ist, und +andernfalls @t{#f}. +@end deffn + + + +@deffn {Prozedur} make-string @var{k} +@deffnx {Prozedur} make-string @var{k} char + +@c \domain{\vr{k} must be a non-negative integer, and \var{char} must be +@c a character.} +@samp{Make-string} gibt eine neu zugeteilte Zeichenkette der Länge +@var{k} zurück. Wenn @var{Char} angegeben wurde, dann werden alle +Elemente der Zeichenkette auf @var{Char} initialisiert, andernfalls ist +der Inhalt der zurückgegebenen Zeichenkette unbestimmt. + +@end deffn + + +@deffn {Bibliotheksprozedur} string char @dots{}, + +Gibt eine neu zugeteilte Zeichenkette zurück, die sich aus den +Argumenten zusammensetzt. + +@end deffn + + +@deffn {Prozedur} string-length string + +Gibt die Anzahl der Zeichen in der gegebenen Zeichenkette @var{String} +zurück. +@end deffn + + + +@deffn {Prozedur} string-ref string @var{k} + +@var{k} muss ein gültiger Index der Zeichenkette @var{String} sein. +@samp{String-ref} gibt das Zeichen @var{k} von @var{String} zurück, +wobei Indizes von null an gezählt werden. +@end deffn + + + +@deffn {Prozedur} string-set! string k char + + +@c \var{String} must be a string, +@var{k} muss ein gültiger Index der Zeichenkette @var{String} sein +@c , and \var{char} must be a character +. +@samp{String-set!} speichert @var{Char} in das Element @var{k} von +@var{String} und gibt einen unbestimmten Wert zurück. +@c <!> + + +@format +@t{(define (f) (make-string 3 #\*)) +(define (g) "***") +(string-set! (f) 0 #\?) ==> @emph{unbestimmt} +(string-set! (g) 0 #\?) ==> @emph{Fehler} +(string-set! (symbol->string 'unveränderlich) + 0 + #\?) ==> @emph{Fehler} +} +@end format + + +@end deffn + + + +@deffn {Bibliotheksprozedur} string=? string1 string2 +@deffnx {Bibliotheksprozedur} string-ci=? string1 string2 + +Gibt @t{#t} zurück, wenn die beiden Zeichenketten dieselbe Länge haben +und dieselben Zeichen an den selben Stellen haben, sonst gibt sie @t{#f} +zurück. +@samp{String-ci=?} behandelt +Groß- und Kleinbuchstaben als wären sie dasselbe Zeichen, aber +@samp{String=?} behandelt Groß- und Kleinbuchstaben als verschiedene +Zeichen. + +@end deffn + + + +@deffn {Bibliotheksprozedur} string<? string1 string2 +@deffnx {Bibliotheksprozedur} string>? string1 string2 +@deffnx {Bibliotheksprozedur} string<=? string1 string2 +@deffnx {Bibliotheksprozedur} string>=? string1 string2 +@deffnx {Bibliotheksprozedur} string-ci<? string1 string2 +@deffnx {Bibliotheksprozedur} string-ci>? string1 string2 +@deffnx {Bibliotheksprozedur} string-ci<=? string1 string2 +@deffnx {Bibliotheksprozedur} string-ci>=? string1 string2 + +Diese Prozeduren sind die alphabetisch geordnete Erweiterung auf +Zeichenketten von der entsprechenden Ordnung auf Zeichen. Zum Beispiel +ist @samp{String<?} die alphabetische Ordnung auf Zeichenketten, die von +der Ordnung @samp{Char<?} auf Zeichen induziert wird. Wenn zwei +Zeichenketten verschiedene Längen haben, aber bis zur Länge der kürzeren +Zeichenkette identisch sind, wird die kürzere Zeichenkette als +alphabetisch kleiner angesehen als die längere Zeichenkette. + +Implementierungen dürfen diese Prozeduren ebenso wie die Prozeduren +@samp{String=?} und @samp{String-ci=?} verallgemeinern, so dass sie mehr +als zwei Argumente annehmen, wie bei den entsprechenden Prädikaten auf +Zahlen. + +@end deffn + + + +@deffn {Bibliotheksprozedur} substring string anfang ende + +@var{String} muss eine Zeichenkette und @var{Anfang} und @var{Ende} +müssen exakte ganze Zahlen sein, so dass gilt + + +@center 0 <= @var{anfang} <= @var{ende} <= @w{@t{(string-length @var{string})@r{.}}} + +@samp{Substring} gibt eine neu zugeteilte Zeichenkette zurück, die aus +den Zeichen von String zusammengesetzt wird, angefangen mit dem Index +@var{Anfang} (einschließlich) und bis zum Index @var{Ende} (nicht +einschließlich). +@end deffn + + + +@deffn {Bibliotheksprozedur} string-append @var{string} @dots{}, + +Gibt eine neu zugeteilte Zeichenkette zurück, deren Zeichen die +Verkettung der übergebenen Zeichenketten darstellt. + +@end deffn + + + +@deffn {Bibliotheksprozedur} string->list string +@deffnx {Bibliotheksprozedur} list->string list + +@samp{String->list} gibt eine neu zugeteilte Liste der Zeichen zurück, +die die übergebene Zeichenkette bilden. @samp{List->string} gibt eine +neu zugeteilte Zeichenkette zurück, die aus den Zeichen in der Liste +@var{List} gebildet wird, welche eine Liste von Zeichen sein muss. +@samp{String->list} und @samp{List->string} sind jeweils +Umkehrfunktionen voneinander bezüglich @samp{Equal?}. +@c Implementations that provide +@c destructive operations on strings should ensure that the result of +@c {\cf list\coerce{}string} is newly allocated. + +@end deffn + + + +@deffn {Bibliotheksprozedur} string-copy string + +Gibt eine neu zugeteilte Kopie der übergebenen Zeichenkette @var{String} +zurück. + +@end deffn + + + +@deffn {Bibliotheksprozedur} string-fill! string char + +Speichert @var{Char} in jedem Element der übergebener Zeichenkette +@var{String} und gibt einen unbestimmten Wert zurück. +@c <!> + +@end deffn + + +@node Vektoren, , Zeichenketten, Andere Datentypen +@subsection Vektoren + + + +Vektoren sind heterogene Strukturen, deren Elements durch ganze Zahlen +indiziert werden. Ein Vektor belegt typischerweise weniger +Speicherplatz als eine Liste derselben Länge und die durchschnittliche +Zeit, die nötig ist, um auf ein zufällig gewähltes Element zuzugreifen, +ist typischerweise weniger für den Vektor als für die Liste. + +Die @emph{Länge} eines Vektors ist die Anzahl der Elemente, die er +enthält. Diese Zahl ist eine nicht negative ganze Zahl, die von der +Erstellung eines Vektors an fest ist. Die @emph{gültigen Indizes} eines +@cindex @w{gültige Indizes} +Vektors sind die exakt nicht-negativen ganzen Zahlen, die kleiner als +die Länge des Vektors sind. Das erste Element eines Vektors hat den +Index null und das letzte Element hat als Index eins weniger als die +Länge des Vektors. + +Vektoren werden mit der Notation @t{#(@var{obj} @dots{},)} geschrieben. +Zum Beispiel kann ein Vektor der Länge 3, der die Zahl null in Element +0, die Liste @samp{(2 2 2 2)} in Element 1 und die Zeichenkette +@samp{"Anna"} in Element 2 hat, wie folgt geschrieben werden: + + +@example + +#(0 (2 2 2 2) "Anna") + +@end example + + +Beachten Sie, dass dies die externe Darstellung eines Vektors ist, kein +Ausdruck, der zu einem Vektor ausgewertet wird. Wie bei konstanten +Listen müssen auch konstante Vektoren maskiert werden: + + +@example + +'#(0 (2 2 2 2) "Anna") + ==> #(0 (2 2 2 2) "Anna") + +@end example + + +@ignore todo +Pitman sez: The visual similarity to lists is bound to be confusing +to some. Elaborate on the distinction. +@end ignore + + + + +@deffn {Prozedur} vector? obj + +Gibt @t{#t} zurück, wenn @var{Obj} ein Vektor ist, und gibt sonst @t{#f} +zurück. +@end deffn + + + +@deffn {Prozedur} make-vector k +@deffnx {Prozedur} make-vector k fill + +Gibt einen neu zugeteilten Vektor mit @var{k} Elementen zurück. Wenn +ein zweites Argument übergeben wurde, dann wird jedes Element auf +@var{Fill} initialisiert. Sonst ist der anfängliche Inhalt jedes +Elements unbestimmt. + +@end deffn + + + +@deffn {Bibliotheksprozedur} vector obj @dots{}, + +Gibt einen neu zugeteilten Vektor zurück, dessen Elemente die +übergebenen Argumente enthalten. Analog zu @samp{List}. + + +@format +@t{(vector 'a 'b 'c) ==> #(a b c) +} +@end format + +@end deffn + + + +@deffn {Prozedur} vector-length vector + +Gibt die Anzahl der Elemente im Vektor @var{Vector} als eine exakte +ganze Zahl zurück. +@end deffn + + + +@deffn {Prozedur} vector-ref vector k + +@var{k} muss ein gültiger Index des Vektors @var{Vector} sein. +@samp{Vector-ref} gibt den Inhalt des Elements @var{k} des Vektors +@var{Vector} zurück. + + +@format +@t{(vector-ref '#(1 1 2 3 5 8 13 21) + 5) + ==> 8 +(vector-ref '#(1 1 2 3 5 8 13 21) + (let ((i (round (* 2 (acos -1))))) + (if (inexact? i) + (inexact->exact i) + i))) + ==> 13 +} +@end format + +@end deffn + + + +@deffn {Prozedur} vector-set! vector k obj + +@var{k} muss ein gültiger Index des Vektors @var{Vector} sein. +@samp{Vector-set!} speichert @var{Obj} im Element @var{k} des Vektors +@var{Vector}. Der von @samp{Vector-set!} zurückgegebene Wert ist +unbestimmt. +@c <!> + + +@format +@t{(let ((vec (vector 0 '(2 2 2 2) "Anna"))) + (vector-set! vec 1 '("Sue" "Sue")) + vec) + ==> #(0 ("Sue" "Sue") "Anna") + +(vector-set! '#(0 1 2) 1 "doe") + ==> @emph{Fehler} ; konstanter Vektor +} +@end format + +@end deffn + + + +@deffn {Bibliotheksprozedur} vector->list vector +@deffnx {Bibliotheksprozedur} list->vector list + +@samp{Vector->list} gibt eine neu zugeteilte Liste der Objekte, die in +den Elementen des Vektors @var{Vector} enthalten sind, zurück. +@samp{List->vector} gibt einen neu erstellten Vektor zurück, der auf die +Elemente der Liste @var{List} initialisiert ist. + + +@format +@t{(vector->list '#(dah dah didah)) + ==> (dah dah didah) +(list->vector '(dididit dah)) + ==> #(dididit dah) +} +@end format + +@end deffn + + + +@deffn {Bibliotheksprozedur} vector-fill! vector fill + +Speichert @var{Fill} in jedem Element des Vektors @var{Vector}. Der von +@samp{Vector-fill!} zurückgegebene Wert ist unbestimmt. +@c <!> + +@end deffn + + +@node Programmflussfunktionalitäten, Eval, Andere Datentypen, Standardprozeduren +@section Programmflussfunktionalitäten + + + +@c Intro flushed; not very a propos any more. +@c Procedures should be discussed somewhere, however. + +Dieses Kapitel beschreibt verschiedene grundlegende Prozeduren, die den +Fluss der Programmausführung auf besondere Arten steuern. +Das Prädikat @samp{Procedure?} wird hier auch beschrieben. + +@ignore todo +@t{Procedure?} doesn't belong in a section with the name +``control features.'' What to do? +@end ignore + + + +@deffn {Prozedur} procedure? obj + +Gibt @t{#t} zurück, wenn @var{Obj} eine Prozedur ist, und sonst @t{#f}. + + +@format +@t{(procedure? car) ==> #t +(procedure? 'car) ==> #f +(procedure? (lambda (x) (* x x))) + ==> #t +(procedure? '(lambda (x) (* x x))) + ==> #f +(call-with-current-continuation procedure?) + ==> #t +} +@end format + + +@end deffn + + + +@deffn {Prozedur} apply proc arg1 @dots{} args + +@var{Proc} muss eine Prozedur und @var{Args} eine Liste sein. +@samp{Apply} (deutsch „anwenden``) ruft @var{Proc} mit den Elementen der +Liste @samp{(append (list @var{arg1} @dots{},) @var{args})} als die +tatsächlichen Argumente auf. + + +@format +@t{(apply + (list 3 4)) ==> 7 + +(define compose + (lambda (f g) + (lambda args + (f (apply g args))))) + +((compose sqrt *) 12 75) ==> 30 +} +@end format + +@end deffn + + + +@deffn {Bibliotheksprozedur} map proc list1 list2 @dots{}, + +Die @var{List}en müssen Listen sein und @var{Proc} muss eine Prozedur +sein, die ebensoviele Argumente nimmt, wie es Listenargumente @i{List} +gibt, und einen einzelnen Wert zurückgibt. Wenn mehr als eine Liste +@var{List} übergeben wird, dann müssen sie alle dieselbe Länge haben. +@samp{Map} (deutsch „abbilden``) wendet @var{Proc} elementweise auf die +Elemente der @var{List}en an und gibt eine Liste der Ergebnisse in +derselben Reihenfolge zurück. Die Reihenfolge, mit der @var{Proc} auf +die Elemente der @var{List}en zur Laufzeit angewandt wird, ist +unbestimmt. + + +@format +@t{(map cadr '((a b) (d e) (g h))) + ==> (b e h) + +(map (lambda (n) (expt n n)) + '(1 2 3 4 5)) + ==> (1 4 27 256 3125) + +(map + '(1 2 3) '(4 5 6)) ==> (5 7 9) + +(let ((count 0)) + (map (lambda (ignoriert) + (set! count (+ count 1)) + count) + '(a b))) ==> (1 2) @var{oder} (2 1) +} +@end format + + +@end deffn + + + +@deffn {Bibliotheksprozedur} for-each proc list1 list2 @dots{}, + +Die Argumente von @samp{For-each} sind wie die Argumente von @samp{Map}, +aber @samp{For-each} ruft @var{Proc} für ihre Wirkungen statt für ihre +Werte auf. Anders als @samp{Map} ruft @samp{For-each} die Prozedur +@var{Proc} garantiert der Reihe nach auf die Elemente der @var{List}en +auf, vom ersten Element @abbr{bzw.} den ersten Elementen bis zu dem +@abbr{bzw.} den letzten, und der von @samp{For-each} zurückgegebene Wert +ist unbestimmt. + + +@format +@t{(let ((v (make-vector 5))) + (for-each (lambda (i) + (vector-set! v i (* i i))) + '(0 1 2 3 4)) + v) ==> #(0 1 4 9 16) +} +@end format + + +@end deffn + + + +@deffn {Bibliotheksprozedur} force promise + +Erzwingt („force``) den Wert vom Versprechen @var{Promise} (siehe @code{Delay}, +@vindex @w{Delay} +Abschnitt @pxref{Verzögerte Auswertung}). Wenn noch kein Wert für +@cindex @w{Versprechen} +@cindex @w{Promise} +das Versprechen berechnet wurde, dann wird ein Wert berechnet und +zurückgegeben. Der Wert des Versprechens wird zwischengespeichert +(gecachet @abbr{bzw.} „memoisiert``), so dass, wenn es ein weiteres Mal +erzwungen wird, der vormals berechnete Wert zurückgegeben wird. +@c without any recomputation. +@c [As pointed out by Marc Feeley, the "without any recomputation" +@c isn't necessarily true. --Will] + + +@format +@t{(force (delay (+ 1 2))) ==> 3 +(let ((p (delay (+ 1 2)))) + (list (force p) (force p))) + ==> (3 3) + +(define ein-Strom ; Strom = englisch Stream + (letrec ((next + (lambda (n) + (cons n (delay (next (+ n 1))))))) + (next 0))) +(define head car) +(define tail + (lambda (stream) (force (cdr stream)))) + +(head (tail (tail ein-Strom))) + ==> 2 +} +@end format + + +@samp{Force} und @samp{Delay} sind hauptsächlich für im funktionalen +Stil geschriebene Programme gedacht. Die folgenden Beispiele sollten +nicht als Vorzeigebeispiele guten Programmierstils angesehen werden, +sondern lediglich die Eigenschaft aufzeigen, dass für ein Versprechen +nur ein Wert berechnet wird, egal wie oft es erzwungen wird. +@c the value of a promise is computed at most once. +@c [As pointed out by Marc Feeley, it may be computed more than once, +@c but as I observed we can at least insist that only one value be +@c used! -- Will] + + +@format +@t{(define count 0) +(define p + (delay (begin (set! count (+ count 1)) + (if (> count x) + count + (force p))))) +(define x 5) +p ==> @i{}ein Versprechen +(force p) ==> 6 +p ==> @i{}ein Versprechen, immer noch +(begin (set! x 10) + (force p)) ==> 6 +} +@end format + + +Hier ist eine mögliche Implementierung von @samp{Delay} und +@samp{Force}. Versprechen werden hier als Prozeduren ohne Argumente +implementiert und @samp{Force} ruft einfach sein Argument auf: + + +@format +@t{(define force + (lambda (object) + (object))) +} +@end format + + +Wir definieren dazu den Ausdruck + + +@format +@t{(delay @r{<Ausdruck>}) +} +@end format + + +als gleichbedeutend mit dem Prozeduraufruf + + +@format +@t{(make-promise (lambda () @r{<Ausdruck>}))@r{} +} +@end format + + +wie folgt + + +@format +@t{(define-syntax delay + (syntax-rules () + ((delay expression) + (make-promise (lambda () expression))))), +} +@end format + + +wobei @samp{Make-promise} wie folgt definiert ist: + +@c \begin{scheme} +@c (define make-promise +@c (lambda (proc) +@c (let ((already-run? \schfalse) (result \schfalse)) +@c (lambda () +@c (cond ((not already-run?) +@c (set! result (proc)) +@c (set! already-run? \schtrue))) +@c result))))% +@c \end{scheme} + + +@format +@t{(define make-promise + (lambda (proc) + (let ((Ergebnis-bereit? #f) + (Ergebnis #f)) + (lambda () + (if Ergebnis-bereit? + Ergebnis + (let ((x (proc))) + (if Ergebnis-bereit? + Ergebnis + (begin (set! Ergebnis-bereit? #t) + (set! Ergebnis x) + Ergebnis)))))))) +} +@end format + + + +@quotation +@emph{Begründung:} +Ein Versprechen darf seinen eigenen Wert referenzieren, wie das letzte +Beispiel oben zeigt. Das Erzwingen eines solchen Versprechens kann dazu +führen, dass das Versprechehen ein weiteres Mal erzwungen wird, bevor +der Wert des ersten Erzwingens berechnet wurde. Dies verkompliziert die +Definition von @samp{Make-promise}. +@end quotation + + +Manche Implementierungen unterstützen eine Vielzahl von Erweiterungen +dieser Semantik von @samp{Delay} und @samp{Force}: + + + +@itemize @bullet + +@item +@samp{Force} auf ein Objekt aufzurufen, das kein Versprechen ist, könnte +einfach dieses Objekt zurückgeben. + +@item +Es kann der Fall sein, dass es unmöglich ist, ein Versprechen von seinem +erzwungenen Wert operativ zu unterscheiden. Das heißt, Ausdrücke wie +die folgenden dürfen entweder zu @t{#t} oder zu @t{#f} ausgewertet +werden, abhängig von der Implementierung: + + +@format +@t{(eqv? (delay 1) 1) ==> @emph{unbestimmt} +(pair? (delay (cons 1 2))) ==> @emph{unbestimmt} +} +@end format + + +@item +Manche Implementierungen könnten „implizites Erzwingen`` +implementieren, wobei der Wert eines Versprechens durch grundlegende +Prozeduren wie @samp{Cdr} und @samp{+} erzwungen wird: + + +@format +@t{(+ (delay (* 3 7)) 13) ==> 34 +} +@end format + + +@end itemize + +@end deffn + + +@deffn {Prozedur} call-with-current-continuation proc + + @var{Proc} muss eine Prozedur mit einem Argument sein. Die Prozedur +@samp{Call-with-current-continuation} verpackt die aktuelle Fortsetzung +(siehe die Begründung unten) als eine „Ausstiegsprozedur`` („escape +procedure``) und übergibt sie als Argument +@cindex @w{Ausstiegsprozedur} +@cindex @w{Escape procedure} +an @var{Proc}. Die Ausstiegsprozedur ist eine Scheme-Prozedur, die, +wenn sie später aufgerufen wird, egal welche Fortsetzung zu diesem +späteren Zeitpunkt aktiv ist, mit dieser Fortsetzung aufhört und +stattdessen mit der Fortsetzung fortfährt, die aktiv war, als die +Ausstiegsprozedur erzeugt wurde. Ein Aufruf der Ausstiegsprozedur kann +einen Aufruf von mit @code{Dynamic-wind} +@vindex @w{dynamic-wind} +installierten @var{Before}- und @var{After}-Thunks verursachen. + +Die Ausstiegsprozedur nimmt dieselbe Anzahl an Argumenten an, wie die +Fortsetzung bis zum ursprünglichen Aufruf von +@t{Call-with-current-continuation}. Abgesehen von Fortsetzungen, die +durch die Prozedur @samp{Call-with-values} erzeugt wurden, nehmen alle +Fortsetzungen genau einen Wert an. Wie es sich auswirkt, wenn kein oder +mehr als ein Wert an nicht durch @t{Call-with-values} erzeugte +Fortsetzungen übergeben wird, ist unbestimmt. + +Die Ausstiegsprozedur, die an @var{Proc} übergeben wird, hat einen +unbeschränkten Gültigkeitsbereich, genau wie jede andere Prozedur in +Scheme. Sie darf in Variablen oder Datenstrukturen gespeichert werden +und so oft aufgerufen werden, wie es gewünscht ist. + +Die folgenden Beispiele zeigen nur die häufigsten Arten, auf die +@samp{Call-with-current-continuation} benutzt wird. Wenn alle +wirklichen Anwendungen so einfach wären wie diese Beispiele, bräuchte +man keine Prozedur, die so mächtig ist wie +@samp{Call-with-current-continuation}. + + +@format +@t{(call-with-current-continuation + (lambda (exit) + (for-each (lambda (x) + (if (negative? x) + (exit x))) + '(54 0 37 -3 245 19)) + #t)) ==> -3 + +(define list-length + (lambda (obj) + (call-with-current-continuation + (lambda (return) + (letrec ((r + (lambda (obj) + (cond ((null? obj) 0) + ((pair? obj) + (+ (r (cdr obj)) 1)) + (else (return #f)))))) + (r obj)))))) + +(list-length '(1 2 3 4)) ==> 4 + +(list-length '(a b . c)) ==> #f +} +@end format + + + +@quotation +@emph{Begründung:} + +Eine übliche Nutzung von @samp{Call-with-current-continuation} sind +strukturierte, nicht-lokale Sprünge aus Schleifen oder Prozedurrümpfen +heraus, aber tatsächlich ist @samp{Call-with-current-continuation} für +die Implementierung einer große Vielfalt fortgeschrittener +Programmflussstrukturen von extremem Nutzen. + +Wann immer ein Scheme-Ausdruck ausgewertet wird, gibt es eine +@dfn{Fortsetzung} („continuation``), die das Ergebnis des Ausdrucks +haben will. Die Fortsetzung +@cindex @w{Fortsetzung} +@cindex @w{Continuation} +stellt die gesamte (standardmäßige) Zukunft der Berechnung dar. Wenn +der Ausdruck zum Beispiel auf oberster Ebene ausgewertet wird, dann kann +die Fortsetzung das Ergebnis entgegennehmen, auf dem Bildschirm +ausgeben, nach der nächsten Eingabe fragen, und ewig so weiter. Die +meiste Zeit schließt die Fortsetzung vom Nutzer-Code festgelegte +Aktionen mit ein, wie zum Beispiel eine Fortsetzung, die das Ergebnis +nimmt, mit dem in einer lokalen Variablen gespeicherten Wert +multipliziert, sieben addiert und die Antwort an die Fortsetzung auf +oberster Ebene zum Ausgeben weitergibt. Normalerweise sind diese +allgegenwärtigen Fortsetzungen im Hintergrund verborgen und +Programmierer denken nicht viel über sie nach. In seltenen Fällen +könnte ein Programmierer jedoch mit Fortsetzungen ausdrücklich umgehen +müssen. +@samp{Call-with-current-continuation} erlaubt es Scheme-Programmierern, +dazu eine Prozedur zu erstellen, die sich genau wie die momentane +Fortsetzung verhält. + +Die meisten Programmiersprachen enthalten eines oder mehr +Ausstiegskonstrukte für ganz bestimmte Zwecke mit Namen wie @t{Exit}, +@w{@samp{Return}} oder sogar @t{Goto}. 1965 hat Peter Landin [Landin65] +jedoch einen für allgemeine Zwecke bestimmten Ausstiegsoperator namens +J-Operator erfunden. John Reynolds [Reynolds72] hat 1972 ein +einfacheres, aber ebenso mächtiges Konstrukt beschrieben. Die +Sonderform @samp{Catch}, die Sussman und Steele im Scheme-Bericht von +1975 beschrieben haben, ist genau dasselbe wie Reynolds' Konstrukt, doch +sein Name kommt von einem weniger allgemeinen Konstrukt in MacLisp. +Mehrere Scheme-Implementierer bemerkten, dass die ganze Macht des +@code{Catch}-Konstrukts durch eine Prozedur statt eines +@vindex @w{Catch} +besonderen syntaktischen Konstrukts bereitgestellt werden könnte, und +der Name @samp{Call-with-current-continuation} wurde 1982 geprägt. +Dieser Name ist beschreibend, aber die Meinungen gehen über die Vorzüge +eines derart langen Namens auseinander und manche Leute benutzen +stattdessen den Namen @code{Call/cc}. +@vindex @w{Call/cc} +@end quotation + + +@end deffn + + +@deffn {Prozedur} values obj @dots{} + +Liefert all ihre Argumente an ihre Fortsetzung. Abgesehen von mit der +Prozedur @code{Call-with-values} +@vindex @w{Call-with-values} +erstellten Fortsetzungen nehmen alle Fortsetzungen genau einen Wert +entgegen. @t{Values} kann wie folgt definiert werden: + +@format +@t{(define (values . things) + (call-with-current-continuation + (lambda (cont) (apply cont things)))) +} +@end format + + +@end deffn + + +@deffn {Prozedur} call-with-values produzent konsument + +Ruft ihr @var{Produzent}en-Argument mit keinen Werten und einer +Fortsetzung auf, die, wenn ihr Werte übergeben werden, die +@var{Konsument}en-Prozedur mit diesen Werten als Argumente aufruft. Die +Fortsetzung des @var{Konsument}enaufrufs ist die Fortsetzung des Aufrufs +von @t{Call-with-values}. + + +@format +@t{(call-with-values (lambda () (values 4 5)) + (lambda (a b) b)) + ==> 5 + +(call-with-values * -) ==> -1 +} +@end format + + +@end deffn + + +@deffn {Prozedur} dynamic-wind before thunk after + +Ruft @var{Thunk} ohne Argumente auf und gibt das Ergebnis oder die +Ergebnisse dieses Aufrufs zurück. @var{Before} und @var{After} werden, +ebenso ohne Argumente, wie von den folgenden Regeln vorausgesetzt +aufgerufen (beachten Sie, dass ohne Aufrufe von mit +@code{Call-with-current-continuation} gefangenen Fortsetzungen die drei +Argumente +@vindex @w{Call-with-current-continuation} +jeweils einmal der Reihe nach aufgerufen werden). @var{Before} wird +immer dann aufgerufen, wenn die Ausführung den dynamischen Bereich des +Aufrufs von @var{Thunk} betritt, und @var{After} wird immer dann +aufgerufen, wenn sie diesen dynamischen Bereich verlässt. Der +dynamische Bereich eines Prozeduraufrufs ist die Zeit zwischen dem +Verursachen des Aufrufs und seiner Rückgabe. In Scheme kann, wegen +@samp{Call-with-current-continuation}, der dynamische Bereich etwas +anderes als eine einzelne, zusammenhängende Zeitspanne sein. Er ist wie +folgt definiert: + + +@itemize @bullet + +@item +Der dynamische Bereich wird betreten, wenn die Ausführung des Rumpfs der +aufgerufenen Prozedur beginnt. + +@item +Der dynamische Bereich wird auch betreten, wenn die Ausführung sich +nicht im dynamischen Bereich befindet und eine Fortsetzung aufgerufen +wird, die (mit @samp{Call-with-current-continuation}) innerhalb des +dynamischen Bereichs eingefangen wurde. + +@item +Er wird verlassen, wenn die aufgerufene Prozedur ihr Ergebnis oder ihre +Ergebnisse zurückgibt. + +@item +Er wird auch verlassen, wenn sich die Ausführung innerhalb des +dynamischen Bereichs befindet und eine Fortsetzung, die außerhalb des +dynamischen Bereichs gefangen wurde, aufgerufen wird. + +@end itemize + + +Wenn ein zweiter Aufruf von @samp{Dynamic-wind} innerhalb des +dynamischen Bereichs des Aufrufs von @var{Thunk} stattfindet und eine +Fortsetzung auf eine Art aufgerufen wird, dass die @var{After}s dieser +beiden Aufrufe von @samp{Dynamic-wind} beide aufzurufen sind, dann wird +die @var{After}, die mit dem zweiten (inneren) Aufruf von +@samp{Dynamic-wind} assoziiert ist, zuerst aufgerufen. + +Wenn der zweite Aufruf von @samp{Dynamic-wind} innerhalb des dynamischen +Bereichs des Aufrufs von @var{Thunk} stattfindet und dann eine +Fortsetzung auf eine Art aufgerufen wird, dass die @var{Before}s dieser +beiden Aufrufe von @samp{Dynamic-wind} beide auszuführen sind, dann wird +@var{Before}, die mit dem ersten (äußeren) Aufruf von +@samp{Dynamic-wind} assoziiert ist, zuerst aufgerufen. + +Wenn das Aufrufen einer Fortsetzung das Aufrufen der @var{Before} des +einen Aufrufs von @samp{Dynamic-wind} und der @var{After} eines anderen +Aufrufs erfordert, dann wird die @var{After} zuerst aufgerufen. + +Die Auswirkung, eine eingefangene Fortsetzung zu benutzen, um aus dem +dynamischen Bereich eines Aufrufs von @var{Before} oder @var{After} +auszusteigen, ist undefiniert. + + +@format +@t{(let ((path '()) + (c #f)) + (let ((add (lambda (s) + (set! path (cons s path))))) + (dynamic-wind + (lambda () (add 'connect)) + (lambda () + (add (call-with-current-continuation + (lambda (c0) + (set! c c0) + 'talk1)))) + (lambda () (add 'disconnect))) + (if (< (length path) 4) + (c 'talk2) + (reverse path)))) + + ==> (connect talk1 disconnect + connect talk2 disconnect) +} +@end format + +@end deffn + +@node Eval, Ein- und Ausgabe, Programmflussfunktionalitäten, Standardprozeduren +@section Eval + + + +@deffn {Prozedur} eval ausdruck umgebungsangabe + +Wertet @var{Ausdruck} in der angegebenen Umgebung aus und gibt seinen +Wert zurück. @var{Ausdruck} muss ein gültiger Scheme-Ausdruck sein, der +als Daten dargestellt ist, und @var{Umgebungsangabe} muss ein von einer +der drei unten beschriebenen Prozeduren zurückgegebener Wert sein. +Implementierungen dürfen @samp{Eval} erweitern, um Programme, die keine +Ausdrücke sind (Definitionen) als das erste Argument zu erlauben und um +andere Werte als Umgebungen zuzulassen, mit der Einschränkung, dass +@samp{Eval} keine neuen Bindungen in den mit @samp{Null-environment} +oder @samp{Scheme-report-environment} assoziierten Umgebungen erzeugen +darf. + + +@format +@t{(eval '(* 7 3) (scheme-report-environment 5)) + ==> 21 + +(let ((f (eval '(lambda (f x) (f x x)) + (null-environment 5)))) + (f + 10)) + ==> 20 +} +@end format + + +@end deffn + + +@deffn {Prozedur} scheme-report-environment version +@deffnx {Prozedur} null-environment version + +@var{Version} muss die exakte ganze Zahl @samp{5} sein, entsprechend +dieser Fassung des Scheme-Berichts (des Revised^5 Report on Scheme). +@samp{Scheme-report-environment} gibt eine Angabe einer Umgebung zurück, +die leer ist bis auf alle in diesem Bericht angegebenen Bindungen, die +entweder notwendig oder sowohl optional als auch von der Implementierung +unterstützt sind. @samp{Null-environment} gibt eine Angabe der Umgebung +zurück, die leer ist außer den (syntaktischen) Bindungen aller +syntaktischen Schlüsselwörtern, die in diesem Bericht definiert werden +und die entweder notwendig oder sowohl optional als auch von der +Implementierung unterstützt sind. + +Andere Werte von @var{Version} können benutzt werden, um zu vergangenen +Fassungen passende Umgebungen zu definieren, aber ihre Unterstützung +wird nicht vorausgesetzt. Eine Implementierung wird einen Fehler +signalisieren, wenn @var{Version} weder @samp{5} noch ein anderer von +der Implementierung unterstützter Wert ist. + +Die Auswirkung davon, eine in einer @samp{Scheme-report-environment} +gebundene Variable (durch Nutzung von @samp{Eval}) zuzuweisen, ist +unbestimmt. Die durch @samp{Scheme-report-environment} angegebenen +Umgebungen dürfen also unveränderlich sein. + +@end deffn + + +@deffn {optionale Prozedur} interaction-environment + +Diese Prozedur gibt eine Angabe der Umgebung zurück, die +implementierungsdefinierte Bindungen enthält, typischerweise eine +Teilmenge der im Bericht aufgelisteten Bindungen. Die Absicht ist, dass +diese Prozedur die Umgebung zurückgibt, in der die Implementierung von +der Nutzerin dynamisch eingetippte Ausdrücke auswertet. + +@end deffn + +@node Ein- und Ausgabe, , Eval, Standardprozeduren +@section Ein- und Ausgabe + +@menu +* Ports:: +* Eingabe:: +* Ausgabe:: +* Systemschnittstelle:: +@end menu + + +@node Ports, Eingabe, Ein- und Ausgabe, Ein- und Ausgabe +@subsection Ports + + + +Ports stellen Ein- und Ausgabegeräte dar. Gegenüber Scheme ist ein +Eingabe-Port ein Scheme-Objekt, das auf Anfrage hin Zeichen liefern +kann, während ein Ausgabe-Port ein Scheme-Objekt ist, das Zeichen +annehmen kann. +@cindex @w{Port} + +@ignore todo +Haase: Mention that there are alternatives to files? +@end ignore + + + +@deffn {Bibliotheksprozedur} call-with-input-file string proc +@deffnx {Bibliotheksprozedur} call-with-output-file string proc + +@var{String} sollte eine Zeichenkette sein, die eine Datei benennt, und +@var{Proc} sollte eine Prozedur sein, die ein Argument nimmt. Für +@samp{Call-with-input-file} sollte die Datei bereits existieren; für +@samp{Call-with-output-file} ist die Auswirkung unbestimmt, wenn die +Datei bereits existiert. Diese Prozeduren rufen @var{Proc} mit einem +Argument auf: dem Port, der durch das Öffnen der benannten Datei zur +Ein- oder Ausgabe erhalten wurde. Wenn die Datei nicht geöffnet werden +kann, wird ein Fehler signalisiert. Wenn @var{Proc} einen Wert +zurückgibt, dann wird der Port automatisch geschlossen und der Wert oder +die Werte, die @var{Proc} geliefert hat, zurückgegeben. Wenn @var{Proc} +keinen Wert zurückgibt, wird der Port nicht automatisch geschlossen, +solange es nicht möglich ist, zu beweisen, dass der Port niemals wieder +für eine Lese- oder Schreibe-Operation benutzt werden wird. +@c Scheme +@c will not close the port unless it can prove that the port will never +@c again be used for a read or write operation. + + +@quotation +@emph{Begründung:} +Weil Schemes Ausstiegsprozeduren einen unbegrenzten Gültigkeitsbereich +haben, ist es möglich, aus der aktuellen Fortsetzung auszusteigen, aber +später wieder hinein zurückzukehren. Wenn Implementierungen den Port +bei jedem Ausstieg aus der aktuellen Fortsetzung schließen dürften, wäre +es unmöglich, portablen Code zu schreiben, der sowohl +@samp{Call-with-current-continuation} als auch +@samp{Call-with-input-file} oder @samp{Call-with-output-file} benutzt. +@ignore todo +Pitman wants more said here; maybe encourage users to call +@var{close-foo-port}; maybe talk about process switches (?). +@end ignore + +@end quotation + +@end deffn + + + +@deffn {Prozedur} input-port? obj +@deffnx {Prozedur} output-port? obj + +Gibt @t{#t} zurück, wenn @var{Obj} jeweils ein Eingabe-Port oder +Ausgabe-Port ist, und gibt sonst @t{#f} zurück. + +@ignore todo +Won't necessarily return true after port is closed. +@end ignore + + +@end deffn + + + +@deffn {Prozedur} current-input-port +@deffnx {Prozedur} current-output-port + +Gibt den aktuellen standardmäßigen Eingabe- oder Ausgabe-Port zurück. + +@end deffn + + + +@deffn {optionale Prozedur} with-input-from-file string thunk +@deffnx {optionale Prozedur} with-output-to-file string thunk + +@var{String} sollte eine Zeichenkette sein, die eine Datei benennt, und +@var{Proc} sollte eine Prozedur ohne Argumente sein. Bei +@samp{With-input-from-file} sollte die Datei bereits existieren, bei +@samp{With-output-to-file} ist die Auswirkungs unbestimmt, wenn die +Datei bereits existiert. Die Datei wird zur Eingabe oder Ausgabe +geöffnet, ein Eingabe- oder Ausgabe-Port mit ihr verbunden, zum +standardmäßigen Wert gemacht, der von @samp{Current-input-port} oder +@samp{Current-output-port} zurückgegeben (und von @t{(read)}, @t{(write +@var{obj})}, und so weiter) benutzt wird, und der @var{Thunk} wird ohne +Argumente aufgerufen. Wenn der @var{Thunk} einen Wert zurückgibt, wird +der Port geschlossen und der vorherige standardmäßige Wert +wiederhergestellt. @samp{With-input-from-file} und +@samp{With-output-to-file} geben den Wert oder die Werte, die +@var{Thunk} geliefert hat, zurück. Wenn eine Ausstiegsprozedur benutzt +wird, um aus der Fortsetzung dieser Prozeduren auszusteigen, ist das +Verhalten der beiden implementierungsabhängig. + +@ignore todo +OK this with authors?? +@end ignore + +@c current continuation changes in such a way +@c as to make it doubtful that the \var{thunk} will ever return. + +@ignore todo +Freeman: +Throughout this section I wanted to see ``the value of @t{(current-input-port)}'' +instead of ``the value returned by @var{current-input-port}''. (Same for +@var{current-output-port}.) +@end ignore + + + +@end deffn + + + +@deffn {Prozedur} open-input-file dateiname + +Nimmt eine Zeichenkette entgegen, die eine existierende Datei benennt, +und gibt einen Eingabe-Port zurück, der in der Lage ist, Zeichen aus +dieser Datei zu liefern. Wenn die Datei nicht geöffnet werden kann, +wird ein Fehler signalisiert. + +@end deffn + + + +@deffn {Prozedur} open-output-file dateiname + +Nimmt eine Zeichenkette entgegen, die eine Ausgabedatei benennt, die zu +erstellen ist, und gibt einen Ausgabe-Port zurück, der in der Lage ist, +Zeichen in eine neue Datei dieses Namens zu schreiben. Wenn die Datei +nicht geöffnet werden kann, wird ein Fehler signalisiert. Wenn eine +Datei mit dem angegebenen Namen bereits existiert, ist die Auswirkung +unbestimmt. + +@end deffn + + + +@deffn {Prozedur} close-input-port port +@deffnx {Prozedur} close-output-port port + +Schließt die mit @var{Port} assoziierte Datei, was den @var{Port} nicht +mehr in der Lage belässt, Zeichen zu liefern oder zu akzeptieren. +@ignore todo +But maybe a no-op +on some ports, e.g. terminals or editor buffers. +@end ignore + +Diese Routinen haben keine Auswirkung, wenn die Datei bereits +geschlossen wurde. Der zurückgegebene Wert ist unbestimmt. + +@ignore todo +Ramsdell: Some note is needed explaining why there are two +different close procedures. +@end ignore + + +@ignore todo +A port isn't necessarily still a port after it has been closed? +@end ignore + + +@end deffn + + +@node Eingabe, Ausgabe, Ports, Ein- und Ausgabe +@subsection Eingabe + + + + +@noindent + @w{ } +@c ??? +@sp 5 +@ignore todo +The input routines have some things in common, maybe explain here. +@end ignore + + + +@deffn {Bibliotheksprozedur} read +@deffnx {Bibliotheksprozedur} read port + +@samp{Read} („lesen``) wandelt externe Darstellungen von Scheme-Objekten +in die Objekte selbst um. Das heißt, sie dient zur Analyse des +nichtterminalen <Datenelement>s (siehe die Abschnitte @pxref{Externe +Darstellung} und @pxref{Paare und Listen}). @samp{Read} gibt das +nächste analysierbare Objekt des angegebenen Eingabe-@var{Port}s zurück +und aktualisiert dabei den @var{Port}, so dass er auf das erste Zeichen +nach dem Ende der externen Darstellung des Objekts zeigt. + +Wenn @samp{Read} auf ein Dateiende in der Eingabe trifft, bevor jegliche +Zeichen gefunden wurden, die der Anfang eines Objekts sein können, dann +wird ein Dateiende-Objekt zurückgegeben. +@ignore todo + +@end ignore + Der Port bleibt offen und weitere Versuche zu lesen, werden auch ein +Dateiende-Objekt zurückgeben. Wenn auf ein Dateiende nach dem Anfang +der externen Darstellung eines Objekts getroffen wird, aber die externe +Darstellung unvollständig und daher nicht analysierbar ist, wird ein +Fehler signalisiert. + +Das @var{Port}-Argument darf weggelassen werden und nimmt in diesem Fall +standardmäßig den Wert an, der durch @samp{Current-input-port} +zurückgegeben wird. Es ist ein Fehler, von einem geschlossenen Port zu +lesen. +@end deffn + + +@deffn {Prozedur} read-char +@deffnx {Prozedur} read-char port + +Gibt das nächste vom Eingabe@var{port} verfügbare Zeichen zurück und +aktualisiert dabei den @var{Port}, so dass er auf das darauf folgende +Zeichen zeigt. Wenn keine Zeichen mehr verfügbar sind, wird ein +Dateiende-Objekt zurückgegeben. @var{Port} darf weggelassen werden und +nimmt in diesem Fall standardmäßig den Wert an, der durch +@samp{Current-input-port} zurückgegeben wird. + +@end deffn + + + +@deffn {Prozedur} peek-char +@deffnx {Prozedur} peek-char port + +Gibt das nächste vom Eingabe-@var{Port} verfügbare Zeichen zurück, +@emph{ohne} den @var{Port} zu aktualisieren, also ohne ihn auf das +nachfolgende Zeichen zeigen zu lassen. Wenn keine Zeichen mehr +verfügbar sind, wird ein Dateiende-Objekt zurückgegeben. @var{Port} +darf weggelassen werden, in diesem Fall nimmt er standardmäßig den Wert +an, der von @samp{Current-input-port} zurückgegeben wird. + + +@quotation +@emph{Anmerkung:} +Der vom Aufruf von @samp{Peek-char} zurückgegebene Wert ist derselbe wie +der von einem Aufruf von @samp{Read-char} mit demselben @var{Port} +zurückgegeben wird. Der einzige Unterschied ist, dass der direkt +folgende Aufruf von @samp{Read-char} oder @samp{Peek-char} auf diesem +@var{Port} den Wert zurückgeben wird, den der vorhergehende Aufruf von +@samp{Peek-char} zurückgegeben hat. Insbesondere wird ein Aufruf von +@samp{Peek-char} auf einem interaktiven Port hängen, während er auf eine +Eingabe wartet, wann immer ein Aufruf von @samp{Read-char} gehangen +hätte. +@end quotation + + +@end deffn + + + +@deffn {Prozedur} eof-object? obj + +Gibt @t{#t} zurück, wenn @var{Obj} ein Dateiende-Objekt ist, und gibt +sonst @t{#f} zurück. Die genaue Menge von Dateiende-Objekten wird sich +je nach Implementierung unterscheiden, jedenfalls wird ein +Dateiende-Objekt aber niemals ein durch Benutzung von @samp{Read} +lesbares Objekt sein. + +@end deffn + + + +@deffn {Prozedur} char-ready? +@deffnx {Prozedur} char-ready? port + +Gibt @t{#t} zurück, wenn ein Zeichen auf dem Eingabe@var{port} bereit +ist, und gibt sonst @t{#f} zurück. Wenn @samp{Char-ready} den Wert +@t{#t} zurückgibt, dann ist garantiert, dass die nächste +@samp{Read-char}-Operation auf dem übergebenen @var{Port} nicht hängen +wird. Wenn der @var{Port} am Dateiende ist, dann gibt +@samp{Char-ready?} den Wert @t{#t} zurück. @var{Port} darf weggelassen +werden, in diesem Fall nimmt er standardmäßig den von +@samp{Current-input-port} zurückgegebenen Wert an. + + +@quotation +@emph{Begründung:} +@samp{Char-ready?} existiert, um es einem Programm zu ermöglichen, +Zeichen von interaktiven Ports zu akzeptieren, ohne im Warten auf +Eingaben festzustecken. Jeder Eingabebearbeiter, der mit solchen Ports +assoziiert ist, muss sicherstellen, dass Zeichen, deren Existenz durch +@samp{Char-ready?} zugesichert wurde, nicht mehr ausradiert werden +können. Wenn @samp{Char-ready?} den Wert @t{#f} am Dateiende +zurückgeben würde, könnte man einen Port am Dateiende nicht von einem +interaktiven Port unterscheiden, der keine bereitstehenden Zeichen hat. +@end quotation + +@end deffn + + +@node Ausgabe, Systemschnittstelle, Eingabe, Ein- und Ausgabe +@subsection Ausgabe + + + +@c We've got to put something here to fix the indentation!! + +@noindent + @w{} +@sp 5 + + +@deffn {Bibliotheksprozedur} write obj +@deffnx {Bibliotheksprozedur} write obj port + +Schreibt eine geschriebene Darstellung von @var{Obj} auf den übergebenen +@var{Port}. Zeichenketten, die in der geschriebenen Darstellung +vorkommen, werden in doppelte Anführungszeichen eingeschlossen, und +innerhalb dieser Zeichenketten wird jeder Backslash und jedes doppelte +Anführungszeichen durch einen Backslash maskiert. Zeichenobjekte werden +durch Nutzung der Notation @samp{#\} geschrieben. @samp{Write} gibt +einen unbestimmten Wert zurück. Das @var{Port}-Argument darf +weggelassen werden, in diesem Fall nimmt es standardmäßig den von +@samp{Current-output-port} zurückgegebenen Wert an. + +@end deffn + + + +@deffn {Bibliotheksprozedur} display obj +@deffnx {Bibliotheksprozedur} display obj port + +Schreibt eine Darstellung von @var{Obj} auf den übergebenen @var{Port}. +Zeichenketten, die in der geschriebenen Darstellung auftauchen, werden +nicht mit doppelten Anführungszeichen umschlossen und keine Zeichen +werden innerhalb dieser Zeichenketten maskiert. Zeichenobjekte kommen +in der Darstellung so vor, als würden sie mit @samp{Write-char} statt +mit @samp{Write} geschrieben. @samp{Display} gibt einen unbestimmten +Wert zurück. Das @var{Port}-Argument darf weggelassen werden, in diesem +Fall nimmt es standardmäßig den Wert an, den @samp{Current-output-port} +zurückgibt. + + +@quotation +@emph{Begründung:} +Die Absicht hinter @samp{Write} ist, maschinenlesbare Ausgaben zu +produzieren, während @samp{Display} dazu dienen soll, menschenlesbare +Ausgaben zu produzieren. Implementierungen, die „Slashifizierung`` +innerhalb von Symbolen zulassen, werden wahrscheinlich wollen, dass +@samp{Write}, aber nicht @samp{Display}, komische Zeichen in Symbolen +slashifiziert. +@end quotation + +@end deffn + + + +@deffn {Bibliotheksprozedur} newline +@deffnx {Bibliotheksprozedur} newline port + +Schreibt ein Zeilenende auf den @var{Port}. Wie genau dies umgesetzt +wird, unterscheidet sich je nach Betriebssystem. Gibt einen +unbestimmten Wert zurück. Das @var{Port}-Argument darf weggelassen +werden, in diesem Fall nimmt es standardmäßig den durch +@samp{Current-output-port} zurückgegebenen Wert an. + +@end deffn + + + +@deffn {Prozedur} write-char char +@deffnx {Prozedur} write-char char port + +Schreibt das Zeichen @var{Char} (nicht eine externe Darstellung dieses +Zeichens) auf den übergebenen @var{Port} und gibt einen unbestimmten +Wert zurück. Das @var{Port}-Argument darf weggelassen werden, in diesem +Fall nimmt es standardmäßig den von @samp{Current-output-port} +zurückgegebenen Wert an. + +@end deffn + + +@node Systemschnittstelle, , Ausgabe, Ein- und Ausgabe +@subsection Systemschnittstelle + + +Fragen der Systemschnittstelle fallen im allgemeinen nicht in den +Zuständigkeitsbereich dieses Berichts. Die folgenden Operationen sind +jedoch wichtig genug, um eine Beschreibung hier zu verdienen. + + + +@deffn {optionale Prozedur} load dateiname + +@ignore todo +Fix +@end ignore + + +@c \domain{\var{Filename} should be a string naming an existing file +@c containing Scheme source code.} The {\cf load} procedure reads +@var{Dateiname} sollte eine Zeichenkette sein, die eine existierende +Datei benennt, welche Scheme-Quellcode enthält. Die Prozedur +@samp{Load} liest Ausdrücke und Definitionen aus der Datei und wertet +sie der Reihe nach aus. Es ist unbestimmt, ob die Ergebnisse der +Ausdrücke ausgegeben werden. Die Prozedur @samp{Load} beeinflusst den +von @samp{Current-input-port} und @samp{Current-output-port} +zurückgegebenen Wert nicht. @samp{Load} gibt einen unbestimmten Wert +zurück. + + +@quotation +@emph{Begründung:} +Der Portabilität wegen wird vorausgesetzt, dass @samp{Load} auf +Quelldateien arbeiten muss. Wie es mit anderen Arten von Dateien +umgeht, unterscheidet sich notwendigerweise zwischen Implementierungen. +@end quotation + +@end deffn + + + +@deffn {optionale Prozedur} transcript-on dateiname +@deffnx {optionale Prozedur} transcript-off + +@var{Dateiname} muss eine Zeichenkette sein, die eine Ausgabedatei +benennt, die erstellt werden soll. Die Auswirkung von +@samp{Transcript-on} ist, die benannte Datei zur Ausgabe zu öffnen und +eine Abschrift der nachfolgenden Interaktion zwischen der Nutzerin und +dem Scheme-System in die Datei schreiben zu lassen. Die Abschrift endet +mit einem Aufruf von @samp{Transcript-off}, welche die Datei der +Abschrift schließt. Nur eine Abschrift darf gleichzeitig angefertigt +werden, wobei manche Implementierungen diese Einschränkung lockern +könnten. Die Werte, die von diesen Prozeduren zurückgegeben werden, +sind unbestimmt. + +@c \begin{note} +@c These procedures are redundant in some systems, but +@c systems that need them should provide them. +@c \end{note} +@end deffn + +@page + +@c @include{syn} +@node Formale Syntax und Semantik, Bemerkungen, Standardprozeduren, top +@chapter Formale Syntax und Semantik + +@menu +* Formale Syntax:: +* Formale Semantik:: +* Abgeleiteter Ausdruckstyp:: +@end menu + + + +Dieses Kapitel bietet formale Beschreibungen dessen, was in vorherigen +Kapiteln dieses Berichts bereits informell beschrieben wurde. + +@ignore todo +Allow grammar to say that else clause needn't be last? +@end ignore + + + +@node Formale Syntax, Formale Semantik, Formale Syntax und Semantik, Formale Syntax und Semantik +@section Formale Syntax + +@menu +* Lexikalische Struktur:: +* Externe Darstellung:: +* Ausdruck:: +* Quasimaskierungen:: +* Umwandler:: +* Programme und Definitionen:: +@end menu + + + +Dieser Abschnitt bietet eine formale Syntax für Scheme, die in einer +erweiterten BNF geschrieben ist. + +Jeglicher Leerraum in der Grammatik dient nur der Lesbarkeit. Groß- und +Kleinschreibung wird nicht unterschieden, zum Beispiel sind @samp{#x1A} +und @samp{#X1a} äquivalent. <leer> steht für die leere Zeichenkette. + +Die folgenden Erweiterungen der BNF werden benutzt, um eine knappere +Beschreibung zu ermöglichen: <Ding>* bedeutet null oder mehr Vorkommen +von <Ding> und <Ding>+ bedeutet mindestens ein <Ding>. + + +@node Lexikalische Struktur, Externe Darstellung, Formale Syntax, Formale Syntax +@subsection Lexikalische Struktur + + +Dieser Abschnitt beschreibt, wie einzelne Tokens („Marken``, +d.h. Bezeichner, +@cindex @w{Token} +Zahlen, etc.) aus Folgen von Zeichen gebildet werden. Die danach +folgenden Abschnitte beschreiben, wie Ausdrücke und Programme aus Folgen +von Tokens gebildet werden. + +<Leerraum zwischen Tokens> darf auf beiden Seiten eines beliebigen +Tokens auftreten, aber nicht innerhalb eines Tokens. + +Tokens, die ein implizites Ende erfordern (Bezeichner, Zahlen, Zeichen +und der Punkt) dürfen von jedem <Trennzeichen> beendet werden, aber +nicht unbedingt von irgendetwas anderem. + +Die folgenden fünf Zeichen werden für spätere Erweiterungen der Sprache +reserviert: @t{[ ] @{ @} |} + + +@format +@cindex @w{Bezeichner} +@cindex @w{Kommentar} +@t{<Token> --> <Bezeichner> | <boolescher Wert> | <Zahl> +@c @cindex @w{Bezeichner} + | <Zeichen> | <Zeichenkette> + | ( | ) | #( | @t{'} | @t{`} | , | ,@@ | @b{.} +<Trennzeichen> --> <Leerraum> | ( | ) | " | ; +<Leerraum> --> <Leerzeichen oder Zeilenvorschub> +<Kommentar> --> ; <@r{alle nachfolgenden Zeichen bis zu einem} + @r{Zeilenvorschub>} +@c @cindex @w{Kommentar} +<Atmosphäre> --> <Leerraum> | <Kommentar> +<Leerraum zwischen Tokens> --> <Atmosphäre>*} + +@end format + + + + + + +@c This is a kludge, but \multicolumn doesn't work in tabbing environments. + + + +@format +@cindex @w{syntaktisches Schlüsselwort} +@cindex @w{Schlüsselwort} +@cindex @w{Variable} +@t{<Bezeichner> --> <Anfangselement> <Folgeelement>* + | <besonderer Bezeichner> +<Anfangselement> --> <Buchstabe> | <spezielles Anfangselement> +<Buchstabe> --> a | b | c | ... | z + +<spezielles Anfangselement> --> ! | $ | % | & | * | / | : + | < | = | > | ? | ^ | _ | ~ +<Folgeelement> --> <Anfangselement> | <Ziffer> + | <spezielles Folgeelement> +<Ziffer> --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +<spezielles Folgeelement> --> + | - | .@: | @@ +<besonderer Bezeichner> --> + | - | ... +<syntaktisches Schlüsselwort> --> <Ausdrucksschlüsselwort> +@c @cindex @w{syntaktisches Schlüsselwort} +@c @cindex @w{Schlüsselwort} + | else | => | define + | unquote | unquote-splicing +<Ausdrucksschlüsselwort> --> quote | lambda | if + | set! | begin | cond | and | or | case + | let | let* | letrec | do | delay + | quasiquote + +@w{@samp{<Variable> @result{} <}}@r{beliebiger Bezeichner, der nicht} +@c @cindex @w{Variable} + @w{ @r{auch ein <syntaktisches Schlüsselwort> ist>}} + +<boolescher Wert> --> #t | #f +<Zeichen> --> #\ <beliebiges Zeichen> + | #\ <Zeichenname> +<Zeichenname> --> space | newline + +<Zeichenkette> --> " <Zeichenkettenelement>* " +<Zeichenkettenelement> --> <beliebiges Zeichen außer " oder \> + | \" | \\ } + +@end format + + + + + + + +@format +@t{<Zahl> --> <num 2>| <num 8> + | <num 10>| <num 16> +} + +@end format + + + +Die folgenden Regeln für <num R>, <complex R>, <real R>, <ureal R>, +<uinteger R> und <prefix R> sollten für @w{R = 2, 8, 10,} und 16 +nachgebildet werden. Es gibt keine Regeln für <decimal 2>, <decimal 8> +und <decimal 16>, was bedeutet, dass Zahlen, die Dezimaltrennzeichen +oder Exponenten enthalten, Radix 10 (d.h. Basis 10) haben müssen. +@ignore todo +Mark Meyer and David Bartley want to fix this. (What? -- Will) +@end ignore + + + +@format +@t{<num R> --> <Präfix R> <complex R> +<complex R> --> <real R> | <real R> @@ <real R> + | <real R> + <ureal R> i | <real R> - <ureal R> i + | <real R> + i | <real R> - i + | + <ureal R> i | - <ureal R> i | + i | - i +<real R> --> <Vorzeichen> <ureal R> +<ureal R> --> <uinteger R> + | <uinteger R> / <uinteger R> + | <decimal R> +<decimal 10> --> <uinteger 10> <Suffix> + | . <Ziffer 10>+ #* <Suffix> + | <Ziffer 10>+ . <Ziffer 10>* #* <Suffix> + | <Ziffer 10>+ #+ . #* <Suffix> +<uinteger R> --> <digit R>+ #* +<Präfix R> --> <Radix R> <Exaktheit> + | <Exaktheit> <Radix R> +} + +@end format + + + + +@format +@vindex #e +@vindex #i +@vindex #b +@vindex #o +@vindex #x +@t{<Suffix> --> <leer> + | <Exponentenmarkierung> <Vorzeichen> <Ziffer 10>+ +<Exponentenmarkierung> --> e | s | f | d | l +<Vorzeichen> --> <leer> | + | - +<Exaktheit> --> <leer> | #i | #e +@c @vindex #e +@c @vindex #i +<Radix 2> --> #b +@c @vindex #b +<Radix 8> --> #o +@c @vindex #o +<Radix 10> --> <empty> | #d +<Radix 16> --> #x +@c @vindex #x +<Ziffer 2> --> 0 | 1 +<Ziffer 8> --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 +<Ziffer 10> --> <Ziffer> +<Ziffer 16> --> <Ziffer 10> | a | b | c | d | e | f } + +@end format + + + +@ignore todo +Mark Meyer of TI sez, shouldn't we allow @t{1e3/2}? +@end ignore + + + +@node Externe Darstellung, Ausdruck, Lexikalische Struktur, Formale Syntax +@subsection Externe Darstellungen + + + +<Datenelement> ist, was die Prozedur @code{Read} (siehe den Abschnitt +@pxref{Eingabe}) +@vindex @w{Read} +erfolgreich analysiert. Beachten Sie, dass jede Zeichenkette, die als +ein <Ausdruck> analysiert werden kann, auch als ein <Datenelement +analysiert werden kann>. + + +@format +@t{<Datenelement> --> <einfaches Datenelement> + | <zusammengesetztes Datenelement> +<einfaches Datenelement> --> <boolescher Wert> | <Zahl> + | <Zeichen> | <Zeichenkette> | <Symbol> +<Symbol> --> <Bezeichner> +<zusammengesetztes Datenelement> --> <Liste> | <Vektor> +<Liste> --> (<Datenelement>*) + | (<Datenelement>+ .@: <Datenelement>) | <Abkürzung> +<Abkürzung> --> <Abk-Präfix> <Datenelement> +<Abk-Präfix> --> ' | ` | , | ,@@ +<Vektor> --> #(<Datenelement>*) } + +@end format + + + + +@node Ausdruck, Quasimaskierungen, Externe Darstellung, Formale Syntax +@subsection Ausdrücke + + + +@format +@t{<Ausdruck> --> <Variable> + | <Literal> + | <Prozeduraufruf> + | <lambda-Ausdruck> + | <Bedingung> + | <Zuweisung> + | <abgeleiteter Ausdruck> + | <Makronutzung> + | <Makroblock> + +<Literal> --> <Maskierung> | <Selbstauswertung> +<Selbstauswertung> --> <boolescher Wert> | <Zahl> + | <Zeichen> | <Zeichenkette> +<Maskierung> --> '<Datenelement> | (quote <Datenelement>) +<Prozeduraufruf> --> (<Operator> <Operand>*) +<Operator> --> <Ausdruck> +<Operand> --> <Ausdruck> + +<lambda-Ausdruck> --> (lambda <Formale> <Rumpf>) +<Formale> --> (<Variable>*) | <Variable> + | (<Variable>+ .@: <Variable>) +<Rumpf> --> <Definition>* <Folge> +<Folge> --> <Befehl>* <Ausdruck> +<Befehl> --> <Ausdruck> + +<Bedingung> --> (if <Test> <Folgerung> <Alternative>) +<Test> --> <Ausdruck> +<Folgerung> --> <Ausdruck> +<Alternative> --> <Ausdruck> | <leer> + +<Zuweisung> --> (set! <Variable> <Ausdruck>) + +<abgeleiteter Ausdruck> --> + (cond <cond-Klausel>+) + | (cond <cond-Klausel>* (else <Folge>)) + | (case <Ausdruck> + <case-Klausel>+) + | (case <Ausdruck> + <case-Klausel>* + (else <Folge>)) + | (and <Test>*) + | (or <Test>*) + | (let (<Bindungsspezifikation>*) <Rumpf>) + | (let <Variable> (<Bindungsspezifikation>*) <Rumpf>) + | (let* (<Bindungsspezifikation>*) <Rumpf>) + | (letrec (<Bindungsspezifikation>*) <Rumpf>) + | (begin <Folge>) + | (do (<Iterationsspezifikation>*) + (<Test> <do-Ergebnis>) + <Befehl>*) + | (delay <Iterationsspezifikation>) + | <Quasimaskierung> + +<cond-Klausel> --> (<Test> <Folge>) + | (<Test>) + | (<Test> => <Empfänger>) +<Empfänger> --> <Ausdruck> +<case-Klausel> --> ((<Datenelement>*) <Folge>) +<Bindungsspezifikation> --> (<Variable> <Ausdruck>) +<Iterationsspezifikation> --> (<Variable> <Anfang> <Schritt>) + | (<Variable> <Anfang>) +<Anfang> --> <Ausdruck> +<Schritt> --> <Ausdruck> +<do-Ergebnis> --> <Folge> | <leer> + +<Makronutzung> --> (<Schlüsselwort> <Datenelement>*) +<Schlüsselwort> --> <Bezeichner> + +<Makroblock> --> + (let-syntax (<Syntaxspezifikation>*) <Rumpf>) + | (letrec-syntax (<Syntaxspezifikation>*) <Rumpf>) +<Syntaxspezifikation> --> (<Schlüsselwort> <Umwandlerspezifikation>) + +} + +@end format + + + +@node Quasimaskierungen, Umwandler, Ausdruck, Formale Syntax +@subsection Quasimaskierungen + + +Die folgende Grammatik für Quasimaskierungsausdrücke ist nicht +kontextfrei. Sie wird als ein Rezept zur Generierung unendlich vieler +Produktionsregeln vorgestellt. Stellen Sie sich eine Kopie der +folgenden Regeln für jedes D = 1, 2,3, @dots{} vor. D misst die +Verschachtelungstiefe. + + +@format +@t{<Quasimaskierung> --> <Quasimaskierung 1> +<qq-Schablone 0> --> <Ausdruck> +<Quasimaskierung D> --> `<qq-Schablone D> + | (quasiquote <qq-Schablone D>) +<qq-Schablone D> --> <einfaches Datenelement> + | <Listen-qq-Schablone D> + | <Vektor-qq-Schablone D> + | <Demaskierung D> +<Listen-qq-Schablone D> --> (<qq-Schablone oder Spleißung D>*) + | (<qq-Schablone oder Spleißung D>+ .@: <qq-Schablone D>) + | '<qq-Schablone D> + | <Quasimaskierung D+1> +<Vektor-qq-Schablone D> --> #(<qq-Schablone oder Spleißung D>*) +<Demaskierung D> --> ,<qq-Schablone D-1> + | (unquote <qq-Schablone D-1>) +<qq-Schablone oder Spleißung D> --> <qq-Schablone D> + | <spleißende Demaskierung D> +<spleißende Demaskierung D> --> ,@@<qq-Schablone D-1> + | (unquote-splicing <qq-Schablone D-1>) } + +@end format + + + +In <Quasimaskierung>en kann eine <Listen-qq-Schablone D> manchmal +verwechselt werden mit entweder einer <Demaskierung D> oder einem +Vorkommen von <spleißende Demaskierung D>. Die Interpretation als eine +<Demaskierung> oder <spleißende Demaskierung D> hat Vorrang. + +@node Umwandler, Programme und Definitionen, Quasimaskierungen, Formale Syntax +@subsection Umwandler + + + +@format +@t{<Umwandlerspezifikation> --> + (syntax-rules (<Bezeichner>*) <Syntaxregel>*) +<Syntaxregel> --> (<Muster> <Schablone>) +<Muster> --> <Musterbezeichner> + | (<Muster>*) + | (<Muster>+ . <Muster>) + | (<Muster>* <Muster> <Auslassungspunkte>) + | #(<Muster>*) + | #(<Muster>* <Muster> <Auslassungspunkte>) + | <Musterdatenelement> +<Musterdatenelement> --> <Zeichenkette> + | <Zeichen> + | <boolescher Wert> + | <Zahl> +<Schablone> --> <Musterbezeichner> + | (<Schablonenelement>*) + | (<Schablonenelement>+ . <Schablone>) + | #(<Schablonenelement>*) + | <Schablonendatenelement> +<Schablonenelement> --> <Schablone> + | <Schablone> <Auslassungspunkte> +<Schablonendatenelement> --> <Musterdatenelement> +<Musterbezeichner> --> <beliebiger Bezeichner außer @samp{...}> +<Auslassungspunkte> --> <der Bezeichner @samp{...}> +} + +@end format + + + +@node Programme und Definitionen, , Umwandler, Formale Syntax +@subsection Programme und Definitionen + + + +@format +@t{<Programm> --> <Befehl oder Definition>* +<Befehl oder Definition> --> <Befehl> + | <Definition> + | <Syntaxdefinition> + | (begin <Befehl oder Definition>+) +<Definition> --> (define <Variable> <Ausdruck>) + | (define (<Variable> <Def-Formale>) <Rumpf>) + | (begin <Definition>*) +<Def-Formale> --> <Variable>* + | <Variable>* .@: <Variable> +<Syntaxdefinition> --> + (define-syntax <Schlüsselwort> <Umwandlerspezifikation>) +} + +@end format + + + +@node Formale Semantik, Abgeleiteter Ausdruckstyp, Formale Syntax, Formale Syntax und Semantik +@section Formale Semantik + + +Dieser Abschnitt bietet eine formale, denotationelle Semantik für die +grundlegenden Ausdrücke von Scheme und ausgewählte eingebaute +Prozeduren. Das hier benutzte Konzept und die Notation werden in +@sc{[Stoy77]} beschrieben. + +@quotation +@emph{Anmerkung:} Der Abschnitt zur formalen Semantik wurde in La@TeX{} +geschrieben, das mit @TeX{}info inkompatibel ist. Siehe den Abschnitt +zur formalen Semantik im Originaldokument, von dem dieses hier eine +Bearbeitung ist. +@end quotation + + +@c @include{derive} +@node Abgeleiteter Ausdruckstyp, , Formale Semantik, Formale Syntax und Semantik +@section Abgeleiteter Ausdruckstyp + + + +Dieser Abschnitt gibt Makrodefinitionen für abgeleitete Ausdruckstypen +aufgebaut aus den grundlegenden Ausdruckstypen an (Literal, Variable, +Aufruf, @samp{Lambda}, @samp{If}, @samp{Set!}). Siehe den Abschnitt +@ref{Programmflussfunktionalitäten} für eine mögliche Definition von +@samp{Delay}. + + +@example + +(define-syntax cond + (syntax-rules (else =>) + ((cond (else result1 result2 ...)) + (begin result1 result2 ...)) + ((cond (test => result)) + (let ((temp test)) + (if temp (result temp)))) + ((cond (test => result) clause1 clause2 ...) + (let ((temp test)) + (if temp + (result temp) + (cond clause1 clause2 ...)))) + ((cond (test)) test) + ((cond (test) clause1 clause2 ...) + (let ((temp test)) + (if temp + temp + (cond clause1 clause2 ...)))) + ((cond (test result1 result2 ...)) + (if test (begin result1 result2 ...))) + ((cond (test result1 result2 ...) + clause1 clause2 ...) + (if test + (begin result1 result2 ...) + (cond clause1 clause2 ...))))) + +@end example + + + +@example + +(define-syntax case + (syntax-rules (else) + ((case (key ...) + clauses ...) + (let ((atom-key (key ...))) + (case atom-key clauses ...))) + ((case key + (else result1 result2 ...)) + (begin result1 result2 ...)) + ((case key + ((atoms ...) result1 result2 ...)) + (if (memv key '(atoms ...)) + (begin result1 result2 ...))) + ((case key + ((atoms ...) result1 result2 ...) + clause clauses ...) + (if (memv key '(atoms ...)) + (begin result1 result2 ...) + (case key clause clauses ...))))) + +@end example + + + +@example + +(define-syntax and + (syntax-rules () + ((and) #t) + ((and test) test) + ((and test1 test2 ...) + (if test1 (and test2 ...) #f)))) + +@end example + + + +@example + +(define-syntax or + (syntax-rules () + ((or) #f) + ((or test) test) + ((or test1 test2 ...) + (let ((x test1)) + (if x x (or test2 ...)))))) + +@end example + + + +@example + +(define-syntax let + (syntax-rules () + ((let ((name val) ...) body1 body2 ...) + ((lambda (name ...) body1 body2 ...) + val ...)) + ((let tag ((name val) ...) body1 body2 ...) + ((letrec ((tag (lambda (name ...) + body1 body2 ...))) + tag) + val ...)))) + +@end example + + + +@example + +(define-syntax let* + (syntax-rules () + ((let* () body1 body2 ...) + (let () body1 body2 ...)) + ((let* ((name1 val1) (name2 val2) ...) + body1 body2 ...) + (let ((name1 val1)) + (let* ((name2 val2) ...) + body1 body2 ...))))) + +@end example + + +Das folgende Makro für @samp{Letrec} benutzt das Symbol +@samp{<undefiniert>} für einen Ausdruck, der etwas zurückgibt, was, wenn +es an einer Stelle gespeichert ist, zu einem Fehler führt, wenn man +versucht, den Wert an der Stelle zu ermitteln (kein solcher Ausdruck ist +in Scheme definiert). Ein Trick wird benutzt, um temporäre Namen zu +generieren, damit die Reihenfolge, in der die Werte ausgewertet werden, +nicht festgelegt wird. Dies könnte auch über ein Hilfsmakro erreicht +werden. + + +@example + +(define-syntax letrec + (syntax-rules () + ((letrec ((var1 init1) ...) body ...) + (letrec "erzeuge temp. Namen" + (var1 ...) + () + ((var1 init1) ...) + body ...)) + ((letrec "erzeuge temp. Namen" + () + (temp1 ...) + ((var1 init1) ...) + body ...) + (let ((var1 <undefiniert>) ...) + (let ((temp1 init1) ...) + (set! var1 temp1) + ... + body ...))) + ((letrec "erzeuge temp. Namen" + (x y ...) + (temp ...) + ((var1 init1) ...) + body ...) + (letrec "erzeuge temp. Namen" + (y ...) + (newtemp temp ...) + ((var1 init1) ...) + body ...)))) + +@end example + + + +@example + +(define-syntax begin + (syntax-rules () + ((begin exp ...) + ((lambda () exp ...))))) + +@end example + + +Der folgende alternative Ausdruck für @samp{Begin} benutzt die +Möglichkeit nicht, mehr als einen Ausdruck in den Rumpf eines +lambda-Ausdrucks zu schreiben. Beachten Sie jedenfalls, dass diese +Regeln nur anwendbar sind, wenn der Rumpf des @samp{Begin} keine +Definitionen enthält. + + +@example + +(define-syntax begin + (syntax-rules () + ((begin exp) + exp) + ((begin exp1 exp2 ...) + (let ((x exp1)) + (begin exp2 ...))))) + +@end example + + +Die folgende Definition +von @samp{Do} benutzt einen Trick, um die Variablenklauseln zu +entfalten. Wie bei obigem @samp{Letrec} würde ein Hilfsmakro auch +funktionieren. Der Ausdruck @samp{(if #f #f)} wird benutzt, um einen +nicht näher bestimmten Wert zu erhalten. + + +@example + +(define-syntax do + (syntax-rules () + ((do ((var init step ...) ...) + (test expr ...) + command ...) + (letrec + ((loop + (lambda (var ...) + (if test + (begin + (if #f #f) + expr ...) + (begin + command + ... + (loop (do "step" var step ...) + ...)))))) + (loop init ...))) + ((do "step" x) + x) + ((do "step" x y) + y))) + +@end example + + +@c `a = Q_1[a] +@c `(a b c ... . z) = `(a . (b c ...)) +@c `(a . b) = (append Q*_0[a] `b) +@c `(a) = Q*_0[a] +@c Q*_0[a] = (list 'a) +@c Q*_0[,a] = (list a) +@c Q*_0[,@a] = a +@c Q*_0[`a] = (list 'quasiquote Q*_1[a]) +@c `#(a b ...) = (list->vector `(a b ...)) +@c ugh. + +@page + +@c @include{notes} +@node Bemerkungen, Weiteres Material, Formale Syntax und Semantik, top +@unnumbered Bemerkungen + +@menu +* Sprachänderungen:: +@end menu + + + +@ignore todo +Perhaps this section should be made to disappear. +Can these remarks be moved somewhere else? +@end ignore + + +@node Sprachänderungen, , Bemerkungen, Bemerkungen +@unnumberedsec Sprachänderungen + + + +Dieser Abschnitt zählt die Änderungen auf, die an Scheme vorgenommen +wurde, seit der „Revised^4 report`` [R4RS] veröffentlicht wurde. + + + +@itemize @bullet + + +@item +Dieser Bericht ist nun eine Obermenge des IEEE-Standards für Scheme +[IEEEScheme]: Implementierungen, die diesem Bericht hier genügen, werden +auch dem Standard genügen. Dies machte folgende Änderungen +erforderlich: + + +@itemize @bullet + + +@item +Es wird nun vorausgesetzt, dass die leere List als wahr zählt. + +@item +Die Klassifikation von Funktionalitäten als essenziell oder nicht +essenziell wurde entfernt. Es gibt nun drei Klassen von eingebauten +Prozeduren: grundlegende Prozeduren, Bibliotheksprozeduren und optionale +Prozeduren. Die optionalen Prozeduren sind @samp{Load}, +@samp{With-input-from-file}, @samp{With-output-to-file}, +@samp{Transcript-on}, @samp{Transcript-off} und +@samp{Interaction-environment}, sowie @samp{-} und @samp{/} mit mehr als +zwei Argumenten. Keine von diesen gibt es im IEEE-Standard. + +@item +Programme dürfen eingebaute Prozeduren umdefinieren. Dies wird das +Verhalten anderer eingebauter Prozeduren nicht verändern. + +@end itemize + + +@item +@emph{Port} wurde zur Liste untereinander typfremder Typen hinzugefügt. + +@item +Der Makro-Anhang wurde entfernt. Hochsprachliche Makros sind nun im +Hauptteil des Berichts zu finden. Die Umschreiberegeln für abgeleitete +Ausdrücke wurden durch Makrodefinitionen ersetzt. Es gibt keine +reservierten Bezeichner. + +@item +@samp{Syntax-rules} erlaubt nun Vektormuster. + +@item +Rückgabe mehrerer Werte, @samp{Eval} und @samp{Dynamic-wind} wurden +hinzugefügt. + +@item +Die Aufrufe, die endständig implementiert werden müssen, werden +ausdrücklich definiert. + +@item +,@samp{@@}` kann innerhalb von Bezeichnern verwendet werden. `@samp{|}' +ist für mögliche zukünftige Erweiterungen reserviert. + + +@end itemize + + +@c %R4%% +@c \subsection*{Keywords as variable names} + +@c Some implementations allow arbitrary syntactic +@c keywords \index{keyword}\index{syntactic keyword}to be used as variable +@c names, instead of reserving them, as this report would have +@c it.\index{variable} But this creates ambiguities in the interpretation +@c of expressions: for example, in the following, it's not clear whether +@c the expression {\tt (if 1 2 3)} should be treated as a procedure call or +@c as a conditional. + +@c \begin{scheme} +@c (define if list) +@c (if 1 2 3) \ev 2 {\em{}or} (1 2 3)% +@c \end{scheme} + +@c These ambiguities are usually resolved in some consistent way within any +@c given implementation, but no particular treatment stands out as being +@c clearly superior to any other, so these situations were excluded for the +@c purposes of this report. + +@c %R4%% +@c \subsection*{Macros} + +@c Scheme does not have any standard facility for defining new kinds of +@c expressions.\index{macros} + +@c \vest The ability to alter the syntax of the language creates +@c numerous problems. All current implementations of Scheme have macro +@c facilities that solve those problems to one degree or another, but the +@c solutions are quite different and it isn't clear at this time which +@c solution is best, or indeed whether any of the solutions are truly +@c adequate. Rather than standardize, we are encouraging implementations +@c to continue to experiment with different solutions. + +@c \vest The main problems with traditional macros are: They must be +@c defined to the system before any code using them is loaded; this is a +@c common source of obscure bugs. They are usually global; macros can be +@c made to follow lexical scope rules \todo{flushed: ``as in Common +@c Lisp's {\tt macrolet}''; OK?}, but many people find the resulting scope rules +@c confusing. Unless they are written very carefully, macros are +@c vulnerable to inadvertent capture of free variables; to get around this, +@c for example, macros may have to generate code in which procedure values +@c appear as quoted constants. There is a similar problem with syntactic +@c keywords if the keywords of special forms are not reserved. If keywords +@c are reserved, then either macros introduce new reserved words, +@c invalidating old code, or else special forms defined by the programmer +@c do not have the same status as special forms defined by the system. + +@c \todo{Refer to Pitman's special forms paper.} +@c \todo{Pitman sez: Discuss importance of having a small number of special forms +@c so that programs can inspect each other.} + +@ignore todo +Move cwcc history back here? --- Andy Cromarty is concerned about +confusion over who the audience is. +@end ignore + + +@ignore todo +Cromarty: +23. NOTES, p.35ff.: This material should stay somehow. We need to + make it clear that R^3 Scheme is not being touted as Yet Another + Ultimate Solution To The Programming Language Problem, but rather + as a snapshot of a *process* of good design, for which not all + answers have yet been found. We also ought to use the opportunity + for publicity afforded us by SIGPLAN to advertise some of the thorny + unsolved problems that need further research, and encourage + language designers to work on them. +@end ignore + + +@c @include{repository} +@node Weiteres Material, Beispiel, Bemerkungen, top +@unnumbered Weiteres Material + + +Das Internet Scheme Repository unter + +@c @center +@center @url{http://www.cs.indiana.edu/scheme-repository/} +@c @center + +enthält eine umfassende Scheme-Bibliographie, sowie wissenschaftliche +Arbeiten, Programme, Implementierungen und anderes Material, das mit +Scheme zu tun hat. + +@page + +@c @include{example} + +@node Beispiel, Bibliographie, Weiteres Material, top +@unnumbered Beispiel + +@c -*- Mode: Lisp; Package: SCHEME; Syntax: Common-lisp -*- + + +@samp{Integrate-system} integriert das System + + +@center y_k^^ = f_k(y_1, y_2, @dots{}, y_n), k = 1, @dots{}, n + +von Differentialgleichungen mit der Methode von Runge-Kutta. + +Der Parameter @t{System-derivative} ist eine Funktion, die einen +Systemzustand nimmt (einen Vektor von Werten für die Zustandsvariablen +y_1, @dots{}, y_n) und produziert eine System-Ableitung (die Werte +y_1^^, @dots{},y_n^^). Der Parameter @t{Initial-state} liefert einen +initialen Systemzustand und @t{h} ist eine erste Schätzung für die Länge +des Integrationsschritts. + +Der von @samp{Integrate-system} zurückgegebene Wert ist ein unendlicher +Strom von Systemzuständen. + + +@example + +(define integrate-system + (lambda (system-derivative initial-state h) + (let ((next (runge-kutta-4 system-derivative h))) + (letrec ((states + (cons initial-state + (delay (map-streams next + states))))) + states)))) + +@end example + + +@samp{Runge-Kutta-4} nimmt eine Funktion, @t{f}, die eine +Systemableitung aus einem Systemzustand produziert. +@samp{Runge-Kutta-4} produziert eine Funktion, die einen Systemzustand +nimmt und einen neuen Systemzustand produziert. + + +@example + +(define runge-kutta-4 + (lambda (f h) + (let ((*h (scale-vector h)) + (*2 (scale-vector 2)) + (*1/2 (scale-vector (/ 1 2))) + (*1/6 (scale-vector (/ 1 6)))) + (lambda (y) + ;; y @r{}ist ein Systemzustand + (let* ((k0 (*h (f y))) + (k1 (*h (f (add-vectors y (*1/2 k0))))) + (k2 (*h (f (add-vectors y (*1/2 k1))))) + (k3 (*h (f (add-vectors y k2))))) + (add-vectors y + (*1/6 (add-vectors k0 + (*2 k1) + (*2 k2) + k3)))))))) +@c |--------------------------------------------------| + +(define elementwise + (lambda (f) + (lambda vectors + (generate-vector + (vector-length (car vectors)) + (lambda (i) + (apply f + (map (lambda (v) (vector-ref v i)) + vectors))))))) + +@c |--------------------------------------------------| +(define generate-vector + (lambda (size proc) + (let ((ans (make-vector size))) + (letrec ((loop + (lambda (i) + (cond ((= i size) ans) + (else + (vector-set! ans i (proc i)) + (loop (+ i 1))))))) + (loop 0))))) + +(define add-vectors (elementwise +)) + +(define scale-vector + (lambda (s) + (elementwise (lambda (x) (* x s))))) + +@end example + + +@samp{Map-streams} ist analog zu @samp{Map}: Sie wendet ihr erstes +Argument (eine Prozedur) auf alle Elemente ihres zweiten Arguments (ein +Strom) an. + + +@example + +(define map-streams + (lambda (f s) + (cons (f (head s)) + (delay (map-streams f (tail s)))))) + +@end example + + +Unendliche Ströme sind als Paare implementiert, deren Car das erste +Element des Stroms enthält und deren Cdr ein Versprechen, den Rest des +Stroms zu liefern, enthält. + + +@example + +(define head car) +(define tail + (lambda (stream) (force (cdr stream)))) + +@end example + + +@sp 6 +Im Folgenden wird die Nutzung von @samp{Integrate-system} illustriert, +um das System + + +@center C dv_C / dt = -i_L - v_C / R + + + +@center L di_L / dt = v_C + +zu integrieren, welches einen gedämpften Oszillator modelliert. + + +@example + +(define damped-oscillator + (lambda (R L C) + (lambda (state) + (let ((Vc (vector-ref state 0)) + (Il (vector-ref state 1))) + (vector (- 0 (+ (/ Vc (* R C)) (/ Il C))) + (/ Vc L)))))) + +(define the-states + (integrate-system + (damped-oscillator 10000 1000 .001) + '#(1 0) + .01)) + +@end example + + +@ignore todo +Show some output? +@end ignore + + +@c (letrec ((loop (lambda (s) +@c (newline) +@c (write (head s)) +@c (loop (tail s))))) +@c (loop the-states)) + +@c #(1 0) +@c #(0.99895054 9.994835e-6) +@c #(0.99780226 1.9978681e-5) +@c #(0.9965554 2.9950552e-5) +@c #(0.9952102 3.990946e-5) +@c #(0.99376684 4.985443e-5) +@c #(0.99222565 5.9784474e-5) +@c #(0.9905868 6.969862e-5) +@c #(0.9888506 7.9595884e-5) +@c #(0.9870173 8.94753e-5) + +@page + +@c \newpage % Put bib on it's own page (it's just one) +@c \twocolumn[\vspace{-.18in}]% Last bib item was on a page by itself. +@c \renewcommand{\bibname}{References} +@c @include{bib} + +@c My reference for proper reference format is: +@c Mary-Claire van Leunen. +@c {\em A Handbook for Scholars.} +@c Knopf, 1978. +@c I think the references list would look better in ``open'' format, +@c i.e. with the three blocks for each entry appearing on separate +@c lines. I used the compressed format for SIGPLAN in the interest of +@c space. In open format, when a block runs over one line, +@c continuation lines should be indented; this could probably be done +@c using some flavor of latex list environment. Maybe the right thing +@c to do in the long run would be to convert to Bibtex, which probably +@c does the right thing, since it was implemented by one of van +@c Leunen's colleagues at DEC SRC. +@c -- Jonathan + +@c I tried to follow Jonathan's format, insofar as I understood it. +@c I tried to order entries lexicographically by authors (with singly +@c authored papers first), then by date. +@c In some cases I replaced a technical report or conference paper +@c by a subsequent journal article, but I think there are several +@c more such replacements that ought to be made. +@c -- Will, 1991. + +@c This is just a personal remark on your question on the RRRS: +@c The language CUCH (Curry-Church) was implemented by 1964 and +@c is a practical version of the lambda-calculus (call-by-name). +@c One reference you may find in Formal Language Description Languages +@c for Computer Programming T.~B.~Steele, 1965 (or so). +@c -- Matthias Felleisen + +@c Rather than try to keep the bibliography up-to-date, which is hopeless +@c given the time between updates, I replaced the bulk of the references +@c with a pointer to the Scheme Repository. Ozan Yigit's bibliography in +@c the repository is a superset of the R4RS one. +@c The bibliography now contains only items referenced within the report. +@c -- Richard, 1996. + +@node Bibliographie, Register, Beispiel, top +@unnumbered Bibliographie + + +@itemize @bullet +@c 999 + + +@item [SICP] +@pindex SICP +Harold Abelson und Gerald Jay Sussman mit Julie Sussman. +@emph{Structure and Interpretation of Computer Programs, second edition.} +MIT Press, Cambridge, 1996. + +@item [Bawden88] +@c new +Alan Bawden und Jonathan Rees. +@pindex Bawden88 +Syntactic closures. +In @emph{Proceedings of the 1988 ACM Symposium on Lisp and + Functional Programming}, Seiten 86--95. + +@item [howtoprint] +@pindex howtoprint +Robert G. Burger und R. Kent Dybvig. +Printing floating-point numbers quickly and accurately. +In @emph{Proceedings of the ACM SIGPLAN '96 Conference + on Programming Language Design and Implementation}, Seiten 108--116. + +@item [RRRS] +@pindex RRRS +William Clinger, Herausgeber. +The revised revised report on Scheme, or an uncommon Lisp. +MIT Artificial Intelligence Memo 848, August 1985. +Auch veröffentlicht als Computer Science Department Technical Report 174, + Indiana University, Juni 1985. + +@item [howtoread] +@c new +William Clinger. +@pindex howtoread +How to read floating point numbers accurately. +In @emph{Proceedings of the ACM SIGPLAN '90 Conference + on Programming Language Design and Implementation}, Seiten 92--101. +Sammelband veröffentlicht als @emph{SIGPLAN Notices} 25(6), Juni 1990. + +@item [R4RS] +@pindex R4RS +William Clinger und Jonathan Rees, Herausgeber. +The revised^4 report on the algorithmic language Scheme. +In @emph{ACM Lisp Pointers} 4(3), Seiten 1--55, 1991. + +@item [macrosthatwork] +@c new +William Clinger und Jonathan Rees. +@pindex macrosthatwork +Macros that work. +In @emph{Proceedings of the 1991 ACM Conference on Principles of + Programming Languages}, Seiten 155--162. + +@item [propertailrecursion] +@c new +William Clinger. +@pindex propertailrecursion +Proper Tail Recursion and Space Efficiency. +Zu erscheinen in @emph{Proceedings of the 1998 ACM Conference on Programming + Language Design and Implementation}, Juni 1998. + +@item [syntacticabstraction] +@pindex syntacticabstraction +R. Kent Dybvig, Robert Hieb und Carl Bruggeman. +Syntactic abstraction in Scheme. +@emph{Lisp and Symbolic Computation} 5(4):295--326, 1993. + +@item [Scheme311] +@pindex Scheme311 +Carol Fessenden, William Clinger, Daniel P. Friedman und Christopher Haynes. +Scheme 311 version 4 reference manual. +Indiana University Computer Science Technical Report 137, Februar 1983. +Abgelöst von [Scheme84]. + +@item [Scheme84] +@pindex Scheme84 +D. Friedman, C. Haynes, E. Kohlbecker und M. Wand. +Scheme 84 interim reference manual. +Indiana University Computer Science Technical Report 153, Januar 1985. + +@item [IEEE] +@pindex IEEE +@emph{IEEE Standard 754-1985. IEEE Standard for Binary Floating-Point +Arithmetic.} IEEE, New York, 1985. + +@item [IEEEScheme] +@pindex IEEEScheme +@emph{IEEE Standard 1178-1990. IEEE Standard for the Scheme + Programming Language.} IEEE, New York, 1991. + +@item [Kohlbecker86] +@pindex Kohlbecker86 +Eugene E. Kohlbecker Jr. +@emph{Syntactic Extensions in the Programming Language Lisp.} +Doktorarbeit (PhD), Indiana University, August 1986. + +@item [hygienic] +@pindex hygienic +Eugene E. Kohlbecker Jr., Daniel P. Friedman, Matthias Felleisen und Bruce Duba. +Hygienic macro expansion. +In @emph{Proceedings of the 1986 ACM Conference on Lisp + and Functional Programming}, Seiten 151--161. + +@item [Landin65] +@pindex Landin65 +Peter Landin. +A correspondence between Algol 60 and Church's lambda notation: Part I. +@emph{Communications of the ACM} 8(2):89--101, Februar 1965. + +@item [MITScheme] +@pindex MITScheme +MIT Department of Electrical Engineering and Computer Science. +Scheme manual, seventh edition. +September 1984. + +@item [Naur63] +@pindex Naur63 +Peter Naur et al. +Revised report on the algorithmic language Algol 60. +@emph{Communications of the ACM} 6(1):1--17, Januar 1963. + +@item [Penfield81] +@pindex Penfield81 +Paul Penfield, Jr. +Principal values and branch cuts in complex APL. +In @emph{APL '81 Conference Proceedings,} Seiten 248--256. +ACM SIGAPL, San Francisco, September 1981. +Sammelband veröffentlicht als @emph{APL Quote Quad} 12(1), ACM, September 1981. + +@item [Pitman83] +@pindex Pitman83 +Kent M. Pitman. +The revised MacLisp manual (Saturday evening edition). +MIT Laboratory for Computer Science Technical Report 295, Mai 1983. + +@item [Rees82] +@pindex Rees82 +Jonathan A. Rees und Norman I. Adams IV. +T: A dialect of Lisp or, lambda: The ultimate software tool. +In @emph{Conference Record of the 1982 ACM Symposium on Lisp and + Functional Programming}, Seiten 114--122. + +@item [Rees84] +@pindex Rees84 +Jonathan A. Rees, Norman I. Adams IV und James R. Meehan. +The T manual, fourth edition. +Yale University Computer Science Department, Januar 1984. + +@item [R3RS] +@pindex R3RS +Jonathan Rees und William Clinger, editors. +The revised^3 report on the algorithmic language Scheme. +In @emph{ACM SIGPLAN Notices} 21(12), Seiten 37--79, Dezember 1986. + +@item [Reynolds72] +@pindex Reynolds72 +John Reynolds. +Definitional interpreters for higher order programming languages. +In @emph{ACM Conference Proceedings}, Seiten 717--740. +ACM, +@ignore todo +month? +@end ignore + 1972. + +@item [Scheme78] +@pindex Scheme78 +Guy Lewis Steele Jr. und Gerald Jay Sussman. +The revised report on Scheme, a dialect of Lisp. +MIT Artificial Intelligence Memo 452, Januar 1978. + +@item [Rabbit] +@pindex Rabbit +Guy Lewis Steele Jr. +Rabbit: a compiler for Scheme. +MIT Artificial Intelligence Laboratory Technical Report 474, Mai 1978. + +@item [CLtL] +@pindex CLtL +Guy Lewis Steele Jr. +@emph{Common Lisp: The Language, second edition.} +Digital Press, Burlington MA, 1990. + +@item [Scheme75] +@pindex Scheme75 +Gerald Jay Sussman und Guy Lewis Steele Jr. +Scheme: an interpreter for extended lambda calculus. +MIT Artificial Intelligence Memo 349, Dezember 1975. + +@item [Stoy77] +@pindex Stoy77 +Joseph E. Stoy. +@emph{Denotational Semantics: The Scott-Strachey Approach to + Programming Language Theory.} +MIT Press, Cambridge, 1977. + +@item [TImanual85] +@pindex TImanual85 +Texas Instruments, Inc. +TI Scheme Language Reference Manual. +Preliminary version 1.0, November 1985. + +@end itemize + + + + +@page + + +@c Adjustment to avoid having the last index entry on a page by itself. +@c \addtolength{\baselineskip}{-0.1pt} + +@node Register, , Bibliographie, top +@unnumbered Alphabetisches Register der Definitionen von Konzepten, Schlüsselwörtern und Prozeduren + + + +Der Haupteintrag für jeden Begriff, jede Prozedur bzw. jedes +Schlüsselwort wird zuerst aufgeführt, von den anderen Einträgen +getrennt. + +@sp 6 + +@unnumberedsec Konzepte +@printindex cp +@page +@unnumberedsec Prozeduren +@printindex fn + +@ifinfo +@unnumberedsec Referenzen +@printindex pg +@end ifinfo + + +@contents +@bye diff --git a/doc/translation-rationale-de b/doc/translation-rationale-de new file mode 100644 index 000000000..79274a957 --- /dev/null +++ b/doc/translation-rationale-de @@ -0,0 +1,263 @@ +The German translation of .texi files is contained in files ending in +.de.texi. An attempt is made to ensure the German translation of +Scheme-specific terms is close to the English term such that German +readers are more likely to understand English error messages and +discussions. Translations follow official new German orthography +because people expect it. Generic masculine form is used for plural +forms (e.g. “students” becomes “Studenten”, “researchers” becomes +“Forscher”) when alternatives that do not generalize the male form are +cumbersome. For singular forms (“user”) the female translation is +preferred (“Nutzerin”). Common variable names (e.g. “char”, “string”, +“tail”) are not translated. For R5RS, which is not case-sensitive, +variable names are capitalized as nouns, but not within code. + +TODO: @samp and other Texinfo constructs do not yet use German +punctuation. @node uses semicolons in place of commas. + +The following mapping was used for translations. German Wikipedia was +frequently consulted for building the mapping. + +absolute value => Absolutbetrag +actor => Akteur +allocation => Zuteilung +alphabetic character => Buchstabenzeichen +alternate [of a logical + implication] => Alternative +appear => vorkommen +approximation => Annäherung +association list => assoziative ListeT +at sign => At-Zeichen (rather than “Klammeraffe” or + other colloquial terms) +backquote => Backquote (there is no common German term) +backslash => Backslash (there is no common German term) +backtracking => Rücksetzverfahren (also mention the more + common English term!) +binding => Bindung +block structure => Blockstruktur +body => Rumpf +boundary condition => Randbedingung +brace => geschweifte Klammer +bracket => eckige Klammer +branch cut [of a complex + function] => Verzweigungsschnitt +call by name => als Namensparameter +call by need => als Bedarfsparameter +call by value => als Wertparameter +carriage return => Wagenrücklauf +category => Kategorie +character => Zeichen +clause [as in logic] => Klausel +coerce => aufzwingen +combination [procedure + call] => Kombination +command => Befehl +comment => Kommentar +compiler => Übersetzer +component => Bestandteil +computer => Rechner +consequent => Folgerung +consistent => widerspruchsfrei, im Einklang, + konsistent, … +constant => Konstante (declined as an adjective, i.e. + plural form is “zwei Konstante”, because it + is more logical than “zwei Konstanten”) +construct => Konstrukt +consumer [opposite of + producer] => Konsument +contagious => ansteckend +continuation => Fortsetzung +control flow => Programmfluss (instead of alternative + Kontrollfluss, because it seems easier to + comprehend) +coroutine => Ko-Routine +datum => Datenelement +definition => Definition +delayed evaluation => verzögerte Auswertung +denotational semantics => denotationelle Semantik +derive => ableiten (rather than “herleiten”) +dimension of type => Größendimension (in analogy to dimensions + in physics, which I suppose is meant by + ) +disjointness of types => Typfremdheit +domain [mathematical + concept] => Definitionsbereich, Definitionsmenge +dotted pair => gepunktetes Paar +dynamic extent => dynamischer Bereich +dynamically typed => dynamisch typisiert +effect => Wirkung, Auswirkung +entry [of the manual] => Eintrag +enumerate => aufzählen +environment => Umgebung +equivalent [math] => äquivalent +equivalent [sense of eqv?] => gleichwertig (this puts more emphasis on + the difference between eq? and eqv? and + math than “äquivalent”) +error situation => Fehlersituation +escape [of a character] => maskieren +escape procedure => Ausstiegsprozedur (because it is easier to + understand than Fluchtprozedur) +evaluation => Auswertung +exact [of numbers] => exakt +exclusive [of an interval] => nicht einschließlich +expand [of a macro] => umschreiben (like “rewrite”, “transcribe”) +expression => Ausdruck +extension => Erweiterung +extent [where an object is + alive] => Gültigkeitsbereich +external representation => externe Darstellung (rather than + “Darstellung nach Außen” because “extern” + is closer to the English term, also rather + than “externe Repräsentation” because + “Darstellung” seems like the more usual + term in non-scientific circles) +feature => Funktionalität +field [of a record] => Komponente +fix point => Festkomma +fixnum => Festkommazahl +floating point => Gleitkomma +flonum => Gleitkommazahl +force [a promise] => erzwingen +form feed => Seitenvorschub +formals => Formale +hygienic => hygienisch +identifier => Bezeichner +inclusive [of an interval] => einschließlich +index [list of terms] => Register +index [position] => Index (plural “Indizes”) +input => Eingabe +integer => ganze Zahl +interned symbol => interniertes Symbol +interpreter => Interpreter (at first glance) +iteration => Iteration +keyword => Schlüsselwort +latent type => latenter Typ +lazy evaluation => verzögerte Auswertung (same as “delayed + evaluation”) +level => Stufe +lexical conventions => Schreibkonventionen +lexical environment => lexikalische Umgebung +lexicographic => alphabetisch (this translation is not + always correct but it is correct and more + common for the usages in the R5RS) +library => Bibliothek +line feed => Zeilenvorschub (not “Zeilenumbruch”, mind + the difference) +list => Liste +literal [kind of constant] => Literal +location => Stelle +loop => Schleife +lower case => Kleinschreibung +lowest terms [of a + fraction] => unkürzbar +machine word => Maschinenwort +macro => Makro +manifest type => ausdrücklicher Typ +memory => Speicher +message passing style => nachrichtenübermittelnder Stil +mutate => verändern (rather than “mutieren”, which + is not usually understood correctly) +mutually recursive => wechselseitig rekursiv +named let => benanntes let (bzw. großgeschrieben “Let” + in R5RS) +newline => Zeilenvorschub +non-local exit => nicht-lokaler Sprung (alternatively + “Sprung heraus” or perhaps “Ausstieg”, + depending on context) +notation => Notation +note => Anmerkung +optional => optional +output => Ausgabe +parenthesis => (runde) Klammer +parse => aufgliedern, verstehen, umwandeln, + verarbeiten, analysieren (as appropriate) +pattern => Muster +polar [coordinates] => polar +port => Port (rather than e.g. “Buchse”, because + “Port” is closer to the English term) +portable => portabel +precision => Genauigkeit +predicate => Prädikat +primitive => Grundbaustein +procedure => Prozedur +proceedings [scientific + publication] => Sammelband +producer [opposite of + consumer] => Produzent +promise => Versprechen +proper [mathematical + concept] => echt +quote => maskieren (see “escape”) +radix => Radix (“die Radix” rather than “Basis”) +range => Bereich, Wertebereich (note similarity to + “scope” and to “extent”) +rational number => rationale Zahl (rather than “Bruchzahl”) +rationale => Begründung +read-only memory => Nur-Lese-Speicher (instead of + “schreibgeschützter Speicher”, because it + is closer to the original wording) +record => Verbund +rectangular [complex + number] => kartesisch +reference [bibliography] => Verweis +reference [naming a value] => Referenz +region [of a binding] => Region +report [of a Scheme +standards document] => Bericht +report [to signal sth] => melden +representation => Darstellung +restriction => Einschränkung +result => Ergebnis +return [of a function] => einen Wert zurückgeben (since Scheme never + returns without a return value, this + translation can always be used), einen + Rücksprung durchführen +rewrite => umschreiben (same as “expand”, + “transcribe”) +rule => Regel +scope => Sichtbarkeitsbereich +sequencing [of operations] => Sequenzierung +shadow [another variable] => überschatten +side effect => Wirkung (rather than “Nebeneffekt”) +signal [an error] => signalisieren +slashification => Slashifizierung +space character => Leerzeichen +splice => spleißen (rather use the not so common + German term instead of the not so common + English term) +state => Zustand +storage => Speicher +stream => Strom +string => Zeichenkette (the term “String” is + mentioned but not preferred within the + text) +strip [remove] => wegnehmen +symbol => Symbol +syntactic sugar => syntaktischer Zucker +tab => Tabulatorzeichen +tag [of a procedure + location] => Beschriftung +tail call => endständiger Aufruf +tail context => endständig +tail recursion => Endrekursion +template => Schablone +test [verb] => prüfen +Test [as an identifier] => Test (because it is easier to understand + compared to “Prüfung”) +token => Token (rather than “Marke”) +top level => oberste Ebene +transcribe [of macros] => umschreiben (same as “rewrite”, “expand”) +transcript [for logging] => Abschrift +transformer [of macros] => Umwandler +type => Typ (genitive “des Typs”) +uninterned symbol => nicht interniertes Symbol +unquote => demaskieren (see “quote”) +unspecified => unbestimmt +upper case => Großschreibung +value => Wert +variable => Variable (declined as an adjective, see + “constant”) +vector => Vektor +violation => Verletzung +whitespace => Leerraum +write [of the ‘write’ + Scheme procedure] => schreiben |