Presentation is loading. Please wait.

Presentation is loading. Please wait.

JavaScript Peter Borovanský, KAI, I-18, borovan(a)ii.fmph.uniba.sk

Similar presentations


Presentation on theme: "JavaScript Peter Borovanský, KAI, I-18, borovan(a)ii.fmph.uniba.sk"— Presentation transcript:

1 JavaScript Peter Borovanský, KAI, I-18, borovan(a)ii.fmph.uniba.sk
alias: digmy(a)lists.dai.fmph.uniba.sk Pon, 12:20, M-XII Zdroje: Douglas Crockford: JavaScript: The Good Parts autor json konceptu JSLint

2 Obsah Statické a dynamické typovanie, rôzne odtiene (1./3)
Good & bad parts of Javascript (ES6) (2./3) scope clojure python generator pomocou clojures tail recursion optimisation, tail calls (3./3) trampolina continuation Passing Style vs. callback

3 JS Či chcete, alebo nie, Javascript je assembler internetu,
Pri písaní aplikácií sa mu nedá vyhnúť, viete ho len zakryť frameworkom/ iným (napr. typovaným) jazykom, ktorý vám nakoniec JS vygeneruje, JS chýbajú typy, môžete v ňom začať písať aj bez príručky, je natoľko intuitívny, a o to viac zradný (najmä pre C++/Java programátora), môžete ho milovať alebo nenávidieť, nič medzi 

4 JS má špecifikáciu (ES6)
550 strán pomerne nudného čítania, reference manual

5 Learn ES2015 (ES 6 features based on Hoban's es6features repo)
550 strán pomerne nudného čítania, reference manual

6 JS má rôzne implementácie (ES6)

7 JavaScript: The Good Parts (Douglas Crockford)
If a feature is sometimes useful and sometimes dangerous, and if there is a better option, then always use the better option. We are not paid to use every feature of the language. We are paid to write programs that work well and are free of errors. A good programming language should teach you. It took a generation to agree that: high level languages were a good idea, goto statement was a bad idea, objects were a good idea, lambdas (functions) were a good idea.

8 Ako to začalo (dnes je to JavaScript ES6)
interactive language for Netscape LiveScript: 10 dní na prototyp vychádzajúci z: Java - syntax, aj kus názvu jazyka Scheme/Lisp – lambdas – funkcie a functionálny pohľad, Self/Smalltalk – Smalltalk bez tried. 1995, zároveň sa úspešne rozvíja Goslingova Java Silná spoločná motivácia pre JS a Java: byť nezávislý od platformy Microsoft ten si vyvýja Jscript(Active Script), J++ Súboj Java Appletov a JavaScript vyhráva JS na plnej čiare Na úvodné programovanie v JS nepotrebujete čítať žiadnu obsiahlu dokumentáciu Stačí si otvoriť konzolu od browsera (alebo repl.it) a “programujete” Brendan Eich

9 Statici vs. dynamici Existuje večná vojna medzi dynamickými a statickými programátormi. Je fajn zistiť, o čom je táto vojna... Dynamicky typované jazyky: typ premennej sa určí počas behu, podľa hodnoty ktorá sa v premennej nachádza, príklad PHP, Groovy, JRuby, JavaScript, ... Typ (aritmetickej) operácie sa určí z typov operandov. Staticky typované jazyky: typ premennej sa určí, resp. je známy, už počas kompilácie, príklad C++, Java, ... Statický môže byť aj jazyk, ktorý nevyžaduje typy tak rigidne ako C++ alebo Java. Z aktuálnych príkladov, Haskell, Go, Scala, Swift, Kotlin... Typová inferencia (u statických jazykov) je, ak jazyk/kompilátor vie zistiť typ premennej bez toho, aby ho programátor musel explicitne písať/deklarovať, príklad Scala, Kotlin, Haskell, ...

10 C++(Java) vs. Python(JavaScript)
kým C++ (Java) oplýva komplikovanosťou a ťažkopádnosťou často spôsobenou statickou typovou kontrolou, interpretované a dynamicky typované jazyky ako Python, Ruby, JavaScript ponúkajú ľahkosť, elegantnosť pri písaní, kódu, malých prototypov. -- aj preto si ich ľudia veľmi obľúbili dynamické typovanie je ale smrť pre väčšie projekty -- osobný názor, s ktorým môžete nesúhlasiť... tradičné kompilované (staticky typované) jazyky ako C, C++, Delphi (Java) ponúkajú efektívnosť na úkor pohodlia pri písaní kódu Go chce uspieť ako: efektívny (t.j. kompilovaný) jazyk vhodný pre veľké projekty s rýchlym kompilátorom ako jazyk s podporou distribuovaných, konkurentných a sieťových aplikácií

11 Typovanie Dynamicky typovaný jazyk – typ premennej môže byť zmenený kedykoľvek na iný, napr. reťazec, int, time, objekt, ... Staticky typovaný jazyk – typ premennej je raz pre vždy určený a nemenný napr. deklaráciou, alebo prvým výskytom (Explicitne/Implicitne) _____________________________________________________ Silne (strong) typovaný jazyk – striknte určuje operácie, ktoré môžete s typovanou premennou, nesmiete miešať typy, inak nastane výnimka Slabo (weakly) typovaný jazyk – možete robiť čokolvek s rôznymi typmi, miešať ich, nenastane výnimka Javascript 

12 Slabé typovanie no typing - assembler
weak static typing (C, C++, Objective C) char z = “hello”; // núti definovať typy všetkých objektov, ale interne … // si pamätá, koľko bajtov zaberá printf(“%i”,z); // keď ju chceme formátovať, treba pripomenúť typ viac a viac typových obmedzení počas času kompilácie (C->C++) Čo je ? = * 3 = “Jana” = GMT: Monday 4. October :04:57 char z = 'A'; printf("%d, %c", z, z); 65, A

13 Silné statické typovanie
strong static typing (Java) informácia o type je prístupná v čase behu, a VM teda môže kontrolovať typ ak chceme pretypovať objekt na iný typ, Java v čase behu realizuje kontrolu výsledok: menej hackov ako C, C++, jazyk je viac rigidnejší public class Person { public String getName() { return "zack"; } } // mimo classy nemôžeme definovať žiaden kód public class Main { public static void main (String args[]) { Person person = new Person(); System.out.println("The name is " + person.getName()); zdroj:

14 Silné dynamické typovanie
strong dynamic typing (JS, Python, Ruby) var person = { getName: function() { return 'zack'; } }; if (new Date().getMinutes() > 29) { person = 5; alert('The name is ' + person.getName()); zdroj:

15 Silné dynamické typovanie
strong dynamic typing (JS, Python, Ruby) if (new Date().getMinutes() > 29): z = “aaa” else: z = 5 print z z = z+z // typ z sa zisťuje až v čase behu programu // - pol hodinu je to String + String // - a pol hodinu int + int zdroj:

16 Duck typing if it walks like a duck and quacks like a duck,
then it must be a duck. Objekt patrí do tej triedy ako kváka... Duck typing duck typing (JS, Python, Ruby) var person = { getName: function() { return 'zack'; } }; person['getBirthday'] = function() { return 'July 18th'; }; person['getName'] = 5; // person.getName is not a function person['getName'] = null; // person.getName is not a function person['getName'] = undefined; // person.getName is not a function console.log('The name is ' + person.getName() + ' ' + 'and the birthday is ' + person.getBirthday());

17 Statici vs. Dynamici (vojnové argumenty)
“Static typing catches bugs with the compiler and keeps you out of trouble.” “Static languages are easier to read because they’re more explicit about what the code does.” “At least I know that the code compiles.” “I trust the static typing to make sure my team writes good code.” “Static typing only catches some bugs, and you can’t trust the compiler to do your testing.” “Dynamic languages are easier to read because you write less code.” “Just because the code compiles doesn’t mean it runs.” “The compiler doesn’t stop you from writing bad code.”

18 == 0.3 if ( == 0.3) { console.log(":-)"); } else { console.log(":-("); } if ( == 0.3): print(":-)"); else: print(":-("); #include <iostream> int main() { if ( == 0.3) { std::cout << ":-)"; } else { std::cout << ":-("; } main = do if ( == 0.3) then putStrLn ":-)" else putStrLn ":-(" (1 ÷ 10)+(2 ÷ 10)-(3 ÷ 10)

19 Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away -- Antoine de Saint-Exupery Viacznačnosť zabíja Ambiguita je smrť !

20 ASCII: (viacznačnosť zabíja)
TAB vs. SPACE ’ vs. ” alert('wow') alert("WOW") UPPERCASE vs. lowercase ( ↑ , ↓) case sensitivity vznikla s ASCII-7 Richard Hendrix HBO Silicon Valley SE03

21 var vs. let function varTest() { var x = 1; if (true) { var x = 2; // rovnaká premenná, var ignoruje block-scope console.log(x); // 2 } console.log(x); // 2 – tvrdá rana pre programátora vyškoleného } v C, C++, Java, ... function letTest() { let x = 1; let x = 2; // rôzne premenné x = x+1; // premenná definovaná let je modifikovateľná console.log(x); // 3 console.log(x); // 1

22 const vs. let function constTest() { const x = 1; if (true) { const x = 2; // rôzne premenné // x = x+1; console.log(x); // 2 } console.log(x); // 1 Množstvo konštánt, ktoré používame v programoch, definujeme ako premenné s inicializáciou a nikdy nezmeníme. Pritom const je konštrukcia deklarujúca, že niečo sa nebude meniť.

23 null vs. undefined (javascript unikát)
JS má dve hodnoty pre nedefinovanú hodnotu null a undefined typeof 12 'number' typeof 'wow' 'string' typeof null 'object' ??? typeof undefined 'undefined' NULL (okrem iných vecí ako QuickSort, CSP, ...) objavil/zaviedol Tony Hoare pre nedokonalosť typového systému vtedy Algolu. Dnešné jazyky (Swift, Kotlin) to riešia typmi String (never null), String? 2009, he apologised for inventing the null reference:[20] I call it my billion-dollar mistake. It was the invention of the null reference in At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOLW). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. Tony Hoare

24 = vs. == vs. === (jediný jazyk, kde == nie je tranzitívne)
0 == '' // true, platí aj opačne 0 == '0' // true, platí aj opačne '' == '0' // false false == 'false' // false false == '0' // true " \t \r \n \t " == // true 0 === '' // false 0 === '0' // false '' === '0' // false false === 'false' // false false === '0' // false " \t \r \n \t " === // false false: false 0 (zero) '' or “” null undefined NaN (napr. 1/0) Všetko ostatné je true: '0’ 'false’ [] (an empty array) {} (an empty object) function(){} (an “empty” f)

25 Vždy === miesto ==

26 Viacriadkové reťazce (indentácia je dôležitá)
Po Fortrane, ktorý zrušil medzery, lebo zaberali drahocenné miesto v 80- stĺpcovom riadku, prišiel Algol/Pascal/C/C+/Java, ktorý ignoroval layout programu. Akýkoľvek počet medzier bol ekvivalentný jednej a konce riadkov sa ignorovali (resp. stáli za medzeru). A každý preferoval iný formát. Viacforemnosť zabíja. Vznikla potreba formátovať programy. Prišiel Python, ktorý za cenu ušetrenia blokových zátvoriek predpísal layout/indentáciu programu. Ale to nie je všetko, prečo je druhý program (JS) zlý ? var long_line_1 = "This is a \ long line"; // ok var long_line_2 = "This is a \ long line"; // syntax error

27 Priradenie v teste let a = 5, b = 7 if (a = b) { ... } // a je 7
čo je vlastne explicitne zapísané toto: a = b if (a) { ... } avšak programátor možno myslel niečo iné if (a == b) { ... } if (a === b) { ... }

28 Scope (deklarujte všetky premenné na začiatku funkcie)
JavaScript prevzal syntax blokov z C/Java, ale ignoruje block-scope, t.j. že premenná deklarovaná v bloku nie je inde viditeľná ak deklarujete (a príp. inicializujete) premennú v strede funkcie, viditeľná je aj pred definíciou, ale nemá hodnotu... function foo() { console.log(a); // je definovaná, ale má hodnotu undefined var a = 0; console.log(a); // 0 } for(var i = 1; i <= 10; i++) { } // ... console.log(i); // 11 // ... takto to bolo v Basicu... Používajte let lebo akceptuje block-scope !

29 Functional scope JavaScript síce používa blokovú syntax, nerešpektuje block-scope, ale pozná funkcie ako hodnoty, a rešpektuje functional-scope... var x = 1, y = 2; function f() { var y = 4, z = 6; // x = 1, y = 4, z = 6 x += y+z; // x = 11, y = 4, z = 6 }; // x = 1, y = 2, z = undefined f(); // x = 11, y = 2, z = undefined

30 with (pravdepodobne pochádza z Pascalu/Pythonu)
with (obj) { a = b; } a znamená (???): a = obj.b; obj.a = b; obj.a = obj.b; V skutočnosti znamená toto (takže všetky štyri možnosti): if (obj.a === undefined) { a = obj.b === undefined ? b : obj.b; } else { obj.a = obj.b === undefined ? b : obj.b;

31 Dobrovoľné zátvorky bloku
Rovnaké v mnohých iných jazykoch if (ok) t = true; zmeníte na: foo( ); a myslíte tým toto: if (ok) { } ale v skutočnosti ste napísali toto:

32 Security update for iOS/OSX
Originány Apple kód na verifikovanie certifikatu (2014, update iOS 7.0.6): Vidíte chybu v tomto kóde ? … nevadí, ani Apple ju nenašiel... if ((err = SSLFreeBuffer(hashCtx)) != 0) fail(); if ((err = ReadyHash(SSLHashSHA1, hashCtx)) != 0) if ((err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0) if ((err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0) if ((err = SSLHashSHA1.update(hashCtx, signedParams)) != 0) if ((err = SSLHashSHA1.final(hashCtx, hashOut)) != 0)

33 Vsúvanie bodkočiarky ... JS za príkazom vyžaduje bodkočiarku
ale svojou benevoletnosťou ju dovolí programátorovi nepísať a dopĺňa ju zaň Aký je rozdiel, výsledok oboch kódov ? function goo() { ... return { errorCode : 0 }; } function goo() { ... return { errorCode : 0 }; } ;

34 Globálne premenné sú zlé, najmä ak projekt presiahne rozumnú veľkosť
deklarácia globálnej premennej var foo = 5 cez globálny objekt window.foo = 5 implicitná deklarácia foo = 5 Našťastie JS ES 6 prichádza s modulmi

35 Moduly (export, import)
// util.js export function add(a, b) { return a + b; } export function mult(a, b) { return a * b; export var grav = 9.81; export { add, mult, grav }; export *; // import.js import {add, mult} from 'util.js'; import * from './util.js'; console.log(add(4,5)); console.log(mult(4,5));

36 Defalutné argumenty function fib(n, a = 0, b = 1) { if (n == 0) { return a; } else { return fib(n-1, b, a+b); } console.log(fib(10)); "use strict"; function fib(n) { var a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var b = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; ...

37 JavaScript: The Good Parts (Douglas Crockford)
A good programming language should teach you. It took a generation to agree that: high level languages were a good idea, goto statement was a bad idea, objects were a good idea, lambdas (functions) were a good idea.

38 GOTO story Edsger Dijkstra (1968). "Go To Statement Considered Harmful", Communications of the ACM Frank Rubin (1987). ""GOTO Considered Harmful" Considered Harmful“ , Communications of the ACM Donald Moore; ...(1987). "" 'GOTO Considered Harmful' Considered Harmful" Considered Harmful?„ Dijkstra, Edsger On a Somewhat Disappointing Correspondence (EWD-1009)

39 clojure Clojure objavil Abelson a Sussman, Sussman v jazyku Scheme, MIT Lisp. Potrebujete vnorené funkcie... Clojure je ak premenná vnútornej funkcie odkazuje na premennú vonkajšej funkcie. Zaujímavý je prípad, ak vonkajšia funkcia vráti potom ako hodnotu vnútornú funkciu, vonkajšia tým zanikne. Výsledná hodnota (vnútorná funkcia) ukazuje na premennú zaniknuvšej vonkajšej funkcie. Takmer 20 rokov si ho nikto nevšimol. Efektívna implementácia na stack-based architektúre nebola evidentná. Objavil sa v Haskelli.

40 clojure function clojure_fun() {
var state = 0; // premenná vonkajšej funkcie return { inc : function(delta) { state += delta }, clr : function() { state = 0 }, get : function() { return state }, set : function(val ) { state = val } }; }; var clo = clojure_fun(); clo je { inc: [Function], clr: [Function], get: [Function], set: [Function] } var get = clo.get, set = clo.set, inc = clo.inc; clo.get() // 0 clo.set(11); set(11); clo.get() // 11 clo.inc(4); inc(4); clo.get() get() // 19

41 clojure function clojure_fun() { var state = 0; return { inc : function(delta) { state += delta }, clr : function() { state = 0 }, get : function() { return state }, set : function(val ) { state = val } }; }; Čo je clojure: funkcia (clojure-fun) vráti ako hodnotu funkciu, resp. viacero fcií, ktorá vidí lokálne premenné práve zaniknuvšej funkcie (state). Lokálna premenná (state) preto nemôže zaniknúť návratom z funkcie (clojure-fun). Stack-frame architektúra preto nemôže byť použitá, ale state musí na heap.

42 Generatory.py a clojures.js (Fibonacci)
JavaScript(clojure): function fibonacci() { let x = 0, y = 1; return function() { let tmp = x; x = y; y = tmp + y; return tmp; } g = fibonacci(); for (var i = 0; i<20; i++) { console.log('fib(' + i + ')='+ g()); fib(0)=0 fib(1)=1 fib(2)=1 fib(3)=2 fib(4)=3 fib(5)=5 fib(6)=8 fib(7)=13 fib(8)=21 fib(9)=34 fib(10)=55 Python: def fibonacci(): x, y = 0, 1 while True: yield x x, y = y, x + y g = fibonacci() for _ in range(20): print(next(g)) // toto sa zacykli, for f in fibonacci(): print(f)

43 Generatory (.js vs. .py) (Fibonacci)
fibonaccy = { [Symbol.iterator]: function*() { var x = 0, y = 1; for (;;) { var tmp = x; x = y; y += tmp; yield y; } for (var n of fibonaccy) { if (n > 1000) break; console.log(n); 1 2 3 5 8 13 21 34 55 Python: def fibonacci(): x, y = 0, 1 while True: yield x x, y = y, x + y g = fibonacci() for _ in range(20): print(next(g)) // toto sa zacykli, for f in fibonacci(): print(f)

44 Generatory a clojures (Eratostenove prvočísla)
JavaScript: function integers(n) { return function() { n ++; return n-1; } }; function sieve(d, sieved) { while(true) { x = sieved(); if (x % d != 0) return x; } } Python: def integers(n): while True: yield n n += 1 def sieve(d, sieved): for x in sieved: if (x % d != 0): yield x

45 Generatory a clojures (Eratostenove prvočísla – pokračovanie)
JavaScript: function integers(n) ... function sieve(d, sieved) ... function eratosten(ints) { return function() { var first = ints(); ints = sieve(first, ints); return first; } era = eratosten(integers(2)); for (var i = 0; i<20; i++) { console.log('prime('+i+')='+ era()); prime(0)=2 prime(1)=3 prime(2)=5 prime(3)=7 prime(4)=11 prime(5)=13 prime(6)=17 prime(7)=19 prime(8)=23 prime(9)=29 Python: def integers(n): ... def sieve(d, sieved):... def eratosten(ints): while True: first = next(ints) yield first ints = sieve(first, ints) def take(n,g): for i in range(n): yield next(g) print(list(take(100, eratosten(integers(2)))))

46 Tail recursion optimisation
bežné vo funkcionálnych jazykoch, Lisp, Scheme, Haskell, Scala ale nie Clojure, v JS len od ES6 Rekurzia: function add(a, b) { if (a == 0) { return b; } else { return add(a - 1, b) + 1; } add(6000, 6000) 12000 add(10000, 10000) too much recursion Iterácia: function add1(a, b) { if (a == 0) { return b; } else { return add1(a - 1, b + 1); } add1(10000, 10000) 20000 add1(20000, 20000) 40000 add1(30000, 30000) too much recursion TRO znamená, že kompilátor/intepreter zbadá, že je to cyklus

47 Tail recursion optimisation
bežné vo funkcionálnych jazykoch, Lisp, Scheme, Haskell, Scala ale nie Clojure, v JS len od ES6 Takto sa to intepretuje: function add(a, b) { label: if (a == 0) { return b; } else { a = a – 1 b = b + 1 goto label; } Iterácia: function add1(a, b) { if (a == 0) { return b; } else { return add1(a - 1, b + 1); } add1(10000, 10000) 20000 add1(20000, 20000) 40000 add1(30000, 30000) too much recursion TRO znamená, že kompilátor/intepreter zbadá, že je to cyklus

48 Tail recursion optimisation (ako písať iteratívne programy)
akumulátor function fib(n, acc = 0, prev = 1) { if (n <= 1) { return acc; } else { return fib(n-1, prev+acc, acc); } fib(500) e+103 function factorial(n) { function fact(n, acc) { if (n < 2) { return acc; } else { return fact(n-1, n*acc); } return fact(n, 1); factorial(100) e+157

49 Tail recursion optimisation (vieme to vždy)
Vieme každú rekurzívnu funkciu prepísať na cyklus (pomocou TRO) ?

50 Trampolina function odd1(n) { return n===0 ? false : even1(n-1); } function even1(n) { n===0 ? true : odd1(n-1); function odd2(n) { return () => n===0 ?false:even2(n-1); } function even2(n) { () => n===0 ? true:odd2(n-1); function trampolina(fn) { while ( // kým je funkcia typeof fn === 'function') { fn = fn(); // aplikuj } // ak už nie, je to výsledok return fn; trampolina(odd2(100)) false trampolina(odd2(1001)) true trampolina(odd2(10010)) trampolina(odd2(100100)) trampolina(odd2( )) trampolina(odd2( )) odd1(100) false odd1(1001) true odd1(10010) odd1(100100) too much recursion

51 Trampolina function factorial1(n, acc=1) { return (n < 2) ? acc : factorial1(n-1, n*acc); } function sum1(n, acc=0) { return (n === 0) ? acc : sum1(n-1, n+acc); function factorial2 (n, acc=1) { return () => (n < 2) ? acc : factorial2(n-1, n*acc); } function sum2(n, acc=0) { (n === 0) ? acc : sum2(n-1, n+acc); factorial1(10) factorial1(100) e+157 factorial1(1000) Infinity factorial1(10000) factorial1(100000) too much recursion trampolina(factorial2(100)) e+157 trampolina(factorial2(1000)) Infinity trampolina(factorial2(10000)) ... trampolina(factorial2( ))

52 Trampolina function factorial1(n, acc=1) { return (n < 2) ? acc : factorial1(n-1, n*acc); } function sum1(n, acc=0) { return (n === 0) ? acc : sum1(n-1, n+acc); function factorial2 (n, acc=1) { return () => (n < 2) ? acc : factorial2(n-1, n*acc); } function sum2(n, acc=0) { (n === 0) ? acc : sum2(n-1, n+acc); sum1(100) 5050 sum1(10000) too much recursion factorial1(10) factorial1(100) e+157 factorial1(1000) Infinity factorial1(10000) factorial1(100000) too much recursion trampolina(factorial2(100)) e+157 trampolina(factorial2(1000)) Infinity trampolina(factorial2(10000)) ... trampolina(factorial2( )) trampolina(sum2( )) trampolina(sum2( ))

53 Continuation Passing Style
console.log(pythagoras(3, 4)); function pythagoras(x, y) { return x*x + y*y; } console.log(pythagoras(3, 4)); function pythagoras(x, y) { return add( square(x), square(y)); } function square(x) { return multiply(x, x); function multiply(x, y) { return x * y; function add(x, y) { return x + y;

54 Continuation Passing Style
pythagoras(3, 4, console.log); function pythagoras(x, y, cont) { square(x, function (x_squared) { square(y, function (y_squared) { add(x_squared,y_squared, cont); }); } function square(x, cont) { multiply(x, x, cont); } function multiply(x, y, cont) { cont(x * y); } function add(x, y, cont) { cont(x + y); } console.log(pythagoras(3,4)); function pythagoras(x, y) { return add( square(x), square(y)); } function square(x) { return multiply(x, x); function multiply(x, y) { return x * y; function add(x, y) { return x + y;

55 Continuation Passing Style
pythagoras(3, 4, console.log); function pythagoras(x, y, cont) { square(x, function (x_squared) { square(y, function (y_squared) { add(x_squared,y_squared, cont); }); } function square(x, cont) { multiply(x, x, cont); } function multiply(x, y, cont) { cont(x * y); } function add(x, y, cont) { cont(x + y); } pythagoras(3, 4, console.log); function pythagoras(x, y, cont) { square(x, (x_squared) => { square(y, (y_squared) => { add(x_squared, y_squared, cont); }); }

56 Continuation Passing Style
pythagoras(3, 4, console.log); function pythagoras(x, y, cont) { var x_squared = callcc(square.bind(null, x)); var y_squared = callcc(square.bind(null, y)); add(x_squared, y_squared, cont); } function callcc(f) { var cc = function (x) { cc = x; }; f(cc); return cc; function square(x, cont) { multiply(x, x, cont); } function multiply(x, y, cont) { cont(x * y); function add(x, y, cont) { cont(x + y);


Download ppt "JavaScript Peter Borovanský, KAI, I-18, borovan(a)ii.fmph.uniba.sk"

Similar presentations


Ads by Google