1 javascript 2.0: evolving a language for evolving systems waldemar horwat netscape
TRANSCRIPT
1
JavaScript 2.0: Evolving a Language for
Evolving Systems
Waldemar Horwat
Netscape
2
Outline
• Background
• Motivation
• Construct the JavaScript 2.0 language
• Process
• Conclusion
3
JavaScript History
• Web page scripting language invented in 1996 by Brendan Eich at Netscape
• Used in over 25% of web pages
• More than an order of magnitude more widely used than all other web client languages combined
4
Terminology
• LiveScript
• JavaScript
• Jscript
• ECMAScript
All the same language
No relation to Java
5
JavaScript Evolution
• JavaScript 1.0 in Navigator 2.0
• JavaScript 1.5 is most recent
• JavaScript 2.0 in 2003
6
JavaScript and ECMAScript
• JavaScript standardized by the ECMA TC39TG1 committee– ECMA 262– ISO 16262
• JavaScript 1.5 = ECMAScript Edition 3
• JavaScript 2.0 = ECMAScript Edition 4
• TC39TG1 leading the design of Edition 4
7
Outline
• Background
• Motivation
• Construct the JavaScript 2.0 language
• Process
• Conclusion
8
JavaScript 2.0 Motivation
• Evolving programs– Compatibility– Modularity– Safety– Interoperability with other languages
• Simplify common patterns– Class declarations– Type declarations– Attributes and conditional compilation
• Compatible with JavaScript 1.5
9
Programming in the Large
• Programs written by more than one person
• Programs assembled from components (packages)
• Programs in heterogeneous environments
• Programs that use evolving interfaces
• Long-lived, evolving programs
10
Non-Goals
• High-performance applications
• General language
• Language for writing huge programs
• Stripped-down version of existing language
11
Outline
• Background
• Motivation
• Construct the JavaScript 2.0 language
• Process
• Conclusion
12
JavaScript 2.0
JavaScript 1.5 +• Packages
13
Scenario 1
Librarypackage Searcher {
public function find(x) { while (x >= 0) if (a[x]) return a[x]; else x -= 2; return null;}}
14
Scenario 1
Library Web pagepackage Searcher {
public function find(x) { while (x >= 0) if (a[x]) return a[x]; else x -= 2; return null;}}
import Searcher;
var c = find(34);var d = find("42");
15
Scenario 1
Library Web pagepackage Searcher {
public function find(x) { x += 2; while ((x -= 2) >= 0) if (a[x]) return a[x]; return null;}}
import Searcher;
var c = find(34);var d = find("42");
16
Scenario 1
Library Web pagepackage Searcher {
public function find(x) { x += 2; while ((x -= 2) >= 0) if (a[x]) return a[x]; return null;}}
import Searcher;
var c = find(34);var d = find("42");// same as find(420)
17
Solution: Type Annotations
Library Web pagepackage Searcher {
public function find(x: Integer) { x += 2; while ((x -= 2) >= 0) if (a[x]) return a[x]; return null;}}
import Searcher;
var c = find(34);var d = find("42");// now same as find(42)
18
Type Annotations
• Optional• Strongly typed — type annotations are enforced• Not statically typed — only dynamic type of an
expression matters
class A { function f()}
class B extends A { function g()}
var a:A = new B;
a.f(); // OKa.g(); // OK
var x = new A; // OKvar b:B = x; // Error
19
JavaScript 2.0
JavaScript 1.5 +• Packages• Strong dynamic typing
20
Scenario 2
Library Web pagepackage ColorLib {
var red = 1;var green = 2;var blue = 4;
function set(color) …function drawPoint(x,y) …}
import ColorLib;
set(red);
drawPoint(3,8);
21
Scenario 2
Library Web pagepackage ColorLib {
var red = 1;var green = 2;var blue = 4;
function set(color) …function drawPoint(x,y) …}
import ColorLib;
set(red);red = blue;
drawPoint(3,8);
22
Solution: const
Library Web pagepackage ColorLib {
const red = 1;const green = 2;const blue = 4;
function set(color) …function drawPoint(x,y) …}
import ColorLib;
set(red);red = blue;
drawPoint(3,8);
23
JavaScript 2.0
JavaScript 1.5 +• Packages• Strong dynamic typing• const
24
JavaScript 1.5 Hoists Declarations
Scenario 3 Equivalent Codefunction f(x) { if (g(x)) { var a = x+3; b = 18; } else { var b = x; var a = "Hello"; } return a+b;}
function f(x) { var a; var b; if (g(x)) { a = x+3; b = 18; } else { b = x; a = "Hello"; } return a+b;}
25
Hoisting Problems
Scenario 3 Equivalent Codefunction f(x) { if (…) { const a = …; var b:Integer = …; } else { var b:String = …; const a = …; } return a+b;}
function f(x) { const a = ?; var b:?; if (…) { a = …; b = …; } else { b = …; a = …; } return a+b;}
26
Solution: Local Scoping
• const declarations are locally scoped• Typed declarations are locally scoped• Class member declarations are locally scoped• Declarations with attributes are locally scoped• That leaves plain var declarations
– Locally scoping would be an incompatible change
– Not locally scoped except in strict mode
27
Solution: Local Scoping
Scenario 3function f(x) { if (…) { const a = …; var b:Integer = …; } else { var b:String = …; const a = …; } return a+b;}
28
JavaScript 2.0
JavaScript 1.5 +• Packages• Strong dynamic typing• const• Local scoping• Strict mode
29
Scenario 4
Library Web pagepackage ColorLib {
function drawPoint(x,y) …}
import ColorLib;
drawPoint(3,8);
30
Scenario 4
Library Web pagepackage ColorLib {
function drawPoint(x,y) …}
import ColorLib;
drawPoint(3,8,true);
31
Scenario 4
Library 1.1 Web pagepackage ColorLib {
function drawPoint( x, y, color = black) …}
import ColorLib;
drawPoint(3,8,true);
32
Solution: Argument Checking
• Calls to functions with typed arguments are checked
• Calls to functions with typed result are checked• Arguments may be optional• Use ... for variable argument lists• That leaves plain, untyped function declarations
– Argument checking would be an incompatible change
– Not checked unless defined in strict mode
33
Scenario 4
Library Web pagepackage ColorLib {
function drawPoint( x:Integer, y:Integer) …}
import ColorLib;
drawPoint(3,8,true);
34
Named Function Parameters
function f(a: Integer, b = 5, named c = 17, named d = 3)
f(4)
f(4, d:6)
• Why is the named attribute needed?
35
JavaScript 2.0
JavaScript 1.5 +• Packages• Strong dynamic typing• const• Local scoping• Strict mode• Named and optional
arguments
• Argument checking
36
Why Classes?
• Ubiquitous idiom, even in prototype-based languages
• Few users get it right in JS 1.5 with prototypes• Difficult to evolve a program that uses prototypes
– Little knowledge of invariants
• Classes model cross-language interaction• Basis for access control• Potential efficiency gains• One of most-requested features
37
Class Definition Syntax
class Dance { const kind; var name: String; static var count; constructor function start(partner, length: Integer) {…}};
class Swing extends Dance { var speed: Integer; function acrobatics(): Boolean {…}};
38
Classes and Prototypes
• Classes and prototypes will co-exist• Language avoids early-binding the decision
of whether to use classes or prototypes– Access syntax identical: a.b, a["b"]– The dynamic keyword on a class enables its
instances to dynamically acquire new properties
• Classes can’t inherit from prototypes or vice versa
39
JavaScript 2.0
JavaScript 1.5 +• Packages• Strong dynamic typing• const• Local scoping• Strict mode• Named and optional
arguments
• Argument checking• Classes
40
Scenario 5
Name conflicts
Librarypackage BitTracker {
public class Data { public var author; public var contents; function save() {…}};
function store(d) { ... storeOnFastDisk(d);}}
41
Library Web pagepackage BitTracker {
public class Data { public var author; public var contents; function save() {…}};
function store(d) { ... storeOnFastDisk(d);}}
import BitTracker;
class Picture extends Data { function size() {…} var palette;};
function orientation(d) { if (d.size().h >= d.size().v) return "Landscape"; else return "Portrait";}
42
Library rev2 Web pagepackage BitTracker {
public class Data { public var author; public var contents; public function size() {…} function save() {…}};
function store(d) { ... if (d.size() > limit) storeOnSlowDisk(d); else storeOnFastDisk(d);}}
import BitTracker;
class Picture extends Data { function size() {…} var palette;};
function orientation(d) { if (d.size().h >= d.size().v) return "Landscape"; else return "Portrait";}
43
Library rev2 Web pagepackage BitTracker {
public class Data { public var author; public var contents; public function size() {…} function save() {…}};
function store(d) { ... if (d.size() > limit) storeOnSlowDisk(d); else storeOnFastDisk(d);}}
import BitTracker;
class Picture extends Data { function size() {…} var palette;};
function orientation(d) { if (d.size().h >= d.size().v) return "Landscape"; else return "Portrait";}
44
Library rev2 Web pagepackage BitTracker {
public class Data { public var author; public var contents; public function ?() {…} function save() {…}};
function store(d) { ... if (d.?() > limit) storeOnSlowDisk(d); else storeOnFastDisk(d);}}
import BitTracker;
class … extends Data {
?};
45
46
Non-Solutions
• Assume it won’t happen– It does, especially in DOM
• Have programmer detect/fix conflicts (C++)– Old web pages linked with new libraries
• Have compiler bind identifier to definition (Java)– Programs distributed in source form
• Explicit overrides + static type system (C#)– Doesn’t work in dynamic languages– Burden on library user instead of library developer
47
Solution: Namespaces
• Each name is actually an ordered pair namespace::identifier
• A use namespace(n) statement allows unqualified access to n’s identifiers within a scope
• Default namespace is public• Namespaces are values
Library Web pagepackage BitTracker {
public class Data { public var author; public var contents; function save() {…}};
function store(d) { ... storeOnFastDisk(d);}}
import BitTracker;
class Picture extends Data { function size() {…} var palette;};
function orientation(d) { if (d.size().h >= d.size().v) return "Landscape"; else return "Portrait";}
48
Library rev2 Web pagepackage BitTracker {namespace v2;use namespace(v2);
public class Data { public var author; public var contents; v2 function size() {…} function save() {…}};
function store(d) { ... if (d.size() > limit) storeOnSlowDisk(d); else storeOnFastDisk(d);}}
import BitTracker;
class Picture extends Data { function size() {…} var palette;};
function orientation(d) { if (d.size().h >= d.size().v) return "Landscape"; else return "Portrait";}
49
Library rev2 Web page rev2package BitTracker {namespace v2;use namespace(v2);
public class Data { public var author; public var contents; v2 function size() {…} function save() {…}};
function store(d) { ... if (d.size() > limit) storeOnSlowDisk(d); else storeOnFastDisk(d);}}
import BitTracker;use namespace(v2);
class Picture extends Data { function dims() {…} var palette;};
function orientation(d) { if (d.dims().h >= d.dims().v) return "Landscape"; else return "Portrait";}
… d.size() …
50
Library rev2 Web page rev2package BitTracker {explicit namespace v2;use namespace(v2);
public class Data { public var author; public var contents; v2 function size() {…} function save() {…}};
function store(d) { ... if (d.size() > limit) storeOnSlowDisk(d); else storeOnFastDisk(d);}}
import BitTracker, namespace(v2);
class Picture extends Data { function dims() {…} var palette; function size() {…}};
function orientation(d) { if (d.dims().h >= d.dims().v) return "Landscape"; else return "Portrait";}
51
52
Versioning
• Namespaces distinguish between accidental and intentional identifier matches
• Library publisher annotates new functionality with new namespaces
• Web page imports a specific namespace
• Versioning affects name visibility only — there is only one library implementation
53
Other Uses of Namespaces
• private, internal, etc. are syntactic sugars for anonymous namespaces
• Export private functionality to privileged clients
• Can use namespaces to add methods to an already existing class (future feature)
54
Property Lookup
Classes Lookupclass A { function f() // fA}
class B extends A { function f() // fB}
class C extends B { function f() // fC}
use namespace(public);
c = new C;c.f(); // fC
55
Classes Lookup 1class A { N function f() // fA}
class B extends A { N function f() // fB}
class C extends B { function f() // fC}
use namespace(public);
c = new C;c.f(); // fC
use namespace(public);use namespace(N);
c = new C;c.f(); // fB, not fC!
56
Lookup 2
57
Property Lookup c.f
• Find highest (least derived) class that defines a member f that’s visible in the currently used namespaces to pick a namespace n
• Find lowest (most derived) definition of c.n::f– Gives object-oriented semantics
58
JavaScript 2.0
JavaScript 1.5 +• Packages• Strong dynamic typing• const• Local scoping• Strict mode• Named and optional
arguments
• Argument checking• Classes• Namespaces,
versioning, and protection
59
Attributes
public var a;v2 v3 v4 var x;v2 v3 v4 function y(…) …;v2 v3 v4 function z(…) …;public const d;v2 v3 v4 const c;
60
Attributes
public var a;v2 v3 v4 var x;v2 v3 v4 function y(…) …;v2 v3 v4 function z(…) …;public const d;v2 v3 v4 const c;
public var a;v2 v3 v4 { var x; function y(…) …; function z(…) …; const c;}public const d;
Distributed Attributes
61
Attributes
public var a;v2 v3 v4 var x;v2 v3 v4 function y(…) …;v2 v3 v4 function z(…) …;public const d;v2 v3 v4 const c;
const v2_4 = v2 v3 v4;
public var a;v2_4 var x;v2_4 function y(…) …;v2_4 function z(…) …;public const d;v2_4 const c;
User-Defined Attributes
62
Attributes
static debug v3 final foo(3) bar var x:Integer = 5;
Restricted expressions that evaluate to:
• Built-in attributes such as final and static
• Namespaces• true or false (conditional compilation) • User-defined attributes
63
Attributes
const debug = true;
static debug v3 final foo(3) bar var x:Integer = 5;
const A = static debug v3;
A bar var y:Integer;
private { var z; function f();}
64
JavaScript 2.0
JavaScript 1.5 +• Packages• Strong dynamic typing• const• Local scoping• Strict mode• Named and optional
arguments
• Argument checking• Classes• Namespaces,
versioning, and protection
• Flexible attributes
65
Additional Types
sbyte, byte
short, ushort
int, uint• Subsets of Number (IEEE double)
• All arithmetic done as though on Number:int(1e9) * int(1e9) 1e18
66
Additional Types
long, ulong• Not subsets of Number• Values distinct from mathematically equal Number values, but coercable
• Exactly represent all integers between -263 and 264–1
67
Additional Types
float• Subset of Number
68
Additional Types
• Sparse arrays as in JavaScript 1.5
• Dense arrays
• Typed arrays
69
JavaScript 2.0
JavaScript 1.5 +• Packages• Strong dynamic typing• const• Local scoping• Strict mode• Named and optional
arguments
• Argument checking• Classes• Namespaces,
versioning, and protection
• Flexible attributes• Types for interacting
with other languages
70
Omitted Features
• Overloading
• Interfaces
• Units
• Operator overriding
• Wraparound integer arithmetic
• Lots of built-in libraries
71
Strict Mode Revisited
An implementation will run three kinds of programs:• JavaScript 1.5
– Run unchanged
• Non-strict JavaScript 2.0– Almost all JavaScript 1.5 programs run unchanged
• Strict JavaScript 2.0– Turns off troublesome quirks (scope hoisting, newline
dependencies, etc.)
72
Strict Mode
• Variables must be declared
• Function argument checking
• Function declarations are immutable
• Semicolon insertion changes
73
Outline
• Background
• Motivation
• Construct the JavaScript 2.0 language
• Process
• Conclusion
74
Process
• JavaScript 1.0 developed at Netscape– Later adopted by Microsoft – Later standardized by ECMA
• JavaScript 1.5 developed and standardized concurrently
• JavaScript 2.0 design discussions occur mainly within ECMA
75
Tools
• ECMAScript standards use semantic descriptions of the language
• Use extended typed lambda calculus with Algol-like syntax for ECMAScript Edition 4
• Wrote Common Lisp engine to:– Run and test grammar and semantics directly– Auto-generate web page descriptions– Auto-generate chapters of draft ECMAScript standard
• Freely available
76
ListExpression AssignmentExpression
| ListExpression , AssignmentExpression
proc Validate[ListExpression] (cxt: Context, env: Environment)[ListExpression AssignmentExpression] do
Validate[AssignmentExpression](cxt, env);[ListExpression
0 ListExpression1 , AssignmentExpression] do
Validate[ListExpression1](cxt, env);
Validate[AssignmentExpression](cxt, env)end proc;
proc Eval[ListExpression] (env: Environment, phase: Phase): ObjOrRef
[ListExpression AssignmentExpression] doreturn Eval[AssignmentExpression](env, phase);
[ListExpression0 ListExpression
1 , AssignmentExpression] dora: ObjOrRef Eval[ListExpression
1](env, phase);readReference(ra, phase);rb: ObjOrRef Eval[AssignmentExpression](env, phase);return readReference(rb, phase)
end proc;
77
Outline
• Background
• Motivation
• Construct the JavaScript 2.0 language
• Process
• Conclusion
78
Availability
• Open source (NPL, GPL, or LGPL)
• JavaScript 1.5 in C or Java
• JavaScript 2.0 in C++
• Compact, stand-alone sources
• Embed or run as a command line tool