Propose that we work as a group to jointly create a report as we go along today.
Presentation
Building a shared understanding of goals
Agreements
Disagreements
What steps we plan to resolve them
How much time will we alot to each?
Not a skilled programmer
Needs things to be really simple
Finds static typing difficult
Doesn't understand data hiding
Doesn't understand object-oriented programming
Writes small scripts for which speed isn't critical
Wants to write large scripts
Cares about object-oriented programming and data hiding
Wants packages and versioning mechanism
Thinks Interfaces are cool
Happy to use static typing
Cares about speed/size
Can we approach the design of ECMAScript 2 by working on the features of:
High performance statically typed language
classes
packages
interfaces
Novice-friendly, dynamically typed language
Easy to learn
Speed is not critical
as natural as possible
as smooth transition as practical from earlier versions
smooth interaction between code that uses types and those that don't
want to be able to evolve programs without breaking existing users' code
single program that works on a variety of environments and which adapts to each environment, e.g. to adapt to whether a particular library is present or not
to retain a lot of dynamism to be able to inspect objects/classes that haven't been seen before
want to support programming in the large - which makes static typing attractive
static versus strong typing - strong typing makes it practical to detect errors, static typing allows this to occur at compile time.
safety - if you declare something as private no one else can access it and nobody can replace your private method with one of theirs
abstraction - private is really private ie invisible outside the class or package
is this the same as C++? Does access equal visibility in C++ ?
Robustness - people generally don't write programs fully formed, and a good language makes it easy to evolve programs
e.g. adding a type annotation doesn't break the program, except in very rare cases (Waldemar) where the compiler should be able to alert you to
to change a member's visibility from private to protected etc.
all components of expressions should be 1st class values, so that you can split expressions into separate parts
Waldemar's example:
a = ((x+y)[z])(p, q, x).z;
which could be factored into
var f=(x+y)[z]; a = f(p, q, f).z
This kind of factoring should be possible. In C++ if f is given too general a type, the compiler will warn you that the second statement is in error.
All types for which knowledge of which might make a difference to the expression can be expressed in the type expressions of the language.
namespace independence
class C { field m; } // should be able to create another class with a field called M.
new style classes should be accessible by old-style code with out having to restructure the old code. It would be unacceptable to limit old code to accessing only ad hoc properties.
Achieving this compatibility shouldn't force you to give up the benefits of classes etc.
good for programming web pages, where compatibility is paramount
want it to be a good high performance language for applications where you can get access to native types
want to be able to access non-ECMAScript code dynamically and which you haven't seen before (security permitting)
to be able to run it on any device?
or to support different profiles?
but that leads to interoperability problems across vendors
try to agree on more concrete things rather than superficial high level agreements
classes with single-inheritance (not precluding multiple inheritance in a future versions
interfaces
as abstract classes (Java)
as per COM
semantics might be implementation dependent?
relationship to versioning
do we want to use the syntax:
class foo implements bar
syntax for using interfaces
syntax for declaring interfaces
the ability to export interfaces?
interfaces are related to static types
the ability to support multiple interfaces on a single class
in the COM world, interfaces offer namespace management similar to versioning
so perhaps drop versioning in favor of interfaces?
if you can declare that a class implements an imported defined interface it would make it easier to link it to external code
Question: interfaces are abstract classes and don't cost much to add once you have classes, right or wrong?
if you allow extension of interfaces, you are getting into multiple inheritance
some concerns about exporting interfaces from ECMAScript to other languages - perhaps we defer this capability for now?
we need to enable linkage into ActiveX and Java
strong user demand for a packaging mechanism
basis for hiding implementation
ability to cache packages permits more efficient use of network
the unit is a collection of classes which are written to work together
some sort of namespace control is critical
is there an anonymous package? can definitions exist outside packages?
should the package be a syntactic unit? YES
we have yet to define the syntax, e.g. whether we need to wrap { and } around the contents.
You have to be able to detect the end of the package
do classes declare which package they belong to?
how do you know whether you have seen the complete package? (this is separate from whether the package is one or more files) We have an agreement that we need to be able to find the limits of packages
we have a shared reluctance for binding the definition of packages to files
the use of an import mechanism to build a package from multiple files (needs to be declarative)
the use of an export mechanism and a way to rename classes and methods etc. on export
may want a textual inclusion mechanism?
the ability to declare that a package is a collection of classes without necessarily embedding the source for those classes?
precompiled packages
fields or slots
methods
static methods and variables
non-method functions and variables, as distinct from static functions/variables? NO (insufficient motivation)
distinct syntax for getters and setters? YES
motivation - allows you to change from assignment to functions without changes to dependent user's code
can we restrict ourselves to getters and setters for properties that don't take arguments?
can these be overridden in subclasses? Aren't these handled in the same way as normal methods, though?
Some concerns to be addressed, e.g. syntax.
a special syntactic construct? NO (we will follow Java)
Java sneaks initialization code in, but raises scoping issues, and what is the impact on old code?
can blocks introduce scopes or are our choices here limited by existing ECMAScript legacy?
when is initialization code executed?
can we instantiate a class before all of its body has been seen? We need more discussion on this.
How do we download packages? Some might be obtained locally while others are obtained from a server
what is the simplest approach?
desire to write code that works on different environments where not all the libraries are available. This motivates the introduction of a conditional compilation mechanism sensitive to the environment
if you wanted to provide different libraries for each set of environmental properties the different choices can lead to a proliferation of libraries
concerns about dependencies between packages and conditional compilation
does the streaming model effect the ability to compile packages offline or are additional restrictions needed?
we have agreement about introducing a mechanism that deals with the global scope - you can determine whether something is there or not.
circular dependencies between classes is quite common, we are less sure about the likelihood of circular dependencies between packages
what information do we need to decide on which way to go?
can we punt on streaming for now but leave the door open for adding it later?
yes, so long as declarations are provided before the things being declared are used
This would be invalid under this rule:
function foo( ) { x = 5 ... some time later ... var x; }
But note it is ok in the current (old) version of ECMAScript.
Herman would like to accept the following for backwards compatibility:
function foo( ) { x = 5 ... some time later ... if (a) var x; else var x; }
But wants to preclude x being declared with different types as in:
function foo( ) { x = 5 ... some time later ... if (a) var x : int; else var x : string; }
Waldemar: streaming closes Pandora's box which is otherwise opened by dynamic types
Rok drew up an example where a class is loaded asynchronously:
<!-- loads a Button class --> <object classid= ..../> <script> ... some code that wants to create and use a Button ... </script>
The example touches upon what the compiler does when Button hasn't yet been downloaded.
Chris writes:
var Button = GetJavaClass("Button"); // now create an instance of the new class var b:Button = new Button( ... )
Microsoft is concerned about complications of dealing with run-time type expression handling
Herman asks for a precise proposal document and a second document for ideas under discussion. Waldemar volunteers to flesh out the semantics in detail.
Microsoft will study the issue and get back to the group for the May meeting. This is predicated on a detailed write up of the semantics from Waldemar.
Herman would love a web-form based access to a trial implementation to test out his understanding. We need to check on progress in the April meeting.
typed variables, how shall we write these?
Waldemar proposes:
var integer a;
and
function f(integer a)
Won't people think if you can write:
function f(x)
then surely you can write:
x
to declare x. We had no consensus this.
Chris prefers:
// f returns a value of type T function f(x : T) : T { var x : T; // declares x of type T }
We agree that we don't want to repeat the precedent set by C++ which suffers from an ambigous grammar for type expressions
The current version of ECMAScript has have labels and labelled breaks, but not goto's. The use of : for labels could make it harder to define the grammar if we adopt : for type expressions
Waldemar would like to reserve syntax for future use:
{a:b, c:d}
The colon syntax could cause people confusion as it means that ECMAScript is no longer fully in the C/Java camp but is now mixing in syntax from the Pascal family.
We nevertheless provisionally agree to the colon syntax but will revisit this in the April meeting to give us all time to check back with our respective companies/customer base.
ECMAScript currently allows you to pass extra arguments without any annotations
Our proposed approach would require special syntax to indicate when methods/functions allow optional arguments
This presents problems for old code!
By saying your code is ECMAScript 2 the compiler can apply the new tight rules for the number of arguments
if you don't say which version of JavaScript your web page is written in, the script is interpreted as the old version of Javascript (not even as JavaScript 1.2)
what is the default - tight argument counts or not?
One proposal is to make tight argument counts conditional on type annotations being used by the function declaration. This is somewhat subtle, but avoids the need for pragmas
Sam proposes that tight argument counts are applied to methods but not to functions. He is scared by a language pragma approach
Waldemar thinks it is more important for functions and methods to work the same way - i.e. he disagrees with Sam's proposal.
Herman doesn't want to have to compile functions and methods to support var args.
We choose to punt on this decision for now. What new information is needed to solve this? Herman needs more time to think this over.
Herman writes an example. What does the following say about foo?
f = new foo()
Waldemar proposes we keep the same syntax as now. Herman asks what will typeof return when applied to f.
Perhaps the programmer started with:
function foo( )
and decided to change the code to define foo as:
class foo { }
typeof on f would now return foo rather than object
one option is to return object and offer a new typeof operator that deals with classes
another is for typeof to return the class object for foo rather than the string "foo".
we could spell the new typeof as:
f.getClass()
Herman now asks:
f instanceof Object
what about:
f.valueOf()
Waldemar asserts all objects are instances of Object. When applicable new objects support the same things as old ones.
Where is the prototype chain etc. for new kinds of objects?
f = new foo() bar.prototype = f; bar.prototype = foo;
Waldemar writes up:
class foo { method m() { } slot a; } f = new foo(); // foo has a method m function bar() { ... } bar.prototype = f; var g = new bar(); var foo x; // the following generate errors x = g; // g is of type f not foo g.m(); // f doesn't define m() // but this works (why?) g.a; // value of slot a of foo
Herman wonders why don't we take a leaf out of Java's book.
class foo { ... } x = foo.class; // the class object for foo x = foo; // the prototype of foo
The above deals with prototype based instances of new style classes. How valuable is this? Do we want to punt, if so where?
We agree that there is something worth exploring here. Can we find a solution that fits existing the expectations of existing users. Herman wonders about package private/public default and how that effects this topic.
Herman will write up a detailed proposal for review at the April meeting.
Herman wants to restrict access to private and protected fields to only references to this object, i.e. to prevent access to private/protected fields in other objects of the same class
Herman's rationale is that it would be hard to explain to folks that the new version of ECMAScript will slower for untyped variables that the current version. This would be true he asserts without the above restriction.
The implication of such a rule is that getters and setters to private fields have to be made public, making private data publically visible
Chris observes that making private variables override other references in the local scope is a simple way to evade this penalty
class X { private field y; method m(x) { // any reference to y must be // to the private field y x.y; } }
Most people find this rule to surprising. It would be too hard to sell to users.
Dave offers an alternative whereby the programmer annotates the reference to make the access explicit:
class Foo { private var f; method m (x) { x.Foo::f // refers to local f } }
Another possibility is to use a cast, e.g.
((Foo)x).f
Rok proposes we adopt Herman's suggestion that references to other objects from untyped variables is restricted to publics unless there is an annotation such as one of the above two choices, or you are using a statically typed variable.
The consequence of this is that adding the annotation can change whether you get the private field of some object or the public field of its base class.
class Foo extends Bar { public var f; } class Bar { private var f method m() { Foo y = new Foo(); y.f; // Foo::f y.Bar::f; // Bar::f ((Bar)y).f; // Bar::f } }
Herman proposes to junk package protected
Waldemar says its really important to users