RE: Understanding Generic Functions

2007-11-15 Thread Lars Hansen
 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of John Resig
 Sent: 15. november 2007 02:27
 
 Generic functions are used like this:
 
 generic function a(b);
 generic function a(b:int){}
 generic function a(b:string){}

Yes.

 Generics offer a point upon which future functions can be 
 bound, like for operator overloading:
 
 class Foo!{}
 
 generic intrinsic function +(a:string, b:Foo){} 
 generic intrinsic function +(a:Foo, b:string){} 
 generic intrinsic function +(a:Foo, b:Foo){}

Yes.

 So that's all well-and-good. Now, where I making an 
 assumption is that it's not possible to do the following:
 
 generic function a(b);
 generic function a(b:int){}
 generic function a(b:string){}
 
 generic function a(b,c);
 generic function a(b:string, c:int){}

An early proposal had this.  It became complicated.  See below.

 also, it's not clear if you can use generics for constructors 
 - so I'm assuming that that's also not possible:
 
 class Foo {
   generic function Foo(b);
   generic function Foo(b:int){}
   generic function Foo(b:string){}
 }

At the moment that is true, but there's no reason I'm aware of why that
restriction can't be lifted, apart from issues of having to use the
settings (the initializer list preceding the body) for nullable
fields; allowances could presumably be made if the use cases were
strong.

 Ok - with all of that assumed, I am seriously struggling to 
 think of a real-world use case for generics beyond the 
 compelling operator overloading example.

Generic functions can be useful for adding type-dispatched functionality
after the fact without creating facades/wrappers.  The visitor pattern
is one example that's repeated in the literature.  I circulated a JSON
approach recently based on generic functions, along these lines:

generic function toJSON(x);

generic function toJSON(x:Object) { 
  for ( let n in obj )
if (obj.hasOwnProperty(n))
  serialize(n, toJSON(obj[n]))
}

generic function toJSON(x:string) { 
  ... 
}

The key here is that the protocol for JSON conversion is defined outside
the object, not inside the object, which can be a real advantage if
you're hooking up to somebody else's code that you don't want to edit.

If you are happy in a class-based OO world and you control all your
source code, you'll probably have limited use for generic functions,
just like you'll have limited use for structural types.  These features
speak to different use cases having to do with evolutionary programming.
(I'm working on a tutorial, which will probably not be finished this
week).

 Assuming that I wanted to continue to try to do method 
 overloading, it sounds like the de-facto solution is to just 
 use the rest arguments to figure out what I want. This is not 
 an acceptable solution. I lose virtually all of the benefits 
 that I had of doing type annotations in the first place if I 
 can't actually use them on overloaded functions.

What you mean is, you want parameter lists of different lengths on the
generic methods.

 For example, I've been pouring through my JavaScript library 
 (jQuery) looking for ways in which ES4 could be of benefit. I 
 immediately looked to using (what I thought was) method 
 overloading to ease some of the severe complexity of the 
 library. We do overloading on virtually every single method: 
 Thus, if there was no form of method overloading included in 
 ES4, then jQuery would receive significantly less, tangible, 
 benefit from these updates.
 
 To give a couple, crude, examples:
 
 function attr(name : string) : string {
   // get attribute value
 }
 
 function attr(name : string, value : (string,int)) : jQuery {
   // set an attribute value, return a jQuery object }
 
 function removeEvent() : jQuery {
   // Remove all events
   for each ( var type in types )
 removeEvent( type );
 }
 
 function removeEvent(type : string) : jQuery {
   // Remove all events of a specific type
   for each ( var fn in events[type] )
 removeEvent( type, fn );
 }
 
 function removeEvent(type : string, fn: Callable) : jQuery {
   // Remove the event handler bound to a type }
 
 Additionally, I've been working on building a DOM 
 implementation to sit on top of the ES4 RI, but have hit some 
 walls, especially with constructors. Thankfully, 
 private/protected/etc. constructors will be implemented at 
 some point (I'm looking forward to it) but I was kind of 
 expecting the ability to do multiple constructors - and even 
 the ability to mix private/protected/public constructors, for example:
 
 class Foo {
   private function Foo(){
 // Do initialization stuff
   }
   function Foo(name : string) {
 this();
 this.name = name;
   }
 }
 
 I'm simply most concerned about getting a useful version of 
 method overloading and constructor overloading. I'd love to 
 find out that I could use generics to achieve this, but I 
 just don't have a way of determining that right now.

As I wrote above, an early 

RE: generic function with structural types questions

2007-11-15 Thread Lars Hansen
It's a spec issue.  --lars 

 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of Yuh-Ruey Chen
 Sent: 15. november 2007 01:53
 To: Lars T Hansen
 Cc: es4-discuss
 Subject: Re: generic function with structural types questions
 
 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
 
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


RE: Understanding Generic Functions

2007-11-15 Thread Lars Hansen
 -Original Message-
 From: P T Withington [mailto:[EMAIL PROTECTED] On Behalf Of 
 P T Withington
 Sent: 15. november 2007 14:02
 To: Lars Hansen
 Cc: John Resig; es4-discuss
 Subject: Re: Understanding Generic Functions
 
 On 2007-11-15, at 02:52 EST, Lars Hansen wrote:
 
 [...]
 
  Generic functions can be useful for adding type-dispatched 
  functionality after the fact without creating facades/wrappers.
 
 My view is that generic functions recognize that any function 
 with more than one class parameter can't logically belong to 
 any particular class.  They allow behaviors between classes 
 to be described logically, rather than being artificially 
 attached to one of the classes of their parameters.

Right, the binary method problem (even for larger values of binary).

 Hey, can I say something like:
 
 generic function get a (this: Foo) ?

Not at the moment, but this came up briefly the other day, I forget if
it was on this list or elsewhere, that maybe there is a global generic
function meta::get (just like there is a global intrinsic::+), and if
property lookup fails in an object the dispatch would go through that
function.  No decision on that (not even a ticket).

This discussion highlights the fact that generic functions sometimes
feel a little bolted on, because there are already class protocols that
do part of what generic functions do.  We're really not trying to do a
MOP for ES4, it's just that once we have generic function it's so easy
to be tempted.  Just a little tweak here.

 [...]
 
  IMO we have a couple of options:
   * remove generic functions from ES4 because they are too limited.
  Operator overloading goes away, too.
   * accept them as they are, recognizing that they are 
 future-proof and 
  that they can be extended in later editions of the language 
 (as we've 
  done for type parameterization)
   * try to extend them with insta
 
 Is my mail client broken, or did you hit send too soon?

The former, probably.  The last bullet (and the end of the message) was:

* try to extend them with instance methods, constructor methods,
variable-length parameter lists without going over the complexity budget

(I'm adding this pointless sentence here in case the bug in your mail
reader has to do with signature removal being thrown off by the bullet
starting the line above, or something silly like that.)

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


Re: like and is like

2007-11-15 Thread Peter Hall
Thanks. A bit more formal than was expecting, but I think it contains
what I'm looking for.

Peter

On Nov 14, 2007 3:36 PM, Brendan Eich [EMAIL PROTECTED] wrote:

 On Nov 14, 2007, at 11:40 AM, Peter Hall wrote:

  After searching through the wiki and ecmascript.org site,  I still
  can't see any formal or informal explanation of how like and is
  like work, except in passing, and not with precision. Does this
  information exist somewhere?

 Sure, like totally! See in http://wiki.ecmascript.org/doku.php?
 id=resources:resourcess=valleyscript (note search term on that URL):

 http://www.soe.ucsc.edu/~cormac/papers/valleyscript.pdf

 /be
 ___
 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: Close review of Language Overview whitepaper

2007-11-15 Thread Kris Zyp

   Various interested parties favored something like the json2.js API
 already, and I think everyone will rally round it and beat on it, to make
 sure it has the right usability and knobs. I'm hopeful.


+1 from me. One request: When a filter function is provided to JSON.parse, I
would like the filter to be called with |this| defined to be the root object
that is being created by the parsed JSON text. Having a reference to the
created root object can be useful for some forms of filters such as
reference resolvers.


  The problem in general is that Bob's classes and Alice's classes were
 written without anticipating Carol's combination of the two, but Carol
 cannot use MI. Nor can she provide objects that match structural types. She
 has to inherit from both Bob's and Alice's classes.

Was multiple inheritance discussed for inclusion in ES4? I am aware of the
general arguments against it, but I was wondering if had been considered or
if there are technical aspects of ES4 that preclude it.


 Does this clear things up?


Yes, that certainly helps me to understand the rationale. Thanks for being
so willing to answer questions about ES4 issues.

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


Re: Close review of Language Overview whitepaper

2007-11-15 Thread Brendan Eich
On Nov 15, 2007, at 9:17 AM, Kris Zyp wrote:

 +1 from me. One request: When a filter function is provided to  
 JSON.parse, I would like the filter to be called with |this|  
 defined to be the root object that is being created by the parsed  
 JSON text. Having a reference to the created root object can be  
 useful for some forms of filters such as reference resolvers.

Interesting -- a short example would help sell this, I bet.


 The problem in general is that Bob's classes and Alice's classes  
 were written without anticipating Carol's combination of the two,  
 but Carol cannot use MI. Nor can she provide objects that match  
 structural types. She has to inherit from both Bob's and Alice's  
 classes.
 Was multiple inheritance discussed for inclusion in ES4? I am aware  
 of the general arguments against it, but I was wondering if had  
 been considered or if there are technical aspects of ES4 that  
 preclude it.

We passed over MI without any regrets, for the general reasons you  
give. Also, even with MI, classes are not as flexible as structural  
types, as I've pointed out. They're different beasts, with different  
as well as some overlapping use-cases from structural types.


 Does this clear things up?

 Yes, that certainly helps me to understand the rationale. Thanks  
 for being so willing to answer questions about ES4 issues.


No problem.

/be

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


Re: Close review of Language Overview whitepaper

2007-11-15 Thread Brendan Eich
On Nov 14, 2007, at 5:34 PM, Brendan Eich wrote:

 On Nov 14, 2007, at 2:03 PM, Maciej Stachowiak wrote:

 Conversions: In addition, any value in the language converts to a
 member of AnyBoolean, but the conversions specified are all to the
 more specific boolean type, so perhaps it should be expressed that
 way to avoid confusion.

 I thought this too, when reviewing this section. I think this is an
 open issue, but I can't find a ticket for it.

Found thanks to Lars:

http://bugs.ecmascript.org/ticket/246

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


Re: Close review of Language Overview whitepaper

2007-11-15 Thread Brendan Eich
On Nov 14, 2007, at 11:56 PM, Brendan Eich wrote:

 Modula 3 had branding for making nominal types from structural  
 types, but going the other way, unbranding a nominal type to get  
 a structural type, has no precedent I know of,

Shaver pointed to generic metaprogramming using C++ templates, which  
is close -- but of course the C++ static type system must make sense  
of everything before runtime, and you can't forge an instance of a C+ 
+ class. Important safety tip!

/be

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


Dylan 'nullable' types [Was: Close review of Language Overview whitepaper]

2007-11-15 Thread P T Withington
On 2007-11-14, at 19:22 EST, Graydon Hoare wrote:

 (As far as I can tell -- not being a dylan hacker -- dylan doesn't  
 even
 go as far as having a global sentinel type like nil)

The Dylan equivalent of a nullable type is a union of your type with a  
singleton that acts as the sentinel.  Most often a singleton of the  
boolean false value is used.  So there is a macro `false-or(type)`  
that expands to `type-union(type, singleton(#f))`.  This works for  
any type other than a nullable boolean.  Because any value other than  
#f coerces to true in a boolean context, #f is very similar to nil.   
I've never known anyone to need a nullable boolean.  (Although I have  
seen whacky es3 code that uses true/false/null as a sloppy 3-valued  
enumeration -- with attended bug reports when null is passed expecting  
it to behave like false.)

I must say, coming from Dylan, es3's undefined _and_ null seem like  
overkill... but we're stuck with them now!
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Close review of Language Overview whitepaper

2007-11-15 Thread liorean
On 14/11/2007, Maciej Stachowiak [EMAIL PROTECTED] wrote:
 Section III.

 Syntax: The new non-contextual keywords, and the resulting need to
 specify dialect out of band, are a problem. I'll have more to say
 about compatibility under separate cover.

The model with version and e4x arguments in the Content-Type for
changing JS parsing has been used by moz already. Can we hear their
experience with regard to this compatibility problem?

Generally I think opt-in versioning such as this is the best you can
get for compatibility. Perhaps it would be wise to have a method that
is not external to the script as well, though, but I fail to see how
that could work compatibly in current ES3 only implementations.

 - The RegExp change - is this really a bug fix? It's likely that this
 is not a big compatibility issue (Safari's ES3 implementation had
 things the proposed ES4 way for some time) but I think ES3's approach
 may be more performance and generating a new object every time does
 not seem especially helpful.

It's a SpiderMonkey+ES3 fix, as I recall. The main problem with the
ES3 spec is that developers don't expect lastIndex to persist when
they evaluate the literal a second time, but also other mutable
properties. Real world code breaks because of this.

 Is there any significant implementation that anyone would claim is
 100% free of ECMAScript 3 compliance bugs?

I don't even think you would get 100% compliance if you counted all
engines taken together - I think there's issues where no engine really
gets it right, or for that matter can afford to get it right. At
least, no browser hosted engine.

 Section IV.

 Classes: If any of the new type system is worthwhile, surely this is.
 The impedance mismatch between the class model used by most OO
 languages and by specifications like the DOM, and ES3's prototype
 model, is needlessly confusing to authors. So I approve of adding
 classes in a reasonable and tasteful way.

somewhat offtopic
For compatibility reasons with the ES3 bindings for the DOM, I think
the train has already left with regards crafting the DOM bindings
fully into the ES4 model. The way the ES bindings work is incompatible
with both ES3 prototype object hierarchies and ES4 classes/interfaces.
In particular we have multiple parallel interfaces, each of which
developers expect to be an object inherited from using the prototype
scheme. The bindings are incompatible with regards to ES4 interfaces
and classes in that ES4 interfaces from what I understand don't carry
implementation, aren't runtime objects nor can they present prototype
objects (obviously, since they aren't runtime objects).

I can only see two ways to solve this problem:
- Add a multiple inheritance scheme to ES4 that works on the prototype
delegation system as well as the nominal type system, solving the
diamond problem*. -- Severely complicating the object system.
- Remove these multiple parallel interfaces being exposed as run time
objects from the ES bindings, allowing a single inheritance hierarchy
to be formed from implementing them using ES4 interfaces. -- Making a
conformant DOM.next implementation not be a conformant DOM.current
implementation.


* A good resolution mechanism solving the diamond problem can be found
in Python and was borrowed by Perl 6, IIRC.
/somewhat offtopic

 Literals:
 - I am surprised to see a decimal type (a type that is not directly
 supported in current mainstream hardware) even though generally
 popular types like single-precision IEEE floating point and 64 bit
 integers are not present.

I guess it directly addresses one large real world problem - that
fifths are inexactly represented in doubles, and there is a large
demand for reliable number handling of decimal values for amongst
other things money and measurements. I doubt the demand for single
floats or 64-bit integers is even close to as large as the demand for
accurate handling of common real world values like money.

 Section V.
 Record and array types: Structural types are confusingly similar to
 yet different from classes. Mostly they offer a subset of class
 functionality (though reading ahead I did see a few features limited
 to them).

They do allow for orthogonal type ideas, and I think many ES3
developers will be more comfortable with structural types than with
classes and interfaces, because they can add contracts without
changing their coding style. Replacing code written for the ES3 system
of using closures for privacy and prototypes for inheritance with code
written for the ES4 classical inheritance system will require
considerably more rethinking one's implementation.

 Also, already having prototype-based objects and class-based
 objects it seems excessive to add yet a third way. I recommend
 removing them and adding any features that are sorely missed as a
 result to classes.

Well, structural types doesn't really affect the object types, do
they? AIUI structural types are part of the contract system, not the
inheritance