JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java -...

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

Transcript of JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java -...

Page 1: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

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

http://dai.fmph.uniba.sk/courses/PARA/alias: digmy(a)lists.dai.fmph.uniba.sk

Pon, 12:20, M-XII

Zdroje:Douglas Crockford: JavaScript: The Good Parts•autor json konceptu•JSLint

Page 2: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Obsahn Statické a dynamické typovanie, rôzne odtiene (1./3)n Good & bad parts of Javascript (ES6) (2./3)n scopen clojuren python generator pomocou clojuresn tail recursion optimisation, tail calls (3./3)n trampolinan continuation Passing Style vs. callback

Page 3: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

JSn Či chcete, alebo nie, Javascript je assembler internetu,

n 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,

n JS chýbajú typy,

n môžete v ňom začať písať aj bez príručky, je natoľko intuitívny,

n a o to viac zradný (najmä pre C++/Java programátora),

n môžete ho milovať alebo nenávidieť, nič medzi ☺

Page 4: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

JS má špecifikáciu(ES6)

n 550 strán pomerne nudného čítania, reference manual

https://www.google.sk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwinofLsm7bWAhXI0hoKHSXADvcQFggmMAA&url=https%3A%2F%2

Page 5: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Learn ES2015(ES 6 features based on Hoban's es6features repo)

n 550 strán pomerne nudného čítania, reference manual

https://babeljs.io/learn-es2015/#ecmascript-2015-features-tail-calls

Page 6: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

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

http://kangax.github.io/compat-table/es6/

Page 7: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

JavaScript: The Good Parts(Douglas Crockford)

If a feature is sometimes useful and sometimes dangerous, and if there is abetter 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:n high level languages were a good idea,n goto statement was a bad idea,n objects were a good idea,n lambdas (functions) were a good idea.

Page 8: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Ako to začalo(dnes je to JavaScript ES6)

n interactive language for Netscapen LiveScript: 10 dní na prototyp vychádzajúci z:

n Java - syntax, aj kus názvu jazykan Scheme/Lisp – lambdas – funkcie a functionálny pohľad, n Self/Smalltalk – Smalltalk bez tried.

n 1995, zároveň sa úspešne rozvíja Goslingova Javan Silná spoločná motivácia pre JS a Java: byť nezávislý od platformy Microsoft

ten si vyvýja Jscript(Active Script), J++

n Súboj Java Appletov a JavaScript vyhráva JS na plnej čiare

n Na úvodné programovanie v JS nepotrebujete čítať žiadnu obsiahlu dokumentáciu

n Stačí si otvoriť konzolu od browsera (alebo repl.it) a “programujete”

Brendan Eich

Page 9: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Statici vs. dynamiciExistuje 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 hodnotyktorá 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, ...

Page 10: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

C++(Java) vs. Python(JavaScript)n kým C++ (Java) oplýva komplikovanosťou

a ťažkopádnosťou často spôsobenoustatickou 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

n dynamické typovanie je ale smrť pre väčšie projekty-- osobný názor, s ktorým môžete nesúhlasiť...

n 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:n efektívny (t.j. kompilovaný) jazyk vhodný pre veľké projektyn s rýchlym kompilátoromn ako jazyk s podporou distribuovaných, konkurentných a sieťových aplikácií

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

Page 11: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Typovanien Dynamicky typovaný jazyk – typ premennej môže byť zmenený

kedykoľvek na iný, napr. reťazec, int, time, objekt, ...n Staticky typovaný jazyk – typ premennej je raz pre vždy určený a nemenný

napr. deklaráciou, alebo prvým výskytom (Explicitne/Implicitne)_____________________________________________________n Silne (strong) typovaný jazyk – striknte určuje operácie, ktoré môžete s

typovanou premennou, nesmiete miešať typy, inak nastane výnimkan Slabo (weakly) typovaný jazyk – možete robiť čokolvek s rôznymi typmi,

miešať ich, nenastane výnimka

http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html

Javascript L

Page 12: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Slabé typovanien no typing - assemblern 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 749711097 ?n 749711097 = 249903699 * 3 n 74 97 110 97 = “Jana” n 74 9711097 = GMT: Monday 4. October 1993 5:04:57

http://coding.smashingmagazine.com/2013/04/18/introduction-to-programming-type-systems/

char z = 'A'; printf("%d, %c", z, z);65, A

Page 13: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Silné statické typovanien strong static typing (Java)

informácia o type je prístupná v čase behu, a VM teda môže kontrolovať typak chceme pretypovať objekt na iný typ, Java v čase behu realizuje kontroluvý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ódpublic class Main {

public static void main (String args[]) {Person person = new Person();System.out.println("The name is " + person.getName());

}} zdroj:http://coding.smashingmagazine.com/2013/04/18/introduction-to-programming-type-systems/

Page 14: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Silné dynamické typovanien 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:http://coding.smashingmagazine.com/2013/04/18/introduction-to-programming-type-systems/

Page 15: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Silné dynamické typovanien strong dynamic typing (JS, Python, Ruby)

if (new Date().getMinutes() > 29): z = “aaa”

else: z = 5

print zz = z+z // typ z sa zisťuje až v čase behu programu

// - pol hodinu je to String + String// - a pol hodinu int + int

zdroj:http://coding.smashingmagazine.com/2013/04/18/introduction-to-programming-type-systems/

Page 16: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Duck typingn 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 functionperson['getName'] = null; // person.getName is not a functionperson['getName'] = undefined; // person.getName is not a function

console.log('The name is ' + person.getName() + ' ' +'and the birthday is ' + person.getBirthday());

http://coding.smashingmagazine.com/2013/04/18/introduction-to-programming-type-systems/

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...

Page 17: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

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.”

http://coding.smashingmagazine.com/2013/04/18/introduction-to-programming-type-systems/

“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.”

Page 18: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

0.1 + 0.2 == 0.3if (0.1 + 0.2 == 0.3) {console.log(":-)");

} else {console.log(":-(");

}

if (0.1 + 0.2 == 0.3): print(":-)");

else: print(":-(");

#include <iostream>int main() { if (0.1 + 0.2 == 0.3) { std::cout << ":-)";

} else { std::cout << ":-(";

}}

main = do if (0.1 + 0.2 == 0.3) then

putStrLn ":-)" else

putStrLn ":-("

(1 ÷ 10)+(2 ÷ 10)-(3 ÷ 10)

Page 19: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Viacznačnosť zabíja

Ambiguita je smrť !

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away-- Antoine de Saint-Exupery

Page 20: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

ASCII: (viacznačnosť zabíja)

n TAB vs. SPACE

n ’ vs. ”n alert('wow')n alert("WOW")

n UPPERCASE vs. lowercase ( ↑ , ↓)n case sensitivity vznikla s ASCII-7

https://www.youtube.com/watch?v=SsoOG6ZeyUI Richard HendrixHBO Silicon Valley SE03

Page 21: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

var vs. letfunction varTest() {var x = 1;if (true) {var x = 2; // rovnaká premenná, var ignoruje block-scopeconsole.log(x); // 2

}console.log(x); // 2 – tvrdá rana pre programátora vyškoleného

} v C, C++, Java, ...function letTest() {let x = 1;if (true) {let x = 2; // rôzne premennéx = x+1; // premenná definovaná let je modifikovateľnáconsole.log(x); // 3

}console.log(x); // 1

}https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

Page 22: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

const vs. letfunction 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ť.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

Page 23: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

null vs. undefined(javascript unikát)

n JS má dve hodnoty pre nedefinovanú hodnotun null a undefined

n typeof 12 'number'n typeof 'wow' 'string'n typeof null 'object'???n typeof undefined 'undefined'

NULL (okrem iných vecí ako QuickSort, CSP, ...) objavil/zaviedol Tony Hoarepre 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 1965. At that time, I was designing the first comprehensive type systemfor references in an object oriented language (ALGOLW). My goal was to ensure that all use of references should beabsolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put ina 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

Page 24: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

= vs. == vs. ===(jediný jazyk, kde == nie je tranzitívne)

n 0 == '' // true, platí aj opačnen 0 == '0' // true, platí aj opačnen '' == '0' // false

n false == 'false' // falsen false == '0' // truen " \t \r \n \t " == 0 // true

n 0 === '' // falsen 0 === '0' // false n '' === '0' // false n false === 'false' // falsen false === '0' // falsen " \t \r \n \t " === 0 // false

false:n falsen 0 (zero)n '' or “”n nulln undefinedn NaN (napr. 1/0)Všetko ostatné je true:n '0’n 'false’n [] (an empty array)n {} (an empty object)n function(){} (an “empty” f)

Page 25: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Vždy === miesto ==

https://dorey.github.io/JavaScript-Equality-Table/

Page 26: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

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 layoutprogramu. Akýkoľvek počet medzier bol ekvivalentný jednej a konce riadkovsa 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ísallayout/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

Page 27: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Priradenie v testen let a = 5, b = 7

n if (a = b) { ... } // a je 7

čo je vlastne explicitne zapísané toto:n a = bn if (a) { ... }

avšak programátor možno myslel niečo inén if (a == b) { ... }n if (a === b) { ... }

Page 28: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Scope(deklarujte všetky premenné na začiatku funkcie)

n JavaScript prevzal syntax blokov z C/Java, ale ignoruje block-scope, t.j. že premenná deklarovaná v bloku nie je inde viditeľná

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 undefinedvar 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 !

Page 29: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Functional scopen 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 = 6x += y+z;// x = 11, y = 4, z = 6

};// x = 1, y = 2, z = undefinedf();// x = 11, y = 2, z = undefined

Page 30: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

with(pravdepodobne pochádza z Pascalu/Pythonu)

with (obj) {a = b;

}a znamená (???):n a = b;n a = obj.b;n obj.a = b;n 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;}

Page 31: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Dobrovoľné zátvorky blokuRovnaké v mnohých iných jazykochif (ok)

t = true;zmeníte na:if (ok)

t = true;foo( );

a myslíte tým toto:if (ok) {

t = true;foo( );

}ale v skutočnosti ste napísali toto:if (ok) {

t = true;}foo( );

Page 32: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Security update for iOS/OSXOriginá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)fail();

if ((err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)fail();

if ((err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)fail();

if ((err = SSLHashSHA1.update(hashCtx, signedParams)) != 0)fail();fail();

if ((err = SSLHashSHA1.final(hashCtx, hashOut)) != 0)fail();

http://www.tidev.io/2014/03/04/how-you-can-learn-from-apples-mistake/

Page 33: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Vsúvanie bodkočiarky

function goo() {...return {errorCode : 0

};}

function goo() {...return {errorCode : 0

};}

;

JS za príkazom vyžaduje bodkočiarkuale svojou benevoletnosťou ju dovolí programátorovi nepísať a dopĺňa ju zaňAký je rozdiel, výsledok oboch kódov ?

Page 34: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Globálne premennén sú zlé, najmä ak projekt presiahne rozumnú veľkosť

n deklarácia globálnej premennej var foo = 5

n cez globálny objektwindow.foo = 5

n implicitná deklaráciafoo = 5

n Našťastie JS ES 6 prichádza s modulmi

Page 35: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Moduly(export, import)

// util.jsexport 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.jsimport {add, mult} from 'util.js';import * from './util.js';console.log(add(4,5));console.log(mult(4,5));

Page 36: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Defalutné argumentyfunction 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;

...

Page 37: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

JavaScript: The Good Parts(Douglas Crockford)

A good programming language should teach you.

It took a generation to agree that:n high level languages were a good idea,n goto statement was a bad idea,n objects were a good idea,n lambdas (functions) were a good idea.

Page 38: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

GOTO story

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

Page 39: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

clojureClojure objavil Abelson a Sussman, Sussmanv 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) ukazujena 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.

Page 40: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

clojurefunction clojure_fun() {

var state = 0; // premenná vonkajšej funkciereturn {

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() // 0clo.set(11); set(11);clo.get() // 11clo.inc(4); inc(4);clo.get() get() // 19

Page 41: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

clojurefunction 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.

Page 42: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

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());

}

Python:def fibonacci():

x, y = 0, 1while True:

yield xx, y = y, x + y

g = fibonacci()for _ in range(20):

print(next(g))

// toto sa zacykli, for f in fibonacci():

print(f)

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

Page 43: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

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);}

Python:def fibonacci():

x, y = 0, 1while True:

yield xx, y = y, x + y

g = fibonacci()for _ in range(20):

print(next(g))

// toto sa zacykli, for f in fibonacci():

print(f)

1235813213455

Page 44: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Generatory a clojures(Eratostenove prvočísla)

Python:def integers(n):

while True:yield nn += 1

def sieve(d, sieved):for x in sieved:

if (x % d != 0):yield x

JavaScript:function integers(n) {return function() {

n ++;return n-1;

}};function sieve(d, sieved) {return function() {while(true) {x = sieved();if (x % d != 0)return x;

} }}

Page 45: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Generatory a clojures(Eratostenove prvočísla – pokračovanie)

Python:def integers(n): ...def sieve(d, sieved):...

def eratosten(ints):while True:

first = next(ints)yield firstints = sieve(first,

ints)def take(n,g):

for i in range(n):yield next(g)

print(list(take(100,eratosten(integers(2)))))

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

Page 46: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Tail recursion optimisationn bežné vo funkcionálnych jazykoch, Lisp, Scheme, Haskell, Scala n ale nie Clojure, v JS len od ES6

Iterácia:function add1(a, b) {if (a == 0) {return b;

} else {return add1(a - 1, b + 1);

}}add1(10000, 10000)20000add1(20000, 20000)40000add1(30000, 30000)too much recursion

Rekurzia:function add(a, b) {if (a == 0) {return b;

} else {return add(a - 1, b) + 1;

}}add(6000, 6000)12000add(10000, 10000)too much recursion

TRO znamená, že kompilátor/intepreterzbadá, že je to cyklus

Page 47: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Tail recursion optimisationn bežné vo funkcionálnych jazykoch, Lisp, Scheme, Haskell, Scala n ale nie Clojure, v JS len od ES6

Iterácia:function add1(a, b) {if (a == 0) {return b;

} else {return add1(a - 1, b + 1);

}}add1(10000, 10000)20000add1(20000, 20000)40000add1(30000, 30000)too much recursion

Takto sa to intepretuje:function add(a, b) {label:if (a == 0) {return b;

} else {a = a – 1b = b + 1goto label;

}}

TRO znamená, že kompilátor/intepreterzbadá, že je to cyklus

Page 48: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Tail recursion optimisation(ako písať iteratívne programy)

n akumulátorfunction fib(n, acc = 0, prev = 1) {if (n <= 1) {return acc;

} else {return fib(n-1, prev+acc, acc);

}}fib(500)8.616829160023833e+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)9.332621544394418e+157

Page 49: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Tail recursion optimisation(vieme to vždy)

n Vieme každú rekurzívnu funkciu prepísať na cyklus (pomocou TRO) ?

Page 50: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Trampolinafunction odd1(n) {

returnn===0 ? false : even1(n-1);

}function even1(n) {

returnn===0 ? true : odd1(n-1);

}

function odd2(n) { return() => n===0 ?false:even2(n-1);

}function even2(n) {

return() => 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ýsledokreturn fn;

}

odd1(100)falseodd1(1001)trueodd1(10010)falseodd1(100100)too much recursion

trampolina(odd2(100))falsetrampolina(odd2(1001))truetrampolina(odd2(10010))falsetrampolina(odd2(100100))falsetrampolina(odd2(100100000))falsetrampolina(odd2(1001000001))true

Page 51: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Trampolinafunction 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) {return () =>

(n === 0) ? acc : sum2(n-1, n+acc);

}factorial1(10)3628800factorial1(100)9.332621544394418e+157factorial1(1000)Infinityfactorial1(10000)Infinityfactorial1(100000)too much recursion

trampolina(factorial2(100))3628800trampolina(factorial2(100))9.332621544394418e+157trampolina(factorial2(1000))Infinitytrampolina(factorial2(10000))Infinity...trampolina(factorial2(10000000))Infinity

Page 52: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Trampolinafunction 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) {return () =>

(n === 0) ? acc : sum2(n-1, n+acc);

}factorial1(10)3628800factorial1(100)9.332621544394418e+157factorial1(1000)Infinityfactorial1(10000)Infinityfactorial1(100000)too much recursion

trampolina(factorial2(100))3628800trampolina(factorial2(100))9.332621544394418e+157trampolina(factorial2(1000))Infinitytrampolina(factorial2(10000))Infinity...trampolina(factorial2(10000000))Infinity

sum1(100)5050sum1(10000)too much recursion

trampolina(sum2(10000000))50000005000000trampolina(sum2(100000000))5000000050000000

Page 53: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Continuation Passing Styleconsole.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;}https://stackoverflow.com/questions/14019341/whats-the-difference-between-a-continuation-and-a-callback

Page 54: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Continuation Passing Stylepythagoras(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;}

https://stackoverflow.com/questions/14019341/whats-the-difference-between-a-continuation-and-a-callback

Page 55: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Continuation Passing Stylepythagoras(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);

});});

}

https://stackoverflow.com/questions/14019341/whats-the-difference-between-a-continuation-and-a-callback

Page 56: JavaScript [Re im kompatibility]dai.fmph.uniba.sk/courses/PARA/Prednasky/JavaScript.pdf · n Java - syntax, aj kus názvu jazyka n Scheme/Lisp – lambdas – funkcie a functionálny

Continuation Passing Stylepythagoras(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;}

https://stackoverflow.com/questions/14019341/whats-the-difference-between-a-continuation-and-a-callback

function square(x, cont) {multiply(x, x, cont);

}

function multiply(x, y, cont) {cont(x * y);

}

function add(x, y, cont) {cont(x + y);

}