Creating classes dynamically

2,332 views
Skip to first unread message

Yury Selivanov

unread,
Mar 11, 2015, 11:10:39 AM3/11/15
to streng...@googlegroups.com
Hello,

First of all kudos for the idea. I've been waiting for something like this implemented in VMs natively for years. I think this will definitely open up a lot of possibilities to make JS faster and safer.

One question I have about Strong Mode classes: Can you guys provide a facility to create classes programmatically? Something like:

   Object.createClass(name, initializer, prototype)

This is something that will be easy to shim in other browsers, and it will allow people to develop new dynamic languages and transpile to Strong Mode. For instance, I'm creating a language that visually looks like Rust, but is closer to Python in its object model, allowing multiple inheritance etc. Having the ability to create classes dynamically is absolutely crucial for me. And I don't mind if the classes will be frozen and instances sealed, if anything, I view this as a positive thing.

Thanks,
Yury

Andreas Rossberg

unread,
Mar 11, 2015, 12:31:18 PM3/11/15
to Yury Selivanov, streng...@googlegroups.com
On 11 March 2015 at 16:10, Yury Selivanov <yseli...@gmail.com> wrote:
One question I have about Strong Mode classes: Can you guys provide a facility to create classes programmatically? Something like:

   Object.createClass(name, initializer, prototype)

Classes are first-class values in ES6, they can be returned from a function, for example. The language even has class expressions. Consider e.g.

function MakeC(parent, methodname) {
  return class extends parent { [methodname]() {} }
}

let C1 = MakeC(Object, 'foo')
let C2 = MakeC(C1, 'bar')

Does that help the kind of dynamism you need?

/Andreas

Yury Selivanov

unread,
Mar 11, 2015, 12:47:22 PM3/11/15
to streng...@googlegroups.com, yseli...@gmail.com
Unfortunately it's not enough. I need an ability to construct a collection of methods dynamically to mimic Python metaclasses (which can alter methods, add new ones etc). I know that will make it almost impossible to statically analyze this kind of code, but that's something some users might be OK to sacrifice in order to be able to have more dynamism, along with other improvements of Strong Mode.

Even if I skip all metaclasses dance & magic, I would have another problem. Multiple inheritance applies some additional requirements on how 'super' works, i.e. I'll need to call a custom 'super' implementation. But I wouldn't be able to pass 'this' or do anything else with it besides accessing/assigning attributes in class' constructor. So I need a way to create classes in a bit less restrained way.

Yury

Andreas Rossberg

unread,
Mar 11, 2015, 2:13:03 PM3/11/15
to Yury Selivanov, streng...@googlegroups.com
On 11 March 2015 at 17:47, Yury Selivanov <yseli...@gmail.com> wrote:
function MakeC(parent, methodname) {
  return class extends parent { [methodname]() {} }
}

let C1 = MakeC(Object, 'foo')
let C2 = MakeC(C1, 'bar')

Does that help the kind of dynamism you need?

Unfortunately it's not enough. I need an ability to construct a collection of methods dynamically to mimic Python metaclasses (which can alter methods, add new ones etc). I know that will make it almost impossible to statically analyze this kind of code, but that's something some users might be OK to sacrifice in order to be able to have more dynamism, along with other improvements of Strong Mode.

Of course, there always is 'eval'. Also, you can always use strong mode selectively, and for more dynamic stuff, call into a function or module that isn't in strong mode.

But I'm not sure I understand how specifically your example relates to strong mode. As far as I can see, ES6 doesn't have any such reflective createClass mechanism regardless of mode (other than 'eval'). So this sounds more like an ES feature wish? If such a mechanism existed, I wouldn't see any particular reason to not make it available in strong mode.

/Andreas



Even if I skip all metaclasses dance & magic, I would have another problem. Multiple inheritance applies some additional requirements on how 'super' works, i.e. I'll need to call a custom 'super' implementation. But I wouldn't be able to pass 'this' or do anything else with it besides accessing/assigning attributes in class' constructor. So I need a way to create classes in a bit less restrained way.

Yury

--
You received this message because you are subscribed to the Google Groups "Strengthen JS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to strengthen-j...@googlegroups.com.
To post to this group, send email to streng...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/strengthen-js/13bebb25-5704-4652-a1d1-b18eaf5575b1%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Yury Selivanov

unread,
Mar 11, 2015, 2:55:26 PM3/11/15
to streng...@googlegroups.com, yseli...@gmail.com
On Wednesday, March 11, 2015 at 2:13:03 PM UTC-4, Andreas Rossberg wrote:
On 11 March 2015 at 17:47, Yury Selivanov <yseli...@gmail.com> wrote:
function MakeC(parent, methodname) {
  return class extends parent { [methodname]() {} }
}

let C1 = MakeC(Object, 'foo')
let C2 = MakeC(C1, 'bar')

Does that help the kind of dynamism you need?

Unfortunately it's not enough. I need an ability to construct a collection of methods dynamically to mimic Python metaclasses (which can alter methods, add new ones etc). I know that will make it almost impossible to statically analyze this kind of code, but that's something some users might be OK to sacrifice in order to be able to have more dynamism, along with other improvements of Strong Mode.

Of course, there always is 'eval'. Also, you can always use strong mode selectively, and for more dynamic stuff, call into a function or module that isn't in strong mode.

But I'm not sure I understand how specifically your example relates to strong mode. As far as I can see, ES6 doesn't have any such reflective createClass mechanism regardless of mode (other than 'eval'). So this sounds more like an ES feature wish? If such a mechanism existed, I wouldn't see any particular reason to not make it available in strong mode.

Well, in ES6 you emulate classes with '.prototype' attribute on functions. And since this mechanism won't work in Strong Mode (am I right?), I was proposing to add some kind of class construction facility (Object.createClass or something similar). ES6 just doesn't need this method, whereas it would be extremely handy to have it in strong mode.

Having a non-strong function creating classes for otherwise strong environment seems possible, but then such objects won't have all the goodies that strong mode provides (TypeError on attribute access etc).

Yury

Andreas Rossberg

unread,
Mar 11, 2015, 3:04:43 PM3/11/15
to Yury Selivanov, streng...@googlegroups.com
I see. Yes, you are right. Such a mechanism could be useful. You can polyfill it with 'eval', but that's not ideal.

Another option is to have a weak mode class (which is patchable), and derive a strong class from that. Then you get most of the benefits of strong mode instances while still being able to add methods after the fact. What you won't get is any optimisations for accessing these methods, though. (And it probably won't work with types.)

/Andreas

Yury Selivanov

unread,
Mar 11, 2015, 4:22:03 PM3/11/15
to streng...@googlegroups.com, yseli...@gmail.com
Weak classes is one good solution. But it's another concept I guess.

If we can have a native function to define Strong Classes dynamically, then we can probably have almost all optimizations enabled for them. If, let's call it createClass function, accepts an object similar to what Object.defineProperties function receives, plus an initializer function, then we can have class objects frozen and their instances sealed.

In other words, I want to be able to customize the composition of the class programmatically, but I don't care if it's sealed and frozen right after it's created. The VM then can optimize method lookups and everything knowing that the class structure is set in stone.

Do you think it's possible to have this? I can help with providing some initial spec for that.

Yury

Andreas Rossberg

unread,
Mar 11, 2015, 4:44:10 PM3/11/15
to Yury Selivanov, streng...@googlegroups.com
Technically speaking, that is totally possible (and easy). However, keep in mind that one main design constraint of strong mode is that it is supposed to be a subset of ES6+ (in a suitably hand-wavy manner). Consequently, such a factory method would have to be an actual ES proposal, not a feature of strong mode per se. And that would be much harder to push through.

/Andreas

Yury Selivanov

unread,
Mar 11, 2015, 5:46:50 PM3/11/15
to streng...@googlegroups.com, yseli...@gmail.com
Can we have this factory method with a vendor prefix? And when/if Strong Mode is standardized, there will be a compelling reason for ECMA to add the method (or an alternative) to the spec.

Yury
Reply all
Reply to author
Forward
0 new messages