class State {
final String value;
final int length;
bool show;
}
var state = new State(value:"bla", length: 10, show: true);
class State {
final String value = "default";
final int length = 3;
bool show = false;
}
var state = new State(value:"bla");
class State {
@required String value; @required int length; bool show;
}
class State {
String value;
int length;
bool? show;
}
var point = Point(2, 3);
Okay, this may sound a bit outrageous hehe. It is probably way too much of change for Dart 2.0, but I find this idea in general interesting for a language and I would like to discuss it.Heavily inspired by this post: https://medium.com/@emilniklas/constructors-considered-harmful-17cccfab8d3#.3nzua8bedI think I also heard Gilad Brach say something that the constructors in Dart are a mess, and I agree.
I think there is just too much ways to do essentially the same way, and I think we can do much better.
So I think instead of having named constructor, factory constructors, initializer lists, etc. I think you should all remove it from the language. And there should be just one way to create a new instance of an object, and that is automatic determined from the public properties of the object.
So say if I have the class
class State {
final String value;
final int length;
bool show;
}
Now the way to create an instance is simply:
var state = new State(value:"bla", length: 10, show: true);
If you want default values, just write:
class State {
final String value = "default";
final int length = 3;
bool show = false;
}
var state = new State(value:"bla");So a final field, is only really final after the object is initialized, may sound a bit strange, but I think it is the most sensible way of doing it, and makes sure there is still just one good way of doing this.And yes, every parameter is named, because it is good to explicitly state which field you are setting.So how do you say if a field could be null, or must be initialized. Well, I propose the exact same as I do here:NNBD would really help there, otherwise, you could do:
class State {
String value;
int length;
@required bool show;
}
But I would prefer instead:
class State {
String value;
int length;
bool? show;
}Now if you want to do some calculation, side effects, error checking or whatever before you initialize an object, I propose that you use just a function for that. So there is just one way to `new` an instance. You can not new it with a factory, because that just don't make sense. However, you can implement this function of course as a static method of the class. And I propose to have some syntax to write a default static method of a class. For example:
class Point {
final num x;
final num y;
final num distanceFromOrigin;
static default(num x, num y) {
return new Point(
x: x, y: y, distanceFromOrigin: sqrt(pow(x,2) + pow(y, 2))}
}
class Point { final num x; final num y; final num distanceFromOrigin;
--Point(x, y) : x = x, y = y, distanceFromOrigin = sqrt(pow(x, 2) + pow(y, 2)); }
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
class Super {
A a;
B b;
static default(String input) {
A a = // calculation
B b = // calculation
return new Super(a: a, b: b);
}
method() {
return a.doSomething(b);
}
}
class Sub extends Super {
C c;
D d;
static default(A a, B b, C c, D d) {
return new Sub(a: a, b: b, c: c, d: d);
}
}
class Sub extends Super {
C c;
D d;
static default(String input, C c, D d) {
var sup = Super(input);
return new Sub(a: sup.a, b: sup.b, c: c, d: d); }
}
class A {
final B b;
A(this.b);
}
class C extends A {
D d;
C(this.d, B b) : super(b);
}
class A {
abstract B b;
}
class C extends A {
abstract D d;
}
new A(b: ...);
new C(b: ..., d: ...);
class C extends A {
@override B b = ...;
D d;
}
new C(d: ...);
class C extends A {
D d;
C(this.d, String somethingElse) :
super(bFromSomethingElse(somethingElse));
}
Factory constructors are generally useless (apart from const factory constructors which are just forwarding constructors, not really "factory" ones, and the fact that you can supply type parameters, but when we get generic methods, that isn't a distinguishing feature any more).
One popular pattern is the Factory Pattern, with examples in many frameworks or toolkits. However, without native language support for the factory pattern, most implementations have to implement it with combinations of static methods and or utility classes. While this works, it exposes the pattern to the consumer of the code. Luckily, the designers of Dart added the factory pattern right into the language. With Dart’s factory constructors, you can natively use the factory pattern and make it appear like a regular constructor.
One great use case for factory constructors is to return objects from a cache.
On Thursday, August 18, 2016 at 7:57:16 AM UTC-5, Lasse Reichstein Holst Nielsen wrote:Factory constructors are generally useless (apart from const factory constructors which are just forwarding constructors, not really "factory" ones, and the fact that you can supply type parameters, but when we get generic methods, that isn't a distinguishing feature any more).Curious why you say that? This is from Classes: Constructors:One popular pattern is the Factory Pattern, with examples in many frameworks or toolkits. However, without native language support for the factory pattern, most implementations have to implement it with combinations of static methods and or utility classes. While this works, it exposes the pattern to the consumer of the code. Luckily, the designers of Dart added the factory pattern right into the language. With Dart’s factory constructors, you can natively use the factory pattern and make it appear like a regular constructor.
One great use case for factory constructors is to return objects from a cache.Could you elaborate? Is this no longer accurate?
One thing factory constructors seem to aid with is allowing fields to more easily be final. The factory constructor can dynamically create fields to pass to another constructor. For instance, a factory constructor can take fields a and b, and compute a reasonable default for c based on a and b then pass them to a ctor allowing all three to be final. But regular constructors don't seem to allow references to or computation on previous final fields passed in.
As soon as "new" is gone, dart can support the view on constructor as static function.
All you need for that is to allow expressions likevar myFooContructor=Foo.constructor; // for default constructorvar foo=myFooConstructor("bar", "baz");var myFooConstructor1=Foo.someFactoryConstructor;var foo1=myFooConstructor1("bar", "baz");etcIMO, the problem is not with generative constructor, and not with factory constructor, and not with multiple inheritance (which is a dead horse already) - it's a problem with "new", which is an arbitrary idea to begin with, and cannot be even consistently implemented (e.g. we never write "new str.Substring(0)").
> There are still problems with generative constructors and the fact that class extension depends on them. Not easily solvable problems, sadly.Sorry, I'm not aware of these problems. Could you provide an example?
super() calls can remain the same as they are now, what's wrong with that?
Adding a "static perspective" (as in the example above) doesn't seem to destroy anything, it's just an "extra", no?