Skip to main content

Zusammenfassung

Wir sind im Begriff, die Vorstellung von Rechenprozessen zu studieren. Ein Rechenprozeß ist ein abstraktes Etwas, das dem Rechner innewohnt. Während er abläuft, bearbeitet ein Prozeß andere abstrakte Dinge, genannt Daten. Der Ablauf eines Prozesses wird durch einen Satz von Regeln gesteuert, genannt Programm. Menschen erzeugen Programme, um Prozesse zu steuern. Im Endeffekt beschwören wir die Geister des Computers mit unseren Zaubersprüchen.

Das Vorgehen des Verstandes, wodurch er sich einfacher Vorstellungen bemächtigt, ist im wesentlichen solcher Art: 1. Kombinieren von mehreren einfachen Vorstellungen zu einer zusammengesetzten; so werden alle komplexen Vorstellungen gemacht. 2. Das Zweite ist, zwei Vorstellungen, einfach oder komplex, zusammenbringen und sie so gegeneinander setzen, daß sie gleichzeitig betrachtet werden können, ohne daß sie eins werden, wodurch er alle seine Vorstellungen von Relationen erhält. 3. Das Dritte ist, sie von allen anderen Vorstellungen zu lösen, die sie in der Wirklichkeit begleiten: Dies nennt man Abstraktion, und so werden alle seine allgemeinen Vorstellungen gemacht.

John Locke, Essay den menschlichen Verstand betreffend (1690)

This is a preview of subscription content, log in via an institution to check access.

Access this chapter

Chapter
USD 29.95
Price excludes VAT (USA)
  • Available as PDF
  • Read on any device
  • Instant download
  • Own it forever
eBook
USD 54.99
Price excludes VAT (USA)
  • Available as PDF
  • Read on any device
  • Instant download
  • Own it forever

Tax calculation will be finalised at checkout

Purchases are for personal use only

Institutional subscriptions

Preview

Unable to display preview. Download preview PDF.

Unable to display preview. Download preview PDF.

Referenzen

  1. Das Lisp 1 Programmer’s Manual erschien 1960 und das Lisp 1.5 Programmer’s Manual (siehe McCarthy 1965) wurde 1962 veröffentlicht. Die Geschichte der Anfänge von Lisp ist in McCarthy 1978 beschrieben.

    Google Scholar 

  2. Die beiden Dialekte, in denen die meisten größeren Lisp-Programme der 70er Jahre geschrieben wurden, sind MacLisp (Moon 1978; Pitman 1983), entwickelt im MIT-Projekt MAC, und Interlisp (Teitelman 1974), entwickelt bei Bolt Beranek and Newman Inc. und am Xerox Palo Alto Research Center. Portable Standard Lisp (Hearn 1969; Griss 1981) ist ein anderer Lisp-Dialekt, konstruiert für die einfache Portierung zwischen unterschiedlichen Rechnern und allmählich immer weiter verbreitet. MacLisp war das Saatkorn für eine Anzahl von Unterdialekten wie Franz Lisp, entwickelt an der University of California in Berkeley und Zetalisp (Moon 1981), gemünzt auf einen speziellen Prozessor, der im Institut für Künstliche Intelligenz am MIT entwickelt wurde, um ein besonders effizientes Lisp zu erhalten. Common Lisp, ein anderer Lisp-Dialekt, der zur Zeit entwickelt wird, soll als Standard für zukünftige Lisp-Produktionssysteme dienen (Steele 1982). Der in diesem Buch verwendete Lisp-Dialekt, genannt Scheme (Steele 1975), wurde 1975 von Guy Lewis Steele Jr. und Gerald Jay Sussman im Institut für Künstliche Intelligenz am MIT entwickelt und später für die Verwendung in der Lehre am MIT wieder implementiert.

    Google Scholar 

  3. Die Charakterisierung von Zahlen als ”einfache Daten” ist schlicht Bluff. Tatsächlich ist die Behandlung von Zahlen einer der trickreichsten und verwirrendsten Aspekte jeder Programmiersprache. Einige typische Fragen, die sich dabei stellen, sind diese: Gibt es einen Unterschied zwischen ganzen Zahlen wie 2, und ”reellen” Zahlen wie 2.00? Sind die arithmetischen Operatoren für ganze Zahlen dieselben wie für reelle Zahlen? Ergibt 6 durch 2 geteilt 3 oder 3.0? Wie große Zahlen können wir darstellen? Wieviele Dezimalstellen Genauigkeit können wir darstellen? Ist der Bereich der ganzen Zahlen der gleiche wie der Bereich der reellen Zahlen? Hinter diesen Fragen steckt natürlich noch ein ganzer Berg von weiteren Problemen, die Fehler beim Abschneiden und Runden betreffen — die ganze Wissenschaft der numerischen Mathematik. Da der Schwerpunkt dieses Buches auf der Konstruktion großer Programme liegt und nicht auf numerischen Techniken, werden wir diese Probleme ignorieren. Der Lisp-Dialekt Scheme unterscheidet, wenn möglich, nicht zwischen ganzen und ”reellen” Zahlen (zum Beispiel ist 3 gleich 3.0). Die numerischen Beispiele in diesem Kapitel werden das übliche Rundungsverhalten aufweisen, das man bei der Verwendung von arithmetischen Operatoren beobachtet, die eine begrenzte Anzahl von Dezimalstellen für die Genauigkeit von gebrochenen Zahlen bereithalten.

    Google Scholar 

  4. Überall, wo wir in diesem Buch den Unterschied zwischen der Eingabe eines Benutzers und der Antwort durch den Interpretierer hervorheben wollen, werden wir die letztere in Schrägschrift zeigen.

    Google Scholar 

  5. Lisp-Systeme stellen dem Benutzer üblicherweise Hilfen für die Formatierung von Ausdrücken zur Verfügung. Zwei besonders nützliche Hilfen sind das automatische Einrücken auf die richtige Pretty-Print-Position zu Beginn einer jeden neuen Zeile und das Hervorheben der dazugehörigen öffnenden Klammer, wenn eine schließende Klammer eingetippt wurde.

    Google Scholar 

  6. Das ausgegebene Symbol ist eigentlich der Wert der define-Kombination. In Lisp besteht die Vereinbarung, daß jeder Ausdruck einen Wert hat. Diese Forderung mag unsinnig erscheinen, aber davon abzuweichen, würde lästige Komplikationen mit sich bringen. Sie hängt auch eng mit der Arbeitsweise des Interpretierers im Lesen-Auswerten-SchreibenModus zusammen, da dadurch sichergestellt wird, daß der Interpretierer immer etwas ausgeben kann als Antwort auf die Auswertung eines Ausdrucks. Wenn sich von selbst kein Wert als Ergebnis einer Operation ergibt, vereinbaren die Sprachimplementierer einen Wert, wie im Falle von define. Die Konventionen für die Auswahl solcher Werte sind stark von der jeweiligen Implementierung abhängig, und es ist eine gefährliche Angelegenheit, Programme zu schreiben, die sich auf eine solche Konvention verlassen. (Die Konvention, daß jeder Ausdruck in Lisp einen Wert haben muß, ist zusammen mit dem alten Ruf von Lisp als ineffiziente Sprache der Ursprung von Alan Perlis’ Witzelei, daß ”Lisp-Programmierer von allem den Wert und von nichts die Kosten kennen.”)

    Google Scholar 

  7. Kapitel 3 wird zeigen, daß dieser Begriff der Umgebung von entscheidender Bedeutung ist sowohl für das Verständnis der Arbeit des Interpretierers als auch für die Implementierung von Interpretierern.

    Google Scholar 

  8. Es mag seltsam erscheinen, daß die Auswertungsregel als Teil von Schritt 1 verlangt, das am weitesten links stehende Element einer Kombination auszuwerten, welches bisher nur ein Operator sein kann, der eine vorhandene elementare Prozedur wie + oder * darstellt. Wir werden später sehen, wie nützlich es ist, mit Kombinationen arbeiten zu können, deren Operatoren selbst zusammengesetzte Ausdrücke sind.

    Google Scholar 

  9. Syntaktische Sonderformen, die einfach passende Alternativen für Strukturen an der Oberfläche von Dingen sind, die auf einheitlichere Weise geschrieben werden könnten, werden manchmal ”syntaktischer Zucker” genannt, um einen Ausdruck zu benutzen, der von Peter Landin geprägt wurde. Verglichen mit Benutzern anderer Sprachen müssen sich Lisp-Programmierer in der Regel weniger um Angelegenheiten der Syntax kümmern. (Als Gegenbeispiel betrachte man ein beliebiges Pascal-Handbuch und man wird bemerken, welch großer Teil davon Syntaxbeschreibungen gewidmet ist.) Diese Geringschätzung der Syntax ist teilweise der Flexibilität von Lisp zu verdanken, die die Veränderung von Syntax an der Oberfläche einfach macht, und teilweise der Beobachtung, daß viele ”bequeme” syntaktische Konstruktionen, die eine Sprache weniger einheitlich machen, letzten Endes mehr Arger verursachen als sie wert sind, wenn die Programme groß und komplex werden. Mit den Worten von Alan Perlis: ”Syntaktischer Zucker verursacht Semikolonkaries.”

    Google Scholar 

  10. Wir werden in diesem Buch die allgemeine Syntax von Ausdrücken unter Verwendung von in Winkelklammern eingeschlossenen, schräggedruckten Symbolen beschreiben — z.B. (name) -, als Platzhalter in dem Ausdruck, die dann ersetzt werden, wenn solch ein Ausdruck tatsächlich verwendet wird.

    Google Scholar 

  11. Noch allgemeiner kann der Rumpf der Prozedur eine Folge von Ausdrücken sein. In diesem Fall wertet der Interpretierer einen Ausdruck der Folge nach dem anderen aus und liefert den Wert des letzten Ausdrucks als Wert der Prozeduranwendung.

    Google Scholar 

  12. Obgleich die Substitution eine ”naheliegende Vorstellung” ist, stellt es sich als überraschend schwierig heraus, eine exakte mathematische Definition des Substitutionsvorgangs anzugeben. Das Problem ergibt sich durch die Möglichkeit, die Namen für die formalen Parameter einer Prozedur mit den (möglicherweise identischen) Namen in den Ausdrücken, auf die die Prozedur angewendet wird, zu verwechseln. Die Reihe der fehlerhaften Definitionen der Substitution in der Literatur der Logik und Semantik des Programmierens ist in der Tat lang. Bei Stoy 1977 findet sich eine sorgfältige Erörterung der Substitution. Und dennoch, aus einer formalen mathematischen Perspektive ist es sehr viel einfacher, sich mit Substitution exakt auseinanderzusetzen, als mit dem vollständigeren Interpretierermodell, das wir in späteren Kapiteln diskutieren werden, und das sich auf dem gegenwärtigen Stand der Forschung fast gar nicht mathematisch behandeln läßt.

    Google Scholar 

  13. In Kapitel 3 werden wir den Begriff der verzögerten Auswertung einführen, um verschiedene ”Zwischenstationen” zwischen normaler und applikativer Reihenfolge zu ermöglichen. Wir werden außerdem die Auswertung nach Bedarf als allgemeine Technik zur Vermeidung von Mehrfachauswertungen einführen, wie sie in streng gehandhabter normaler Reihenfolge immer wieder vorkommen. Siehe Kapitel 3, Abschnitt 3.4.3.

    Google Scholar 

  14. Abs verwendet auch den ”Minus”-Operator -, der mit nur einem Operanden wie in (- x) Negation bedeutet.

    Google Scholar 

  15. Ein geringfügiger Unterschied zwischen if und cond in Scheme besteht darin, daß der ‹a› -Teil einer jeden Klausel eine Folge von Ausdrücken sein kann. Wenn das dazugehörige Prädikat den Wert wahr ergibt, werden die Ausdrücke ‹a› der Reihe nach ausgewertet, und der Wert des letzten Ausdrucks in der Reihe wird als Wert des cond zurückgegeben. In einem if-Ausdruck darf hingegen die ‹folge› und die ‹alternative› jeweils nur ein Ausdruck sein.

    Google Scholar 

  16. Deklarative und imperative Beschreibungen sind eng miteinander verwandt, wie auch die Mathematik mit der Informatik verwandt ist. Zum Beispiel ist die Aussage, die von einem Programm erzeugte Antwort sei ”korrekt”, eire deklarative Aussage über das Programm. Es wird sehr viel Forschung mit dem Ziel betrieben, Techniken zum Beweisen der Korrektheit von Programmen zu finden, und viele technische Schwierigkeiten bei diesem Thema haben mit dem Übergang von imperativen Aussagen (aus denen Programme aufgebaut sind) zu deklarativen Aussagen (die für Ableitungen verwendet werden können) zu tun. In einem verwandten Forschungszweig, der Entwicklung von Programmiersprachen, ist ein wichtiges aktuelles Gebiet die Erforschung von sogenannten sehr hohen Sprachen, in denen man tatsächlich mit deklarativen Ausdrücken programmieren kann. Interpretierer sollen so weit entwickelt werden, daß sie aus ”Was ist”-Wissen, das der Programmierer eingibt, automatisch ”Wie geht das”-Wissen erzeugen können. Dies ist nicht in allen Fällen möglich, aber in wichtigen Bereichen wurden bereits Fortschritte erzielt. In Kapitel 4 werden wir solch eine Sprache implementieren, eine Sprache der Logikprogrammierung, eingesetzt für das Abrufen von Information.

    Google Scholar 

  17. Dieser Algorithmus zur Berechnung der Quadratwurzel ist in Wirklichkeit ein Sonderfall des Newtonschen Verfahrens, das eine allgemeingültige Technik zur Berechnung von Wurzeln in Gleichungen ist. Der eigentliche Quadratwurzelalgorithmus wurde von Heron von Alexandria im ersten nachchristlichen Jahrhundert entwickelt. Wir werden in Abschnitt 1.3.4 sehen, wie sich das allgemeine Newtonsche Verfahren als Lisp-Prozedur ausdrücken läßt.

    Google Scholar 

  18. Wir wollen den Prädikaten Namen mit Fragezeichen am Ende geben. Dies ist eine rein stilistische Angelegenheit. Soweit es den Interpretierer betrifft, handelt es sich nur um ein gewöhnliches Symbol.

    Google Scholar 

  19. Leser, die sich um die Effizienz bei der Verwendung von Prozeduraufrufen zur Implementierung von Iterationsverfahren sorgen, seien auf die Bemerkungen zur ”Endrekursion” in Abschnitt 1.2.1 hingewiesen.

    Google Scholar 

  20. Es ist noch nicht einmal klar, welche der beiden Prozeduren die effizientere Implementierung darstellt. Das hängt von der verwendeten Hardware ab. Es gibt Maschinen, für die die ”offensichtliche” Implementierung die weniger effiziente ist. Man denke sich nur eine Maschine, die umfangreiche Tabellen mit Logarithmen und Antilogarithmen unterhält, die zudem auf eine sehr effiziente Weise abgespeichert sind.

    Google Scholar 

  21. Der Begriff der konsistenten Namensänderung ist tatsächlich kompliziert und nur schwer formal zu definieren. Berühmte Logiker sind hier schon peinlichen Irrtümern erlegen.

    Google Scholar 

  22. Lexikalische Bindung schreibt vor, daß freie Variablen in einer Prozedur sich auf Variablen in übergeordneten Prozeduren beziehen; das heißt, sie gehören zu der Umgebung, in der die Prozedur definiert wurde. Wir werden in Kapitel 3 sehen, wie dies im Detail funktioniert, wenn wir Umgebungen und das Verhalten des Interpretierers im Einzelnen untersuchen.

    Google Scholar 

  23. Eingebettete Definitionen müssen in einer Definition zuerst angeführt werden. Das Management ist nicht für die Folgen von Programmläufen verantwortlich, die Definition und Verwendung durcheinanderbringen.

    Google Scholar 

  24. In einem richtigen Programm würden wir wahrscheinlich die im letzten Abschnitt eingeführte Blockstruktur verwenden, um die Definition von fak-iter zu verstecken: (define (fakultaet n)

    Google Scholar 

  25. Wenn wir in Kapitel 5 die Implementierung von Prozeduren auf Registermaschinen erörtern, werden wir sehen, daß jeder iterative Prozeß ”in Hardware” realisiert werden kann, als Maschine, die eine feste Anzahl von Registern hat und keinerlei Hilfsspeicher. Im Gegensatz dazu wird für die Realisierung eines rekursiven Prozesses eine Maschine mit einer zusätzlichen Datenstruktur, dem sogenannten Keller benötigt.

    Google Scholar 

  26. Endrekursion galt lange Zeit als Trick zur Übersetzeroptimierung. Eine einheitliche semantische Basis für Endrekursion wurde von Carl Hewitt (1977) geschaffen, der sie mit Hilfe des ”Nachrichtenweitergabe”-Modells von Rechenvorgängen beschrieb, das wir in Kapitel 3 erörtern werden. Dadurch inspiriert, konstruierten Gerald Jay Sussman und Guy Lewis Steele Jr. (siehe Steele 1975) einen endrekursiven Interpretierer für Scheme. Steele zeigte dann später, daß Endrekursion sich von selbst aus der Art und Weise ergibt, wie Prozeduraufrufe übersetzt werden (Steele 1977).

    Google Scholar 

  27. Auf ein Beispiel dafür haben wir bereits in Abschnitt 1.1.3 hingewiesen: Der Interpretierer selbst wertet Ausdrücke mit Hilfe von baumrekursiven Prozessen aus.

    Google Scholar 

  28. Wenden Sie die Reduktionsregel zum Beispiel auf das Problem an, 5 Pfennig mit Einund Zweipfennigstücken zu wechseln, wobei Sie die Schritte einzeln durcharbeiten.

    Google Scholar 

  29. Diese Idee ist nicht so abwegig, wie es im ersten Moment scheinen mag. Man kann mit redundanten Rechenvorgängen umzugehen versuchen, indem man automatisch eine Tabelle von Funktionswerten aufbaut, während diese Werte berechnet werden. Jedesmal, wenn die Funktion mit einem Eingabewert berechnet werden soll, wird erst in der Tabelle nachgesehen, ob der Wert dort bereits gespeichert ist. Ist das der Fall, wird die redundante Berechnung vermieden. Diese Strategie, bekannt als Tabellenführung (engl. Memoization) kann auf sehr direkte Weise implementiert werden. Tabellen können manchmal verwendet werden, um Prozesse, die exponentielle Rechenzeit brauchen (wie wechselgeld) in Pro- zesse umzuwandeln, deren Bedarf an Speicherplatz und Rechenzeit linear mit der Eingabe wächst. Siehe Übung 3.27 in Kapitel 3.

    Google Scholar 

  30. Diese Aussagen sind stark vereinfacht. Wenn wir zum Beispiel Prozeßschritte mit ”Zeit” gleichsetzen, gehen wir davon aus, daß die benötigte Rechenzeit zur Ausführung einer Multiplikation unabhängig von der Größe der zu multiplizierenden Zahlen ist, was nicht zutrifft, wenn die Zahlen genügend groß sind. Ahnliche Anmerkungen gelten für die Schätzung des Speicherbedarfs. Wie der Entwurf und die Beschreibung von Prozessen kann auch die Analyse von Prozessen auf unterschiedlichen Ebenen der Abstraktion durchgeführt werden.

    Google Scholar 

  31. Genauer ist die Anzahl der benötigten Multiplikationen gleich 1 weniger als log n zur Basis 2 plus die Anzahl der Einsen in der binären Darstellung von n. Das Ergebnis dieser Rechnung ist immer kleiner als zweimal log n zur Basis 2. Die beliebige Konstante K in der Definition der Größenordnung impliziert, daß bei einem logarithmischen Prozeß die Basis des Logarithmus keine Rolle spielt; so werden alle derartigen Prozesse mit O(log n) beschrieben.

    Google Scholar 

  32. Der Leser mag sich wundern, wozu jemand die 1000ste Potenz einer Zahl bilden sollte. Siehe dazu Abschnitt 1.2.6.

    Google Scholar 

  33. Dieser iterative Algorithmus ist uralt. Er erscheint bereits im Chandah-sutra des Hindu Acharya Pingala, geschrieben vor 200 v.Chr. Siehe Knuth 1969, Abschnitt 4.6.3, wo diese und andere Methoden der Potenzrechnung ausführlich diskutiert und analysiert werden.

    Google Scholar 

  34. Dieser Algorithmus, der auch ”Methode des russischen Bauern” zur Multiplikation genannt wird, ist uralt. Beispiele seiner Verwendung finden sich im Rhind-Papyrus, einem der zwei ältesten mathematischen Dokumente überhaupt, das ungefähr 1700 v.Chr. von einem ägyptischen Schreiber mit dem Namen A’h-mose geschrieben (bzw. von einem noch älteren Dokument abgeschrieben) wurde.

    Google Scholar 

  35. Der Euklid’sche Algorithmus wird so genannt, weil er in Euklids Elemente der Mathematik (Buch 7, ca. 300 v.Chr.) erscheint. Nach Knuth (1969) kann er als der älteste bekannte nicht triviale Algorithmus betrachtet werden. Die alte ägyptische Methode der Multiplikation (Übung 1.13) ist sicher älter, aber Euklids Algorithmus ist, wie Knuth erklärt, der älteste bekannte, der als allgemeingülltiger Algorithmus vorgestellt wird, und nicht als eine Reihe von erläuternden Beispielen.

    Google Scholar 

  36. Die Reduktionsschritte für die Fälle, in denen der Exponent e größer als 1 ist, basieren auf der Tatsache, daß wir für beliebige ganze Zahlen x, y und m den Rest von x mal y modulo m finden können, indem wir den Rest von x modulo m und von y modulo m separat berechnen, diese multiplizieren, und dann den Rest des Ergebnisses modulo m nehmen. Zum Beispiel berechnen wir im Fall, daß e gerade ist, den Rest von be/2 modulo m, quadrieren ihn und nehmen den Rest von diesem Ergebnis modulo m. Diese Technik ist nützlich, denn wir können mit ihr unsere Berechnungen durchführen, ohne jemals mit Zahlen umgehen zu müssen, die viel größer als m sind. (Vergleiche Übung 1.20.)

    Google Scholar 

  37. Zahlen, die den Fermatschen Test überlisten, heißen Carmichael-Zahlen, und es ist nur wenig über sie bekannt, außer, daß sie äußerst selten sind. Es gibt 16 Carmichael-Zahlen unter 100.000. Die kleinsten sind 561, 1105, 1729, 2465, 2821 und 6601.

    Google Scholar 

  38. Wenn sehr große zufällig gewählte Zahlen daraufhin überprüft werden, ob sie Primzahlen sind, ist die Wahrscheinlichkeit, auf einen Wert zu stoßen, der den Fermatschen Test überlistet, geringer als die Wahrscheinlichkeit, daß bei der Ausführung eines ”korrekten” Algorithmus im Computer durch kosmische Strahlung ein Fehler hervorgerufen wird. Einen Algorithmus aus dem ersten Grund als nicht adäquat einzustufen, nicht aber aus dem zweiten Grund, veranschaulicht den Unterschied zwischen Mathematik und Ingenieurwissenschaft.

    Google Scholar 

  39. Eine der verblüffendsten Anwendungen von probabilistischen Primzahltests fand sich in der Kryptographie. Obgleich heute die Zerlegung einer beliebigen 200-stelligen Zahl in Primfaktoren mit dem Computer nicht machbar ist, kann mit dem Fermatschen Test in wenigen Sekunden überprüft werden, ob eine solche Zahl Primzahl ist. Diese Tatsache bildet die Grundlage für eine Technik zur Konstruktion von ”nicht entschlüsselbaren Codes”, vorgeschlagen von Rivest, Shamir und Adelman (1977). Aufgrund dieser und ähnlicher Entwicklungen haben sich für die Erforschung von Primzahlen, einst als Inbegriff der ”reinen” Mathematik angesehen und nur um ihrer selbst willen erforscht, wichtige praktische Anwendungen in der Kryptographie, im elektronischen Geldverkehr und beim Abrufen von Information ergeben.

    Google Scholar 

  40. Die Übungen 1.25–1.27 sollen die Ausdrucksfähigkeit der Sprache demonstrieren, die sich da zeigt, wo durch eine geeignete Abstraktion eine gemeinsame Basis für viele scheinbar verschiedene Operationen gefunden wird. Unsere Hände sind jedoch an dieser Stelle noch in gewisser Weise gebunden, so elegante Ideen wie die der Akkumulation und des Filterns zu verwenden, da wir bisher noch nicht die Datenstrukturen kennen, die uns die geeigneten Mittel zur Kombination dieser Abstraktionen liefern können. Wir werden in Kapitel 3 auf diese Ideen zurückkommen, wenn wir Datenstrukturen untersuchen, die Datenströme genannt werden. Datenströme sind Schnittstellen, die uns die Kombination von Filtern und Akkumulatoren ermöglichen, um noch wirkungsvollere Abstraktionen zu konstruieren. Wir werden in Abschnitt 3.4.2 sehen, wie diese Methoden als leistungsfähige und elegante Vorgehensweisen bei der Konstruktion von Programmen erst richtig zur Geltung kommen.

    Google Scholar 

  41. Diese Formel wurde im siebzehnten Jahrhundert von dem englischen Mathematiker John Wallis entdeckt.

    Google Scholar 

  42. Es wäre klarer und würde jemanden, der Lisp lernt, weniger einschüchtern, wenn ein näherliegender Name als lambda, zum Beispiel konstr-prozedur, verwendet würde. Aber der vereinbarte Begriff ist fest verwurzelt. Er wurde vom λ-Kalkül übernommen, einem mathematischen Formalismus, der von dem Mathematiker und Logiker Alonzo Church (1941) eingeführt wurde. Church entwickelte das λ-Kalkül, um eine exakte Grundlage zum Studium von Funktionen und Funktionsanwendungen zu haben. Das λ-Kalkül wurde zu einem elementaren Werkzeug für mathematische Untersuchungen der Semantik von Programmiersprachen.

    Google Scholar 

  43. Das kann mit der elementaren Prozedur error erreicht werden, die ihre Argumente als Fehlermeldung ausdruckt.

    Google Scholar 

  44. In Kapitel 2 (Abschnitt 2.1.3) werden wir sehen, daß eine Sprache, die Prozeduren als Ergebnis zuläßt, im Prinzip keine weiteren Hilfsmittel für den Umgang mit Datenstrukturen benötigt, auch wenn die Implementierungen von Lisp solche Hilfsmittel aus Effizienzgründen beinhalten. Darüber hinaus werden wir sehen, daß Prozeduren als Ergebnis es uns erlauben, mit unendlichen Datenstrukturen mittels der Technik der Verarbeitung von Datenströmen umzugehen, die in Kapitel 3 eingeführt wird.

    Google Scholar 

Download references

Author information

Authors and Affiliations

Authors

Rights and permissions

Reprints and permissions

Copyright information

© 1993 Springer-Verlag Berlin Heidelberg

About this chapter

Cite this chapter

Abelson, H., Sussman, G.J., Sussman, J. (1993). Konstruktion von Abstraktionen mit Prozeduren. In: Struktur und Interpretation von Computerprogrammen. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-662-01163-8_1

Download citation

  • DOI: https://doi.org/10.1007/978-3-662-01163-8_1

  • Publisher Name: Springer, Berlin, Heidelberg

  • Print ISBN: 978-3-540-56934-3

  • Online ISBN: 978-3-662-01163-8

  • eBook Packages: Springer Book Archive

Publish with us

Policies and ethics