Lambda Kalkül für Javascript
  • Lambda Kalkül für praktisches JavaScript
  • Einfache Kombinatoren
  • Church Encodings - Booleans und Zahlen
  • Der lambdafizierter Taschenrechner
  • Immutable Stack
  • Immutable Stack Erweiterungen
  • Immutable ListMap
  • Observable
  • Either
  • Maybe
  • Box
  • Benchmark und unsere Erkenntnisse
  • Test-Framework
  • Code Convention
Powered by GitBook
On this page
  • Beschreibung
  • Kern des lambdafizierten Taschenrechner
  • Rechnen mit Zahlen
  • Rechnen mit Church Encodings-Zahlen
  • Die Probleme mit den Church-Zahlen
  • Taschenrechner User-Interface
  • Eigenschaften des lambdafizierter Taschenrechner

Was this helpful?

Export as PDF

Der lambdafizierter Taschenrechner

PreviousChurch Encodings - Booleans und ZahlenNextImmutable Stack

Last updated 2 years ago

Was this helpful?

Beschreibung

Ein Einstieg-Projekt, um sich am beste mit den und den auseinander zusetzen, ist Taschenrechner daraus zu bauen.

Link zum lambdafizierten Taschenrechner:

Kern des lambdafizierten Taschenrechner

Eine Verkettung der arithmetischen Zahlen und Operationen.

Als Helferfunktion gibt es einen sogenannter CalculatorHandler, mit dem solch eine Verkettung von Konstruktion ermöglichen.

const calculatorHandler = op => n => k => f => f(op(n)(k));

Der calculatorHandler nimmt jeweils eine arithmetische Operation (Addition, Subtraktion, Multiplikation usw.), zwei Werte und zum Schluss eine Funktion entgegen.

Rechnen mit Zahlen

Um mit Zahlen zu rechnen reichen die Arithmetischen-Operatoren (+, -, * etc.) von JavaScript:

const plus              = n => k => n + k;
const multiplication    = n => k => n * k;
const subtraction       = n => k => n - k;
const exponentiation    = n => k => n ** k;
const division          = n => k => n / k;

// example
plus(1)(2)            // 3
multiplication(2)(3)  // 6 
subtraction(5)(2)     // 3

Mit dem CalculatorHandler und den Arithmetischen-Operatoren kombiniert, ist es möglich via Point-Freestyle aus den vorhing erstellten Operatoren neue Funktionen zur Berechnung zu erstellen:

const add   = calculatorHandler(plus);            
const multi = calculatorHandler(multiplication);  
const sub   = calculatorHandler(subtraction);
const pow   = calculatorHandler(exponentiation);
const div   = calculatorHandler(division);

Anwendung der Operator-Funktionen

T(1)(add)(2)(pow)(6)(sub)(2)(div)(8)(add)(7)(multi)(4)(sub)...
T(1)(add)(2)(id)                     //   3
T(1)(sub)(2)(id)                     //  -1
T(5)(multi)(4)(add)(2)(id)           //  22
T(5)(div)(5)(multi)(100)(add)(1)(id) // 101

Um die Leserlichkeit des Code zu verbessern, wird für die Trush- und id-Funktion ein passender Variablename gewählt.

Implementation (Umbenennung):

const calc   = T;
const result = id;

Beispiel:

calc(5)(multi)(4)(sub)(4)(pow)(2)(div)(8)(add)(10)(result) // 42

Rechnen mit Church Encodings-Zahlen

const churchAdd     = calculatorHandler(churchAddition);
const churchMulti   = calculatorHandler(churchMultiplication);
const churchPow     = calculatorHandler(churchPotency);
const churchSub     = calculatorHandler(churchSubtraction);
calc(n5)(churchMulti)(n9)(churchAdd)(n4)(churchSub)(n7)(result) // n42

Die Probleme mit den Church-Zahlen

Church-Zahlen encoden

Chuch-Zahlen sind Nested-Funktionen und es ist schwer mit blossem Auge zu entziffern welche Zahl sich hinter versteckt. Schon nur die Church-Zahl n7 gibt dir diese Funktion:

f => a => f(f(f(f(f(f(f(a))))))); //n7
jsNum(n42) // 42

Negative Zahle

Was der lambdafizierter Taschenrechner im vergleich zum JavaScript-Taschenrechner nicht kann sind mit negative Zahlen rechnen, da Church-Zahlen nur Werte der Natürlichen-Zahlen repräsentiert werden kann:

calc(1)(sub)(7)(result)         // -6

calc(n1)(churchSub)(n7)(result) // 0 bzw. n0

Division

Gleiches Problem wie mit den negativen Zahlen, können die Church-Zahlen keine Rationale-Zahlen repräsentiere. Deswegen gibt es keinen lambdafizierten Division-Operator.

Maximum call stack size exceeded

Bei Berechnung mit grösseren Church-Zahlen und längerer Verkettungen kann es zu einem Maximum call stack size exceeded - Error kommen:

calc(n5)(cpow)(n8)(cmulti)(n6)(cadd)(n8)(csub)(n9) ... // Maximum call stack size exceeded

Taschenrechner User-Interface

Um den lambdafizierten Taschenrechner, wie ein gewöhnter Taschenrechner auch visuell bedienen zu können, wurde eine statische HTML-Webseite, mit einem grafischen Taschenrechner und den von hier gezeigten Funktionen implementiert:

Eigenschaften des lambdafizierter Taschenrechner

  • Alle Funktionen sind rein

  • In allen Funktionen gibt es keine Ausdrücke wie for, while oder do Schleifen.

Mit der (T = x => f => f(x) ) als den Taschenrechner-Starter und den neuen Operator-Funktionen, ist es mögliche eine unendliche Verkettungen von Zahlen und Operationen zu erstellen.

Um dieser Verkettung ein Ende zu setzen und das Resultat der Berechnung zu erhalten, benötigt es jeglich die als Letztes anzuwenden.

Das der Taschenrechner nicht nur mit JavaScript-Zahlen sondern auch mit rechnen kann, braucht es nur die mit dem CalculatorHandler zu kombinieren.

Mit diesen und den lässt sich der Taschenrechner gleich bequem bedienen.

Die Hilfe zum die Zahl hinter einer Church-Zahl zu Entziffern ist die Funktion

Link zum lambdafizierten Taschenrechner:

Kombinatoren
Church-Zahlen
Calculator.html
Thrush-Funktion
Identitäts-Funktion
Calculator.html
Church-Zahlen
lambdafizierte Arithmetik-Operatoren
lambdafizierte Arithmetik-Operatoren mit Church-Zahlen
Church-Zahlen
jsNum