Class method addition and replacement (was Re: AOP Compatibility)

2008-04-03 Thread Kris Zyp
 the moment, but I assume you can't do replace a method on a user  class 
 with
 another ad-hoc function.

 Absolutely not with fixtures,

I was thinking about this, is there any reason why you can't replace a 
class's method with another method or install a method on an instance object 
that overrides the class's method, assuming that the method signature 
remains the same, the body has correct typing use of |this|, and the class 
is non-final? This seems to have the same integrity as method overriding in 
subclasses. Being able to do this (and possibly dynamically adding methods 
to classes) would bring the level of dynamicism that Mark had suggested with 
his ES4 sugar proposal (being able to create classes on the fly), but 
without destroying the fundamental ES4 typing/fixture system. This could be 
used to solve AOP as well, and bring a distinctly higher level of dynamicism 
which could be leveraged to progressively build, serialize (with proper 
introspection), and deserialize classes.

Essentially, are there mutations to classes and object instances that do not 
effect integrity and do not violate explicit contracts against mutation 
(final annotation=no method mutations) that we could allow?

Thanks,
Kris

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


Re: Class method addition and replacement (was Re: AOP Compatibility)

2008-04-03 Thread Peter Hall
Replacing a method effectively changes the type, even if the signature
is the same. If some code creates an instance of a class using new
it should be able to rely on it being that type, and make assumptions
about how that object will behave. (This is not a matter of breaking
polymorphism because the same code created the instance such that
there is no possibility of a sub-type instance being present).
Allowing methods to be replaced means that other parts of a program
could alter the behaviour of an object in a way that could contradict
those assumptions.

Additionally, allowing methods to be replaced could reduce the
effectiveness of early binding optimisations. (Jeff Dyer can correct
me if I'm inaccurate here..) In AS3, class methods are referenced via
the class's traits table. They may be accessed by name, but calls are
bound to addresses where possible, at compile time via the traits.
Allowing methods to be overridden would mean a choice of copying the
traits for each instance, which would increase memory usage
dramatically; or else checking for overrides at runtime for every
method call, which would hurt performance.


Peter


On Thu, Apr 3, 2008 at 4:23 PM, Kris Zyp [EMAIL PROTECTED] wrote:
  the moment, but I assume you can't do replace a method on a user  class
   with
   another ad-hoc function.
  
   Absolutely not with fixtures,

  I was thinking about this, is there any reason why you can't replace a
  class's method with another method or install a method on an instance object
  that overrides the class's method, assuming that the method signature
  remains the same, the body has correct typing use of |this|, and the class
  is non-final? This seems to have the same integrity as method overriding in
  subclasses. Being able to do this (and possibly dynamically adding methods
  to classes) would bring the level of dynamicism that Mark had suggested with
  his ES4 sugar proposal (being able to create classes on the fly), but
  without destroying the fundamental ES4 typing/fixture system. This could be
  used to solve AOP as well, and bring a distinctly higher level of dynamicism
  which could be leveraged to progressively build, serialize (with proper
  introspection), and deserialize classes.

  Essentially, are there mutations to classes and object instances that do not
  effect integrity and do not violate explicit contracts against mutation
  (final annotation=no method mutations) that we could allow?

  Thanks,
  Kris

  ___
  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: Strict mode recap

2008-04-03 Thread Jon Zeppieri
On Wed, Apr 2, 2008 at 11:15 PM, Lars Hansen [EMAIL PROTECTED] wrote:
  
   Is this already in AS3?  If so, is it often used?

  The syntax comes from E4X, which is incorporated into AS3 and
  Spidermonkey.  Try this in Firefox:

   script type=text/javascript;e4x=1
   var x = ns:p xmlns:ns=http://www.opera.com/;ns:qHi
  there/ns:q/ns:p
   var ns = new Namespace(http://www.opera.com/;);
   var em = q
   document.writeln(x.ns::[em]);
   /script

I'm aware of E4X.  I meant: is it possible to refer to lexical
bindings in this manner in AS3?

I guess I don't see what use case is satisfied by this feature that
isn't already met by the existence of Map.  After all, the effect of
this feature is to turn lexical environments into (quasi) first class
maps, with the peculiar restriction that new name/value pairs cannot
be added, though existing ones can be mutated.  If a user actually
needs that functionality, it wouldn't be difficult to subclass Map to
get it.

And, yes, I know it's already possible to do this with lexically
scoped eval.  But why do you want to add another way to do it?

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


RE: Class method addition and replacement (was Re: AOP Compatibility)

2008-04-03 Thread Lars Hansen
Just to echo Peter here, changing a method violates integrity in
the worst way.  If I say new Cls I *know* that the object I get
is of type Cls, and if I know the implementation of that class I
know what a call to a method of the type will do.  There is no
way subclassing can get in the way of that knowledge, but allowing
methods to be arbitrarily assigned to (even with constraints on
type compatibility) completely destroys that invariant.  But that
invariant is one of the main benefits of having classes in the
first place.

(There are efficiency concerns too, but I think the violation of
integrity is the important part.)

--lars

 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of Peter Hall
 Sent: 3. april 2008 09:58
 To: Kris Zyp
 Cc: es4-discuss Discuss
 Subject: Re: Class method addition and replacement (was Re: 
 AOP Compatibility)
 
 Replacing a method effectively changes the type, even if the 
 signature is the same. If some code creates an instance of a 
 class using new
 it should be able to rely on it being that type, and make 
 assumptions about how that object will behave. (This is not a 
 matter of breaking polymorphism because the same code created 
 the instance such that there is no possibility of a sub-type 
 instance being present).
 Allowing methods to be replaced means that other parts of a 
 program could alter the behaviour of an object in a way that 
 could contradict those assumptions.
 
 Additionally, allowing methods to be replaced could reduce 
 the effectiveness of early binding optimisations. (Jeff Dyer 
 can correct me if I'm inaccurate here..) In AS3, class 
 methods are referenced via the class's traits table. They may 
 be accessed by name, but calls are bound to addresses where 
 possible, at compile time via the traits.
 Allowing methods to be overridden would mean a choice of 
 copying the traits for each instance, which would increase 
 memory usage dramatically; or else checking for overrides at 
 runtime for every method call, which would hurt performance.
 
 
 Peter
 
 
 On Thu, Apr 3, 2008 at 4:23 PM, Kris Zyp [EMAIL PROTECTED] wrote:
   the moment, but I assume you can't do replace a method 
 on a user  
   class
with
another ad-hoc function.
   
Absolutely not with fixtures,
 
   I was thinking about this, is there any reason why you 
 can't replace 
  a  class's method with another method or install a method on an 
  instance object  that overrides the class's method, 
 assuming that the 
  method signature  remains the same, the body has correct 
 typing use of 
  |this|, and the class  is non-final? This seems to have the same 
  integrity as method overriding in  subclasses. Being able 
 to do this 
  (and possibly dynamically adding methods  to classes) would 
 bring the 
  level of dynamicism that Mark had suggested with  his ES4 sugar 
  proposal (being able to create classes on the fly), but  without 
  destroying the fundamental ES4 typing/fixture system. This 
 could be  
  used to solve AOP as well, and bring a distinctly higher level of 
  dynamicism  which could be leveraged to progressively 
 build, serialize (with proper  introspection), and 
 deserialize classes.
 
   Essentially, are there mutations to classes and object 
 instances that 
  do not  effect integrity and do not violate explicit 
 contracts against 
  mutation  (final annotation=no method mutations) that we 
 could allow?
 
   Thanks,
   Kris
 
   ___
   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: Strict mode recap

2008-04-03 Thread Lars Hansen
 

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On 
 Behalf Of Jon Zeppieri
 Sent: 3. april 2008 10:10
 To: Lars Hansen
 Cc: es4-discuss@mozilla.org
 Subject: Re: Strict mode recap
 
 On Wed, Apr 2, 2008 at 11:15 PM, Lars Hansen 
 [EMAIL PROTECTED] wrote:
   
Is this already in AS3?  If so, is it often used?
 
   The syntax comes from E4X, which is incorporated into AS3 and  
  Spidermonkey.  Try this in Firefox:
 
script type=text/javascript;e4x=1
var x = ns:p xmlns:ns=http://www.opera.com/;ns:qHi
   there/ns:q/ns:p
var ns = new Namespace(http://www.opera.com/;);
var em = q
document.writeln(x.ns::[em]);
/script
 
 I'm aware of E4X.  I meant: is it possible to refer to 
 lexical bindings in this manner in AS3?

Yes.  AS3 has an annoying restriction on where 
user-defined namespaces may be used, but the 
following example captures it without using E4X:

  package X {
namespace myns;

class C {
myns var v = 37;
}

var x = myns;
var y = v;

print((new C).x::[y]);
  }

This does print '37' if compiled with ASC and run through 
the Tamarin VM.

 I guess I don't see what use case is satisfied by this 
 feature that isn't already met by the existence of Map.  

 After all, the effect of this feature is to turn lexical 
 environments into (quasi) first class maps, with the peculiar 
 restriction that new name/value pairs cannot be added, though 
 existing ones can be mutated.  If a user actually needs that 
 functionality, it wouldn't be difficult to subclass Map to get it.
 
 And, yes, I know it's already possible to do this with 
 lexically scoped eval.  But why do you want to add another 
 way to do it?

Let me turn it around.

The syntax ns::v is in the language, for constant identifier v.
If E4X is implemented in an implementation (as it will be in 
ActionScript and presumably in Firefox, at least), so is 
ns::[expr].  How would a restriction to require ns to be a 
compile-time constant (in either form) and not a run-time 
value, or a restriction to disallow the latter form in ES4
but not in E4X, benefit ES4?

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


Re: Class method addition and replacement (was Re: AOP Compatibility)

2008-04-03 Thread Brendan Eich
On Apr 3, 2008, at 8:23 AM, Kris Zyp wrote:

 the moment, but I assume you can't do replace a method on a user   
 class
 with
 another ad-hoc function.

 Absolutely not with fixtures,

 I was thinking about this, is there any reason why you can't replace a
 class's method with another method or install a method on an  
 instance object
 that overrides the class's method, assuming that the method signature
 remains the same, the body has correct typing use of |this|, and  
 the class
 is non-final? This seems to have the same integrity as method  
 overriding in
 subclasses. Being able to do this (and possibly dynamically adding  
 methods
 to classes) would bring the level of dynamicism that Mark had  
 suggested with
 his ES4 sugar proposal (being able to create classes on the fly)

Mark's sketch did not allow method replacement, however.

AOP is not the root password to mutation barriers added to enforce  
integrity properties. It is not even formally sound, last I looked.  
And its main use-case is logging or other such post-hoc, cross- 
cutting instrumentation. If the universe of objects already contains  
some (like certain built-in objects including DOM nodes in most  
browsers) whose methods cannot be replaced, which must therefore be  
wrapped for AOP-style hacking, then why wouldn't we want classes to  
behave as proposed in ES4?

Wrappers will be required; they already are for security in browsers  
I've studied (or they are coming soon, at any rate). Any code not  
insisting on a nominal type relation, i.e., using * (implicitly as in  
untyped code today, or explicitly), or a like test, or a structural  
subtype test, could let wrappers through. Just as DOM wrappers can  
satisfy hand-coded shape tests in today's untyped libraries that  
use AOP.

/be

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


RE: Class method addition and replacement (was Re: AOP Compatibility)

2008-04-03 Thread Lars Hansen
Most of the time I would not agree that changing a method
is an explicit indication that a developer doesn't want 
the class to be invariant.  Most of the time it's just an
indication that I'm (a) hacking to make something (appear to)
work or (b) tired and making a mistake.  And this goes
doubly for team programming and for programs that have a
long maintenance life.

Classes provide the integrity that is necessary for large 
systems written by many people over significant periods of
time to work; such systems reward commitments to invariants
even if those invariants later can become a straightjacket
(and require reengineering).  In such a system the variation
points are (and need to be) explicit.  

--lars

 -Original Message-
 From: Kris Zyp [mailto:[EMAIL PROTECTED] 
 Sent: 3. april 2008 18:02
 To: Lars Hansen; Peter Hall
 Cc: es4-discuss Discuss
 Subject: Re: Class method addition and replacement (was Re: 
 AOP Compatibility)
 
  Just to echo Peter here, changing a method violates 
 integrity in the 
  worst way.  If I say new Cls I *know* that the object I get is of 
  type Cls, and if I know the implementation of that class I 
 know what a 
  call to a method of the type will do.  There is no way 
 subclassing can 
  get in the way of that knowledge, but allowing methods to be 
  arbitrarily assigned to (even with constraints on type 
 compatibility) 
  completely destroys that invariant.  But that invariant is 
 one of the 
  main benefits of having classes in the first place.
 
 But if I want the class to behave exactly the same as when I 
 created, why would I change the method? Isn't changing a 
 method an explicit indication that a developer doesn't want 
 the class to be invariant?
 I believe this is more a philosophical/preferential question. 
 Do you value class integrity/immutably more or 
 dynamicism/mutably? Obviously my preference is towards the 
 latter camp, but perhaps I am in the minority, and the 
 concerns over efficiency are certainly important as well.
 Thanks,
 Kris
 
 
 
  (There are efficiency concerns too, but I think the violation of 
  integrity is the important part.)
 
  --lars
 
  -Original Message-
  From: [EMAIL PROTECTED] 
  [mailto:[EMAIL PROTECTED] On Behalf Of Peter Hall
  Sent: 3. april 2008 09:58
  To: Kris Zyp
  Cc: es4-discuss Discuss
  Subject: Re: Class method addition and replacement (was Re:
  AOP Compatibility)
 
  Replacing a method effectively changes the type, even if the 
  signature is the same. If some code creates an instance of a class 
  using new
  it should be able to rely on it being that type, and make 
 assumptions 
  about how that object will behave. (This is not a matter 
 of breaking 
  polymorphism because the same code created the instance such that 
  there is no possibility of a sub-type instance being present).
  Allowing methods to be replaced means that other parts of 
 a program 
  could alter the behaviour of an object in a way that could 
 contradict 
  those assumptions.
 
  Additionally, allowing methods to be replaced could reduce the 
  effectiveness of early binding optimisations. (Jeff Dyer 
 can correct 
  me if I'm inaccurate here..) In AS3, class methods are 
 referenced via 
  the class's traits table. They may be accessed by name, 
 but calls are 
  bound to addresses where possible, at compile time via the traits.
  Allowing methods to be overridden would mean a choice of 
 copying the 
  traits for each instance, which would increase memory usage 
  dramatically; or else checking for overrides at runtime for every 
  method call, which would hurt performance.
 
 
  Peter
 
 
  On Thu, Apr 3, 2008 at 4:23 PM, Kris Zyp [EMAIL PROTECTED] wrote:
the moment, but I assume you can't do replace a method
  on a user
class
 with
 another ad-hoc function.

 Absolutely not with fixtures,
  
I was thinking about this, is there any reason why you
  can't replace
   a  class's method with another method or install a method on an 
   instance object  that overrides the class's method,
  assuming that the
   method signature  remains the same, the body has correct
  typing use of
   |this|, and the class  is non-final? This seems to have the same
   integrity as method overriding in  subclasses. Being able
  to do this
   (and possibly dynamically adding methods  to classes) would
  bring the
   level of dynamicism that Mark had suggested with  his ES4 sugar 
   proposal (being able to create classes on the fly), but  without 
   destroying the fundamental ES4 typing/fixture system. This
  could be
   used to solve AOP as well, and bring a distinctly higher 
 level of 
   dynamicism  which could be leveraged to progressively
  build, serialize (with proper  introspection), and deserialize 
  classes.
  
Essentially, are there mutations to classes and object
  instances that
   do not  effect integrity and do not violate explicit
  contracts against
   mutation  (final annotation=no 

Re: Strict mode recap

2008-04-03 Thread Jon Zeppieri
On 4/3/08, Lars Hansen [EMAIL PROTECTED] wrote:

   package X {
 namespace myns;

 class C {
 myns var v = 37;
 }

 var x = myns;
 var y = v;

 print((new C).x::[y]);
   }

  This does print '37' if compiled with ASC and run through
  the Tamarin VM.

This is like the E4X example in one crucial respect:  in both cases,
you're accessing a property of a first-class object.  I'm not arguing
against this use of computed names.  I don't see any significant
difference between the above and:

var obj = { x: hello };
print(obj[x]);

My claim is simply that...

function foo() {
  var x = hello;
}

... here, x is not a property of a first-class object.  x's binding
environment isn't a datum.  But:

function foo(name) {
  ...
  return null::[name];
}

... treats the environment as if it were a datum.  I know that in the
ES3 spec all bindings are referred to as properties of objects, but
activation objects are only notional entities.  The current ES4
proposal seems to raise their status by giving programmers a simple
mechanism to (practically) reify them.


   I guess I don't see what use case is satisfied by this
   feature that isn't already met by the existence of Map.
  
   After all, the effect of this feature is to turn lexical
   environments into (quasi) first class maps, with the peculiar
   restriction that new name/value pairs cannot be added, though
   existing ones can be mutated.  If a user actually needs that
   functionality, it wouldn't be difficult to subclass Map to get it.
  
   And, yes, I know it's already possible to do this with
   lexically scoped eval.  But why do you want to add another
   way to do it?


 Let me turn it around.

  The syntax ns::v is in the language, for constant identifier v.
  If E4X is implemented in an implementation (as it will be in
  ActionScript and presumably in Firefox, at least), so is
  ns::[expr].  How would a restriction to require ns to be a
  compile-time constant (in either form) and not a run-time
  value, or a restriction to disallow the latter form in ES4
  but not in E4X, benefit ES4?


From my perspective, it isn't an E4X vs. ES4 distinction; it's a
looking up a property of a first-class object vs. using a local
variable (or, if you prefer, looking up a property of an activation
object) distinction.  It's not as if this is an uncommon distinction
in programming languages, and the advantage of keeping the distinction
is better static analysis, better performance, more tractable code.

-Jon





  --lars


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


Re: Strict mode recap

2008-04-03 Thread liorean
On 04/04/2008, Jon Zeppieri [EMAIL PROTECTED] wrote:
 This is like the E4X example in one crucial respect:  in both cases,
  you're accessing a property of a first-class object.  I'm not arguing
  against this use of computed names.  I don't see any significant
  difference between the above and:

  var obj = { x: hello };
  print(obj[x]);

  My claim is simply that...

  function foo() {
   var x = hello;
  }

  ... here, x is not a property of a first-class object.  x's binding
  environment isn't a datum.  But:

  function foo(name) {
   ...
   return null::[name];
  }

  ... treats the environment as if it were a datum.  I know that in the
  ES3 spec all bindings are referred to as properties of objects, but
  activation objects are only notional entities.  The current ES4
  proposal seems to raise their status by giving programmers a simple
  mechanism to (practically) reify them.

Except you can't actually make the activation object a first class
object. The null namespace (or any other namespace) is orthogonal to
the activation object - you can now look up local variables
dynamically instead of just statically, but the scope still cannot be
leaked out of the function in any way.

The only notable change is that you now have a method of making
dynamic lookup of the local variables in a scope instead of only
static lookup. The method of doing so is considerably better than
locally scoped eval because it's restricted to doing just that and
nothing more.
-- 
David liorean Andersson
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Strict mode recap

2008-04-03 Thread Jon Zeppieri
On 4/3/08, liorean [EMAIL PROTECTED] wrote:
 On 04/04/2008, Jon Zeppieri [EMAIL PROTECTED] wrote:
  
function foo(name) {
 ...
 return null::[name];
}
  
... treats the environment as if it were a datum.  I know that in the
ES3 spec all bindings are referred to as properties of objects, but
activation objects are only notional entities.  The current ES4
proposal seems to raise their status by giving programmers a simple
mechanism to (practically) reify them.


 Except you can't actually make the activation object a first class
  object. The null namespace (or any other namespace) is orthogonal to
  the activation object - you can now look up local variables
  dynamically instead of just statically, but the scope still cannot be
  leaked out of the function in any way.

Right, hence the 'practically.'  There's no meaningful difference,
though; the function simply acts as a proxy for the environment.  I
mean, what important difference is there (as far as the current
discussion is concerned) between:

var map = new PeculiarMap([foo, bar, baz]);

... where PeculiarMap is a subclass of Map that maintains a constant
set of keys, but allows those keys to be associated with new values,
and:

var map = (function() {
 var foo, bar, baz;

 return {
   get: function(name) {
 return null::[name];
   },

   set: function(name, value) {
 null::[name] = value;
   }
 };
})();

The fact that you can't pass around the activation object itself
doesn't seem terribly significant.  What would you be able to do if it
were a real first-class object that you can't do here?


  The only notable change is that you now have a method of making
  dynamic lookup of the local variables in a scope instead of only
  static lookup. The method of doing so is considerably better than
  locally scoped eval because it's restricted to doing just that and
  nothing more.

That's fine, but why would you want to do that, at all?  My point is
this:  there's an obvious downside to this kind of lookup (inhibiting
static analysis and all that), but there's no obvious upside to it.

I suppose the argument goes: if the choice is between calling eval to
perform this kind of lookup or using ns::[expr], it's better to use
ns::[expr].  I won't argue with that, but it's a false dilemma.  You
could just use an actual data structure.

eval has a real use: runtime code generation.  (This does not require
dynamically scoped eval, but that's beside the point here.)  Dynamic
lookup of activation object properties, however, doesn't seem...
useful.  (I certainly could be wrong about this, but I can't think of
a compelling use case.  And, again, this does *not* apply to dynamic
lookup of first-class object properties, which is obviously useful.)
The point being:  ES3 programmers who are using eval to perform
dynamic lookup of activation object properties don't need a better
mechanism to do the same thing, because what they're doing doesn't
make sense to begin with.

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


Re: Strict mode recap

2008-04-03 Thread Jon Zeppieri
On 4/4/08, Jon Zeppieri [EMAIL PROTECTED] wrote:

  eval has a real use: runtime code generation.  (This does not require
  dynamically scoped eval, but that's beside the point here.)

Uh, I meant lexically scoped eval, of course...
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss