Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Metaclasses #4

Closed
gbracha opened this issue Feb 25, 2015 · 11 comments
Closed

Metaclasses #4

gbracha opened this issue Feb 25, 2015 · 11 comments

Comments

@gbracha
Copy link

gbracha commented Feb 25, 2015

This is a proposal to endow Type objects with type-specific behavior, effectively creating a distinct metaclass for each class. This will make classes behave as first class runtime values.

Repository: https://github.com/gbracha/metaclasses

@polux
Copy link

polux commented Feb 25, 2015

/sub (Isn't there a better way to subscribe to issues in github by the way?)

@munificent
Copy link
Contributor

@sethladd and @polux, you'll just want to watch the repo for the DEP. (I added a link to it in the bug.) This bug basically just tracks the status of the DEP. the DEP itself lives in its own repository.

@sethladd
Copy link
Contributor

Thanks for the tip!

@danschultz
Copy link

@polux there's subscribe button over on the right.

@sethladd
Copy link
Contributor

sethladd commented Apr 1, 2015

Can we discuss this proposal in one of the next DEP meetings? We have a customer that would love use this feature, if available. Thanks!

@munificent
Copy link
Contributor

We have a customer that would love use this feature, if available.

Can they provide some details on what they want to use it for?

@sethladd
Copy link
Contributor

sethladd commented Apr 1, 2015

cc @Hixie

@munificent
Copy link
Contributor

Note that the right place to provide feedback isn't on this issue. Either email core-dev@ or file issues on the proposal's repo.

@sethladd
Copy link
Contributor

sethladd commented Apr 1, 2015

Should we just lock the issue? I've seen others be confused about all the different places one can leave a comment.

@Hixie
Copy link

Hixie commented Apr 1, 2015

Metaclasses are the main pain point I have in dealing with Dart in the context of developing extensible platforms, i.e. platforms where core features get extended post-hoc. In particular I miss:

  • the ability to define types whose range is a class and its subclasses

For example:

   abstract class LayoutManager { ... }
   void registerLayoutManager(Class<LayoutManager> manager, String name) { ... }

...where registerLayoutManager()'s first argument has to be a subclass of LayoutManager (or indeed LayoutManager itself, if it wasn't abstract).

  • the ability to call static methods, static fields, and constructors on class types

For example:

   class Foo {
     Foo() { print("constructor"); }
     static String get name => 'my-name';
     static void test() => print('foo');
   }
   void main() {
     var X = Foo;
     Foo f = new X(); // prints "constructor"
     print(X.name); // prints "my-name"
   }
  • virtual static methods and virtual static fields
   // assume Foo from above exists
   class Bar extends Foo {
     @override static String get name => 'bar';
     @override void test() { print('bar'); super.test(); }
   }
   void register(Class<Foo> x) {
     print("going to register ${x.name}");
   }
   void main() {
     Foo X = Bar;
     X.test(); // prints "bar" then "foo";
     register(X); // prints "going to register bar"
     register(Foo); // prints "going to register my-name"
   }

Virtual static fields are great for storing data about the class, as above. Virtual static methods are really useful too, though, for the same reason that regular static methods are useful: it lets you do logic that applies to all instances, without having to know which exact class you're dealing with. For example, a class could define a method that verifies if some data is valid input to the class; you would then check this before calling the constructor. With metaclasses, you don't know exactly which class you have, but you still need to check the data. See the example below.

  • virtual constructors

The above are all useful, but really virtual constructors are the most important:

   abstract class Element {
     new(String input);
     static String get tagName;
     static bool isValid(String input);
     // ...
   }
   class FooElement extends Element {
     @override new(String input): super.new(input) { /*...*/ }
     @override static String get tagName => 'foo';
     @override static bool isValid(String input) => (input == 'true') || (input == 'false');
   }
   class BarElement extends Element {
     // inherits Element's constructor
     @override static String get tagName => 'bar';
     @override static bool isValid(String input) => (input == 'one') || (input == 'two');
   }
   Map<String, Class<Element>> registrations = {};
   registerElement(Class<Element> e) {
     registrations[e.tagName] = e;
   }
   instantiateElement(String tagName, String input) {
     var c = registrations[tagName](input);
     if (c.isValid(input))
       return new c(input);
     return null;
   }
   void main() {
     registerElement(FooElement);
     registerElement(BarElement);
     // ...
     assert(instantiateElement('foo', 'true') is FooElement);
     assert(instantiateElement('bar', 'one') is BarElement);
   }

@lrhn
Copy link
Contributor

lrhn commented Feb 5, 2019

The DEP process has been discontinued, so closing this issue.
Any new discussion about metaclasses should happen in the language repo.

@lrhn lrhn closed this as completed Feb 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

7 participants