A few questions and suggestions.
Just a quick word about this:
*** Exceptions
Currently, I really miss the ability to catch exceptions given it's
type. In the new ES spec, will the following code be possible?
Try { ... } catch(e : TypeError) { ... } catch(e : ReferenceError) { ... }
The correct syntax is in today's SpiderMonkey implementation already, and it goes like this:
try {...} catch (e if e instanceof TypeError) { ... }
In short: JavaScript supports conditional catches, and you can, of course, check the type of an error this way.
Michael
On Apr 29, 2007, at 8:24 PM, Michael Daumling wrote:
Hi Thiago,
Just a quick word about this:
*** Exceptions
Currently, I really miss the ability to catch exceptions given it's type. In the new ES spec, will the following code be possible?
Try { ... } catch(e : TypeError) { ... } catch(e : ReferenceError) { ... }
The correct syntax is in today's SpiderMonkey implementation already, and it goes like this:
try {...} catch (e if e instanceof TypeError) { ... }
In short: JavaScript supports conditional catches, and you can, of course, check the type of an error this way.
Actually, that's a SpiderMonkey extension proposed for ES3 and
rejected. We favored it instead of what ES3 forces you to do:
try { ... } catch (e) { if (guard1) ... else if (guard2) ... ... else if (guardN) ... else throw e }
where the guardN expressions involve e somehow. We observed that it's
easy to forget to rethrow on mismatch.
ES4 has catch (e : type) ... clauses, as Thiago wants.
On 4/30/07, Brendan Eich <brendan at mozilla.org> wrote:
The correct syntax is in today's SpiderMonkey implementation already, and it goes like this:
try {...} catch (e if e instanceof TypeError) { ... }
[...] ES4 has catch (e : type) ... clauses, as Thiago wants.
/be
Yes, as Brendan said, I found this at www.carsoncheng.com/Ecma/tc39-tg1-2006-001.pdf
By the way, I forgot to CC to this list a reply I sent to Brendan. So, I'm pasting it below (with minor corrections):
Hello Brendan,
On 4/27/07, Brendan Eich <brendan at mozilla.org> wrote:
Did you read through developer.mozilla.org/es4 ?
At the time I wrote the email, I just looked around it. Now, I belive I read most of it. Looking more carefully, I found answers for 2 questions mentioned in my previous email:
I think catchalls are pretty much what I was looking for when it comes to have something similar to Ruby's method_missing. Also, reading the tc39-tg1-2006-001.pdf answered my question about the exceptions (being able to specify exception types in the catch()). Thanks for the info.
Some of the questions remains, and a few more came to my mind. Here are my (updated) notes:
*** toSource()
I have found the "source" property for function objects in: developer.mozilla.org/es4/spec/chapter_19_native_objects.html
Knowing that such feature is agreed for the spec, I have two questions about it:
a) Currently, firefox returns "{[native code]}" for native function bodies when using toSource(). AFAIK the meaning of the "source" property is to return the actual source of the function. Even if native bodies can't be returned, I think it's awkward to return a string that is not syntax valid:
eval(eval.toSource()); //syntax error!
Is it appropriate to specify that native functions should return syntax valid code (in this case, a comment "/* native code */" could be used, instead)?
b) As I mentioned before, how about making comments part of the source? I like to think that the comment is part of the source as well ;) and, as I explained in my previous email, it would be great for programming UIs (things like Squeak's Class Browser, for example).
function f() { //say hello alert("hello") } print(f.source) //the comment "//say hello" is part of the string returned since it is part of the f's body
*** Access control
It is of my understanding that access control will be implemented using namespaces, as explained in: developer.mozilla.org/es4/spec/chapter_9_classes.html#access_control_namespace_attributes
So I ask: What about being able to define a namespace for an object's property without using the class declaration? What I'm really looking for is a way to define access control without being forced to use the new class declaration. For instance, something equivalent to:
private o.foo = "bar" //property "foo" is defined as private
*** include directive
I assume the include directive is also an accepted feature: developer.mozilla.org/es4/spec/chapter_16_directives.html
Reading it, I came up with two questions:
a) What happens if the file specified can't be read? b) What happens if the file included has syntax errors?
Personally, I would hope both situations to throw a catchable exception.
Thanks again,
a) Currently, firefox returns "{[native code]}" for native function bodies when using toSource(). AFAIK the meaning of the "source" property is to return the actual source of the function. Even if native bodies can't be returned, I think it's awkward to return a string that is not syntax valid:
eval(eval.toSource()); //syntax error!
Is it appropriate to specify that native functions should return syntax valid code (in this case, a comment "/* native code */" could be used, instead)?
Even better would be to return some source that just invoked the same function. For example, eval.toSource() would return "/* native function */ return eval(str);":
Then you could eval it, as you describe, and not only would it not throw an error but it would run as expected too...
Peter
On Apr 30, 2007, at 10:22 AM, Peter Hall wrote:
a) Currently, firefox returns "{[native code]}" for native function bodies when using toSource(). AFAIK the meaning of the "source" property is to return the actual source of the function. Even if native bodies can't be returned, I think it's awkward to return a string that is not syntax valid:
eval(eval.toSource()); //syntax error!
Is it appropriate to specify that native functions should return syntax valid code (in this case, a comment "/* native code */" could be used, instead)?
Even better would be to return some source that just invoked the same function. For example, eval.toSource() would return "/* native function */ return eval(str);":
Then you could eval it, as you describe, and not only would it not throw an error but it would run as expected too...
You can't eval a return statement or any such statement illegal in
the top level of a Program (the non-terminal goal for the grammar
that eval parses).
ok, in that case it doesn't make much sense to do any work to support evaling any source string from toSource().
Peter
On 4/30/07, Peter Hall <peter.hall at memorphic.com> wrote:
Even better would be to return some source that just invoked the same function. For example, eval.toSource() would return "/* native function */ return eval(str);":
Then you could eval it, as you describe, and not only would it not throw an error but it would run as expected too...
You can't eval a return statement or any such statement illegal in the top level of a Program (the non-terminal goal for the grammar that eval parses).
Which is why you'd want it to return:
function () { /* native function */ return eval.apply(this, arguments); }
or some such.
Mike
On 4/30/07, Peter Hall <peter.hall at memorphic.com> wrote:
ok, in that case it doesn't make much sense to do any work to support evaling any source string from toSource().
Peter
But, isn't this kindda odd? I mean, knowing what eval() do and what toSource() do, one assumes that they can (should?) be interoperable.
I belive that the code such as "eval(eval.toSource())" emitting an error breaks a presumable consistency. I know that being unable to actually have a native source evaluated already breaks this consistency, but injecting an invalid syntax string in it's source seems too much to me.
Thiago Silva wrote:
But, isn't this kindda odd? I mean, knowing what eval() do and what toSource() do, one assumes that they can (should?) be interoperable.
You also forget about cyclic structures. SpiderMonkey has sharp variables for this, but there's no concise ES3 way to serialize such structures. (You can hack it by constructing it in an evaluated closure in ES3, and let expressions provide a cleaner ES4 syntax, but it seems highly unlikely either will ever be spec-mandated.)
I know that being unable to actually have a native source evaluated already breaks this consistency, but injecting an invalid syntax string in it's source seems too much to me.
Just so you know, SpiderMonkey already injects invalid syntax into the generated string for a native method:
js> Array.prototype.push.toSource()
function push() {[native code]}
On 4/30/07, Thiago Silva <tsilva at sourcecraft.info> wrote:
*** include directive
I assume the include directive is also an accepted feature: developer.mozilla.org/es4/spec/chapter_16_directives.html
The committee agreed in their 27 July 2006 meeting to remove the "include" directive from the language, with the justification that "packages are better both semantically and from a performance point of view".
On 4/30/07, Thiago Silva <tsilva at sourcecraft.info> wrote:
*** Access control
It is of my understanding that access control will be implemented using namespaces, as explained in: developer.mozilla.org/es4/spec/chapter_9_classes.html#access_control_namespace_attributes
So I ask: What about being able to define a namespace for an object's property without using the class declaration? What I'm really looking for is a way to define access control without being forced to use the new class declaration. For instance, something equivalent to:
private o.foo = "bar" //property "foo" is defined as private
Based on this and your previous message I think what you're suggesting is that lookup though "this" should somehow be privileged (more like "protected" than "private"), so that "external" lookups cannot see all the properties that "internal" lookups can. Is that right?
Example:
function Account(initial) { this.balance = initial } Account.prototype = { withdraw: function (n) { if (this.balance < n) throw new OverdrawnError; this.balance -= n; }, deposit: function (n) { this.balance += n } }
var a = new Account(100)
The problem is that anyone can access the account a and manipulate the balance: "a.balance += 2000", and you'd like to hide the balance so that only withdraw and deposit can access it, and you want to do that without using classes.
You should be able to do something like what you want using namespaces and packages:
package Bank { namespace ns;
public function Account(initial) {
this.ns::balance = initial
}
Account.prototype = {
withdraw: function (n) {
if (this.ns::balance < n) throw new OverdrawnError;
this.ns::balance -= n;
},
deposit: function (n) { this.ns::balance += n }
}
}
Now a client would import the Bank package and use the public Account function to create the account:
import Bank.*; var a = new Account(100)
but the namespace "ns" is hidden and can't be forged by code outside the Bank package, so your money should be secure.
(However, since packages can't be sealed it is still possible for the attacker to put new code into Bank, just like it's possible to subclass non-final classes to get at "protected" methods and data. So the trick mostly works against accidental problems, not determined attacks.)
Hello Lars,
On 5/7/07, Lars T Hansen <lth at acm.org> wrote:
On 4/30/07, Thiago Silva <tsilva at sourcecraft.info> wrote:
*** Access control
It is of my understanding that access control will be implemented using namespaces, as explained in: developer.mozilla.org/es4/spec/chapter_9_classes.html#access_control_namespace_attributes
So I ask: What about being able to define a namespace for an object's property without using the class declaration? What I'm really looking for is a way to define access control without being forced to use the new class declaration. For instance, something equivalent to:
private o.foo = "bar" //property "foo" is defined as private
Based on this and your previous message I think what you're suggesting is that lookup though "this" should somehow be privileged (more like "protected" than "private"), so that "external" lookups cannot see all the properties that "internal" lookups can. Is that right?
Yes, that's right. I'm sorry about the poor example I gave.
[...] (However, since packages can't be sealed it is still possible for the attacker to put new code into Bank, just like it's possible to subclass non-final classes to get at "protected" methods and data. So the trick mostly works against accidental problems, not determined attacks.)
Yes, accidental problems are my big concern. Thanks a lot for your examples.
Hello, I'm happy to have found this list, since I care very much about the future of ECMAScript. As a student who is using ES for an academic project, I'm looking for some answers and, pehaps, suggest a few things (if I'm allowed to).
*** Exceptions
Currently, I really miss the ability to catch exceptions given it's type. In the new ES spec, will the following code be possible?
Try { ... } catch(e : TypeError) { ... } catch(e : ReferenceError) { ... }
*** Encapsulation
Another feature I miss in the current spec is the ability to deny direct access to an object's property (internal state) without the object itself being aware of such access/changes. I share the opinion that using closures to access local variables and it's performance impact doesn't seem to be a good choice as encapsulation mechanism.
Reading about the upcoming spec, I understand that the new class notation with access control for members (public, private,etc) will provide such mechanism. But I'm not a "class enthusiastic" when using ES because I like the idea of expanding the class declaration (like in ruby or smalltalk) to support highlevel definitions of an object, such as the famous "has_many" and the like in Ruby on Rails. Therefore, I appreciate the use of methods to define new classes of objects, such as:
Animal.subclass({ name: "Person", doc: "I define a Person object", attributes: "name email", //defines the properties, setters and getters methods: { ... }, has_many: "pets" });
But, when the new ES spec and implementations arrive, I fear that I will have to chose between two approaches when creating classes:
a) Define a class object using "class" and be able to control access to properties but not being able to extend the class notation (ie. with "has_many" or "doc" above);
b) Define a class object using functions instead of "class" (like the above approach) but not being able to control the properties access.
I didn't like very much the situation, so I ask: will/would it be possible to support some mechanism to define access control on properties? A reflection API offering such means, maybe? To illustrate:
o = new Object; o.name = "thiago"; o.name.setAccessControl("private"); o.name = "foobar"; //not possible.
Forgive the poor illustration. I appreciate having the access control as (meta) data just as I appreciate having the property "prototype" in the objects.
*** toSource()
I'm a great user of toSource(), so I ask: will it be in the new spec?
One thing I don't like about this function is that it ignores the comments writen in the function bodies. So:
function f() { //say hello alert("hello"); }
f.toSource(); // retuns 'function f() { alert("hello"); }'. //"//say hello" is not part of the source :-(
This is unfortunate, since I'm working on tools inspired on Smalltalk's class browser, object inspector, etc. Using such UIs to define classes, functions, etc, makes harder to maintain inline comments (if viable, at all). Anyway, if something like toSource becomes standard (and I hope so), wouldn't this make it more precise when it comes to it's meaning?
*** Ruby's method_missing (AS's __resolve / __call ?)
Other thing I miss: giving objects the oportunity to react to "improper" usage. This was suggested and explained in the following messages:
mail.mozilla.org/private/es4-discuss/2006-June/000079.html, mail.mozilla.org/private/es4-discuss/2006-June/000090.html
I also would like very much to see that in the new spec.
*** Function expression verbosity
Vassily Gavrilyak brought this in the thread: mail.mozilla.org/private/es4-discuss/2007-March/000456.html
I hope to see something like that as well, even tough, for what I understood, it seemed harder to come up with a good alterative syntax.
Not willing to ressurect the discussion, but I would like to say that I don't think, in any way, this is a matter of typing. I'm very pleased with Smalltalk block's syntax not because I only have to type a couple of brackets, but because a couple of brackets rightly and soundly are identified as a block object, as much as a literal array or object in ES. So, not much about compactness, but readability as literal values (hope my english is right).
Anyway, I think "function() {}" verbosity suppress the desire one have to brodly use it around the code as a literal value being transfered to properties, parameters, etc.
*** Thank you
I appreciate the members attention and I'm sorry if some of those issues are inappropriate, already discussed, or "too late" (it took a while for me to find this mailing list). I wait for your inputs.