Ja. Guten Morgen, alle zusammen, dann lassen wir
uns mal loslegen. Können Sie mich hören, weiterhin?
Ja. Ja, gut. Okay. Bevor wir mit
dem eigentlichen Teil heute beginnen, Datenabstraktionen in Recke,
zum Beispiel kurz noch etwas zum Aufgabenplatz sagen,
das wir heute verteilen.
Für das Aufgabenplatz brauchen Sie ein eigenes Modul, namens Flackengeduld.
Das haben wir in Recket eingestellt.
In Recket finden Sie auch
Eine Bibliothek von ziemlich vielen Hilfsprogrammen,
die wir so brauchen und die von uns vorbereitet sind.
Und zum Verwenden einiger dieser Module, die sie aufrufen sollten,
ist es wichtig, dass sie ihre Kids-System richtig einstellen.
Also zum einen wollte ich mal kurz zeigen,
weg in den Tisch, erwartet Dreck jetzt all die Dinge,
die sie als Zusatzmodule verwenden, entweder einfach direkt in dem Pfad,
wo sie auch das Programm haben, das sie zurzeit schreiben.
Also wenn sie irgendein Recket-Programm schreiben Wir versuchen mit Require etwas einzuziehen.
Er wird reckett auf jeden Fall in dem Verzeichnis schauen,
wo das Programm, das es gerade liest, auch ist.
Aber es gibt auch einen speziellen Installationsvater, was sie tun kann.
Und auf dem Meck-in-Tosh erwartet Recket alles in einem Unterverzeichnis.
Reckett in der Bibliothek Library. Ah, toll.
Willen wir wieder zurück. Und dann in einem Unterordner mit
der Versionsnummer des Recket-Systems, was wir gerade haben.
Und ich papiere im Moment sechs, sieben installiert.
Das habe ich unserer SE3 gibt. Im Unterverzeichnis Collect.
Das sind die Bibliotheken, zusätzlich gelesen werden,
da habe ich SE3 bei Pinning getan und da gibt es auch schon einen Flakkenmodus.
Und das hat sich jetzt geöffnet. Mit,
wo ist man, was ist jetzt da? Okay,
wenn wir das jetzt starten, dann wird es also gelesen.
Und das Besondere an diesem Modul und der Übungsaufgabe,
die sie haben, ist, dass sie üben werden,
als Datenwerte, Bilder zurückzugeben.
Wenn wir hier mal reingucken in diesem Modul,
definiere ich zum Beispiel, dass der Buchstabe A,
also der Symbol A, den Wert dieser Flakke bekommt.
Wir können einfach übereinfügen, da in Rackett einsetzen,
Bild einfügen und das Bild als Variablen Wert nehmen und dann mit Bildern arbeiten.
Ja, also ich habe hier jetzt als Sicklerin das ganze Flattenalphabet
hier gerade mal reingeschrieben und ihre Übungsafribe wird es sein,
dass sie das verwenden, um Listen mit buchstabiertem Text im Flattenalphabet auszugeben.
Also diese Aufgaben bleibt, denke ich, werden sie
sehr gut bearbeiten können, indem sie das Flattenmodul verwenden.
Ich kann hier einfach sagen, zum Beispiel das Symbol A, was ist es denn?
Ich kann eine Liste machen und da einsetzen, so.
List. Und ich habe meinen Namen Buch stabiert,
im Flattenalphabet und kann die Flatten setzen, so.
Also sehr bequem mit den Bildern zu arbeiten und wir werden
häufiger in dieser Vorlesung mit Bildern arbeiten, damit es funktioniert,
wenn sie mit Triquaya im Flattenmodul das einbinden,
gibt es eine Stelle,
die wollte ich jetzt ganz zentral in der Vorlesung zeigen.
Gehen Sie ins Menü
Sprache,
Sprache auswählen
So, und dann, eine Sprache auswählen,
wählen sie recket und dann gehen sie auf Details einblenden.
Hier sind die Details schon ostgeblendet. Also ich pflanzen,
das Sprachemenü öffnen, dann sehen sie hier Detail einblenden,
da klicken sie hin.
Und dann gibt es hier eine Checkmark, die ist gefährlich.
Also Kompaltverzeichnisse bestücken, das klingt ja führerisch, für schnelleres Laden.
Ja, das muss deaktiviert sein. Wenn es aktiviert ist,
dann wird recket ihnen die ganzen Bilder,
die ich von Hand eingefügt habe und die jetzt eingebunden sind
in diesem Modul,
einfach wegwerfen,
das funktioniert nicht
Also beim Kompilieren macht er die Vorarbeit kaputt. Also merken Sie sich bitte
die Stelle, Sprache auswählen, Details einblenden ganz unten.
Kompilt, Verzeichnisse bestücken, deaktivieren, dann sollte es gehen.
Okay, also viel Spaß mit diesem Aufgabenblatt, was wir heute verteilen.
Ich möchte heute in der Vorlesung mit Ihnen noch einmal über Datentypen sprechen.
Also für Brit-Semester wird es nicht viel Überraschendes sein.
Aber wir können noch mal darauf gucken,
was eigentlich Datenabstraktion aus der funktionalen Sicht ist
Wenn ich mich recht erinnere,
was sie so in den ersten zwei Semestern gemacht haben,
dann ging es vor allem um die Modellierung der Daten.
Aus der Sicht der Objekte konzentriert man sich geradezu auf die Datenstrukturen,
die die Dinge beschreiben. Wollen wir mal gucken,
was eigentlich Datenabstraktionen ist und wie man es funktional sehen könnte.
Und vor allem, welche Typen sie stundenlang recket, fertig vorfinden.
Ganz kurz blicken wir zu Anfang auf die Elementaren Datentypen,
weil da einige Sachen ein bisschen überraschend sind.
Hauptthema heute sollten die Listen sein. Wir möchten Listen sein
. Also das kennen sie jetzt natürlich
Schon aufgrund ihrer Programmierausbildung nicht alle Werte können an jede Funktion weitergegeben werden.
Das ist die erste Beobachtung, die man hat. Ja,
wenn wir hier einen Apfel definieren, als eine Zahl einzelne Birne,
als eine Liste von Werten, ja,
und dann noch eine Banane, ist ein Wahrheitswert,
dann können wir sehr gut Apfel plus Apfel rechnen oder zwei Zahlen addieren.
Aber wenn da Äpfel und Birnen verknüpfen wollen, dann knallst,
weil wir eben nicht eine Zahl zu einer Liste definieren können,
mit Hilfe addieren können, mit Hilfe der Plusfunktion.
So, kriegen wir treffende Fehlermeldungen,
die sind in Recket
recht gut gelöst
Es wurde der Typ Number erwartet, aber böse, böse.
Ich habe eine Liste gekriegt. Datenabstraktion, der hat einen Typen,
werden eingeführt, indem wir das als Abstraktionsvorgang sehen können.
Wir nehmen das unendliche Universum aller denkbaren Werte.
Ich habe mal hier einen kleinen Ausschnitt gezeichnet.
Da gibt es eben Werte wie den Mund und die Sterne,
es gibt Listen, es gibt Funktionen, es gibt Strinks,
es gibt Zahlen in unterschiedlicher Ausprägung und alles Mögliche.
Das Universum ist unendlich. Wenn wir das jetzt strukturieren wollen,
dann können wir sagen, wir bilden Gruppen von Werten,
die sich dadurch auszeichnen, äquivalent sind,
indem dieselben Funktionen auf sie angewendet werden können.
Und das nennen wir dann einen Datentyp.
Also aus diesem Universum der Werte, alles,
worauf hier die aratometischen Operationen anwenden können, nennen wir zahlen.
Oder alles, worauf wir Listenoperationen anwenden können,
nennen wir Liste und so weiter. Der Abstraktionsvorgang heißt hier,
dass wir das Universum der Werte partitionieren bezüglich der Funktionsklassen,
die darauf anwendbar sind.
Dann nennen wir es, ist derselbe Typ.
Äquivalenzklassen von Bärten, auf die
dieselben Operationen angewendet werden
Und jede dieser Klassen bildet einen Datentyp. So, weshalb sind Datentypen
interessant? Zum einen um uns vor Lockzeit-Fehlern zu bewahren,
wir sollten die Datentypen kennen, eBay-Funktionen darauf anwenden wollen.
Und dann haben wir aber auch über den Datentyp definiert,
was die Menge der möglichen Werte ist. Kann unendlich sein,
kann endlich sein. Aber die Menge der Werte bestimmt,
wie viel Speicheraufwand wir brauchen für jedes Element des Typs. Gut,
also Typen, die Sie schon kennen aus Ihrer bisherigen Programmiererfahrung,
das ist klar, die Elementaren, die in jeder Programmiersprache netterweise vordefiniert sind,
wie Zahlen, Wahrheitswerte, Zeichen, Strukturierte, die Listenmengen,
Zeichenketten, verbundene Records, Funktionstypen, unterschiedlicher Art.
Polymorphe-Typen, die sind vor allem auch im funktionalen Programmierstil sehr interessant,
weil es Funktionen sind, wo wir den Ablauf schreiben,
aber unterschiedliche Datentypen übergeben können und die Funktionen funktionieren trotzdem.
Und dann noch generische Datentypen, die im Klassen von Strukturgleichen Datentypen sind.
So, im Bereich des imperativen Programmierens unterscheiden wir, zwischen konkreten Datentypen.
Das ist das, was wir elementar durch die Sprache haben,
strukturierte Typen, die wir mit Konstrukturen aufbauen,
oder mit Selektoren, Elemente rausnehmen können.
Und dann aber abstrakte Datentypen, um die wir selbst erweitern.
Wenn wir Module bauen, die sich hinterher so verhalten,
als wäre es ein Datentyp, dann haben wir einen neuen abstrakten Datentyp gebaut.
Die Mächtigkeit der Menge der möglichen Werte. Das ist die Kardinalität.
Das ist die Mächtigkeit der Wertemenge. Und wenn wir einen Datentyp haben,
dessen Mächtigkeit endlich ist, dann kann man sich ausrechnen,
wie viel Speicherplatz man braucht,
um alle endlichen Werte dieses Typs unterscheiden zu können.
Und wenn wir strukturierte Datentypen haben, wie ein Rekord oder Verbund auf Deutsch,
dann wäre die Kardinalität das Produkt der Kardinalitäten der Basistypen,
auf denen es ausgebaut ist.
Ein Rekord, wo wir einen Namen und einen Vornamen haben,
würden wir schauen, wie viele Vornamen gibt es,
wie viele Nachnamen gibt es und das Produkt von beiden
wäre dann für diesen Verbund
die Kardinalität
Das ist das Mals für einen Speicherplatz. Und der
Mindeste Speicherplatz wird berechnet. Speicherplatz S für einen Typ,
ist der Logarithmus-Duals von der Kardinalität. Das bleibt ein Typ
. Das heißt, wenn wir unendlich großen Wertevorrat haben,
dann ist eigentlich der Speicherplatz, der benötigt wird, unendlich groß.
Und solche Rechner können wir gar nicht bauen.
Also man merkt an der Stelle schon,
dass bei der Implementation von Programmiersprachen in irgendeiner Stelle geschummelt wird.
Das Recke tut so, als hätten wir die unendliche Menge,
Natürlichen Zahlen als Badestyp zur Verfügung oder die unendliche Menge der Rationalzahlen.
Und diese Formel sagt uns, na gut,
dann brauchen wir einen Speicherplatz, Lugarothmus, Duales von unendlich.
Und das wäre immer noch unendlich. Es ist etwas schwierig. Gut. Das heißt,
bei unendlichen Datentypen wird abgekürzt und man versucht,
so zu implementieren, dass das, was natürlicherweise und sinnvollerweise geht,
funktioniert und bei allen anderen kriegt man dann Fehlermeldungen.
Gut, wir haben auch Typen von Funktionen, das werden Bitte,
möchte ich Sie bitten bei den Kommentaren zu beachten?
Und wenn wir Zusicherungen für Korrektheitsbeweise brauchen, ja,
jede Funktion in Recket bildet ab von einem Definitionsbereich auf einen Wertebereich.
Und der Datentyp A wäre der Quelltyp,
der wertet Definitionsbereich und der fühlt sich in zwei Männer B
und dann können wir das in den Kommentaren so schreiben,
F-Doppelpunkt, Doppelpunkt A, B. Wir betrachten, sagen damit,
F ist eine Funktion, die von A auf B abbildet.
In Recket werden diese Typdefinitionen nicht berücksichtigt. Es ist anders in Häskel oder Miranda,
da können wir direkt mit solchen Typ-Definitionen arbeiten,
aber in Reckett, wenden wir es vor allem für die Kommentare.
Und wir haben es teilweise in den Bibliotheken,
mit denen wir Testfälle beschreiben können.
Da kommen wir später noch drauf zurück. Also wenn Sie meinen,
ist es für die Verständlichkeit Ihres Programmes wichtig,
dann sollten Sie auf jeden Fall immer in Kommentar reinschreiben,
von wonach, wo diese Funktionen abbildet.
Gut. Wir unterscheiden, das kennen Sie sicherlich auch,
aber da wollte ich noch mal dran erinnern,
latente und manifeste Typsysteme
Programmiersprache hätten manifestes Typsystem, wenn die Variablen bei der Deklaration
schon gleich spezifiziert werden müssen.
Und das ist ganz, ganz typisch für imperative Programmiersprachen.
Ein latentes Typsystem ist, wenn wir Variablenwerte zuweisen können,
die Variable selbst ist gar nicht spezifiziert für einen bestimmten Typ.
Und wenn gerechnet wird, wird das Objekt gefragt,
was für ein Typ bist du denn?
Und gesehen passt es oder nicht. Das kann in
zwei Weisen geschehen, also im Racket,
passiert es wirklich zur Laufzeit des Programms
Dass der Typ geprüft wird, wenn die Funktionen darauf angewendet werden.
Und das heißt, eine einzelne Variable kann wie ein Chameleon
mal mitwerten, dieses Typs oder eines anderen belegt werden.
Wir sind da relativ frei. Zur Laufzeit muss es dann
nur stimmen, wenn wir die Funktionen drauf anwenden.
In den strengen getypten, funktionalen Sprachen, wie hässgelunden Miranda,
da muss zur Übersetzungszeit des Programms aus dem Kontext erschlossen werden können,
was der Typ,
der Argumente ist und auch der Typ der Funktion
Auch im Miranda und Testgeld, sind sie nicht gezwungen,
den Typ zu deklarieren, aber das Typ Kalkalkül,
was in die Sprache eingebettet ist, errechnet beim Übersetzen,
was denn die Datentypen sind und erzeugt einen effizienten Code.
Das Problem ist, wenn in diesen Sprachen programmiert, dann muss man,
dann ist man beschränkt in dem, was man sagen kann.
Man darf nämlich nur solche Sachen sorgen,
wo das Typ Kalkül sich nicht aufhängt. Das ist,
es sind einfach, es ist unmöglich, ein Programm zu schreiben,
bei dem jetzt bei dem zur Besetzungszeit nicht klar ist, was der Typ ist.
Also so simple Sachen wie in einer Rekursion,
die Verschachtelungstiefe einer Liste zu bestimmen, geht nicht, wenn sie den normalen Datentyp-Liste nehmen.
Da müssen sie auf abstrakte Datentypen zurechtgreifen. Ja,
weil es in Recket,
in Miranda zum Beispiel einfach nicht möglich ist,
dass sie eine Funktion schreiben,
der sie im ersten Moment eine sechsfach verlistete,
verschachtelte Liste geben und im nächsten Rekursionsschritt würde dieselbe Funktion mit
einer Fünffach verschachtelten Liste aufgerufen werden müssen,
weil sie in der Rekursion
die Schachtelungstiefe verringern
Das gibt einen Typkonflikt. Das Typ Kalkül sagt,
nee, Moment. Hier ist die Verschachtelungstief,
um einen zu höher als beim nächsten Aufruf.
Das Programm ist in taktisch inkorrekt. Das sind so Restriktionen,
die sich aus der statischen Überprüfung zur Übersetzungszeit aus dem Typ Kalkül ergeben können.
Das ist mit ein Grund, weshalb ich die Sprache Recket
genommen habe. Da sind wir bei der Typprüfung zur Laufzeit
. Also wenn es aufgerufen wird, muss es stimmen.
Macht es für Sie aber schwerer als Programmiererinnen und Programmierer,
weil Sie erst beim Ausführen des Programms dann auf die Fehler
stoßen,
es sei denn
Sie verwenden schon beim Schreiben selbst für sich Korrektheitsbeweise und Überlegen
, in jedem Schritt kann es so stimmen, ja.
Gut. Der latente Typisierung wird wie viel Zeitwing genannt,
das ist das, was wir hier in unserem Programmierwelt haben.
Und Manifest, wo man es gleich hinschreibt. Und da
muss man auch bei dem bleiben, was man bestellt hat.
Das ist die statische Typensierung, das SpongeTyping, ne?
Okay. Gut. Auf dem Übungsblatt,
was Sie zurzeit bearbeiten, haben Sie auch schon gesehen,
das findet das Jungteil von Typen haben.
Also es ist per Sprachdefinition definiert.
Es ist in Recket
kein Objekt gibt
Das mehr als eins. Dieser Typ Prädikate erfüllt.
Ich kann gar keins erfüllen, das ist gut möglich,
aber mehr als eins von denen darf es nicht erfüllen,
sonst hätten sie einen Fehler.
Also ist entweder Bulien, es ist ein Symbol,
es ist ein Charakter, ein Vector, eine Procedure,
das ist der Typ für die Funktionen, mit denen wir arbeiten.
Es ist ein Fair, ein Number-Sring oder ein Port, ja.
Gut, gucken wir noch mal auf generische Funktionen.
Also den Klassiker, den kennen sie auch aus anderen Programmiersprachen,
zum Beispiel die Identitätsfunktion. Wenn wir sagen, ich habe
eine Funktion, Die bildet ein Objekt auf sich selbst ab.
Also das sind, das sind die typischen Füllfunktionen,
wenn man einen Rahmen hat, der eine Funktion erwartet,
aber man möchte eigentlich nichts mit dem Ding tun,
was man übergibt, sondern nur weil im Rahmen diese Stelle da ist.
Man muss irgendwas da reinplappen, ja, dann nehmen wir die Identitätsfunktion.
Und das Bild wird auf sich selbst abgebildet. So,
wenn wir die fein aufrufen, dann ist das Resultat eines
die feinstes, eine Plusite oder ein Wert definiert ist.
Es wird etwas in der Symboltabelle eingetragen,
aber das Berechnungsresultat, was zurückkommt,
ist undefiniert
Der ganzen Record-Welt. Und schon Beginn weiß gehen. So,
jetzt haben wir die Identitätsfunktion definiert, die euch selbst abbildet.
Und wenn wir hier sagen, Bit von 2 plus 5,
2 plus 3, dann kommt der Wert 5 zurück,
wenn wir Identität auf den Wahrheitswert anwenden,
dann kommt mit einmal druth zurück.
Wir sehen also die Funktionen, es hat einen Typ,
der dafür sorgt, dass das Resultat immer vom selben Typ ist,
wie das Argument ist.
Aber das kann sich ändern. So,
und dafür gibt es eben Typ Variable,
die man verwenden kann,
um das im Kommentar
zu beschreiben
Function Ott, die prüft, ob etwas, gerade oder ungerade ist,
die könnten dir sagen, die Bilder zahlen auf Wahrheitswerte ab.
Die Funktion geht. Die bildet irgendeinen Typ Alpha auf denselben
Typ ab. Die Funktion Equals, die vergleicht Dinge,
ob sie gleich sind und die lässt es zu,
dass die beiden Argumente, die verglichen werden,
von unterschiedlichen Typen sind, Alpha und Better,
aber wir können zumindest ein zusicheres Resultat,
ist ein Wahrheitswert, Fruhe der False.
Okay. Gehen wir jetzt mal auf die konkreten Zahlen und
überhaupt auf die Datentypen, die wir haben.
Wir haben Eine Hierarchie von Typen, es gibt Number komplex
real Regional Infeature. Und das sind hier echte Teilnehmer,
Mengen Infeature ist ein echter Teilmänner von Röschenl,
das ist echt eine Teilmenge von Rial, vom Komflex.
Und dann gibt es die Zahlen hier. So,
für jeden Datenzahlentyp haben wir auch ein Prädikat,
mit dem wir prüfen können, ob es da ist.
Und die heißen dann, wie der Typ selbst,
Number komplex real, jeweils mit einem Fragezeichen dahinter.
Typ Prädikate enden, wie alle Prädikatsfunktionen,
wenn sie vordefiniert sind im Namen mit einem Fragezeichen.
Und das sollten sie auch so durchhalten.
So der Wert der größten intitscher Zahl ist implementationsabhängig
Und das hängt dann auch noch davon ab,
auf was für einem Rechner sie es laufen lassen.
Ob das dann gut geht. Einfach mal Beispiele,
das zu sehen, wie sie in Reckett schreiben können.
Die Zahlenhierarchie kennen sie natürlich von anderen Programmiersprachen,
aber wir sagen, dass dem Rechner in Reckett.
Also wenn wir eine komplexe Zahl angeben wollen,
dann nennen wir den Realschein und den Imaginärteil verbunden durch
die Plus und dahinter noch ein I beim Imaginärteil,
um zu sagen,
das ist mein Imaginärteil.
Und drei plus viermal
imaginär I ist Schuh
Die natürliche Zahl 3 ist auch eine komplexe Zahl.
Warum? Aufgrund der Typ Hierarchie. Die natürliche Zahl gehört
zur Zahl, Menge komplex. Dann haben wir die Realzahlen,
ja, das ist richtig. Und nett projektet,
ist benutzerfreundlich, selbst wenn wir es so schreiben,
minus 2.5 bis 0 mal imaginär Teil, dann kriegen wir Zurist,
ja, das ist eine reelle Zahl.
Okay. Sechs durch zehn geschrieben, wer eine Rationalzahl sechs
durch 3A. Und drei ohne dezemmal.plus lehren imaginären Teil ist auch noch eine Insitzer-Zahl.
Das ist eine, ja, und acht durch vier perfekt gekürzt für auch eine Indizer-Zahl.
Die Zahlen, die man, die Funktionen auf Zahlen,
Standardoperationen, die wir haben, das sind erst mal größer,
kleiner für die Vergleiche.
Der echte Bruchquotient, ja, Divisionsrecht. Oder Modulo haben wir,
wir haben Maximum, Minimum, Absolutbetrag, Junggeräte,
Zähler und Nenner, hat jemand eine Idee,
was das ist,
hier CD
Ja. Das kann man sich... Richtig, ja.
Größter gemeinsamer Teiler, ne? Und das jetzt... Kleinste
gemeinsame Vielfache, ne? Die kommen mini. Lore und Zieling,
wenn wir abschneiden, schneiden wir nach oben oder nach unten ab.
Also, die Zahlen sind erwartungsgemäß gar. Wichtig ist noch,
exakte Repräsentation und nicht exakte. Ja. Sie haben schon gesehen,
wenn Sie drei durch 17 teilen und wollen eigentlich wissen,
was ist das als Dezimalzeit,
kriegen Sie drei Siebzehntel zurück und wissen immer noch nicht,
was das Ergebnis ist
Breckett gibt nach Möglichkeit, solange wir nichts anderes sagen,
uns das exakte Ergebnis zurück.
Und wenn wir eine Zahl exakt repräsentiert haben wollen,
eine flutigen Polizei, dann würden wir einen Gartenzaun eh davor schreiben,
dann wird es exakt repräsentiert.
Machen wir mal als erste Übung die Fakultätsfunktion,
um zu sehen, wann wir exakt und inexakt brauchen.
Sie haben auf dem Aufgabenblatt, was Sie zurzeit bearbeiten,
schon gesehen als erste Fingerübung,
steht da,
definieren Sie
die Fakultät
Die finden sie überall, also können wir es auch schon mal hier
in der Vorlesung sprechen. Fakultät ist ja das Produkt,
das Fakultät einer natürlichen Zahl ist das Produkt an der natürlichen Zahlen,
die kleiner sind, inklusive der Zahl selbst.
Und wir machen so eine Rekursion immer über eine Verankerung,
wenn N gleich eins ist, dann haben wir den elementaren Fall,
geben eins zurück, wir könnten es auch für null zurückgeben.
Und dann rechnen wir N mal Fakultät für die um eins kleinere Zahls.
Und wenn wir eins erreicht haben, wird eins zurückgegeben und dann wird alles ausmütipliziert.
Und damit können wir ziemlich genau zum Beispiel die Fakultät von 200 Ausrechnung,
die Zahl ist ein bisschen lang, aber sei es drum.
Wenn wir jetzt die Größenordnung sehen wollen, dann könnten wir sagen,
exakt nach Index, Fakukultät von 200 und Sie sehen,
dass hier Rekic schon alle Vierer von sich streckt und sagt,
die Zahl ist so groß, da sage ich lieber positiv unendlich.
In der exakten Darstellung. Wenn wir dagegen die Fakultät nur bis 100 berechnen,
dann kriegen wir tatsächlich einen Wert heraus und sehen,
okay, da sind wir jetzt Größenordnung von 9.3,
3, mal 10, 157.
Also mit exakt nach Indexakt, wandern können Sie diese
endlos lang natürlichen Zahlen oder die Dezimalbrüche wandeln in etwas,
was sie als Fluting-Pointsal darstellen können.
Auch wenn wir jetzt hier irgendetwas hochrechnen wollen, dann ist Beispiel
eine ähnliche Rekursion. Auslöschung tritt in Reckett auch ein,
wenn sie innenexakt rechnen, dann passiert es eben,
wenn sie die Argumente inneexact repräsentieren und die Zahlen sehr,
sehr groß sind,
dass kleine Differenzen nicht mehr auffallen
Solange wir exakt rechnen, können wir 10 Uhr 100 nehmen. Gut,
davon 10 Uhr 100 subtrahiert und noch eins drauf addieren,
dann bekommen wir als Ergebnis tatsächlich diese Eins zurück.
Wenn wir dasselbe machen, aber unexakt gerechnet haben,
dann wird jetzt plus eins hier untergehen,
weil eins plus 10 Uhr 100 in exakt gerechnet verschluckt die Eins.
Und wenn wir dann das in exakt subtrahieren, kommt neu raus.
Also für exakte Arrathmetik im Regnet lohnt es sich möglichst,
solange es geht, durchzuhalten und exakt zu rechnen.
In den Übungen haben sie auch gesehen,
dass Regnet Spezielle Zahlen hat einmal das Ergebnis not numberg.
Das bekommen wir dann zurück. Wenn das Ergebnis nicht berechenbar ist,
innerhalb des Zahlenbereichs, wo wir die Operationen ausgeführt haben.
Also wenn sie hier eins durch, exakt eins durch,
null rechnen, kriegen wir not and number raus,
wenn sie jetzt aber,
im Moment habe ich hier den Unterschied gehabt,
hier teile ich durch Unendliches
Dasselbe hier noch mal mache, dann bekommen wir innen
einen positiv unendlich raus und hier einen negativ unendlich.
Einen Vergleichsprädikate sind nur anwendbar auf Zahlen.
Dieses kleiner Größer gilt wirklich nur für Zahlen,
wenn wir spezifische Datentypen haben, müssen sie immer bei Recket nachschauen.
Aber es ist für diesen Datentyp der spezifische ist jetzt Live-Spring-Prädikat.
Zum Beispiel um Strings auf ihre Sortierung zu vergleichen,
können sie es trinken, zwingen lässigen.
Bei den Wahrheitswerten. Wir sind in Recket in besonderer Weise
implementiert, ein bisschen benutzerfreundlich zu sein
So unsere Kontrollstrukturen kommt, ist, ja,
die können jedes Objekt als Wahrheitswert nehmen.
Auch die logischen Operatoren, End- und Ohr, ja.
Wenn wir an diese Strukturen irgendeinen Wert übergeben,
kann er als Wahrheitswert gesehen werden, einfach aufgrund seiner Existenz.
Und egal, was wir übergeben,
es wird, sofern es nicht der Wert voll ist,
wird es als Truge wertet
Das ist etwas, was über die Welt der Listenfamilien unterschiedlich implementiert ist.
Also entkommen lös und in den Anfängen von Skim war es so,
dass so etwas wie die leere Liste den Wahrheitswert False gab.
Dass es auch an anderen Programmiersprachen wie Pearl und so,
dass ein Wert null als falsch genommen wird und eine leere Liste als falsch.
Aber in Recket ist es so, dass alles,
wenn es denn existiert, den Wahrheitswert tut, hat,
außer es ist der Wahrheitswert falsch.
Also auch dies nüll für die leere Liste wird eben nicht
als Wahrheitswert False genommen
Tour und Volks, evaluieren zu sich selbst, die brauchen wir nicht zu cutieren,
wenn wir diese Werte angehen. Mal ein Beispiel. Also,
wenn wir einfach nur Tour hinschreiben, evaluiert zu tun,
falsch über die R zu 4, bezeugt,
gibt es quotierte Forts, evaluiert zu Forts, not too,
ergibt Falt, not three, gibt Forts,
oder not your liste, die den sehr drei hat,
ergibt Forts, weil die Liste drei, B2 wirkt,
und das ist ganz relegiert, ne?
Ja, Forts ist too, not leere Liste,
das ist für mich sehr enttäuschende Teil, gibt Forts,
not leere Liste gibt Forts, ja,
not nill gibt falls, also alles Die Lehrerliste gilt einfach,
als sie existiert und wird als Tubelmann.
Ja, also wenn wir hier fragen, ist das Auto,
wir haben ein Auto, dann wollen wir fahren,
andernfalls laufen, ja?
If not outdoor kommt, laufen zurück. Schauen wir,
der Turm fehlt. Doch dann. Ja,
Gleichheit gilt für Zahlen, aber nicht für Wahrheitswerte.
Da müssen wir mit Äquival fragen, dann geht's. Oder,
okay, die Beispiele müssen wir nicht alle einzeln durchgehen.
Equal ist Polymorph, die kann wirklich jedes mit jedem vergleichen
Was ganz praktisch ist, ist, dass die logischen Operatoren,
die Reihenfolge der Auswertung garantieren. Und sobald sie wissen,
was rauskommt, evaluieren sie die weiteren Argumente nicht mehr.
Wir schreiben die Konjunktion, das ist mathematische und mit Endgystianktion,
schreiben wir mit Ort, die Negation schreiben wir mit Not.
Und die sind eben nichts direkt in der Auswertung.
Also wenn wir, sind beide Argumente zur Falschevaluieren,
dann kriegen wir falsch zurück
Beim End. Wenn das Gaste schon falsch ist und das Zweite ist,
tu, können wir uns darauf verlassen, dass Recket,
das zweite Argument bei einem End nicht mehr auswertet.
Also wenn wir fragen, ist die Liste leer und
dann gibt uns das erste Element der Liste.
Wenn wir das in einem End machen und das bis End stellt,
fest, die Liste ist leer, dann kümmert wird es nicht mehr versuchen,
das erste Element der leeren Liste zu kriegen.
Das ist, wenn wir dagegen ein Uder haben,
das würde aufhören zu berechnen, wenn es feststellt im Ohr,
dass der erste Teilausdruck schon zugibt,
dann berechnet er nicht mehr
den zweiten
Bei einem, oder, wenn der erste Teil ausdruck undefiniert ist,
dann kriegen wir auch den undefinierten Wert zurück fürs zweiten Ausdruck,
würde es nichts machen.
Und diese, das können wir uns, also so vorstellen,
die Argumente werden immer strikt von links nach rechts ausgewertet beim und,
und, oder. Und die Auswertung wird beendet,
sobald Recket weiß, aha, bei diesem End,
da habe ich den ersten falschen Ausdruck gefunden,
das kann nicht mit True werden,
also gebe ich falls zurück
Das oder hört auf, sobald es den ersten Teil ausdruckt,
der wahr ist und dann werden die anderen nicht mehr ausgewertet.
Okay. Ein Beispiel, wie wir es praktisch verwenden können,
also wenn wir zum Beispiel sicher sein wollen,
dass wir nicht durch Null teilen und nur rechnen,
wenn der Nenner verschieden von Null ist,
könnten wir es so schreiben, ent x größer Null.
Und dann können wir ausrechnen, ob eins durch x größer ist als 0,2.
Weil an diesem Teil kommen wir nur ran,
wenn x größer als Null ist,
also kannst nicht
gleich Null sein
Wenn wir, dagegen einen kleinen Fehler machen und in der verkehrten Reihenfolge fragen, ja,
wir wollen sicher sein, dass etwas eine Zahl ist,
bevor wir das größere oder kleiner drauf an,
wenn wir zum Beispiel, wenn wir Suche machen,
geht es gut, wir fragen zuerst,
ist dieses XXXXXX hier überhaupt eine Number?
Und dann vergleiten wir das XXXXXX7, das geht gut.
Wenn wir dagegen erst in Vergleichen schreiben und hinterher fragen,
ach so, war es eigentlich eine Zahl,
dann geht es schief,
weil das erste Laufzeitfehler gegeben hat
Also es ist, man kann sich viele If Stan und Ertis ersparen,
wenn man die Wahrheit, die Kombinatoren für die Wahrheitswerte,
die Operatoren statt If und dann verwendet.
Ich finde, dies hier ist übersichtlicher, vielleicht aber nicht
so einfach zu verstehen. Wir hatten schon die Funktionen für
ein Schaltjahr gesehen mit If und Zen und Con programmiert.
Jetzt machen wir es mal einfach nur unter der Verwendung von den logischen Operatoren.
Das sieht ja mit sehr schick funktional aus, ja.
Und da haben wir jetzt geschrieben,
dann ist etwas
ein Schaltjahr
Wenn, ist es entscheidend, ja, fangen wir mit dem einfachen Teil an,
wenn der Divisionsrecht gegen 400 gleich null ist,
dann haben wir auf jeden Fall einen Schaltjahr.
Oder aber, wenn der Divisionsrest gegen 4 gleich null ist,
aber der Divisionsrest gegen 100 nicht gleich null ist,
ja, dann haben wir einen Schaltjahr.
Also, dass wir sagen, wir haben zwei Fälle im Ohr,
einmal den und einmal den und in der einen Variante müssen
zwei Bedingungen erfüllt sein.
Das können dann mit End- und Ohr wunderbar hinschreiben,
ohne dass wir
ein einziges IF brauchen
Okay. Gucken wir nochmal auf Datentypen und Strinks.
Das ist wie in anderen Programmiersprachen auch. Da ist
nicht viel Überraschendes dabei. Wir haben den Datentyp Charakter für
einzelne Zeichen und wir haben den Datentyps dringend für Zeichenketten.
Und die können wir noch ins Steuerzeichen, sichtbare Zeichen und so weiter unterscheiden.
Wichtig ist, wie geben wir jetzt Charakters im Racket an?
Also wenn wir hier ein Hash-Seichen machen und dann
ein Backflash und dann dahinter irgendwie ein Zeichen geben,
dann ist das gesundheits,
mit der wir sagen,
wir meinen das Zeichen A
und nicht die Variable
Und auch nicht diskutierte A. Also so können wir sagen,
ich meine, ein Objekt vom Typ Character und das ist der Buchstabe A, Klein A.
Und manche sind vordefiniert zum Beispiel Space und Newline für die
unsichtbaren Zeichen, die man schlecht ins Programm reinschreiben kann.
Entsprechend der Asky-Kurt-Tabelle sind die Zeichen alle sortiert. Ja,
wir können, wenn wir K lässt, die Funktion,
die zwei Zahlen vergleicht, welches ist der kleinere oder der größere,
dann werden sie einfach entsprechend ihres Asky-Kurs verglichen.
Und wir können für Zeichen, die man nicht sehen kann,
und die wir auf der Tastatur nicht eingeben können,
oder die Reckett uns nicht eingeben lässt,
die können wir auch als Oktalcode direkt angeben.
Also wenn wir die Oktalzahl aus der Aski-Tabelle nehmen,
können wir das Zeichen auch so angeben. Und wir haben Konversionsfunktionen,
mit denen man Strings zerlegen kann fürs Paarsen und so weiter.
Die liefern uns dann einfach die Buchstaben aufgelistet.
Oder neben der Liste mit Buchstaben und machen uns daraus einstringen.
Zum einen die Position in der Aski-Tabelle kriegen wir mit Car
to Inditec. Und wenn wir ein Inditec haben,
können wir auch das Zeichen draus machen,
zum Beispiel Car to Imtitschefan nullein gibt es 10 und wenn wir es umkehren,
intitsche to car von 10 würden wir einen Newline-Charakter bekommen.
Wir können fragen, ob es ein Charakter ist.
Und wenn wir jetzt buchstabieren wollen, könnten wir es zum Beispiel so machen.
Wir wollen den Nachfolger von A im Alphabet haben.
Dann wird Card to Intitschefan Aff,
dann haben wir die Position im Alphabet,
addieren eins drauf und dann wandeln wir es zurück in
die Chat2K und dann kriegen wir das Zeichen B.
So können wir durch eine Tabelle von Zeichen durchgehen
Jetzt kommen wir zu den Datentypen, die ich im Racket
eigentlich am spannendsten und leichtesten zu benutzen finde.
Das sind die Listen. Gucken wir erst mal auf die Grundoperationen auf Listen.
Also eine Liste. Selbst, die können wir immer dann verwenden,
wenn wir eine geordnete Sammlung von Werten und Objekten haben wollen, ja?
Und was in Racket sehr bequem ist, ist,
dass wir in einer Liste alles zusammenschmeißen können.
Die Liste, die Elemente in einer Liste müssen nicht alle denselben Typ haben.
Also wir können in der Liste Funktionen, Werte, zahlen,
was reinschmeißen, solange man es in eine Liste tun kann,
dürfen wir es reintun.
Jetzt sind aber andere bestimmte Fälle interessant. Also wenn jetzt alle Elemente vom selben Typ sind,
also derselbe Basistyp und wir haben so eine Liste und wollen damit arbeiten,
dann können wir es mit dieser Liste alles tun,
was man in formalen Sprachen tun kann.
Wir können es betrachten, als die Elemente aller gleichen Types,
als Worte über einem Alphabet, über dem Basislänge des Datentyps.
Da kriegt die Liste, gibt uns alle sinnvollen Teilmengen ordneten Anordnung von Worten über diesen Basistyp.
Wir können aber das auch mathematisch als Mengen betrachten.
Also für beide Zwecke verwenden wir es,
wenn es der Basistyp gleich ist, können wir alles mit diesen Listen machen,
was mit formalen Sprachen machen könnten, Sprachen generieren und so,
das werden wir sehen.
Wir können es als Mengenoperationen betrachten, ist A-Element der Liste,
ist B-Element der Liste der Vereinigung, Durchschnitt und so weiter.
Dann sollten wir dafür sorgen, dass wir in unsere Listen
keine doppelten Elemente reintun. Und für beide Sichten,
als Worte über einem Altarbet oder als Mengen Operationen haben wir in Recket-Zöhne-Standardfunktionen.
So, wie kommen wir an eine Liste? Wir können,
solange sie endlich sind und unsere Geduld reicht,
können wir sie einfach aufzählen. Wir machen ihnen Quattierungszeichen,
Klammer auf, zählen alle Elemente ohne Kommata getrennt auf,
machen das Ganze wieder zu.
In Pro-Log würden sie eckige Klammern nehmen und Kommata dazwischen sitzen.
Ansonsten ist es dasselbe in Grünen, ja? Wir können,
wenn wir die Werte erst berechnen müssen zur Laufzeit,
dann ist es irgendwie ärgerlich, wenn hier Diskutierungszeichen vorsteht,
das unterdrückt ja die Auswertung
In dem Fall nehmen wir die Funktionen List. Das ist
der Konstrukt der Verlisten. Und schreiben wir Ausdrücke rein,
die den Wert ergeben. Also List, dann nehmen wir die Zahl.
Angst zum Beispiel, der Symbolbus. Und das wollten wir
nicht von dem Kopf ausrechnen müssen, zweimal 21,
das wird ausgewertet und noch eine andere Liste als Teilliste.
Ja, und jetzt haben wir wieder Unterliste. Also das
erzeugt uns eine vier Elemente, die gemüsste mit diesen Werten.
Wir wollen oft wissen, wie lang die Liste eigentlich ist,
dann nehmen wir die Längsfunktion.
Einfach zwischen den Klammern gar nichts haben, ist die Lehreliste.
Wir können testen, ob eine Liste leer ist mit der Neilfunktion
1, 2, 3 vom False und hier kommt Tod zurück
. Die Lehreliste ist Polymorph, das ist eine leere Liste für jeden denkbaren Basistyp.
Aber eine Liste, die nur die leere Liste entfällt,
die hat die Länge 1 und ist eben nicht die leere Liste.
Lehreliste hat einen singulären Datentyp und sie erfüllt überhaupt keines
der Basisprädikate, die ich vorhin genannt habe.
Das Prädikat Peer, es war, sobald eine Liste
wenigstens ein Element hat. Also die Lehreliste erfüllt,
kann es
diese Typredikate
Okay. Ja, wenn wir jetzt die Listen einfach haben wollen,
wir wollen eine Liste haben,
die enthält als erstes das Wort, Sinus als zweites,
das Wort 3. Wir müssen es quittieren.
Andernfalls macht Dreckig mit seiner vorgezogenen Auswertung, aha,
da ist eine Klammer auf, nicht quotiert,
dann gucken wir doch mal, was ist das erste Element.
Aha, das ist eine Funktion und die wende ich dann
an aufs zweite Element. Und diese Auswertung müssen wir stoppen,
deshalb ist das Klutierungszeichen wichtig. Also wenn wir das so schreiben,
dann haben wir eine Liste mit der Prestige Jasinus als erstes
Element und dann der drei als zweiten.
Okay, wir müssen auch in der Listenwelt im Reckett natürlich immer
die Klammmann alle schön aufeinander abstimmen, genau wie im Pro-Log.
Okay, Listen können wir mit Appent zu längeren Listen verbinden.
Wir nehmen, schreiben Appent 1, 2, 3,
4, 5, 6, da können beliebig viele Listen drinstehen und die werden alle hintereinander gehängt. In Beweisen,
wenn wir zeigen wollen, dass etwas iterminiert und korrekt ist,
dann können wir uns darauf verlassen, dass Appent so funktioniert,
wenn wir eine Liste XS haben und hängen die leere Liste dahinter ist es dasselbe,
als wenn der erste Lehrerliste nehmen würden,
dann das X ist dahinter hängen und alles ist gleich den Argument Xs.
Zusammensetzung mit dem, die Lehrerliste ist das neutrale Element für Appent.
Diese Konkordination ist auch assoziativ, da können wir uns auch drauf verlassen.
Also wenn wir zweimal nacheinander ein Appent machen,
dann ist es egal, wir können zuerst schreiben,
es fängt die ersten beiden Listen an,
dann ist nächste dahinter oder zuerst das erste und dann die anderen beiden verbinden.
Ja, das ist auch garantiert. Können wir feststellen,
indem wir die Listen mit Equal vergleichen
Mhm. Bei der männentheoretischen Interpretation können wir sagen,
dass dies appent eine Vereinigung zweierlisten ist. Wir haben,
wenn die Mengen keine doppelten Elemente enthalten, dann kommt genau das raus,
was wir bei der Vereinigung zweierlenken müssten hätten.
Und wir können feststellen, ob etwas in einer Liste ist, mit der Member-Funktion.
Ja. Okay. Also Standardfunktion, Member testet.
Okay. Und ja, die würde ich mal nicht alle durchgehen.
Das meiste können sich selbst herleiten. Member ist insofern interessant,
dass es ein Semi-Prädikat ist,
das gibt uns solange wir kein Fragezeichen hinter dem Namen haben,
also wir haben eine Funktion, die soll testen,
ob etwas wahr oder falsch ist, aber der Name hat kein Fragezeichen dahinter.
Wir können sie davon ausgehen, dass es ein Simi-Prädikat ist.
Es kommen nicht notwendigerweise Wahrheitswerte zurück, sondern etwas anderes Hilfreiches.
Wenn du hier meine Liste haben,
die hat die Elemente ein, zwei, drei,
A und vier, und wir wollen jetzt wissen,
es ist fünf in dieser Liste drin, Member 5,
Xes, dann kommt falsch zurück, weil die fünf wurde nicht gefunden.
Aber wenn wir nach dem Symbol A in der Liste suchen,
dann kommt jetzt nicht tot zurück,
sondern der kommt zurück
Teilliste A4. Also Regnet gibt uns die Teilliste ab der Stelle zurück,
wo das Element gefunden wurde. Das ist ja praktisch und
sehr kooperativ, ist ungefähr so wie, sagen wir,
wir fragen unseren Nachbarn, weißt du, wie spät es ist?
Und er sagt ja. Denn es ist nicht hilfreich,
es wäre viel nett, er hätte uns die Uhrzeit gesagt.
Also jemand, der dann immer ja oder nein sagt,
der verhält sich wie ein Prädikat.
Semi-Prädikate sind hilfreicher. Und weil eben,
egal was es ist, solange es nicht fort ist,
wie true wirkt, geht das auch gut.
Wir können Aufrufe von Member
im Wahrheitsausfunktionen verwenden
Ja. Okay. Wenn wir jetzt aber fragen wollen,
kommt die Teilenliste ein, zwei drin vor, dann sind wir böse enttäuscht.
Ein, zwei ist zwar eine Teilliste, aber es gibt
kein Element dieser Liste ein, zwei, ja?
Dagegen. Hier wäre eins, zwei, die Unterliste und das
kommt dann tatsächlich zurück. Wir kriegen die Teilliste,
ab der die Unterliste eins, zwei als erstes Element auftaucht.
So. Alles, was wir jetzt gesehen haben,
um Listen zu erzeugen, auf eine Fleißarbeit rein hinaus.
Wir nehmen ein Fortierungszeichen, schreiben alle Elemente auf oder wir nehmen
die Listfunktion und geben die Konstrukturen für die Elemente an.
Geht alles nur bei endlichen Listen, sonst werden unsere Programme ein bisschen lang.
Das heißt, wir brauchen eine Möglichkeit, um potenziell unendliche Listen zu erzeugen.
Und das ist das Arbeitspferd in der Lispray schlechthin.
Das ist die Kunstfunktion. Ja, das ist der Konstruktor für Paare.
Wir sagen einfach Cons und sagen, bau mir ein Tubel daraus.
Und wenn wir Cons verwenden mit irgendeinem Element und dahinter etwas,
das wir eine Liste dann würden wir zurückzukommen, die Liste,
die jetzt dieses Element als erstes Element hat und die zweite Liste als Restliste.
Und so weiter und so weiter. Wir können mit Cons
immer mehr davor hängen. Das sieht jetzt nach mehr Schreib
auf, wenn auch als die Liste die Elemente anzugeben.
Also das Kunst lohnt sich nur, wenn wir dann in einer Schleife,
in einer Rekursion damit die Listen aufbauen, so lange,
bis sie lang genug sind.
Was ein Cons erzeugt,
ist als Resultat vom Typ her und das Typ Predikat her,
das sagt uns tu, wenn wir gesagt haben,
Cons eins auf die leere Liste
Ja, da haben wir ein paar erzeugt. Das zweite
Argument vom Cons braucht nicht notwendigerweise eine Liste zu sein.
Wir können damit, du kannst ganz allgemein verwenden, um Tupel aufzubauen.
Zum Beispiel, wenn wir sagen würden, Cons XXY,
dann kriegen wir hier ein solches Paar zurück.
Und der Punkt dazwischen, das ist die Infix-Notation vom Cons-Opperator.
Also in Recket ist der Kunst der einzige Infix-Opperator,
den ich kenne, der sagt, ah, ist mit B,
mit YX ist mit Y konstruiert zu ein Paar.
In der Listewelt heißen diese Dinger, dottet fair,
gepunktetes Paar,
der so
einen Punkt drinsteht
Und wenn wir hier so das direkt hinschreiben,
als gepunktetes Paar und den Operator irgendwie zu erwenden,
geht es auch gut, da kommt Truth zurück.
Wenn wir die Kaskade von Consis haben,
dann wäre es in voller Schönheit, würde es eigentlich so geschrieben werden,
ah, gepunktetes Paar, B, gepunktetes Paar,
Punkte, das Partie und so weiter.
Das kann kein Mensch mehr lesen, wenn es lang wird.
Und deshalb haben wir eben in dem Fall
diese Kurzform und Drecke zeigt es uns so.
Aber das ist ein taktischer Zucker, was im Ethan
im Speicher steht, ist genau das.
Also dieser Dot-Opperator,
Infixultation für Cons
So, an die Beispiele können sie sich auch in Ruhe zu Hause mal angucken.
Schauen wir mal lieber drauf, wie wir jetzt unsere gepunkteten
Paare wieder auseinandernehmen. Also wenn wir eine Liste haben,
dann werden wir sie wieder zerlegen können,
indem wir mit der Funktion K das erste Element nehmen,
mit der Funktion Köder, CDR, den Rest.
Ja, Kaliber den Kopf der Liste und CDR,
den Schwanz oder Körper der Liste. Also alle Elemente außer
dem Ersten. Und wir haben die Folgen Zusicherung,
das erste Element von einer solchen Konstruktion aus X und Dixes
, ist das X,
also das erste Argument hier
Der Güttern, das Restelement ist das zweite Argument des entsprechenden Konses,
dass wir in dem Fall Ipsis, von der Lehrenliste ist undefiniert,
der Gütter von der Lehrenliste ist und definiert.
Meistens äußert sich das, indem wir einen Laufzeitfehler gemeldet bekommen.
Und wir können sagen, die Liste XS ist die Konstruktion
aus ihrem ersten Element K und aus dem Rest Imköder.
Diese Funktionen, K und Gütter,
stehen für eine ganze Familie von Funktionen und deshalb werden sie
gerne verwendet
Nehmen Sie mal das C am Anfang und dass er am Ende
als Klammer und dazwischen können abwechselnd bis zu vier verschiedene,
vier verschiedene Zeichen, die entweder D oder A sind, stehen.
Und jedes D oder A steht für einen verschachtelten Aufruf von
K oder Köder. Also wenn Sie in Kurzform schreiben,
C-A-A-R, dann ist es dasselbe, als hätten Sie geschrieben,
K von K voll Yxes.
Sie dreimal A und dann lässt er der K vom K von K
und so weiter, bis zu viermal können Sie es treiben.
Oder Sie können auch die durchnehmen, Creditor,
das Köder von Kötter oder Creditor oder Creditor
Und so weiter. Und sie können auch, wenn es
ihnen zu langweilig wird, meinenselben Buchstaben, die mal wechseln.
Also ganz oft braucht man die Funktion Kados. Das ist
das erste Element der Restliste. Andere Art auf zweite Elemente
zuzugreifen, ja. Oder die Restliste vom ersten Element der Restliste
. K von K von Kütter. Also ich finde,
die ist sehr viel lesbarer, als wenn man es so schreibt.
Und deshalb haben sich diese antiken Namen,
K und Kütter gehalten, für erstes Element und letztes Element.
Sonst gibt es eigentlich keinen logischen Grund,
dass man die Funktion fürs erste Element Auto tauft
Wie holen wir das denn als Junggut sein, die Schachtel,
bringe ich jetzt zum Beispiel C-A-A-D-R-Scheibe, ist es dann die Karre-Karte?
Also Sie können das expandiert schreiben für jedes D- und A in der Reihenfolge,
bis hier stirbt, kriegen Sie diese Aufrufe C-A-D-R-Chaos da.
Genau, ja. Alles andere wäre zu abstrus.
Und mit diesem Konstruktor, wir nehmen Cons,
um etwas für eine Liste dazuzufügen und Kötter und K,
um es wieder zu zerlegen in die Bestandteile,
haben wir die Basis um Listen
rekursiv aufzubauen
Also wir, und potenziell unendliche Listen bauen wir,
indem wir mit einer Lehrerliste anfangen, dann mit Konst etwas davor tun,
mit Konst noch was davor und Konst noch was davor.
Und wenn wir raufgucken und es zerlegen mit K und Köther,
haben wir als Resultat immer etwas,
was ein erstes Element hat und ein Rest.
Und das erinnert mich sehr daran, wie so ein Amonit aussieht.
Der wächst und wächst immer ein Schecht zu viel mehr davor,
der Rest ist schon ein Amonit, aber wenn Chef durch ihn davor kommt,
bleibt der Rest immer noch ein Amonit.
Quicktime geht schon wieder nicht mehr. Gehen wir mal.
Ich habe das Movie woanders
Okay. Spielen das mal. Die Con-Version hat nur leider
keine Musik. Wir bauen den Ammoniten einfach rekursiv auf,
immer nochmal ein Stinks davor, ein Links davor,
ein Element davor. Und wir sehen, wir bauen Listen,
indem wir immer etwas davor setzen in einem Schritt auf ein
Bestehendes,
was Struktur gleich ist
Lange nicht machen genug, leider. Und wir bauen es
auch wieder so ab, indem wir immer ein Element wegnehmen,
solange bis wir bei der Restliste angekommen sind.
Ja, also,
wir nehmen das Cons zur Konstruktion und dann kriegen wir eine rekursive Struktur,
indem wir sagen,
die Liste ist entweder die Lehrerliste oder eine Konstruktion aus dem
ersten Element und irgendeiner Liste,
inklusive der Lernliste
Und also, wenn wir dann zugreifen auf die Liste,
dann kriegen wir in jedem Schritt immer ein erstes Element in
dem Venkar nehmen und dann kriegen wir so eine Blackbox mit
dem Kütter und mit der reingucken wollen,
müssen wir wieder den Kran nehmen und dann wieder den Kütten.
Ich bin K vom Kütter und so weiter und so
hangeln wir uns durch die Liste durch.
Ich weiß, ich nehme mal einen Schritt.
Gut. Ich habe es mal einmal
Animieren lassen, weil bis hier wäre sinngemäß eine Liste,
ne? Wir haben den K, das erste Element und
den Köder ist wieder eine Liste, ja?
K. Äh, muss ich mal ölen. Wieder die Liste.
In jedem Schritt für das Ding kleiner, was auch sinnvoll ist.
Es soll ja irgendwann charminieren. Und sie sehen,
also das, was ich hier in Russland gekauft habe,
im Kloster. Es ist sehr gut für Recketlisten geeignet.
Es sind nicht alle Elemente sind typgleich, ne?
Also, und so weiter und so weiter
Also, wenn wir hineinschauen könnten und es aufsägen,
das wollte ich mit meinem kunstvollen Objekt da nicht machen,
dann sehen wir innen drin eben geschachtet,
soweit wir reingehen, die Elemente stecken hier.
Und jedes für sich können wir wieder als Liste betrachten und es aufbauen.
Okay, Listen sind besonders nützlich, wenn wir damit Textverarbeitung machen wollen. Ja,
also wir haben gesehen, wir können mathematisch,
können wir es als Mengen betrachten, dann können wir uns überzahlen,
Gedanken machen oder Mengen von bestimmten Objekten, okay,
wir können es Aber auch als Wort wie beim Alphabet betrachten.
Und dann können wir Listen eben für ein Jahr wirklich mächtige Textverarbeitung machen,
was sehr, sehr schnell geht und wo wir auch über mit Symbolen hantieren können.
Und easy hingehen und alle Daten,
wenn es um einen Text geht, als dringend hinschreiben,
da müssen sie stringtokenal sehr verwenden und recular Expressions und so weiter,
schreiben sie es einfach als Liste von Worten.
Und die Syntaxanalyse in Record nimmt es ihnen auseinander und liefert
ihnen die einzelnen Worte einfach als Symbole in einer Liste.
Also wenn wir, sagen wir mal,
über Namen nachdenken wollen
Ja, der welterste Programmiererin, nee, die Eda,
könnten wir sagen, die feinen Eda,
Eda Account ist of loveless, ne?
Und nachdem wir nach ihrer Heirat,
wo sind wir noch einen weiteren Lady-Titel hätte,
können wir nochmal Lady davor hängen mit Conslay.de,
der Account ist of Lovelist hier.
Oder wir wollen zwei Dinge verbinden, können damit auch mit
Appent machen. Wir können Listen bauen und so weiter.
So, wenn auf dieser Liste mit Symbolen können wir
auch die Lenksfunktionen anwenden
Aber bittet tun Sie mir einen Gefallen,
wenn Sie feststellen wollen, ob eine Liste leer ist.
Unsere Übungshelfer, die rasten echt aus, wenn man hingeht,
wenn eine Liste mit 10 Millionen Elementen zu fragen,
ist die Länge gleich null, wenn man wissen will,
ob sie leer ist.
Verwenden Sie die NAL-Funktion, weil die Längstfunktion zählt erstmal alle 10 Millionen durch.
Und das könnte etwas aufwendig sein. Also immer fragen,
NAL, das sagt Ihnen sofort, ob sie leere Liste ist,
wenn sie längst aufrufen, dann denkt Practice,
sie wollen ja erstmal die Länge ausrechnen.
Gut. Ja, und hier kommen wir jetzt,
also nach den Bestandteilen,
Fragen mit K und Kutter und so weiter,
wie wir
es besprochen haben
Schreiben wir mal unser erstes Programm mit Namen und die jetzt für Namensdrinks stehen sollen.
Ja, wir wollen feststellen, was ist der Nachname eine Person?
Und dafür sagen wir einfach der Nachname, nehmen wir mal
an, ist immer das Letzte im langen Namen.
Also können wir es so definieren? Wir drehen den Namen
um mit Triverse und nehmen dann das erste Element vom umgedrehten Namen.
Es klappt ganz gut, wenn wir jetzt zum Beispiel für
Charles Babbage fragen, was ist der Nachname?
Lars Leben von Charles Babbage kommt der Bitch raus
Und bei Edie, der Account ist of Lovelisher,
verliert alle Adelstitel für den Nachnamen, aber egal, kriegen wir Lovelis raus.
Bei Grey Sopper würden wir Rear Admiral Griss Mary Hopper nehmen,
kriegen wir Hopper, bläst Pascal und selbst für ihre Tostbindes,
wo ich gar nicht weiß, ob das Nachnamen oder Vorname war,
weiß das jemand, kriegen wir ihre Tastelis wieder raus.
So, jetzt sollen wir den Vornamen haben. Na gut,
der Vorname bei simplen Damen könnte der erste sein,
hier hängt der Samuel dann einfach kein Name, oder würden wir,
weil First nehmen von Charles Babbage geht, gut,
First nehmen von der Lonzo-Chirt, geht Gut, ja.
Also eigentlich haben wir hier nur die Funktion K,
umbenannt in First nehmen oder ihr einen zweiten Namen gegeben.
Das sollten sie aber immer machen. Selbst wenn es nur
ein Umbenennen ist, wenn sie damit dokumentieren, ja,
ich möchte an dieser Stelle jetzt einen Vornamen haben.
Gut, wir machen jetzt, legen uns jetzt mal
eine kleine Datenbank von berühmten Informatikerinnen und Informatiker an,
ja, als Liste. Nennen wir Computerscientists, Quote,
Klammer auf und jetzt haben wir eine Liste von Unterlisten
und da stehen jetzt all die Namen drin,
die wir eben schon mal eingeführt haben
Wenn wir jetzt wissen wollen, ist jemand ein Computer-Scientist,
also Informatikerin oder Informatiker, dann wollen wir unsere Liste von Namen durchsuchen.
Und dafür halt dreckig die schöne Funktion Essoc. Ja. Achso,
der geben wir einen Suchschlüssel und dann eine Liste von Listen
und Essoc vergleicht den Suchschlüssel mit den Einträgen in der Datenbasis.
Er sucht das erste Paar, dessen erstes Element mit
dem Schlüssel übereinstimmt. Also wenn wir jetzt wissen wollen,
ist Ellen Thüringen ein Computer-Scientist, kommt er hier vor,
Ich glaube, hier hatte ich ihn noch nicht drin.
Ja, denn, können wir hier mit Esther suchen,
der Rechner? Als Schlüssel nehmen wir das Symbol Allen
und dann bekommen wir Allen Thüring zurück, ja.
Wenn wir seinen Nachnamen haben wollen, sie sagen,
wir lassen von Esther Allen im Computerscientist und wir kommen dann in Thüringen.
Wir finden den ersten Eintrag bei Esther. Und dazu haben wir noch Zeit,
ha, gut, das verwenden wir jetzt mal,
um tatsächlich ein bisschen mit formalen Sprachen zu hantieren.
Also wir haben jetzt gesehen, dass wir Listen von Listen
machen können und das können wir als Liste von Sätzen verstehen und so weiter.
Und wir schreiben jetzt mal als erste kleine Übung ein Programm,
mit dem wir den Computer dazu bringen,
nach einer gegebenen Grammatiksätze von sich zu geben.
Wir geben ein Thema vor und soll also,
stellen Sie vor, Situationen Party geplaudert. Jemand sagt einem,
was man möchte, ohne dass man eigentlich zuhört, irgendwas antworten.
Irgendwas von sich geben, was aber grammatikalisch korrekt ist.
Und deshalb sagen wir, egal was an Worten kommt,
ein Satz soll aus einer Nominalphrase und einer Verbfries bestehen.
Und die Non-Fries, das soll halt irgendein Artikel sein und
ein Rückstandship
Werbfräs ist ein Verb und dahinter noch irgendein Objekt,
auf das man es anwendet, noch mal wieder eine Nown-Frace.
Der Wortschatz von unserem automatisch sprechenden Computer ist ein bisschen begrenzt,
aber für die Party sollte es reichen.
Also das Symbol Artitel binden wir anders. Als Substantive lassen wir
zu Manwall, Woman, Schäbe. Und als Werben kennt er
die Worte Hittuk zu How neigt und vielleicht ein paar mehr.
So, mit dieser Grammatik können wir jetzt loslegen und Sätze bilden.
Ableitungsbaum. Also ich hoffe, sie haben alle schon
so weit in formalen Grundlagen der Informatik das mitgemacht,
dass sie wissen, gehst du einen Ableitungsbaum bedeutet.
Wir haben unsere Grammatik, haben ein Staatssymbol und sagen,
okay, im Zentren ist noch unsere Grammatik, ist entweder dies oder das.
Es ist dies zusammengesetzt mit Wordfress. Und für Non-Press
können wir jetzt einen Artikel nehmen und einen Nomen.
Und dann nehmen wir aus der Menge der Terminalsymbole,
was wir so haben und haben jetzt abgeleitet, The Women's Sortherman.
Schöner englischer Satz. Okay. Und können wir zu Fuß
machen immer wieder und dann mit Sätze generieren, aber zu viel einfacher.
So ein Ableitungsbaum wird für uns von einem Bracket-Programm hergestellt.
Diesen Ableitungsbaum
Den können wir jetzt auch wieder rekursiv sehen. Und das bringt uns sein,
dass wir alles mit Listen machen können. Also rekursive Definitionen,
der Abgleitungsbaum ist entweder ein einzelner Knoten mit einem Terminalzeichen.
Blatt des Baumes. Oder aber ist ein Knoten mit der
linguistischen Variablen, Nowen, Sentance und so weiter.
Und daran hängen Teilbäume. Und der Knoten heißt Wurzels.
Wenn er keinen übergeordneten Knoten hat, sehen wir schon mal
für Informatiker, stehen solche Abgleitungsbäume immer auf dem Kopf.
Nur die Wurzel ist immer oben, wenn es gezeichnet wird.
Und sie wachsen nicht in den Himmel,
sondern gehen nach unten
Ich finde, Escher hat das ganz gut gezeichnet in seinem Drei-Welten-Bild.
Da sehen wir die Bäume, die nach unten wachsen im Wasser.
So, jetzt als Programm, damit uns Brackets abnimmt, das Partygeschwätz hinzukriegen.
Wir suchen ein Programm, das jetzt zufällige Sätze mit dieser Grammatik erzeugt.
Und der direkte Lösungsansätze, der funktionalen Programmiersprache ist,
dass wir für jede Regel aus unserer Grammatik eine Recket-Funktion schreiben.
Und das Verfahren ist bekannt im Compilerbau als rekursive Abstieg.
Nach der Art kann man eben Programme analysieren,
das ist zum ersten Mal richtig schick gemacht worden in der
Programmiersprache Pascal oder auch automatisch Programme erzeugen.
Das ist gut. Also um jetzt den rekursiven Abstieg für
unsere Grammatik in Rackett hinzukriegen, dann nehmen wir die Tabinalsymbole,
ich gehe nochmal ganz kurz zurück bis zu der Stelle,
wo wir gestehen hatten, also The of Man World und so weiter.
Dafür nehmen wir ein Racket-Symbole. Und für jede dieser Nicht-Klaminalsymbole,
die metallinguistischen Variablen, schreiben wir eine Funktion,
die versucht, das,
was hier rechts steht,
zu machen
Geld. Also die Sätze der Sprachen werden zu listen und
die Regeln werden zu Funktionen und für die Komkartonation
nehmen wir das erpennt und dazu sind wir fertig.
Das Aufgabenblatt, was ich heute verteilen werde,
was dann so im Laufe der nächsten Woche bearbeitet werden soll,
das verwendet genau, für das sollten sie genau dieses Verfahren verwenden,
um andere Dinge damit zu machen, ja.
Also die neue Aufgabenblatt 4, was rauskommt, das ist eins,
an dem sie üben sollten, Etwas mit einer Grammatik zu beschreiben.
Und dann ein Programm zu schreiben, das setzte dieser Grammatik automatisch erzeugt.
Ja, gucken wir mal. Nach den metallinguistischen Variablen,
die wir gesehen haben, und den Regeln dazu, hatten wir doch gesagt,
ein Satz besteht immer aus einer Nonfields und einer Worffress.
Ja, wir definieren ja eine Funktion Zentenz, die hat überhaupt keine Argumente.
Ja, sondern, damit ich einen Satz bekomme,
mache ich einen Appent vom Aufruf der Funktion Nonfrist,
die erzeugt mir eine Nominalphase, entsprechend unserer Grammatik oder eine Worprace.
So, jetzt muss ich definieren,
dass Nonfrist tun soll
Da stand in unserer Regel doch,
dass wir einen Artikel und dann ein Substantiv haben sollen.
Also macht sie einen Appent von dem, was Artikel zurückgibt,
Article und Now. Beim Serb kriegen wir einen,
bei der WordPress bekommen wir einen Werb zurück von der Funktion Werb und dahinter
hängen wir mit Appent die Liste, die Nowenpress zurückgibt.
So, ein Artikel, der muss jetzt endlich mal was
tun und uns Worte besorgen. Und alle zulässigen Artikel,
die wir haben, das sind Tür und in dieser Liste
und wir rufen dazu die Funktionen,
wann auf die zufällig eins von diesen beiden nimmt.
Für substantiv werden wir wann auf Menwall,
Themen Table
Und beim Verb, Then of Hittuk zur liked.
Und fertig ist unsere Grammatik in Reckett geschrieben und die kann
uns Sätze erzeugen. Die Sprache, die Grammatik ist endlich,
die Sprache ist endlich, weil wir noch keine Rekursionen drin haben.
Mit Rekursion wird es richtig spaßig. Wir müssen wann oft
noch definieren, es ist keine Standardfunktion.
Das können wir einfach machen. Wir übergeben hier eine Liste,
die habe ich hier Set getauft und rufen auf die Funktion.
Random-Element, die eins nimmt und geben eine Liste zurück
Die dieses einzelne Element einhöhlt,
das mir die Liste zurückkriegen und nicht das Element selbst.
Und Rennen-Element besteht jetzt im Aufruf der Standardfunktion Listrep.
Listrep bekommt eine Liste und anschließend den Index in der Liste,
den wir haben wollen.
Also Choices sind die möglichen Elemente, die hier übergeben werden.
Und für die Position rufen wir die Funktion random auf.
Mit der Länge der Liste. Ja,
damit kommen Werte zwischen Null und dem letzten Element
So, und damit können wir zufällig, also aus diesen Listen
dann ein Element auswählen und damit unseren Satz aufbrauen spielen,
wenn wir da mit.
Das erkläre ich später. Okay, also Sentence. Ja,
wir sagen einfach Sentence und als erstes kommt vom Ableitungsbaum heraus,
okay, zusammengesetzte Woman his aball.
Sentence the ball like the woman, e woman,
rough fris, so e woman.
Oder wir testen jetzt mal die Funktion Nown,
Komfort zurück, Sentence the Woman saw the ball.
Und sie sehen auch, dass dieses hier,
sehr random ist, vermehrtes Aufrufen von Sentence produziert,
meistens verschiedene andere Sätze
als vorher
Okay. Wir können uns jetzt mal anschauen,
was Srecket macht, wenn wir da einen Tris reingeben.
Also schreiben Sie am Anfang Geseckett-Programmes, Require, Recket Claesias.
Und dann sagen Sie, welche Funktionen Sie verfolgen wollen.
Drees, Sentence, Non-Frace, Love, Friss, yes.
Und stimmt, dann wird's Non-Frace, sehen wir,
wie Aufruf verschachtelt lumpft. Non-Frace, Swift Artikel auf,
Artikel, liefert das Element A zurück. Ja,
und dann wird als nächstes von Non-Frace 9 aufgerufen und dann
kommt Ball zurück und Your Ball, der Artikel davor gesetzt.
Und wir haben das Ergebnis, wenn sie genug von Dresden haben,
sagen sie Andres und nehmen das raus,
was sie nicht mehr sehen wollen
Und da können wir die ganze Aufrufverschachtelung im Threes mal sehen,
bis wir beim Satz angekommen sind.
Und wir sehen, wir nach und nach die Regeln angewendet werden.
Okay. Ja, die Sprache ist, wie gesagt,
endlich und damit wird der, ist die Sprache auch nicht blumig genug.
Also es fehlen noch ein paar schmückende Worte wie Adjektive und so, ja.
Die ist vielleicht eindrucksvoller machen könnten. Wir erweitern die Grammatik
jetzt und zwar so, dass wir jetzt die Sprache rekursiv definieren.
Also wir führen noch Adjektive ein und Präpositionen,
damit wir nicht nur substantive und werben haben,
die sind Knochenhakenstiel,
sondern bis
die blumiger werden können
Es bleibt dabei,
der Satz ist eine Non-Freest gefolgt von der Wordfrace und die Non-Freest,
seinen Artikel, aber zwischen Artikel und Substantiv,
da können wir jetzt beliebig viele Adjektive reinschieben.
Entweder gab es eins oder Adjektivstern, das ist die kleine Sternennotation.
Das kann also leer sein oder aber wir nehmen
ein Adjektiv gefolgt von einer potenziell leeren Liste von Adjektiven.
Und bei der Wordfrist lassen wir jetzt noch das Präpositionen zu.
Und dahin kommt eben Sprepositionen in die Liste von möglichen Präpositionen.
Und als Adjektive lassen wir zu Big Little Blue Green
to in by with
Und der Rest bleibt gleich. Okay. Also die kleine Sternennotation kennen Sie ja,
denke ich mal, aus den formalen Grundlagen der Informatik.
Jetzt müssen wir dieses Adjektiv stern programmieren.
Also entweder soll da ein Adjektiv kommen oder keins.
Und wenn eins genommen wurde, soll man rekursiv wiedergucken,
vielleicht noch eins mehr und so weiter.
Und da würfeln wir einfach. Bremdem 2 gibt um Zahlen
zwischen 0 und 1, wer das gleich 0 ist,
nehmen wir kein Adjektiv.
Andernfalls machen wir ein Essent von einem Adjektiv
und hängen dahinter Adjektivstern.
Genauso bei Pipis da
Rennendem Element tue oder voll. Und machen einen Appenge,
wo wir wenigstens eins nehmen und dahinter vielleicht noch ein anderes hängen.
So. Und jetzt hat sich die Nordenfries ein bisschen geändert.
Wir müssen noch diese PP-Dinger damit reinbauen. Ansonsten,
und die Abjektive. Und die Präpositionen da reintun. Wenn
wir jetzt Zensins aufrufen, könnten wir zum Beispiel kriegen,
Öwoman Byronman, Hit it taper.
Ja, das ist auch by the mervest time,
like,
it's even that
you do
Okay. Online-Turk-Libbling, my turk-Libbling, my turk-Libbling,
my turk, my turk, my, my,
my, my, my, my, my,
die, die, die Grammatiken sehen, jetzt,
die Sätze werden länger und länger,
als wenn wir Pech haben, hört es nicht mehr auf,
ne,
für die Rekursion keine Abbruchsbedingungen vorgesehen,
es wird immer gewürfelt
Okay, aber verwenden Sie das Schema bitte für das Aufgabenblatt,
was Sie heute ins Netz stellt?
Dann sollen Sie selbst eine Sprache erzeugen und die hätten
Sätze erzeugen und seine Ausgaben halten sich an der Schema.
Ein wichtiges Thema, noch, oh ja, Mensch, haha.
Zehn Minuten haben wir immer noch. Wir haben jetzt drüber gesprochen,
dass es Datenobjekte gibt und das Zahlen und so weiter.
In der funktionalen Sprache in Randkultur sind Zahlen selbst eigentlich auch nur syntaktische Schätzungen.
Wenn sie eine wirklich reine funktionale Programmiersprache haben,
wird man zunächst mal die Zahlen gar nicht implementieren.
Weil die Mathematik hat es doch gezeigt, wir können die Zahlen rekursiv konstruieren.
Es reicht die natürliche Zahl, eins zu haben. Irgendwas,
was wir eins nennen, dann können wir rekursiv die Nachfolger dazu schaffen.
Und wenn wir natürliche Zahlen haben, haben wir schon gewonnen,
dann können wir nämlich auch Rationalzahlen machen.
Und dann reelle Zahlen und so weiter. Dass man das
als eigenen Datentyp einführt mit eigenen Operationen und so Eigenkonstruktoren,
das ist eigentlich ein ziemlicher Luxus. Man braucht es allerdings,
wenn man nicht zur Gruppe der geduldigen Menschen gehört,
wenn man ein Rechenergebnis noch im selben Jahr erfahren möchte,
dann würde man die Zahlen nicht unbedingt regulsiv bauen wollen.
Und deshalb werden Sprachen, die für die praktische Anwendung gedacht sind,
immer die Zahlen so implementieren, dass die Arrithmetik der Maschine genommen wird,
um auch zu rechnen.
Aber wir könnten Zahlen und Listen rein funktional für Beweise,
so als Objekte definieren. Also, indem wir zunächst mal,
die uns die Funktion Konstilisten aufbaut, bauen.
Und dann können wir die Zahlen, wenn wir Listen erzeugen können,
ja, auch Lusten sind Schalle drauf,
da brauchen wir eigentlich auch nur Funktionen.
Dann können wir eine Liste mit zehn Werten drin, als die Zahl 10 nehmen.
Die Liste mit 100 Werten, als die Zahl 100 und so weiter.
Und fangen wir mal an. Als erstes,
uns sind Daten zur Liste zu bauen und dann werden wir,
wenn wir über Piano-Aktionen noch mal kurz sprechen, auch sehen,
wie wir die jetzt zu den Zahlen kommen.
Also, wir sagen eine Konstruktion von zwei Werten,
also der Konstrupperator, ah, Punkt Baby werden gesehen,
haben Infixnotationen oder Konstruktion, ja, A, B,
kriegt zwei Argumente und soll uns ein Paar zurückgeben
Das machen wir in Reckett. Ganz einfach, indem wir
eine anonyme Procedure zurückgeben. Ein Land der Ausdruck.
Mike Kunz bekommt die beiden Argumente Head und Ziel.
Das erste Element und den Rest. Und was zurückkommt,
ist eine Funktion, die uns auf Aufforderung,
entweder das Kopfelement oder den Rumpf geben kann.
Diese Funktion steht hier. Die bekommt einfach eine Nachricht.
Was soll ich tun? Willst du den Kopf oder willst
du den Körper der Liste? Parameter ist Message, Land
der Message. Und wenn diese Message ein Haar ist,
dann kriegen wir Den Kopf der Liste zurück oder aus diesem Tubel,
den Kopf, das erste Element.
Und wenn das die Nachricht Tee ist, kriegen wir den Tale,
das M. Den Schwanzbody oder wie auch immer.
Also einen Kunz liefert uns eine Funktion zurück,
die uns auf Wunsch die beiden Teile wieder beschaffen kann.
Wenden wir sie mal an, wenn wir hier sagen,
exist my cons 1, 2. Das echte Kunst würde uns,
Klammer auf, 1.2 zurückgeben.
Was wir hier zurückbekommen, ist dann ein Xis.
Und dieses Xis, das können wir fragen
Ja, kriegt die Nachricht aber halt, dann kriegen wir
die eins zurück, reginarité, dann kriegen wir die zwei zurück.
Und wenn wir das jetzt noch einhöllen, ja,
eine Funktion Maika, von X ist mein erstes Element,
das heißt, sende den Funktion Maika,
von X ist mein erstes Element, das heißt,
sende den Objekt, X ist die Nachricht haar und wir kriegen die eins zurück.
Das sieht jetzt ein bisschen wie Spielerei aus, aber das Objektsystem,
mit dem wir nach Weihnachten arbeiten werden in Recket,
also das Kommandos Object System, was zu Recket portiert worden ist,
wenn wir das verwenden, dass die Implementation Von Objekten und Nachrichten,
genau über diese Closures gelaufen.
Ja, ein Objekt in Zählers ist eine solche Closure.
Ein Landerausdruck, der als Resultat einer Funktion zurückkommt und das
in seiner Bindungsumgebung sich noch dran erinnert,
was denn der Wert von Head und Zill war.
Es ist definiert worden im Lokalen im Kontext an der Funktion,
wo die Variablen Head und Zill definiert sind.
Die Closure in ihrer Bindung kennt sie doch und können sie
jederzeit verwenden, selbst wenn wir das Ganze außerhalb dieses Definierenden
Aufrufs aufrufen
Diese Bindungsumgebung ist da und genau auf diese Weise ist das Objektsystem,
sind die letzt, ist eigentlich alles implementiert.
Was sich an Werte erinnert, Werte zurückgeben muss.
Und dieser Nachrichtenstil ist da auch ganz typisch drin,
gäbe dieser Closure eine Nachricht, ich brauche den Schwanz,
ich brauche den Kopf und dann kommen die Werte zurück.
Wenn es funktional aussieht, hüllen wir das in Funktionen ein,
wie Maika. Okay. Wie es das Ganze implementiert,
die Repräsentationen von Listen,
die sollte man verstanden haben,
damit man nicht
unnötig viel Rechenaufwand verschwendet
Dass eigentlich in der ganzen Liste Welt so implementiert,
wie wir es kennen, auch in Sprachen,
wo man einfach Referenzen hat zwischen den einzelnen Zellen.
Die Basis in allen Lispdialekten ist, dass eine Liste immer aus einer Kunstzelle besteht.
Und das ist einfach eine Zelle, in der eine Referenz
aufs erste Element und auf dem Rest der Liste ist.
Und so geht es weiter, in der die Liste rekursiv aufbauen,
um immer wieder neue Kunstzellen,
das erste Element und den Rest und so weiter
Wichtigste Frage bei Listen ist, wann sind die eigentlich gleich?
Das hängt jetzt, das können wir uns gut erklären an diesem Kunstzellenbeispiel.
Wenn wir wissen wollen, ist A gleich B. Wollen wir
da wissen, ob es wirklich dasselbe Objekt in denselben Speicherzellen ist?
Oder wollen wir wissen, ob sie nur gleich aussehen?
Oder ob sie sich gleich verhalten? Wenn sie gleich ausgebaut
sind oder gleichgedruckt werden. Es sind alles unterschiedliche,
gerade von Gleichheit und für die unterschiedlichen Grade von Gleichheit
gibt es auch unterschiedliche Gleichheitsprädikate
Listen ist es, können wir es uns an diesem Beispiel,
wie wir immer vorstellen, wir definieren hier eine Liste X,
hat die Elemente, wandern zu.
Wir definieren eine Liste Y,
auch weinen und zu und wir definieren eine Liste Fett,
in dem wir sagen, die ist,
hat denselben Wert wie X. Gedruckt wird alles,
als wandern zu.
Sehen völlig gleich aus, ja. Sind sie jetzt identisch
im Sinne von der Funktion EQ,
die auf Identität vergleicht oder sind sie einfach nur sie cool?
Und das testen wir
gleich mal
Wir können das mit Kennzellen so vorstellen, diese erste Liste hier.
X hat die eine Konzelle, die zeigt auf wann.
Die nächste Zeit auf 2. Y hat eine Kunstzelle, die zeigt auf wann.
Eine zweite, die zeigt auf die. Wir sehen,
wann und tue, sind identische Affekte, auf die sich
beide Listen beziehen, aber Y hat unterschiedliche Kunstzellen.
Y ist nicht identisch zu X. Es ist im Sinne von EQ.
Es ist identisch im Sinne von EQ, aber nicht EQ.
Fakt dagegen zeigt auf dieselbe Folge von Kunstzellen und is
identisch zu
Ja. Also Identität in dem Fall bei Listen überhaupt bedeutet,
sind es dieselben Objekte im Speicher? Wenn wir jetzt die Konnsoperationen durchführen,
dann wird in der funktionalen Programmiersprache viel gespart und nicht alles kopiert.
Das Kunst würde hier einfach nur ein weiteres Element davorhängen.
Der Rest hier zeigt auf die bestehende Liste, die wir schon haben.
Und ab da wären die Listen identisch. Für die Liste,
die hier beginnt, genauso wie für die, die hier ist.
Also ein Kunstaufruf erzeugt genau eine Kunstzelle und die enthält die
Referenz auf den Kopf und den Körper der neuen Liste.
Und der Körper der neuen Liste ist immer identisch.
Und das zweite Element mit dem, was in Konts übergeben wurde.
Wenn wir jetzt hingehen mit Modifikaturen und in den Elementen einer Liste herummanschen,
dann kann es sehr gut sein,
dass wir damit alle anderen Listen auch verändern,
die über Referenz denselben Teil der Liste verwenden.
Deshalb ist das bei Listenoperationen sehr gefährlich, imperative Sprachelemente zu verwenden.
Außer wir wissen genau, was wir tun.
So jetzt die Gleichheitsfunktionen, die sind noch bekennen sollten.
Denkt mir mal an George Orwells schönes Zitat aus Animal Form.
All Animals are equal, but sub animals are more equal, then others.
Wir haben die Gleichheitsprädikate, haben wir in Recket,
einmal EQ, das ist wahr für identische Objekte.
Ja, wenn wirklich etwas identisch ist,
dann sagt uns die EQ-For-Uktion, ja, EQV,
es war für identische Objekte oder gleiche Zahlen- und Wahrheitswerte.
EQ ist tatsächlich nicht unbedingt wahr, wenn wir zweimal
eins vergleichen
Equal, es war für Objekte, die EQV sind,
oder für Listenmengen des Drinks, mit Elementen,
wo die Elemente in dieser Liste jeweils das EQV-Predikat erfüllen.
Gleiche ist für humerische Werte da. Und String,
Equal ist für gleiche Zeichenketten da. Die Funktionen,
die wir verwenden, Member, Assoc und so weiter,
die gibt es jetzt mit verschiedenen Ausprägungen,
wie die Gleichheit getestet wird, wenn ich Messkristen will,
ob etwas in der Liste ist, mit der Member-Funktion,
die sie natürlich sagen, wie verglichen werden soll.
Und das noch Es gibt Member,
das Vergleich mit Yquill, wenn wie vergleicht mit eQV.
Und wenn ein Few vergleicht mit eQ. Also wenn sie Intellisten suchen,
müssen sie auch noch dazu sagen, wie verglichen werden soll.
Okay, dann danke erstmal für heute für die Aufmerksamkeit.
Bis zum nächsten Mal