Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ES6 Deep Dive
Search
dherman
August 30, 2012
Programming
14
4k
ES6 Deep Dive
A deep dive into three features of ECMAScript Edition 6: symbols, structs, and generators.
dherman
August 30, 2012
Tweet
Share
More Decks by dherman
See All by dherman
Rust + Node = Neon
dherman
1
330
Evolving the World's Most Popular Programming Language
dherman
0
660
Closing iterators
dherman
0
780
A better future for comprehensions
dherman
0
2k
Evolution is Awesome
dherman
0
570
Status Report: ES6 Modules
dherman
16
4k
Discussion with TC39 about the semantics of symbols
dherman
1
400
September 2013 Modules Status Update
dherman
2
1.2k
Rust: low-level programming without the segfaults
dherman
13
9k
Other Decks in Programming
See All in Programming
Perplexity Slack Botを作ってAI活用を進めた話 / AI Engineering Summit プレイベント
n3xem
0
330
漸進。
ssssota
0
1.5k
RubyKaigi Hack Space in Tokyo & 函館最速 "予習" 会 / RubyKaigi Hack Space in Tokyo & The Fastest Briefing of RubyKaigi 2026 in Hakodate
moznion
1
130
「兵法」から見る質とスピード
ickx
0
240
ワイがおすすめする新潟の食 / 20250530phpconf-niigata-eve
kasacchiful
0
290
型安全RESTで爆速プロトタイピング – Hono RPC実践
tacke_jp
0
110
OpenNext + Hono on Cloudflare でイマドキWeb開発スタックを実現する
rokuosan
0
110
2度もゼロから書き直して、やっとブラウザでぬるぬる動くAIに辿り着いた話
tomoino
0
130
TypeScriptのmoduleオプションを改めて整理する
bicstone
4
460
Rails産でないDBを Railsに引っ越すHACK - Omotesando.rb #110
lnit
1
150
単体テストの始め方/作り方
toms74209200
0
350
Step up the performance game with Spring Boot and Project Leyden
mhalbritter
0
150
Featured
See All Featured
YesSQL, Process and Tooling at Scale
rocio
172
14k
Typedesign – Prime Four
hannesfritz
42
2.6k
How STYLIGHT went responsive
nonsquared
100
5.6k
The Cost Of JavaScript in 2023
addyosmani
49
8.3k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
For a Future-Friendly Web
brad_frost
178
9.8k
Why Our Code Smells
bkeepers
PRO
337
57k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Faster Mobile Websites
deanohume
307
31k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
14
1.5k
Statistics for Hackers
jakevdp
799
220k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Transcript
Dave Herman ES6 Deep Dive Symbols, Structs, Generators
None
About me • @littlecalculist • http://calculist.org • http://github.com/dherman • Mozilla
Research • TC39 • Also…
In print this December http://effectivejs.com
Symbols
JS property names are strings var obj = { foo:
42 }; obj["foo"]; // 42
The all-powerful _ character function Dict() { this._entries = {};
} Don’t touch me, I’m private!
When you mean business… __proto__ private SO PRIVATE REALLY GUYS
SOOO TOTALLY PRIVATE private!
Conventions are no guarantee function SuperClass() { this._data = "superclass
private data"; } function SubClass() { SuperClass.call(this); this._data = "subclass private data"; // collision! } SubClass.prototype = Object.create(SuperClass.prototype);
Closures for information hiding function SuperClass() { var data =
"private data"; this.method = function() { /* ... */ data /* ... */ }; } no sharing: one method per instance!
Introducing symbols
Introducing symbols var sym = new Symbol("data");
Introducing symbols var sym = new Symbol("data"); function SuperClass() {
this[sym] = "private data"; }
Introducing symbols var sym = new Symbol("data"); function SuperClass() {
this[sym] = "private data"; } SuperClass.prototype.method = function() { /* ... */ this[sym] /* ... */ };
Introducing symbols var obj = new SuperClass(); "data" in obj;
// false "_data" in obj; // false sym in obj; // true
Performance • Engines already do string interning • Convertible to
a fixed offset with inline caches
Proposal: scoped symbols private @sym; function SuperClass() { this.@sym =
"private data"; } SuperClass.prototype.method = function() { /* ... */ this.@sym /* ... */ };
Structured binary data
Typed arrays var a = new Uint32Array(1024); a[17] = 42;
Typed arrays var vertices = new Float32Array([ -1.0, -1.0, 0.0,
// vertex 1 0.0, 1.0, 0.0, // vertex 2 1.0, -1.0, 0.0 // vertex 3 ]); -1.0 -1.0 0.0 0.0 1.0 0.0 1.0 -1.0 0.0 0 4 8 12 16 20 24 28 32
Structs var Point = struct({ x: float32, y: float32, z:
float32 }); var origin = new Point(0.0, 0.0, 0.0); origin.x; // 0.0 origin.y; // 0.0
Arrays of structs var vertices = new Point.array([ { x:
-1.0, y: -1.0, z: 0.0 }, { x: 0.0, y: 1.0, z: 0.0 }, { x: 1.0, y: -1.0, z: 0.0 } ]); -1.0 -1.0 0.0 0.0 1.0 0.0 1.0 -1.0 0.0 0 4 8 12 16 20 24 28 32
JIT compilers — types
Applications of structs • WebGL data • File and network
I/O • Compiling other languages to JS
Generators
Lies, lies, lies “JS doesn’t have concurrency.” “JS is single-threaded
so it can’t have race conditions.” “Event-based programming is easy.”
Download three files load("foo", function(foo) { load("bar", function(bar) { //
why wait? load("baz", function(baz) { use([foo, bar, baz]); }); }); });
Download three files load("foo", function(foo) { load("bar", function(bar) { //
why wait? load("baz", function(baz) { use([foo, bar, baz]); }); }); });
Download three files var files = []; ["foo", "bar", "baz"].forEach(function(url,
i) { load(url, function(file) { files.push(file); // no! if (i === 3) // no! use(files); }); });
Download three files var files = []; ["foo", "bar", "baz"].forEach(function(url,
i) { load(url, function(file) { files[i] = file; if (files.length === 3) // still no! use(files); }); });
Download three files var files = [], count = 0;
["foo", "bar", "baz"].forEach(function(url, i) { load(url, function(file) { files[i] = file; if (++count === 3) use(files); }); });
JavaScript is concurrent Cooperative concurrency: easier, but not easy! Handlers
run sequentially but start concurrently. Shared state 㱺 race conditions 㱺 pain and suffering
task.js: Beautiful concurrency spawn(function*() { var files = yield join(load("foo"),
load("bar"), load("baz")); use(files); }); http://taskjs.org
task.js: Beautiful concurrency spawn(function*() { var files = yield join(load("foo"),
load("bar"), load("baz")); use(files); }); create a task that can be paused pause! http://taskjs.org
Generator functions function* evenNumbers() { for (var next = 0;
true; next += 2) { yield next; } }
Generator functions function* evenNumbers() { for (var next = 0;
true; next += 2) { yield next; } }
Generator functions function* evenNumbers() { for (var next = 0;
true; next += 2) { yield next; } } evenNumbers(); ✗
Generator functions function* evenNumbers() { for (var next = 0;
true; next += 2) { yield next; } } evenNumbers(); ✗
Generators function* f() { }
Generators function* f() { } .next: var g = f();
⋮
Generators function* evenNumbers() { /* ... */ } var g
= evenNumbers(); g.next(); // 0 g.next(); // 2 g.next(); // 4 starts out paused
Lazy iteration Dict.prototype.keys = function*() { for (var key in
this._entries) yield key; };
Iterators work with for-of var dict = new Dict(); //
... for (var key of dict.keys()) { console.log(key + ": " + dict.get(key)); }
Pausing is powerful load("config.json", function(config) { db.lookup(JSON.parse(config).table, username, function(user) {
load(user.id + ".png", function(avatar) { // ... }); }); });
Pausing is powerful load("config.json", function(config) { db.lookup(JSON.parse(config).table, username, function(user) {
load(user.id + ".png", function(avatar) { // ... }); }); }); later later later
Pausing is powerful load("config.json", function(config) { db.lookup(JSON.parse(config).table, username, function(user) {
load(user.id + ".png", function(avatar) { // ... }); }); }); later later later
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Pausing with promises load("config.json") .then(function(config) { return db.lookup(JSON.parse(config).table); }) .then(function(user)
{ return load(user.id + ".png"); }) .then(function(avatar) { /* ... */ });
Tasks yield promises spawn(function*() { var config = JSON.parse(yield load("config.json"));
var user = yield db.lookup(config.table, username); var avatar = yield load(user.id + ".png"); // ... });
Tasks yield promises spawn(function*() { var config = JSON.parse(yield load("config.json"));
var user = yield db.lookup(config.table, username); var avatar = yield load(user.id + ".png"); // ... });
Tasks yield promises spawn(function*() { var config = JSON.parse(yield load("config.json"));
var user = yield db.lookup(config.table, username); var avatar = yield load(user.id + ".png"); // ... }); looks like a synchronous API!
What about errors? load("foo", function(foo) { load("bar", function(bar) { load("baz",
function(baz) { use([foo, bar, baz]); }, function(err) { /* ... */ }); }, function(err) { /* ... */ }); }, function(err) { /* ... */ });
What about errors? load("foo", function(err, foo) { if (err) return
onError(err); load("bar", function(err, bar) { if (err) return onError(err); load("baz", function(err, baz) { if (err) return onError(err); use([foo, bar, baz]); }); }); });
Error handling with promises var p = load("config.json") .then(function(config) {
/* ... */ } .then(function(user) { /* ... */ }) .then(function(avatar) { /* ... */ }); when(p, function(result) { /* ... */ }, function(err) { /* ... */ });
Error handling with tasks spawn(function*() { try { var config
= JSON.parse(yield load("config.json")); var user = yield db.lookup(config.table, username); var avatar = yield load(user.id + ".png"); // ... } catch (e) { /* ... */ } });
Wait for multiple events spawn(function*() { var [foo, bar, baz]
= yield join(load("foo"), load("bar"), load("baz")); // ... });
Purposefully race events spawn(function*() { try { var foo =
yield select(load("foo"), timeout(3000)); // ... } catch (e) { /* timed out */ } });
Generators • Interruptible computations 㱺 custom iterators • Pausing with
yield 㱺 concurrency minus the callbacks
Something completely different
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "[object Object]"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "[object Object]"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "[object Object]" true true true
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "[object Object]" 3
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "j"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "false" "j"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "false" 3 "j"
({}+[])[!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]] "j" "s"
! + { } [ ] ( ) \n ===
JavaScript
Um. So… why?
• No reason. Um. So… why?
• Yosuke Hasegawa: JSF*ck • Patricio Palladino: Hieroglyphy • Me:
pure JS, no browser API’s Not the first deranged weirdo
> String+[] "function String() { [native code] }" "S"
> "".constructor+[] "function String() { [native code] }" "S"
> ""["constructor"]+[] "function String() { [native code] }" "S"
> [].slice.call(""["constructor"]+[]) ["f","u","n","c","t","i","o","n"," ","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) [" ","f","u","n","c","t","i","o","n"," ","S","t","r", /* ... */] "S"
> function nonWhitespace(s) { return !/^\s*$/.test(s) } > [].slice.call(""["constructor"]+[]).filter(nonWhitespace) ["f","u","n","c","t","i","o","n","S","t","r",
/* ... */] "S"
> Number("f") NaN > Number(" ") 0 > isNaN("f") true
> isNaN(" ") false "S"
> [].slice.call(""["constructor"]+[]).filter(isNaN) ["f","u","n","c","t","i","o","n","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) .filter(Function("return isNaN")()) ["f","u","n","c","t","i","o","n","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) .filter(Array.constructor("return isNaN")()) ["f","u","n","c","t","i","o","n","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) .filter([].constructor.constructor("return isNaN")()) ["f","u","n","c","t","i","o","n","S","t","r", /* ... */] "S"
> [].slice.call(""["constructor"]+[]) .filter([].constructor.constructor("return isNaN")())[8] "S" "S"
> (9).toString() "9" > (15).toString(16) "f" > (16).toString(17) "g" "p"
> (25).toString(26) "p" "p"
> (25)["toString"](26) "p" "p"
> escape(" ") "%20" "%"
> Function("return escape")()(" ") "%20" "%"
> Function("return escape")()(" ")[0] "%" "%"
> Function("return unescape")()("%3b") ";" Any ASCII character
> (({}+[])[!![]+!![]+!![]]+[]+(![]+[])[+!![]]+(+(!![]+!![]+!![]+[]+ (+!![])))[(!![]+[])[+![]]+[]+({}+[])[+!![]]+[][(![]+[])[!![]+!![] +!![]]+[]+(![]+[])[!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!! []]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]] [({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+(![]+[])[+!![]]+(![]+[])[!![] +!![]]+(![]+[])[!![]+!![]]](+[![]]+[]+(!![]+[])[({}+[])[!![]+!![] +!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!! []+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+ ({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+
(!![]+[])[+!![]]])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!! []+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!! []]+(!![]+[])[+!![]]]([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+ [])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[]) [+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![] +!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+ [])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]] +(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]] +[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+ [])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!! []+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][!
[]]+[])[+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]] +[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]])) ())[+(+!![]+[]+(+!![]))]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+ [])[!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[+!![]]+[][(![]+[])[!![] +!![]+!![]]+[]+(![]+[])[!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![] +!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]] [({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+(![]+[])[+!![]]+(![]+[])[!![] +!![]]+(![]+[])[!![]+!![]]]((!![]+[])[({}+[])[!![]+!![]+!![]+!![] +!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!! []]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!!
[]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[]) [+!![]]]+[])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!! []]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+ (!![]+[])[+!![]]]([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[]) [+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+! []]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![] +!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!! []+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+ [])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[]) [+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[]) [+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![
]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][! []]+[])[+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]] +[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]])) ())[+(+!![]+[]+(!![]+!![]+!![]))]](+(!![]+!![]+!![]+[]+(!![]+!! [])))+(![]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+({}+[])[!![]+!![]+!! []+!![]+!![]]+(!![]+[])[+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!! []]+(+(!![]+!![]+[]+(!![]+!![]+!![]+!![]+!![])))[(!![]+[])[+![]]+[] +({}+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[])[!![]+!![]]+ ([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![] +!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]
+[]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]](+[![]] +[]+(!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+ ([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+ [])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!! []+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]])[(![]+[])[+![]]+[]+ ([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+ [])[+![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]]([][({}+[])[!! []+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+ [])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[]) [+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[]) [+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+
[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[]) [+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![] +!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]((!![]+ [])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+ [])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+!![]]+({}+[])[!![]+!![]+!! []+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![] +[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+(+!![]))]+(!![]+[])[+! []]+(!![]+[])[+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+([][! []]+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[])[!![]+!![]]+ ([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]
+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]] +[]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]]((!![]+ [])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+ [])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!! []]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[]) [+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]+[])[(![]+[])[+![]]+[]+([][! []]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+! []]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]]([][({}+[])[!![]+!! []+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[]) [!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+! []]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!!
[]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[]) [+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+! []]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![] +!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]((!![]+[]) [+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[]) [+![]]+(!![]+[])[+!![]]+([][![]]+[])[+!![]]+({}+[])[!![]+!![]+!![] +!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+ [])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+(!![]+!![]+!![]))]](+ (!![]+!![]+!![]+[]+(+![])))+(!![]+[])[+![]]) "javascript"
(({}+[])[!![]+!![]+!![]]+[]+(![]+[])[+!![]]+(+(!![]+!![]+!![]+[]+(+!![])))[(!![]+[])[+![]]+[]+({}+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+ [])[!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!! []]+[]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]](+[![]]+[]+(!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+ [])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[]) [+!![]]+(!![]+[])[+!![]]])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+ (!![]+[])[+!![]]]([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!! []]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+ [])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![] +[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][! []]+[])[+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+
(+!![]))]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[])[!![] +!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+(! []+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]]((!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[]) [!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!! []]]+[])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]] ([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[]) [+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][! []]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+ [])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+!![]]+ ({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+(!![]+!![]+!! []))]](+(!![]+!![]+!![]+[]+(!![]+!![])))+(![]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+!![]]+([][![]]+[]) [!![]+!![]+!![]+!![]+!![]]+(+(!![]+!![]+[]+(!![]+!![]+!![]+!![]+!![])))[(!![]+[])[+![]]+[]+({}+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[]) [!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+ []+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]](+[![]]+[]+(!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[]) [+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!! []]+(!![]+[])[+!![]]])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(!![] +[])[+!![]]]([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+ ([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[]) [+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+ [])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][! []]+[])[+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+ (+!![]))]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[+!![]]+[][(![]+[])[!![]+!![]+!![]]+[]+(![]+[])[!![] +!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[!![]+!![]+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+(! []+[])[+!![]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]]((!![]+[])[({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[]) [!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!! []]]+[])[(![]+[])[+![]]+[]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]] ([][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][![]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[]) [+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+[])[+!![]]+(!![]+[])[+!![]]][({}+[])[!![]+!![]+!![]+!![]+!![]]+[]+({}+[])[+!![]]+([][! []]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+![]]+({}+[])[!![]+!![]+!![]+!![]+!![]]+(!![]+[])[+![]]+({}+ [])[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+[]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+![]]+([][![]]+[])[+![]]+(!![]+[])[+!![]]+([][![]]+[])[+!![]]+ ({}+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]]+([][![]]+[])[!![]+!![]+!![]+!![]+!![]]+(![]+[])[!![]+!![]+!![]]+(+[![]]))())[+(+!![]+[]+(!![]+!![]+!! []))]](+(!![]+!![]+!![]+[]+(+![])))+(!![]+[])[+![]])
None