Re: function hoisting like var

2008-08-02 Thread Yuh-Ruey Chen
FWIW, I definitely like this proposal more than any convoluted 
var-scoping block proposal.

I just don't see the value of adding var-scoping blocks for the added 
parser complexity, and problematic return/break/continue.

Even if the return/break/continue problem is solved, it shouldn't just 
be for var-scoping blocks - it should be generalized to first-class 
Ruby-esque block.

So if we ever want to add var-scoping blocks with proper 
return/break/continue, consider Ruby-esque blocks. Something like:

function treePreorder(tree, func) {
func(tree.value);
if (tree.left)
   treePreorder(tree.left, func);
if (tree.right)
   treePreorder(tree.right, func);
}

function treeContains(tree, x) {
treePreorder(some_tree, block(val) {
if (val == x) return true;
});
return false;
}

Though, I'd imagine implementing this would also be difficult (at the 
very least, non-trivial), and this example can be easily replaced with 
one that used exceptions/try/catch anyway.

-Yuh-Ruey

Igor Bukanov wrote:
> 2008/7/28 Ingvar von Schoultz <[EMAIL PROTECTED]>:
> >
> > {{ }} is just the same as a scoping function used on ES3:
> >
> >(function() { code })()
>
> As Lars Hansen has pointed out any proposal for a shorthand for
> (function() { code })() has to deal with break/continue/return inside
> the code. This is the the reason if anything I would prefer in ES3.1
> just shorthands for function definitions like
>
> function() expr  - equivalent to function () { return expr; }. This is
> already in ES4 and is implemented by at least on implementation
> (SpiderMonkey).
>
> or
>
> function optional_name { code } - equivalent to function
> optional_name() { code } - a hypothetical shortcut that would allow to
> write a pseudo-blocks like
>
> function {
> }();
>
> with clear emphasis that this is a lambda with usual rules for
> break/continue/return.
>
> Regards, Igor
> ___
> Es3.x-discuss mailing list
> [EMAIL PROTECTED]
> https://mail.mozilla.org/listinfo/es3.x-discuss
>
>   
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Namespaces on definitions

2008-04-15 Thread Yuh-Ruey Chen
I agree. I don't see why there should be multiple syntaxes that are as 
concise as each other and both have about equal precedent (AS3 vs. E4X). 
If in some futuer spec, properties can inhabit multiple namespaces, then 
we can consider the |ns1 ns2 ... var foo| syntax again.

-Yuh-Ruey

Waldemar Horwat wrote:
> My views on this are:
>
> - There should be only *one* syntax for specifying namespaces in definitions. 
>  It shouldn't be
>   ns::foo = xyz
> in one place (object initializers) and
>   ns var foo = xyz
> someplace else (variable definitions).
>
> - The historical reason I chose the syntax
>   ns var foo = xyz
> for ES4 was that I allowed the same definition to simultaneously go into 
> several namespaces:
>   ns1 ns2 ns3 var foo = xyz
> would create ns1::foo, ns2::foo, and ns3::foo, which would be aliases of the 
> same variable (not three different variables).  ES4 doesn't support that any 
> more, so this reason goes away and the issue can be reconsidered.
>
> Now that the issue has been brought up, I'm warming up to the syntax 
>   var ns::foo = xyz
> everywhere.  It's simpler to remember.  It doesn't match Java, but if that 
> were a goal then we should first change our type annotation syntax to that of 
> C++ and Java.
>
> Waldemar
>   
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Controlling DontEnum

2008-03-13 Thread Yuh-Ruey Chen
Garrett Smith wrote:
> The order of the boolean parameters is kind of annoying to have  to remember.
>
> Would it be OK to shorten the method?
>
> obj.__setProperty__("c"); // undefined value
> obj.__setProperty__("c", 2);
> obj.__setProperty__("c", undefined, "dontenum", "readonly");
> obj.__setProperty__("c", undefined, "dontdelete");
>   

Not sure what ES4 policy is on how to pass "flags". Obvious method 
should be named parameters, but ES3/4 lack that feature. I also don't 
recall any ES3/4 method that uses bitflags (e.g. Object.READ_ONLY | 
Object.DONT_DELETE) or any variant of such flags. So that leaves strings 
(as you have), or an array of strings, both of which are less efficient. 
Hmm, this gives me an idea - more below.

> -- or --
>
> obj.__setProperty__("c", undefined). // Reference type.
>   dontEnum().
>   readOnly().
>   dontDelete();
>   

That kind of defeats the purpose of setting all the flags during 
assignment, since this would allow you do so after assignment.

Ok, new suggestion based off previous ones:

obj.__setProperty__(prop, value)
obj.__setProperty__(prop, value, Object.DONT_ENUM)
obj.__setProperty__(prop, value, Object.READ_ONLY, Object.DONT_DELETE)
obj.__getPropertyAttribute__(prop, Object.READ_ONLY) // returns true or 
false

BTW, names subject to change (could be just DONT_ENUM, or 
Object.dontenum, or whatever).

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-13 Thread Yuh-Ruey Chen
Peter Hall wrote:
> >  The latter. It is weird, I agree. But the enumerator can easily be
> >  customized, so I want the default enumerator be as non-magical as
> >  possible - and therefore, as simple as possible. In fact, I'm a bit
> >  bothered that propertyIsEnumerable is a method of Object yet can be
> >  rendered useless when changing the enumerator - along this line of
> >  reasoning, one would think that such a specific method shouldn't be a
> >  method of Object at all, but rather the enumerator itself.
> >
>
> So how would you go about enumerating the properties of an arbitrary
> dynamic object, whose properties could be in namespaces?
>   

I thought there was an iterator that would enumerate all properties 
regardless of enumerability (including those in other namespaces), but 
apparently not. There should be such an iterator though.

> >  Yeah, I vaguely remember some discussion concerning multiple namespaces
> >  per property a long time ago (maybe a year ago). It was rejected
> >  probably due to complexity.
>
> Not being able to combine them effectively makes many of the initial
> proposal's use-cases useless, because two use-cases may arise
> simultaneously when integrating two codebases, and be irreparably
> conflicting.
>
> Peter
>   

What "initial proposal" are you talking about?

-Yuh-Ruey
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-13 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> If we end up making all namespaced properties non-enumerable, then we  
> may want a property iterator that returns the names of all properties  
> in a given object. Even if this is not in the standard, it's likely  
> to be an extension. Or it could be added in the future.
>   

Absolutely. In fact, I thought there was already an iterator that yields 
all properties regardless of enumerability, just that this iterator 
would not be the default iterator for objects. If it's not in ES4, it 
should definitely be there because it's essential for those that want to 
customize enumerability.

> The question of whether ES3+4 mixtures might not want enumerable ES3  
> properties to appear to be in a predefined-in-ES4 namespace seems to  
> me worth considering, at the limit as a future-proofing step.
>   

What do you mean by ES3+4 mixture - how would you tell that one part is 
ES3 and another part ES4, or how a program is pure ES4?

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-11 Thread Yuh-Ruey Chen
Peter Hall wrote:
> Yuh-Ruey Chen <[EMAIL PROTECTED]> wrote:
> >  Which gets me back to the cognitive load issue. Even with a name like
> >  'hidden', they may think they may have to do some funky syntax like
> >  |obj.hidden::other_ns::prop| do hide a prop in another namespace.
>
>
> This was confusing me... How would you define a property to have a
> qualified name and be in the dontenum namespace at the same time? Or
> are namespaced properties non-enumerable anyway? (That would feel
> wrong to me..)
>   

The latter. It is weird, I agree. But the enumerator can easily be 
customized, so I want the default enumerator be as non-magical as 
possible - and therefore, as simple as possible. In fact, I'm a bit 
bothered that propertyIsEnumerable is a method of Object yet can be 
rendered useless when changing the enumerator - along this line of 
reasoning, one would think that such a specific method shouldn't be a 
method of Object at all, but rather the enumerator itself.

> ES4
> doesn't currently have a way to express AND/OR namespace combinations.
>   

Yeah, I vaguely remember some discussion concerning multiple namespaces 
per property a long time ago (maybe a year ago). It was rejected 
probably due to complexity.

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-10 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> On Mar 9, 2008, at 3:01 PM, Yuh-Ruey Chen wrote:
>
> > Brendan Eich wrote:
> >> ES3 code can't detect namespaces, so arguably shouldn't care if we
> >> were to implement DontEnum using an open namespace. But this could be
> >> a problem for mixed ES3 and ES4 scenarios where the ES4 code does
> >> introspect via Name objects and is surprised to find "ES3" objects
> >> with qualified property names.
> >>
> >
> > I'm talking about how the enumerability (or lack thereof) of
> > Object.prototype.* are determined. Or are prototype methods also not
> > enumerable by default like fixtures?
>
> My reply was not meant to be an answer, but a question: should we  
> drop this dontenum-namespace idea because it will break ES3+ES4  
> mixtures where the ES4 code reflects on a property's namespace  
> qualifier by using a Name object?
>   

> > Does this included ES3-style prototype methods? And would it
> > be possible to init a fixture to be enumerable?
>
> In the sketch I mailed, you didn't see any mention of fixtures --  
> IIRC you asked about them in reply. Just to explain what my proposal  
> was aiming to do: It seems to me that if we have to add a magic bit  
> back into the skinny is-it-enumerable decision tree, we may as well  
> keep DontEnum.

> > And the RI does print
> > it, so I'm not sure what you're talking about.
>
> The RI is (a) not normative (nothing apart from ES3+fixes is yet),  
> (b) based on a DontEnum attribute model, not on my proposal. Not sure  
> why you thought I was talking about it. I was making a new proposal.
>   
Ok, that cleared things up a bit. I didn't realize you were making a 
proposal and asking questions based off it :) I thought you were 
mentioning how the RI was implemented today at the moment.

Can you elaborate on cases where "ES4 code does introspect via Name 
objects and is surprised to find "ES3" objects with qualified property 
names."? I can't think of any.

> > BTW, what exactly is a fixture?
>
> That's a good question, and it seems the answer is not in the wiki.  
> Trying the trac:
>
> http://bugs.ecmascript.org/ticket/233
>
> which references the overview document.
>
> In ES3 terms, a fixture is a property with the DontDelete attribute set.
>
> But there's more to it than that, for reasons expanded on in #233 to  
> do with namespace lookup and early binding. And there is another case  
> that Lars pointed out recently to do with dynamic classes, but I'll  
> avoid trying to summarize it except to say that a fixture is a fixed  
> property that can't be deleted or shadowed.
>   

Thanks, that's a good summary, though some of the commentary in the 
ticket was confusing (like lth's example - was x.toString decided to be 
ambiguous?).

> >> Is that the right design?
> >>
> >> dynamic class C {
> >>  public var fixture;
> >>  function C() { this.expando = 42; }
> >> }
> >> for (var i in new C)
> >>  intrinsic::print(i);
> >>
> >> wouldn't you expect to see "expando" printed? Is it printed because
> >> the default namespace for expando is the public-default one? I
> >> believe it is not, in the current proposal and the RI. Rather, each
> >> class or package gets a nonce-named public namespace, different from
> >> every other such per-class or per-package public. IIRC package trumps
> >> class -- classes within a package share the package's nonce-named
> >> public namespace (Jeff, Lars, please correct me if I'm wrong).
> >>
> >
> > I meant non-expando vars and methods defined within the class,  
> > whatever
> > the terminology is used (I see 'fixture' thrown around everywhere), are
> > not enumerable. So yes, expando should be printed.
>
>  From your numbered steps above, step 3 must have been reached -- so  
> expando is in the public-public (null qualifier in Name object  
> reflection) namespace. Not in the class-C-public namespace. My  
> question is whether that is the right design choice.
>   

Are they any particular disadvantages that you can think of? Maybe 
another ES4 designer can chime in here.

BTW, a bit off topic: if a class is defined in a namespace, are the 
properties of that class also defined in that namespace (instead of just 
public/class-public)? Namespaces aren't clearly specified in the wiki or 
the overview, the tickets are unorganized, and the RI tends to barf when 
it comes to them. Ugh, I feel Apple's pain when they complain that they 
don

Re: ES4 draft: Object

2008-03-09 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> On Mar 8, 2008, at 1:16 PM, Yuh-Ruey Chen wrote:
> > But doesn't DontEnum still have to be there for ES3 objects? How else
> > would you prevent the enumeration of ES3 builtin methods, e.g.
> > Object.prototype.toString()? Or is there some more open namespace  
> > magic
> > that I'm unware of?
>
> ES3 code can't detect namespaces, so arguably shouldn't care if we  
> were to implement DontEnum using an open namespace. But this could be  
> a problem for mixed ES3 and ES4 scenarios where the ES4 code does  
> introspect via Name objects and is surprised to find "ES3" objects  
> with qualified property names.
>   

I'm talking about how the enumerability (or lack thereof) of 
Object.prototype.* are determined. Or are prototype methods also not 
enumerable by default like fixtures?

Let me get this straight. The rules of enumerability are:
1) If a property is a fixture, it's not enumerable. BTW, what exactly is 
a fixture? Does this included ES3-style prototype methods? And would it 
be possible to init a fixture to be enumerable?
2) If a property is not in the public namespace, it's not enumerable.
3) Otherwise, it is enumerable.
4) No hidden DontEnum attribute.

Are we trying to simplify this to the last three rules using some 
namespace voodoo to handle the fixture rule? I'm confused.

> > Well, I think the only overlap is that public-in-class-context methods
> > (or any method really) default to be non-public in terms of  
> > enumerability
>
> Is that the right design?
>
> dynamic class C {
>  public var fixture;
>  function C() { this.expando = 42; }
> }
> for (var i in new C)
>  intrinsic::print(i);
>
> wouldn't you expect to see "expando" printed? Is it printed because  
> the default namespace for expando is the public-default one? I  
> believe it is not, in the current proposal and the RI. Rather, each  
> class or package gets a nonce-named public namespace, different from  
> every other such per-class or per-package public. IIRC package trumps  
> class -- classes within a package share the package's nonce-named  
> public namespace (Jeff, Lars, please correct me if I'm wrong).
>   

I meant non-expando vars and methods defined within the class, whatever 
the terminology is used (I see 'fixture' thrown around everywhere), are 
not enumerable. So yes, expando should be printed. And the RI does print 
it, so I'm not sure what you're talking about. Are you saying that each 
property is defined in a "class-specific public" namespace, and 
therefore does not get enumerated? I would say that expando properties 
should be defined in the "global public" namespace, so that they would 
be enumerated.

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-08 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> > - Users may think this dontenum namespace is magical and yet another
> > thing to keep in mind, when it really just relies on the namespace  
> > trick
> > you mentioned. With the introduction of classes and namespaces, the
> > rules of enumerability are already more complex, so this adds to the
> > cognitive load slightly.
>
> Slightly, but it takes away the magic DontEnum attribute, formerly  
> hogged by the specification and magic predefined objects.
>   

But doesn't DontEnum still have to be there for ES3 objects? How else 
would you prevent the enumeration of ES3 builtin methods, e.g. 
Object.prototype.toString()? Or is there some more open namespace magic 
that I'm unware of?

> > BTW, if setPropertyIsEnumerable() is added,
> > would it be possible to make fixtures enumerable? Enumerability is
> > orthogonal to static analysis (which fixtures are meant to help with),
> > so I don't see why not.
>
> This gets to the heart of the public vs. public-in-context-of-class- 
> or-package issue. We need to sort this out to find out exactly how  
> orthogonal enumerability is, as well as decide how flexible it should  
> be.
>   

Well, I think the only overlap is that public-in-class-context methods 
(or any method really) default to be non-public in terms of enumerability

> > - The name sucks :p
>
> Indeed. How about 'hidden' or 'nonEnumerable'?
>   

I'd prefer 'hidden', since 'nonEnumerable' implies more strongly that a 
prop needs to be in that namespace to not be enumerable, when that's not 
the case.

Which gets me back to the cognitive load issue. Even with a name like 
'hidden', they may think they may have to do some funky syntax like 
|obj.hidden::other_ns::prop| do hide a prop in another namespace.

While we're on the topic of namespaces, I read in the ES4 overview: "In 
addition, the names internal, public, protected, and private denote 
namespace values, but the values depend on the context of the use." As 
the wiki doesn't talk about this, and the online spec is 
inaccessible/outdated, can you elaborate on this? I wonder if 'private' 
could be used somehow for enumerability.

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-07 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> Suppose we had a predefined, open namespace, say dontenum  (surely  
> not the best name). If you write
>
> obj = {dontenum::cant_see_me: 33}
>
> then
>
> for (i in obj) print(i)
>
> shows nothing. But
>
> obj.cant_see_me
>
> works, because dontenum is always open. No more need for an  
> orthogonal DontEnum attribute.
>
> Instead of
>
> obj.propertyIsEnumerable('i_want_to_hide', false)
>
> users would just say
>
> obj.dontenum::i_want_to_hide = ...
>   

Interesting and clever proposal. Some thoughts:

- It would become harder to change the enumerability of a property 
(compared to a enumerability method): |obj.prop=obj.dontenum::prop; 
delete obj.dontenum::prop;| That said, I'm not sure there are many use 
cases that involving changing enumerability after the prop's 
enumerability is initially defined.

- If you add setPropertyIsEnumerable(), how would that interact with 
this? Would it change the namespace as described above, or just toggle 
the hidden DontEnum attribute?

- Users may think this dontenum namespace is magical and yet another 
thing to keep in mind, when it really just relies on the namespace trick 
you mentioned. With the introduction of classes and namespaces, the 
rules of enumerability are already more complex, so this adds to the 
cognitive load slightly. BTW, if setPropertyIsEnumerable() is added, 
would it be possible to make fixtures enumerable? Enumerability is 
orthogonal to static analysis (which fixtures are meant to help with), 
so I don't see why not.

- The name sucks :p

> > Object.prototype.iterator::setPropertyIsEnumerable(prop,
> > enable). For consistency, you could also have
> > Object.prototype.iterator::isPropertyEnumerable(prop) which  
> > delegates to
> > Object.prototype.isPropertyEnumerable(prop).
>
> Clever relocation of "is" in the predicate names ;-). We're probably  
> stuck with propertyIsEnumerable.
>   

Honestly, that wasn't intentional - it just came off my fingers naturally :)

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-07 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> To avoid injecting a public name into Object.prototype, we could put  
> a new "setPropertyIsEnumerable" (yechh) name in the __ES4__  
> namespace. Then there's no breaking change. We do this already, of  
> course, but not for property attribute fiddling.
>   

Since enumerability only applies to for-in, how about the iterator 
namespace? Object.prototype.iterator::setPropertyIsEnumerable(prop, 
enable). For consistency, you could also have 
Object.prototype.iterator::isPropertyEnumerable(prop) which delegates to 
Object.prototype.isPropertyEnumerable(prop).

> An alternative we've discussed, which Ian also brought up: add a  
> keyword for declaring DontEnum properties.

This dontenum modifier can be used in addition to the method for 
convenience - it would make class declarations cleaner.

But despite that, I think dontenum is inelegant. Its only effect would 
be on the default enumerator, which is only one iterator, and AFAIK is 
not special at all. IMO, it isn't worth the bloat. If there was a way to 
define such modifiers within script, then I think the dontenum modifier 
would be nice. If such a capability is planned for a future ES edition, 
then I think dontenum is fine.

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Name

2008-03-05 Thread Yuh-Ruey Chen

Lars Hansen wrote:



  Name (a, b=…)

*Description*

The |Name| class object called as a function creates a new |Name| 
object by passing its arguments /a/ and /b/ to the |Name| constructor.


*Returns*

The |Name| class object called as a function returns a |Name| object.

*Implementation*

static meta function invoke(a, b=undefined): Name
new Name(a, b);
  


If a is already a Name, shouldn't Name(a) simply return a? Not sure what 
the policy on this is, but if you've changed Map to work similarly, then 
I don't see why not here as well.


-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Add call and apply methods to RegExp.prototype

2007-12-23 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> On Dec 21, 2007, at 7:33 AM, StevenLevithan wrote:
>
> > Yes, its easy to pull off oneself, so I don't care much other way.  
> > Still, it
> > seems pretty weird to me to be able to do ``regex(str)`` but not
> > ``regex.call(context, str)``. This is accentuated when typeof returns
> > "function" for regexes (though it seems ES4 will change this to  
> > "object").
>
> Hey Steve, Yuh-Ruey (I owe both of you replies to the list, for Steve  
> agreeing about ES3 capturing paren broken design, Yuh-Ruey on fine  
> points about instanceof, etc. -- I wanted to drop a note here,  
> quickly, and catch up next week while I'm off).
>   

I'm glad you still remember it :)

> This raises the question: since there is only one argument to exec or  
> test, so why do you ever need to delegate invocation using apply or  
> call? The only case that comes to mind is a generic programming use- 
> case where you might have either a function object or a regexp and  
> you want to .apply it with an argument array. But again, you could  
> just invoke foo(arg) given foo denoted either a function or a regexp.  
> True, the most generic program would not want to hardwire argument  
> count, so would want .apply. But still, the motivation for call and  
> apply in RegExp.prototype seems weak.

With currying, I find that use case a moot point. For example, we could do:

foo(regex.exec.bind())

and foo would still be generic. So really, regex invocation is not
needed. Speaking of bind (or whatever it's called), I hope the function
is memoized, since it might be used a lot.
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Add call and apply methods to RegExp.prototype

2007-12-21 Thread Yuh-Ruey Chen
Sounds like a good idea to me. On the other hand, this can already
easily be done in ES3.

Steven L. wrote:
> ES4 proposals include making regexes callable as a function on a
> single string argument, which serves as a shorthand for calling the
> regex's exec method. To further extend this idea, what about also
> including call and apply methods on RegExp.prototype, so that regexes
> can more easily be used with functional programming? For e.g., if one
> were to model a "where" function after JS 1.6's Array.prototype.filter
> like so:
>
> function where (array, func, context) {
> var results = [];
> for (var i = 0; i < array.length; i++) {
> if (func.call(context, array[i], i, array))
> results.push(array[i]);
> }
> return results;
> }
>
> ...They could then use, e.g., where(["ab", "ba", "a", "b"], /^a/) to
> return all array elements starting with the letter "a" (["ab", "a"]).
>
> Thoughts? Is this possibly already included in the proposals? (sorry
> if I missed it)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: need some clarification on compile-time type vs. run-time type

2007-11-19 Thread Yuh-Ruey Chen
More clarifications and updates to my proposal:

Yuh-Ruey Chen wrote:
> The only real non-syntactic issue between type exprs and value exprs is
> that in type exprs, the identifiers must be fixed type properties.
> Everything else, such structural types and function types (ignoring the
> identifiers), is fixed. For ex, |{p: x}| will always mean the same
> thing, given that x is a fixed type; it can't be mutated. The rest of
> the issues are syntactic ambiguities. So for each of these ambiguities
> that I'm aware of, I'll either prefix it with |type| or "match" the
> semantics between the value and type expr. Note that |type| is no longer
> an operator; it can only be used in certain situations as listed below
> (and as the type declaration/alias statement).
>   

Just realized a problem. The grouping operator (parentheses) means
something different for type exprs and value exprs. Type exprs can only
nest type exprs within parenthesis, while value exprs can nest any value
expr within them. Couple choices here:

1) Leave this is a distinction between type expr and value expr.
Downside to this is that type expr and value expr won't fully be unified
(and the downside to that has been amply discussed).

2) Eliminate the ambiguity in the grammar. Introduce |type (...)|.
Downside is the verbosity and possible confusion as to when to use |type
(...)| rather than |(...)| (or at least why they have to be different).

3) Don't change the grammar and handle the ambiguity by keeping track of
whether a particular expression resolves to a type and throwing early
errors when we're in a type expr context and we're trying to perform an
illegal operation on the type (e.g. non-type operators like +). Since
types are computed early, determining whether a particular expr resolves
to a type can also be computed early, so this type of processing can be
done. I have some experience making a pseudo-C parser, and this is
similar to keeping track of whether an expr is an lvalue. In essence,
the term "type expr" is not a grammar production and is unrelated to
operator precedence; it's an "aspect" of an expression (just like
lvalues). Downside to this is that it complicates the parser logic.

I think (3) is the best solution. It's the most convenient for the user.
It does make the learning curve slightly steeper in that now the user
needs to keep in mind that type exprs cannot contain non-type exprs AND
in type annotations and all type operators besides |is| and
|instanceof|, type exprs must contain only fixed type prop identifiers.
But I don't think it's that bad.

Also, although it's not strictly necessary to keep the "type exprs only
nest type exprs" principle outside of type annotations et al., I think
it makes type annotations and |is| more coherent, in that the only
difference between them is the fixed type prop identifier restriction.
BTW, we really need a term that represents type exprs in type
annotations et al.; it's getting repetitive to say "type exprs in type
annotations and all type operators besides |is| and |instanceof|" all
the time...

> 2) union types:
> Create a new union meta-object type so that "x | y", where both x and y
> are meta-objects, evaluates to a meta-object of this type representing
> the union of the types within x and y. The enclosing parentheses can be
> omitted, but |()| still means the bottom type. Thus, the parenthesis
> only purpose now is grouping. However, since |is| and |instanceof| have
> higher precedence than "|", the parentheses must be used for "|" in
> those exprs.
>   

The way I've defined the union operator here introduces another value
vs. type expr conflict. Although pretty nifty, it would allow exprs
like: "x | func()" or "(b? int : double) | string", which shouldn't be
allowed in type exprs considering that type exprs should only nest other
type exprs. The precedence of "|" also poses an issue since it's
completely different from that of type primaries. The operands of "|"
can not only be type primaries but also any value expr with higher
predence than "|". This violates the principle that type exprs can only
nest type exprs.

I think solution (3) above can handle this though with some
modification, especially because it redefines the term "type expr" to
have nothing to do with operator precedence. Specifically, if an operand
of "|" resolves to a type, throw early errors if the other operand
doesn't resolve to a type. This would invalidate and throw early errors
for the above "|" examples.

> 4) type parameters:
> With the above changes, not sure if anything needs to be changed since
> type exprs are now a subset of value exprs.

I'm wrong here because th

Re: Exception handling vs. hasNext()

2007-11-19 Thread Yuh-Ruey Chen
Garrett Smith wrote:
> How is it possible to iterate over the keys in a Map? I'd like to
> avoid using try/catch, unless something in the loop body might require
> it, and in that case, I'll want to be very clear on what might throw
> an exception, how, and why, as well as provide correct handling of
> that exception. Is there a way to get a maps keys as an Array?
>   

I think you're misunderstanding how iterators work. You don't need to
explicitly use the next() method or catch StopIteration. Please look at
how Python does it. There are plenty of examples on the web; here's one:

for x in range(10):
print(x)

which is practically equivalent in ES3 to:

for (let x = 0; x < 10; ++x)
print(x);

The Python for-in is equivalent in ES4 (assuming range is defined
equivalently) to:

for (let x in range(10))
print(x);

This practically translates to:

let $iter = range(10);   // $iter not visible to rest of code
try {
for (;;)
{
  let x = $iter.next();
  print(x);
}
} catch (e: StopException) {}

As you can see, the for-in loop syntax completely hides the next() and
StopIteration. It's definitely not as cumbersome as you think - in fact,
it's even easier to use than hasNext()/next()-style iterators.

To answer your specific question, Map should have a getKeys() method
(according to the wiki) that returns an iterator iterating over the keys
of the map:

for (let k in map.getKeys())
print(k);

FYI, the original ES3 for-in is actual a special case of the ES4 for-in.
When you do |for (let p in obj)|, it's actually iterating over obj's
intrinsic iterator (obj.iterator::get() according to the wiki), which
enumerates obj's properties, just like what it does in ES3.

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: need some clarification on compile-time type vs. run-time type

2007-11-17 Thread Yuh-Ruey Chen
Yuh-Ruey Chen wrote:
> If the main problem is that value exprs and type exprs are incompatible,
> then why not make them compatible? Make it so that the only difference
> between the two is that type-expr-like value exprs evaluate to
> meta-objects and actual type exprs require fixed type properties. With
> these as the only two differences and with no exceptions, I hope it will
> be as intuitive as possible. The additional benefits is that type exprs
> can be used much more freely since they will be a subset of value exprs.
> Since the syntax of value exprs is fixed (due to compatibility
> constraints), the only way to do this is to adjust the syntax of type
> exprs. And this is where I'll violate the syntax brevity goal, which may
> not be such a bad thing since it the intent of the syntax is now more
> clear. Now to get into details:
>
> The only real non-syntactic issue between type exprs and value exprs is
> that in type exprs, the identifiers must be fixed type properties.
> Everything else, such structural types and function types (ignoring the
> identifiers), is fixed. For ex, |{p: x}| will always mean the same
> thing, given that x is a fixed type; it can't be mutated. The rest of
> the issues are syntactic ambiguities. So for each of these ambiguities
> that I'm aware of, I'll either prefix it with |type| or "match" the
> semantics between the value and type expr. Note that |type| is no longer
> an operator; it can only be used in certain situations as listed below
> (and as the type declaration/alias statement).

Also, the elimination of the separation between type exprs and value
exprs in favor of focusing on fixed type properties vs. non-fixed
properties should be vaguely familiar with C++ programmers. If you
consider fixed type properties in type exprs as a form of C++ "const",
then it's similar in that you have to make sure everything that
everything that is const, only contains const exprs, and ultimately
const identifiers. Actually, a more proper analogous example would be
C++ templates, which work on the equivalent of ES4 fixed types (and
const values). This fixed vs. non-fixed distinction is the only thing
users need to be aware of - otherwise, they can mix and match type and
value exprs freely. That's why I argue that this is easier to grasp (or
at least more familiar) than the current type expr vs. value expr
distinction.

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Bringing up the issue of numerical constraints again

2007-11-17 Thread Yuh-Ruey Chen
Is it not possible to emulate this already with classes? I think you can
use the implicitly-called construct method, e.g.

class myint {
private var i: int;
function myint(x: int) {
   this.i = int;
}
meta static function invoke(x: int) {
   if (x > SOME_MAX_VALUE || x < SOME_MIN_VALUE)
  throw some_error;
   return new myint(x);
}
}

Or something like that. Above code is probably wrong. I'm not sure
exactly when and how invoke is called or even what the implicit type
conversion customization protocol is.

However, if it isn't possible to create a class to emulate such
constraints, maybe we ought to do something about it...

-Yuh-Ruey Chen

liorean wrote:
> Hello!
>
> Since we now have a namespace for uint specific math operations, and
> discussion in another thread about using pragmas for throwing if
> assigning to ReadOnly properties... Is it possible we could have a
> look at the idea of adding constrained primitive types or adding a
> pragma changing the mechanism for, or adding a separate set of
> operations, constraining number types by the simple rule of (input >
> output_type.MAX_VALUE) and (input < output_type.MIN_VALUE) throwing an
> out-of-bounds error.
>
> I'm a little concerned that a type of uint allows assigning negatives
> with a silent round-the-corner conversion and allows values of NaN and
> Infinity. (I imagine for example the DOM interfaces that have uint
> constraints really would like these to throw an out-of-bounds
> exception or similar.)
>
> Also, the RI gives an Overflow exception for values 2^32 or greater,
> which I'm not sure whether it's the intended behaviour or a result of
> the underlying implementation that is in fact intended to fail
> silently like the other cases.
>
> >> function fn(input:uint):uint input;
> >> fn(0x7fff);
> 2147483647
> >> fn(-0x8000);
> 2147483648
> >> fn(Infinity);
> 0
> >> fn(NaN);
> 0
> >> fn(0x1);
> unhandled exception: Overflow
>
> >> function fn(input:int):int input;
> >> fn(0x7fff)
> 2147483647
> >> fn(0x8000)
> -2147483648
> >> fn(-0x8000)
> -2147483648
> >> fn(NaN)
> 0
> >> fn(Infinity)
> 0
> >> fn(0x1)
> unhandled exception: Overflow
>   
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: need some clarification on compile-time type vs. run-time type

2007-11-17 Thread Yuh-Ruey Chen
pe exprs, the identifiers must be fixed type properties.
Everything else, such structural types and function types (ignoring the
identifiers), is fixed. For ex, |{p: x}| will always mean the same
thing, given that x is a fixed type; it can't be mutated. The rest of
the issues are syntactic ambiguities. So for each of these ambiguities
that I'm aware of, I'll either prefix it with |type| or "match" the
semantics between the value and type expr. Note that |type| is no longer
an operator; it can only be used in certain situations as listed below
(and as the type declaration/alias statement).

1) structural record and array types:
Require prefixing with |type|. e.g. |type {p: int}|.

2) union types:
Create a new union meta-object type so that "x | y", where both x and y
are meta-objects, evaluates to a meta-object of this type representing
the union of the types within x and y. The enclosing parentheses can be
omitted, but |()| still means the bottom type. Thus, the parenthesis
only purpose now is grouping. However, since |is| and |instanceof| have
higher precedence than "|", the parentheses must be used for "|" in
those exprs.

3) function types:
Require prefixing with |type|, e.g. |type function(a: int): void|.

4) type parameters:
With the above changes, not sure if anything needs to be changed since
type exprs are now a subset of value exprs.

Furthermore, now that type exprs and value exprs are unified, |is| can
now accept value exprs. For type annotations, type declarations, and
every other type operator besides |is| and |instanceof| (and |new|), if
any identifier would resolve to a non-fixed type property, then throw a
syntax error. As for future-proofing, we just have to make sure that new
type exprs are unambiguous and prefix the new syntax with |type| as
necessary.

With this I should meet all goals except the brevity one, and even that
goal isn't violated very much. So what does this all mean? I love
examples, so I'll be liberal with them:

Given:
type T1 = int
type T2 = double
V1 = int
V2 = double

// valid (note how V1 and V2 are freely used):
x is int
x is type {p: int}
x is like int
x is like type {p: int}
x is (T1 | T2)
x is V1
x is (V1 | T2)
x is {p: V2}
x is (like V1 | type {p: V2} | string)
x is ()
x is (T1)
x is (V1)
x is [like V2]
x is type function(a: T1, b: type {p: V1}): V2

// invalid (|type| is no longer an operator):
x is type int
x is type T1
x is type V1

// although "|" has low precedence, that precedence is higher than
statements and type annotations
type T3 = T1 | T2
V3 = T1 | V2
var x: T1 | T2
function foo(a: T1 | T2)

// invalid (|type| prefix is required)
type T5 = {p: int}
type T5 = [T1]
type T5 = function(): void
function foo(a: {p: int})

// |instanceof| shares same syntax with |is| now:
x instanceof int
x instanceof like int
x instanceof (like T1 | type {p: V2})
// but still works with constructors (even if meaningless)
x instanceof function(){}

// valid type annotations:
var x: T1
var x: type [T1]
var x: like type {p: T2}
var x: T1 | T2
function foo(a: T1, b: T2)

// invalid type annotations (if they contain any non-fixed type property
identifiers)
var x: V1
var x: T1 | T2 | V1
var x: T1 | (type {p: T2, q: type [like V1]}
function foo(a: T1, b: V2)

|new| remains the same. All the other type operators have the same
restrictions as type annotations (allow only fixed type properties), so
don't need examples for them.

Thoughts? I hope I haven't missed anything.

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Exception handling vs. hasNext()

2007-11-17 Thread Yuh-Ruey Chen
More advantages to StopIteration:

1) There are some iterations in which calculating whether the next
iteration exists is non-trivial, such as iterating on trees.

2) While one could work around non-trivial hasNext() calculations by
"pre-advancing" the iterator, i.e. if an iterator has returned the i-th
item, it has already calculated the (i+1)-th item, making hasNext()
simply check if the (i+1)-th item exists, such an approach is not only
less efficient, but won't work if the iterator makes side effects.

3) Repeated hasNext() checks can be slower than throwing and catching a
StopIteration, especially if the compiler is optimized to expect that
StopIteration from an iterator.

4) Iterator-generators hide the messy business of StopIteration:

// range is an iterator-generator (note the yield statement)
function range(len) {
for (let i = 0; i < len; ++i)
   yield i;
}

for (let x in range(10))
print(x);

No mention of StopIteration - or even next() - anywhere in that code yet
|range(10)| is clearly an iterator.

In case you were wondering, ES4's iteration protocol is heavily inspired
from Python, and I think Python has handled this iteration business very
well.

-Yuh-Ruey Chen

Erik Arvidsson wrote:
> One benefit of StopIteration is that code inside map/some/every etc
> can just throw a StopIteration to stop the iteration.  The same thing
> is harder to keep clean with a hasNext/next pattern.
>   
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: generic function with structural types questions

2007-11-14 Thread Yuh-Ruey Chen
By "fixed", do you mean an RI bug or a spec issue? If it's just an RI
bug, can you tell me what those exprs are supposed to evaluate to?

-Yuh-Ruey Chen

Lars T Hansen wrote:
> At present, generic functions do not discriminate on structural types.
>  This probably needs to be fixed, but I've not looked into it.
>
> --lars
>
> On 11/12/07, Yuh-Ruey Chen <[EMAIL PROTECTED]> wrote:
> > Given the following definitions:
> >
> > class C {var p: int};
> > type S1 = {p: int};
> > type S2 = {p: int, p2: double};
> > generic function foo(x);
> > generic function foo(x: *) 0
> > generic function foo(x: C) 1
> > generic function foo(x: S1) 2
> > generic function foo(x: S2) 3
> > generic function foo(x: like S1) 4
> > generic function foo(x: like S2) 5
> > var o1: C = new C();
> > var o2: S1 = {p: 10};
> > var o3: S2 = {p: 10, p2: 3.14};
> > var o4 = {p: 10};
> > var o5 = {p: 10, p2: 3.14};
> > var o6 = {p: 10, p2: 3.14, p3: "hi"};
> >
> > What do the following exprs evaluate to?
> > foo(o1);
> > foo(o2);
> > foo(o3);
> > foo(o4);
> > foo(o5);
> > foo(o6);
> >
> > Also, I know that S1 <: Object, but is S2 <: S1? I've looked at
> > http://wiki.ecmascript.org/doku.php?id=clarification:type_system and
> > it's not clear to me. Is it still true that C <: S1?
> >
> > -Yuh-Ruey Chen
> > ___
> > Es4-discuss mailing list
> > Es4-discuss@mozilla.org
> > https://mail.mozilla.org/listinfo/es4-discuss
> >
>
>   
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: need some clarification on compile-time type vs. run-time type

2007-11-13 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> > I think that would be a good thing. Another thought: if |x is v|,  
> > where |v| is a meta-object, works, then one would think that it  
> > should also work for |like|, e.g.
> >
> > var x = int
> > 10 is x; // ok
> > 10 is like x; // ?
> >
> > But if that last statement is allowed, then so is |var y: like x|,  
> > which is undecidable (if that's the correct term), so evidently | 
> > like| shouldn't work with value exprs.
>
> This is a hot topic. We could indeed allow all sorts of type  
> expressions, and define evaluation rules so that (I hope) nothing  
> diverges and we don't need to set a watchdog timer on strict mode's  
> type checker. The static guarantees go down because strict mode will  
> punt anything it can't figure out to runtime, treating the compile- 
> time type as *. It seems wiser at the moment to restrict type  
> annotations and remain future proof, but make 'is' friendlier as you  
> and I have been discussing.
>   

I agree.

> > Might want to mention this in any clarification you put into the  
> > spec, even if it's strictly disallowed in the formal grammar - that  
> > even though |is| allows a value expr on the right side, it cannot  
> > be nested within a type expr. That means given |var x|, none of |10  
> > is like x|, |10 is (x)|, |10 is {p: x}|, etc. are syntactically  
> > allowed.
>
> I think we're now inclined to allow those but insist on a type at  
> runtime. But this is something to discuss more.
>   

I don't see how that's workable. I mean, technically it is, since |is|
is a runtime check. But it creates another "incompatibility" between
type annotations and |is|, and you seem pretty adamant to keep the two
as coherent as possible. Just consider:

T = cond? int : double;
x is {p: T}; // ok
var y : like {p: T}; // early type error

> > There are couple potential problems with upgrading |instanceof| to  
> > match the syntax of the revised |is|:
> >
> > 1) Function expr syntax ambiguity. Consider:
> >
> > a) x is function(p: int): int // ok
> > b) x is function(p: int): int {} // syntax error
> > c) x instanceof function(p: int): int // ok?
> > d) x instanceof function(p: int): int {} // syntax error?
>
> Oh, I see -- on second thought I meant nothing like allowing (d) --  
> sorry. instanceof only takes a value expression on its right, but if  
> that evaluates to a type meta-object, it does something sane and  
> "instance-of"ish.
>   

So I take that |x instanceof {p: int}| won't work, and we'd have to use
|T = type {p: int}; x instanceof T| instead?

>From your other email:
> Er, I meant (c), if you remove type annotations from the function  
> param and result. In ES3 today, you can write
>
> js> ({}) instanceof function (){}
> false
>
> It's silly, of course, because the function expression is captured by  
> the right operand and could not have been constructed via operator  
> new to get the left operand. But it's valid ES3 syntax, so we can't  
> switch instanceof's right operand to favor a function structural type.

I truly doubt there is any code out there with (d). It's a backwards
incompatibility I'd be willing to break. If there is code out there with
this, well, the new syntax error should tell them that they're doing
something really stupid.

> > 3) Parenthesis ambiguity. This is the most troublesome one. Consider:
> >
> > a) x is (int) // ok
> > b) x is (some_constructor) // syntax error
> > c) x is ({p: int}) // ok
> > d) x instanceof (int) // ok
> > e) x instanceof (some_constructor) // syntax error?
> > f) x instanceof ({p: int}) // how should this be treated?
>
> Yes, and parenthesized expression may follow operator new, so this is  
> a hard limit.
>   

Plenty of discussion going on in ticket 300 concerning this. Ugh, this
semi-merging of value and type exprs is getting awkward. We're ending up
with just as many gotchas as we had before at this rate.

Alright, overview time again. Our current goals are:
1) Make |is| less restrictive and allow it accept (some) value exprs.
2) Keep |is| and type annotations coherent.
3) Keep |is| and |instanceof| (somewhat) coherent.
4) Keep all the type operators coherent (to a certain extent).
5) Try not to introduce too many exceptions to the rule a.k.a. gotchas.

Whatever we do to advance one goal, another goal becomes more
compromised. Maybe we can place priorities on these goals? If we can
abandon one or two of these in favor of the other goals, this job would
be much simpler. Need to think on this some more...

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Is ES3 good enough? Was incrementally strengthening ES3 paradigms considered?

2007-11-13 Thread Yuh-Ruey Chen
c to those who are "defending the  
> Shire" (if you get my reference) by objecting to ES4's bigness. And  
> there's a real risk that ES4, even though backward compatible, will  
> be twisted via bad programming "culture wars" that in effect stamp  
> out the old ways. Should it come to this, I'll be on the other side  
> of those wars, with the Hobbits and Doug Crockford (if they'll have  
> me. :-/).
>   

Heh, with the super-multi-paradigm-ness of ES4, those programming
cultures wars are bound to happen. Witness the creation of hundreds of
"ES4/JS2 style" articles that all disagree with each other :)

I am glad to hear that the people behind ES4 are very cognizant of the
"bigness" of the language. My hope is that a future ES5 will revamp the
language into a smaller core syntax with much of the ES4 extensions (and
some ES3) somehow morphed into syntactic sugar - or even better,
user-defined syntactic sugar (could take bootstrapping to a whole new
level).//

> But I don't think the old ways suffice. I've seen too many users  
> waste hours and days struggling to enforce latent types with ad-hoc  
> checks, or no checks at all. I've seen lots of security exploits that  
> take advantage of mutability and extensibility at the heart of JS1.  
> And I hope we all can see the onslaught of alternative but near-the- 
> web (typically browser plugin at first, but then embrace, extend,  
> extinguish soon follow) runtimes that boast bigger, stronger, and  
> more scaleable (in practice) programming languages.
>
> Against these, JS1 or a small "cleanup" of it cannot compete, not  
> only in my opinion, but in the successful marketing judgments of  
> several mighty companies (including Microsoft and Yahoo!). And to be  
> fair to those big companies, many (most?) programmers do deserve  
> better programming-in-the-large and integrity support, including an  
> expressive type system with optional static checking. If they have to  
> switch to C# or ActionScript to get it, many programmers will. JSLint  
> is not enough.
>   

Yeah, the proprietary vs. open language war again.

> > Nonetheless, I see that languages based on the old ES4 draft  
> > (2002?) that have been successful, namely ActionScript. I'm not  
> > very familiar with it, but the overall feeling I get from ppl  
> > developing in AS is positive. I also want to get my hands dirty  
> > testing out classes in ES4, but sadly the RI is too buggy at the  
> > moment.
>
> Please mail me about these RI bugs, or file them yourself at http:// 
> bugs.ecmascript.org/ -- I have access to the monotone repository, and  
> I see classes and interfaces doing more right than wrong, but we need  
> to see your testcases. Thanks.
>   

Oops, didn't mean to say that the class system in the RI was buggy. I've
tried some basic classes and it's working so far, but I haven't gotten
knee-deep into it yet. It's just that the best way for me to learn all
the ins and outs of a language, learning all its merits and whatnot, is
to use for some sort of small experimental project. To give you an
example, I didn't really appreciate all the little features Python had
until I tried make a game mod with the language. Currently, the RI just
doesn't seem stable enough for that.

> > Basically, what I'm saying is, I'm willing to give the Java-esque  
> > type system a chance.
>
> Java-esque is not fair, even if you are talking only about the  
> nominal types. Unbounded type parameters are not classically "Java- 
> esque", and Java generics go beyond what we are doing in some ways  
> (variance annotations) while still being much less (erased, static  
> only) in others. ES4 is a dynamic language. Java-esque doesn't begin  
> to do it justice.
>   

Oh come on :) I was referring to the syntax of the class system, which
is undoubtedly Java-esque. Lot of Java haters in the functional (no
1st-class functions!) and scripting (too verbose!) programming crowd.
Pretty much everyone's first impression of the class system in ES4 is
that Java is being merged into the language. Kinda like how everyone
thinks that Java inherited its type system from C++ instead of Modula-3.

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


generic function with structural types questions

2007-11-11 Thread Yuh-Ruey Chen
Given the following definitions:

class C {var p: int};
type S1 = {p: int};
type S2 = {p: int, p2: double};
generic function foo(x);
generic function foo(x: *) 0
generic function foo(x: C) 1
generic function foo(x: S1) 2
generic function foo(x: S2) 3
generic function foo(x: like S1) 4
generic function foo(x: like S2) 5
var o1: C = new C();
var o2: S1 = {p: 10};
var o3: S2 = {p: 10, p2: 3.14};
var o4 = {p: 10};
var o5 = {p: 10, p2: 3.14};
var o6 = {p: 10, p2: 3.14, p3: "hi"};

What do the following exprs evaluate to?
foo(o1);
foo(o2);
foo(o3);
foo(o4);
foo(o5);
foo(o6);

Also, I know that S1 <: Object, but is S2 <: S1? I've looked at
http://wiki.ecmascript.org/doku.php?id=clarification:type_system and
it's not clear to me. Is it still true that C <: S1?

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: need some clarification on compile-time type vs. run-time type

2007-11-11 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> On Nov 11, 2007, at 3:09 PM, Yuh-Ruey Chen wrote:
>
> > Sorry, I'm still not getting it. The upgraded |instanceof| will behave
> > exactly the same for the inputs non-upgraded |instanceof| works on.
> > There are new guarantees, but they in no way affect the original ones.
>
> They're stronger than the original ones, and different in kind too.  
> Seems like apples and oranges mixed under one operator. Not obviously  
> necessary given 'is', but here's a thought: instanceof does its  
> prototype chain walk on the left operand, looking for an object equal  
> to the value of the right operand's 'prototype' property, iff the  
> right operand has [[HasInstance]] as function objects do in ES3.  
> Otherwise it does a dynamic form of 'is', and for syntactic  
> disambiguation, you may have to use unary 'type' on the right operand.
>   

Yes, the upgraded |instanceof| would have to perform two different types
of checks. But while the value of |instanceof| can change for function
operands, its value cannot change for type operands, just like |is|. The
two different type checks are distinct, and the new |is|-like type check
in no way affects the former prototype-chain type check, considering
that the only overlap between the two is type checking against classes
and the two type checks always agree on classes.

> > There's no way to change the prototype chain of an object instantiated
> > from a class, right? |obj instanceof klass| is practically  
> > equivalent to
> > |obj is klass|. Am I missing something?
>
> No, classes are not really the issue. The key difference is that  
> instanceof results can change over time for a given object on the  
> left and plain old function on the right, while 'is' results cannot  
> vary over the lifetimes of the same operands.
>   

If |is| is a purely runtime check, does this really matter? Can you give
me a use case involving a runtime type check that requires that the type
check always be the same for a pair of operands?

> > 2) |is| expects either a type expr or a meta-object, but in the latter
> > case, that meta-object must be from a |type| expr. This is a weird
> > restriction. Furthermore, I though the |x| in |type x| had to be a  
> > type
> > expr, yet in this case, |x| is a value expr (evaluating to the
> > meta-object). Again, very confusing.
>
> Agreed, and not what anyone wanted.
>   

Ok, thanks for the clarification. However, that still doesn't answer
this question: if the |x| in |type x| has to be a type expr, then how
did |type x| in the example work? |x| in that case was a value expr
(evaluating to a meta-object), not a type expr.

> > Namely, I can imagine
> > a user coming from an ES3 background to instantly see the  
> > usefulness of
> > structural types, yet not care at all about classes, type  
> > parameters, or
> > early type checking.
>
> Possibly, although structural types either are useful for 'is like'  
> spot-checks (shape tests), or you end up defining names for them, and  
> using those names to type objects, arrays, etc. created by  
> initialisers, so as to get fixed property guarantees.
>
> Classes come into the picture with 'wrap'. If you are upgrading an  
> existing API with structural type annotations, but you can't afford  
> to change all the callers to pass fixture-laden objects (this is  
> highly likely; and it shouldn't be necessary to change all the  
> callers of the API anyway), just structural type annotations will  
> result in type errors for all calls that pass plain old dynamic  
> objects and arrays. The API upgrader then has a choice: use 'like'  
> for spot checks, or use 'wrap' for complete coverage (in case the API  
> client mutates something behind the API implementations back).
>
> GIven wrap, which creates some built-in nominal proxy type that does  
> (efficient, we hope, not exponentially complex) checks on all reads  
> and writes, you get type safety. But it can cost, even if optimized.  
> As your API evolves and new users come along, if they can use ES4,  
> you could provide nominal types for their use.
>
> And even if you never expose nominal types in your API, the API's  
> factory methods could return nominal types matching the structural  
> type constraints in the API parameter and result annotations.
>
> Just pointing out that even without early type checking, there are  
> use-cases for programmable nominal types.
>
> Type parameters are used by the iteration protocol (not yet  
> implemented in the RI, but it's close). See
>
> http://wiki.ecmascript.org/doku.php? 
&

Re: ES3 quasi incompatibilities

2007-11-11 Thread Yuh-Ruey Chen
Garrett Smith wrote:
> JavaScript does not provide basic functionality for unique collections.
>   

It's trivial to implement an efficient Set class even in ES3 (with
certain restrictions on the "type" of the key) - just use objects which
are pretty much specialized hash tables (maps from string to values,
keys collides with prototype keys). For ES4, we have maps which are hash
tables as bareboned as you'll get in the language. I'm not sure why you
have all those |!Map.containsKey(lisx[i])| checks in your Map example,
since they're totally unnecessary.

A SortedSet is a bit trickier, because that would require some sort of
binary search tree to be efficient. But it can be done.
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: need some clarification on compile-time type vs. run-time type

2007-11-11 Thread Yuh-Ruey Chen
 operand  
> which must be a type expression. Get used to it, poindexter! ;-) But  
> really, it's a bit harsh and anti-JS to say this, for 'is' at any  
> rate. Possibly the verb is too short and overloaded. More work  
> needed, I think.
>
> /be
>   

Hmm, I can see why it kind of makes sense for |is|, |cast|, and |wrap|
all to require type exprs, considering they are all type operators. But
since |is| is a purely runtime check (pending Graydon's reply), it makes
no sense for it to not accept value exprs.

So far I see a couple solutions:

1) Let |is| work on value exprs, but leave |instanceof| alone. Then the
difference between the two resolves to whether the operand has a
prototype chain. That is, the only inputs that both will work on are
classes. It's still a gotcha, but a minor one.

2) Unify |is| and |instanceof| into a single |instanceof| operator. I'm
still not sure what you mean by guarantees, so at the moment I don't see
an issue other than |is| currently requiring a type expr. I also just
learned from your post that AS3 already has an |is| operator that works
similarly, so that may be another barrier to this solution. |instanceof|
composed with |like| also sounds awkward, e.g. |instanceof like type {a:
int}|, unless it's the other way around, e.g. |instanceof type like {a:
int}|.

3) Let |is| work on value exprs, and upgrade |instanceof| to work on
everything |is| works on. Again, not sure what you mean be guarantees.
This solution doesn't require the removal of |is| and so is more
compatible with AS3. On the other hand, the fewer keywords, the better.

4) As you say (I think), |is| may be too overloaded. That it works both
classes/interfaces and structural types even though the two are very
distinct tests is a cause for concern. Yet it is convenient to group
them into one operator.

In addition to all that, if |is| works on value exprs, there's still the
confusion I've previously pointed out:

// |b| is a class, |a| is instance of |b|
a is type b
a is b

Maybe we can just explain to the user that |type| is only required for
structural types to avoid syntactical ambiguity (in the same vein as
block {} vs. object literal {})?

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: need some clarification on compile-time type vs. run-time type

2007-11-11 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> I'm going to summon Graydon and stand back now.
>
> /be
>   

Right, I'll wait to reply in full until then. I just want to point out
that the spec namespace isn't public.
http://wiki.ecmascript.org/doku.php?id=spec:spec gives me a "permission
denied" page.
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: need some clarification on compile-time type vs. run-time type

2007-11-10 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> On Nov 9, 2007, at 11:24 PM, Yuh-Ruey Chen wrote:
> > Ah, so expressions can be annotated with types?
>
> Array and object initialisers can be annotated with array and object  
> ("record") structural types to make the expressed object have fixed  
> properties named by the type, instead of just being a plain old Array  
> or Object instance that has ad-hoc ("expando") properties given by  
> the initialiser, where the properties could be deleted in the very  
> next statement.
>   

I see. I wonder if this can somehow be extended so that it works on
non-structural types as well. For example, to initialize a Map, you
could use {a: 0, b: 1, c: 2} : Map, instead of Map({a:0, b:1, c:2}).
Perhaps it would map onto the |meta static function invoke| method. The
downside of this syntax sugar though, is that it hides the cost of the
creation of the object literal, fooling the user into thinking that the
Map is directly initialized from the literal.

> > I acknowledged that |is| is different from |instanceof| but I was  
> > using
> > |instanceof| because it is similar to |is| yet works on value exprs. A
> > more proper example would be a combination of |instanceof| and all the
> > other checks that |is| allows via reflection.
>
> Right. You can see from:
>
> http://wiki.ecmascript.org/doku.php? 
> id=proposals:syntax_for_type_expressions
>
> and Graydon's reply that we originally had 'is' take a value  
> expression right operand, and you had to use 'type E' (the unary type  
> operator mentioned at the bottom of the above-linked page) to force E  
> to be treated as a type expression. We've moved away from that to get  
> experience with the alternative design, where 'is' takes a type  
> expression on the right, in order to get earlier and more certain  
> type checking. But this is all subject to change based on feedback --  
> such as yours ;-).
>   

I like this revised syntax: |a is type b| is much clearer than |a is b|,
which a newbie can mistake for object equality, especially if he comes
from a Python background. On purely aesthetic grounds though (ignoring
the type vs. value expr distinction), I think |isa| would be even
better, but on the other hand, |isa like| sounds like something Mario
would say.

Can you elaborate on the "earlier and more certain type checking"? I
thought you said for |is| checks (along with |instanceof| checks) there
can be no early type errors, so that leaves |is| to be a purely runtime
check.

Anyway, we still have a similar confusion to what we had with
|instanceof|, except this time it's all in |is|:

// assume |b| is a class and |a| is an instance of it
a is type b
a is b

Since both work, this can fool the user into thinking that the |type|
operator is optional. Furthermore, the latter can still lead to newbie
confusion (thinking that the expr is equivalent to |a == b|). So I'm not
sure there is a net win.

> > Again, I did not mean to use the strict definition of |instanceof|; I
> > meant some abstract operator (which |instanceof| could be  
> > "upgraded" to)
> > that does the same thing as |is| except that it works on value exprs.
>
> It's not clear (to me at any rate) that you can upgrade instanceof in  
> a backward-compatible fashion, given mutable prototype properties of  
> functions.
>
> For the built-ins (which become classes, not constructor functions),  
> you could, and that's what we've done.
>
> For user-defined functions that instanceof takes as right operands,  
> there's no need to upgrade beyond how things work as in ES3. But the  
> guarantees with classes are gone: if one changes F.prototype after x  
> = new F, (x instanceof F) could change from true to false.
>   

Well, I was just suggesting adding additional functionality to
|instanceof|, not changing the original behavior of it, so I'm not sure
where the compatibility issue is coming into play.

> > If |instanceof| works for classes, then I propose that |instanceof|  
> > also
> > work for interfaces for the sake of completeness. Getting this to work
> > is a bit trickier than for classes, since a class can implement  
> > multiple
> > interfaces or a parent class and multiple interfaces, but it can still
> > work. This change is perfectly backwards compatible, considering that
> > interfaces aren't even in ES3.
>
> It would involve some algorithm other than the prototype chain walk  
> from x, looking for an object === to y.prototype, for (x instanceof  
> y), since interfaces do not have prototypes.
>
> But since (x is I) and (x is J) work fine for x = new C where class C  
> implements I, J {...}, perhaps for interface

Re: need some clarification on compile-time type vs. run-time type

2007-11-09 Thread Yuh-Ruey Chen
Brendan Eich wrote:
> On Nov 9, 2007, at 5:29 PM, Yuh-Ruey Chen wrote:
>
> > The confusion I'm getting is that there seems to be many ways to check
> > or differentiate between types. For example, consider the following  
> > ES3
> > function:
> >
> > function foo(x, t) {
> > if (!(x instanceof t))
> > throw some_type_error;
> > print(x);
> > }
> >
> > If t were a fixed type property, then foo could be redefined as:
> >
> > function foo.(x) {
> > if (!(x is t))
> >throw some_type_error;
> > print(x);
> > }
>
> Here t is the name of a type parameter to foo, so it is by definition  
> fixed -- it doesn't matter how you instantiate foo. for some T --  
> but there again, in the foo. expression, you need a fixed type  
> term T.
>   

That's what I meant. If t could never be non-fixed, i.e. it's a type
alias, class name, or other type expr, then type parameters could be
used. But if, for example, t is a constructor or is otherwise computed
at runtime, it couldn't be used as a type argument.

> > Or maybe the following is possible (it's currently disallowed in  
> > the RI):
> >
> > function foo.(x: t) {
> > print(x);
> > }
>
> I'll let Graydon reply in full, and give an update -- I heard he  
> nearly has type params working.
>
> > Which one is preferred in ES4? The ES3 version is more flexible in a
> > way, since it treats types as first-class values,
>
> A constructor function is not a type in ES1-3, it's a function  
> object, which if user-defined has a completely writable prototype  
> property that instanceof checks. So it is not bad (or good), but I'm  
> here to say: it's not about types in the ES4 sense.
>
> Indeed user-defined constructor functions all make Object instances,  
> by definition, although you could strengthen them to make structural  
> subtypes of Object in ES4:
>
> function MyConstructor(a, b) {
>  return {a: a, b: b} : {a: int, b: string};
> }
>   

Ah, so expressions can be annotated with types? Didn't see that on the
wiki and it's not implemented in the RI yet.

> > but the last version
> > is the most efficient. Users will have to deal with this choice,  
> > but it
> > requires a decent understanding of the type system to make a good  
> > choice.
>
> Users can buy by the yard. The old ways work for the dynamic  
> constructor/prototype world everyone knows.
>
> Above you have made three different things. The instanceof check is  
> not the same as the |is| check. The type paramter example is yet  
> again different -- it's just printing x assuming x is compatible with  
> t -- that is, that there's no type error on attempt to call foo.,  
> e.g. foo.(new RegExp).
>   

I acknowledged that |is| is different from |instanceof| but I was using
|instanceof| because it is similar to |is| yet works on value exprs. A
more proper example would be a combination of |instanceof| and all the
other checks that |is| allows via reflection.

What's the rationale behind not throwing a type error when calling
foo.(new RegExp)? I'm looking at the type_parameters page in the
wiki and I'm not seeing anything... It's odd that this would not throw
an exception while the following would:

function bar(x: int) { print(x); }
bar("hi");

> > And it doesn't end there. I haven't even addressed the |is like|
> > compound operator,
>
> It's not a compound operator: 'like' is a type constructor or type  
> unary operator if you prefer: like T is a type, you can use it  
> freely. Thus because (x is T) can be tested, and T can be defined as  
> like U, you can write (x is like U). Make sense?
>   

Yes indeed, thanks.

> > of which there is no counterpart in |instanceof|
> > since structural types apparently can't be stored as non-fixed type
> > properties (|type x={a:int};y=x;| doesn't work in the RI).
>
> Type are types, not functions; the instanceof right operand is a  
> *function* per ES1-3 and backward compatibility.
>   

Again, I did not mean to use the strict definition of |instanceof|; I
meant some abstract operator (which |instanceof| could be "upgraded" to)
that does the same thing as |is| except that it works on value exprs.

The line between types and constructors is somewhat blurred by allowing
|instanceof| to work on class objects, which I would hardly consider
constructors, if not for the fact that they have an intrinsic::construct
method. Allowing |instanceof| to work on classes can trick people into
thinking that |instanceof| can work on type exprs. Yet at the sa

Re: need some clarification on compile-time type vs. run-time type

2007-11-09 Thread Yuh-Ruey Chen
Graydon Hoare wrote:
> Yuh-Ruey Chen wrote:
> > I've been experimenting with the ES4 RI lately. I've discovered that the
> > following doesn't work:
> > 
> > x = int;
> > 10 is x;// error
> > 10 to x;   // error
> > 10 cast x;   // error
> > var y: x;   // error
> > 
> > Of course, if I had used |type x = int|, it would work. Is this because
> > x is not a compile-time type? 
>
> Roughly. Some refinements to terminology: there are no "compile-time 
> types" or "run-time types". There are types (and interfaces, and 
> classes). They get bound to property names. Some of those properties are 
> fixed, some are not. Some fixed properties are additionally constrained 
> to hold types, classes or interfaces. Some are not.
>
> Your example fails because x is not a fixed type-property. Properties 
> introduced by 'type', 'class' or 'interface' are.
>
> Type names in type expressions only consult fixed type-properties, 
> because we want evaluation of type expressions to be as predictable as 
> possible. There are only ever 2 results to evaluating any type expression:
>
>#1 full evaluation to a specific "ground" type term
>#2 suspended partial evaluation due to incomplete information
>
> The flow of program control may affect which of these two results we 
> get, and it can provide new information to restart a suspended 
> evaluation -- by loading new code containing type definitions using 
> 'eval', for example -- but it *cannot* invalidate a result of an 
> evaluation. Types never need to be "re-evaluated" to reflect "mutation" 
> in their environment. The evaluation of type expressions can (and 
> should) memoize types.
>   

Ah, so that's why I couldn't delete types. I ended up having to restart
the RI once the environment got cluttered with all these test types that
I defined. I need to get used to declaring them in scopes...

Speaking of which, there's a little bug in the RI: if you try to
constrain a property to specific type e.g. |var x: t| (is that the
proper terminology?) where t is undefined, then the interpreter
correctly reports an error, albeit one that didn't make sense until you
explained the "ground" type terminology. However, x remains constrained
to this undefined t, so attempts to redeclare x always result in an
error (even when trying to reconstrain it to the undefined t again),
e.g. |var x: int| results in an "incompatible redefinition of fixture
name" error. This bug probably doesn't matter in production, where such
errors are supposed to be fatal (I think), but in a REPL interpreter it
gets annoying.

> I find it a bit odd that |10 is x| didn't
> > work while |10 instanceof x| does work, considering that |is| is touted
> > as the successor to the |instanceof| operator. Or is |instanceof| the
> > run-time counterpart to |is|? Then should |instanceof| work on
> > everything that |is| can work on?
>
> instanceof consults the prototype chain. It happens to be the case that 
> for classes, the prototype chains are arranged to follow the class 
> inheritance hierarchy. But there are a variety of differences; for 
> example, "x instanceof z" may return false in cases where "x is z" 
> returns true (if z is an interface, say).
>   

Then how would we do a check against an interface bound in a non-fixed
property? Is there an expression that does the same thing as |is| except
for non-fixed type properties?

The confusion I'm getting is that there seems to be many ways to check
or differentiate between types. For example, consider the following ES3
function:

function foo(x, t) {
if (!(x instanceof t))
throw some_type_error;
print(x);
}

If t were a fixed type property, then foo could be redefined as:

function foo.(x) {
if (!(x is t))
   throw some_type_error;
print(x);
}

Or maybe the following is possible (it's currently disallowed in the RI):

function foo.(x: t) {
print(x);
}

Which one is preferred in ES4? The ES3 version is more flexible in a
way, since it treats types as first-class values, but the last version
is the most efficient. Users will have to deal with this choice, but it
requires a decent understanding of the type system to make a good choice.

And it doesn't end there. I haven't even addressed the |is like|
compound operator, of which there is no counterpart in |instanceof|
since structural types apparently can't be stored as non-fixed type
properties (|type x={a:int};y=x;| doesn't work in the RI).

> > These distinctions between compile-time types and these run-time types
> > (e.g. x in the above example) are subtle and confusing. I fi

need some clarification on compile-time type vs. run-time type

2007-11-09 Thread Yuh-Ruey Chen
I've been experimenting with the ES4 RI lately. I've discovered that the
following doesn't work:

x = int;
10 is x;// error
10 to x;   // error
10 cast x;   // error
var y: x;   // error

Of course, if I had used |type x = int|, it would work. Is this because
x is not a compile-time type? I find it a bit odd that |10 is x| didn't
work while |10 instanceof x| does work, considering that |is| is touted
as the successor to the |instanceof| operator. Or is |instanceof| the
run-time counterpart to |is|? Then should |instanceof| work on
everything that |is| can work on?

These distinctions between compile-time types and these run-time types
(e.g. x in the above example) are subtle and confusing. I figure that
all these distinctions will trip many ES4 newcomers coming from an ES3
background.

BTW, it doesn't seem like the "like" and "wrap" operators are
implemented in the RI yet, so I couldn't really test out structural types.

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Syntax for union types

2007-11-09 Thread Yuh-Ruey Chen
Yuh-Ruey Chen wrote:
> By "generic functions ought to be available on instances", do you mean
> non-global generic methods? TBH, I consider generic functions a bit of
> an odd fuck in ES4, because of its many restrictions compared to normal
> functions (see the "non-features, future directions, etc." section on
> the generic functions proposal).
>
> -Yuh-Ruey Chen
>   

odd duck *sigh*
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Syntax for union types

2007-11-09 Thread Yuh-Ruey Chen
Lars Hansen wrote:
> > Not only is (int | string) more intuitive than (int, string), 
> > the (int, string) syntax can be reserved for another yet-unknown
> purpose.
>
> Intuition tends to be personal, and the other argument can be turned on
> its head (why wouldn't I want to use "int | string" for something else
> in the future?).  Since "|" is bitwise or, "||" would have been better,
> but that has yet other connotations.
>   

Well, I didn't draw that intuitiveness primarily from ES3 operators. It
comes from regexes (which are already in the langauge) and common
grammar notation (which are well-known to CS majors), which all tend to
use "|" as the "or" operator.

> > Along the same lines, I find the syntax for constraining list 
> > types to be unintuitive. [int] is very different from [int, 
> > string], and [int, string] is very different from (int, 
> > string). Perhaps that (int, string) can describe the tuple 
> > type. And [int | string] could be syntactic sugar for [(int | 
> > string)]. The usage of "|" improves readability in that 
> > there's no way to confuse a union type with a tuple type.
>
> This has been discussed at considerable length, and we've concluded that
> the current solution represents a workable compromise.
>   

A compromise between what? I'm not aware of any existing implementation
(besides the RI) that uses union types. I'm also unaware of any
published discussion concerning the syntax of union types (didn't find
any in the wiki).

> (More interesting open questions about the language are whether generic
> functions ought to be available on instances or discriminating on
> structural types, or whether packages ought to be sealable for security,
> or whether ES4 precludes the use of current ES3 AOP patterns and how
> that might be solved.  Among other things.)
>
> --lars
>   

By "generic functions ought to be available on instances", do you mean
non-global generic methods? TBH, I consider generic functions a bit of
an odd fuck in ES4, because of its many restrictions compared to normal
functions (see the "non-features, future directions, etc." section on
the generic functions proposal).

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Syntax for union types

2007-11-09 Thread Yuh-Ruey Chen
Is there any reason why this proposal isn't being considered?

Not only is (int | string) more intuitive than (int, string), the (int,
string) syntax can be reserved for another yet-unknown purpose.

Along the same lines, I find the syntax for constraining list types to
be unintuitive. [int] is very different from [int, string], and [int,
string] is very different from (int, string). Perhaps that (int, string)
can describe the tuple type. And [int | string] could be syntactic sugar
for [(int | string)]. The usage of "|" improves readability in that
there's no way to confuse a union type with a tuple type.

-Yuh-Ruey Chen

Jason Orendorff wrote:
> On Oct 26, 2007 6:35 PM, James Clark <[EMAIL PROTECTED]> wrote:
> > (int, string) doesn't seem to me to be a syntax that the average JS
> > programmer will guess means union. I would have thought a better choice
> > would be (int | string) (especially given that regexps use |) or a keyword.
>
> Yep.  I read (int, string) as a tuple type every time.  ML, Haskell,
> Python 3.0... I'm not sure what we gain by going against the grain
> here.
>
> So it's not a big deal, but switching to (t1 | t2) seems all upside to
> me.  It's a shallow change.  +1.
>
> -j
> ___
> Es4-discuss mailing list
> Es4-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es4-discuss
>
>   
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Es4-discuss Digest, Vol 8, Issue 44

2007-11-02 Thread Yuh-Ruey Chen
As far as I can see it, there are a couple of non-technical issues here
that have to be resolved, but they all boil down to who is willing to
implement what. Is there truly no way to compromise?

MS says that they think ES4 deserves to a be a new language. Suppose
that is true and ES4 is renamed, say ES++. Then would MS be willing to
implementing ES++ in their new browser? Or is the name truly a scapegoat
to blame their misgivings of ES4 the language itself?

Or if you consider the feature set of ES4 to be too bloated, that ES4 is
trying to tackle problems it was never meant to handle, what exactly do
you dislike about ES4? What features would do you want to cut out of the
language? What features would the pro-ES4 people be willing to cut out?
I know this will be hard, but let's ignore feature dependencies for the
moment. Say, for example, that you dislike the class system but are fine
with the type system (as nonsensical as that sounds). Perhaps you're
fine with grafting a type system on top of the prototype system without
classes. Or if you also dislike the type system, what do you propose
instead? For encapsulation, you might propose sticking with closures.
Now, how are you going to address the pitfalls of closures, namely
memory usage and inefficiency? ES4 advocates may also be concerned that
encapsulation via closures is plain ugly, while ES4 critics say that
classes make the language inelegant. Perhaps there is another solution?
Anyway, do you see where I'm getting with this? There should be some
room for compromise. I'd like to see some active discussion concerning
these feature disagreements.

Lastly, all this accusations concerning intentions need to stop.
Mozilla, this concerns you too - I find that saying you won't let big
bully MS block ES4 is somewhat hypocritical, considering that the SVG
1.2 committee did something similar to you guys (make no mistake, I'm
not accusing anyone and I hope this is the last time SVG is mentioned on
this mailing list). In any case, hypocritical or not, all these
accusations are not constructive at all. Responding to accusations with
more accusations is plain sophomoric in my book. Please, I have enough
of my political bullshit from the news - I don't expect that here.

Thanks, Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: is ES4 getting too bloated?

2007-10-21 Thread Yuh-Ruey Chen
Don't get me wrong - I love most of the new features (some others I'm
just indifferent too). But I'm not implementing the interpreter; I would
be a user of it. My concern is that of the implementator's burden, and
from my point of view, if it takes a long time to implement ES4, it'll
be a long time before I can get to use ES4 in practice. What Michael
O'Brien just posted sounds very promising though.

I haven't had the time to look at the whole spec as a whole, and since
the spec is rather disorganized atm with a bunch of proposals, I'd have
a hard time doing that in any case. But what I've seen so far is pretty
good. I do kind of feel that there is some redundancy, i.e. there are
distinct features that seem to overlap a lot. For example, packages and
namespaces are both used to make programs more modular, albeit in
different ways. Likewise for program units and packages. But like I
said, I don't have a clear view of the spec as a whole, so I'll wait
until there are good prose sections describing the usage of features
before coming to a conclusion.

-Yuh-Ruey Chen

Garrett Smith wrote:
> On 10/21/07, Yuh-Ruey Chen <[EMAIL PROTECTED]> wrote:
> > Hey all,
> >
> > I've been watching ES4 development and occasionally contributing input,
> > and I have noticed a somewhat disturbing trend. ES4 is getting ever more
> > and more complex.
> >
> > I understand ES4 is a multi-paradigm language and so must be packed with
> > features, but I don't think we want a repeat of the C++ template problem
> > (where it took nearly a decade just to get most compilers near
> > compliance with the C++ spec). My point is that although a significant
> > update to ES is needed, if it takes too long to implement a conforming
> > compiler/interpreter for it, the adoption of new features is going to be
> > slow. Heck, I wonder how willing MS would be to provide a fully (or near
> > enough to it) conforming interpreter for ES4 if the spec is so large.
> >
> Tamarin will be included as a plugin for IE.
>
> > Small proposals like bug fixes and reformed with and company, or
> > proposals that generalize syntax to make the language more elegant are
> > perfectly fine by me. But we already have such huge features like
> > classes, generators, namespaces, type system, and now generic functions.
> > Perhaps we should start deferring more features to ES5?
> >
> Which features do you feel are unjustified? Can you bring a specific issue?
>
>   
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


is ES4 getting too bloated?

2007-10-21 Thread Yuh-Ruey Chen
Hey all,

I've been watching ES4 development and occasionally contributing input,
and I have noticed a somewhat disturbing trend. ES4 is getting ever more
and more complex.

I understand ES4 is a multi-paradigm language and so must be packed with
features, but I don't think we want a repeat of the C++ template problem
(where it took nearly a decade just to get most compilers near
compliance with the C++ spec). My point is that although a significant
update to ES is needed, if it takes too long to implement a conforming
compiler/interpreter for it, the adoption of new features is going to be
slow. Heck, I wonder how willing MS would be to provide a fully (or near
enough to it) conforming interpreter for ES4 if the spec is so large.

Small proposals like bug fixes and reformed with and company, or
proposals that generalize syntax to make the language more elegant are
perfectly fine by me. But we already have such huge features like
classes, generators, namespaces, type system, and now generic functions.
Perhaps we should start deferring more features to ES5?

-Yuh-Ruey Chen
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss