Discussion:
[dart-misc] Dart 2.0 suggestion: Remove all the constructors from Dart
Kasper Peulen
2016-08-18 11:17:45 UTC
Permalink
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#.3nzua8bed

I 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:
https://groups.google.com/a/dartlang.org/forum/?fromgroups#!topic/misc/Lnj2sRQaITQ

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+***@dartlang.org.
'Lasse R.H. Nielsen' via Dart Misc
2016-08-18 12:56:49 UTC
Permalink
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).

Generative constructors have two purposes: Initializing new instance state
and initializing an inherited superclass state.

That means that the constructor is API that clients of the class uses.
If you decide to change the internal representation of a class, say storing
multiple bool fields in a single integer, or changing a field to a getter,
having a constructor that is directly linked to actual state means that you
change your API.
The constructors that we have now are abstractions that encapsulate the
actual state. You can change the object state without changing the API
exactly because the constructor isn't linked directly to the state.

That's not really a problem, we can just make the "physical constructor"
you propose be private and then you just expose factory functions returning
new instances as the API, using the real constructor internally.

That hits the other usage - calling the superclass generative constructor.
You can't use plain functions for that (at least not the way most OO
languages are wired up, but that's another story). So, you need to expose a
real generative constructor to the subclass, and you still need to keep
that API constant when you refactor the class. You need the generative
constructor *and* you need the abstraction layer, which is how we got to
where we are now.

Now, I'm personally not particularly happy about generative constructors
being unchangeable API. You can't change a generative constructor to a
factory constructor if someone is subclassing your class - and that was
really the reason for having factory constructors to begin with.
I don't think we'll change that though. The alternatives are a little too
weird for a mainstream language :)

/L
Post by Kasper Peulen
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.
emilniklas/constructors-considered-harmful-17cccfab8d3#.3nzua8bed
I 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;
}
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");
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,
https://groups.google.com/a/dartlang.org/forum/?fromgroups#!topic/misc/
Lnj2sRQaITQ
class State {
String value;
int length;
@required bool show;
}
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.
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
--
Lasse R.H. Nielsen - ***@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 KÞbenhavn K
- Denmark - CVR nr. 28 86 69 84
--
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+***@dartlang.org.
Emil Persson
2016-08-18 14:46:49 UTC
Permalink
As the author of that Medium-post I should explain.

The main idea is that every class has a list of fields (you could easily
think of methods like fields that happen to have function types). If you
want to make a new instance of a class, you have to provide all the fields
that are not already implemented. That is generally all we do in our
constructors.

class A {
final B b;
A(this.b);
}

When we extend a class, we not only have to initialize our own fields, but
our superclass':

class C extends A {
D d;
C(this.d, B b) : super(b);
}

Consider a world without constructors, where abstract fields dictate how we
initialize the class. I'm going to indicate them with an abstract keyword,
to make it more clear.

class A {
abstract B b;
}

class C extends A {
abstract D d;
}

To initialize A, we need to supply the implementation of the abstract field:

new A(b: ...);

To initialize C, we need to supply the implementations of both the abstract
fields of A and C:

new C(b: ..., d: ...);

If a subclass doesn't want to "forward" the abstract class, but instead
provide its own implementation, it can do that:

class C extends A {
@override B b = ...;
D d;
}
new C(d: ...);

With constructors, a subclass can use its constructor to modulate arguments
before sending them to the super constructor:

class C extends A {
D d;
C(this.d, String somethingElse) :
super(bFromSomethingElse(somethingElse));
}

This is what my post considered to be "harmful", since it's the source of
many issues with multiple inheritance, like the diamond problem.

Without constructors, the top of the diamond never receives two instances
of a dependency, because it has no constructor that can be called twice.
Instead, when initializing the bottom of the diamond, the user must pass
along the implementation of the field that the top-class has left abstract.

If one of the subclasses in the diamond provides that implementation
itself, you don't need to. If both subclasses implement the same field,
then it's a compile time error.

If a base class changes what fields are abstract, that is, in fact, a
breaking change to its "constructor". But that is just like adding another
generative constructor argument.

On Thursday, August 18, 2016 at 2:57:16 PM UTC+2, Lasse Reichstein Holst
Post by 'Lasse R.H. Nielsen' via Dart Misc
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).
Generative constructors have two purposes: Initializing new instance state
and initializing an inherited superclass state.
That means that the constructor is API that clients of the class uses.
If you decide to change the internal representation of a class, say
storing multiple bool fields in a single integer, or changing a field to a
getter, having a constructor that is directly linked to actual state means
that you change your API.
The constructors that we have now are abstractions that encapsulate the
actual state. You can change the object state without changing the API
exactly because the constructor isn't linked directly to the state.
That's not really a problem, we can just make the "physical constructor"
you propose be private and then you just expose factory functions returning
new instances as the API, using the real constructor internally.
That hits the other usage - calling the superclass generative constructor.
You can't use plain functions for that (at least not the way most OO
languages are wired up, but that's another story). So, you need to expose a
real generative constructor to the subclass, and you still need to keep
that API constant when you refactor the class. You need the generative
constructor *and* you need the abstraction layer, which is how we got to
where we are now.
Now, I'm personally not particularly happy about generative constructors
being unchangeable API. You can't change a generative constructor to a
factory constructor if someone is subclassing your class - and that was
really the reason for having factory constructors to begin with.
I don't think we'll change that though. The alternatives are a little too
weird for a mainstream language :)
/L
Post by Kasper Peulen
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.
I 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;
}
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");
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,
https://groups.google.com/a/dartlang.org/forum/?fromgroups#!topic/misc/Lnj2sRQaITQ
class State {
String value;
int length;
@required bool show;
}
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.
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
--
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 KÞbenhavn K
- Denmark - CVR nr. 28 86 69 84
--
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+***@dartlang.org.
Daniel Davidson
2016-08-18 15:21:08 UTC
Permalink
On Thursday, August 18, 2016 at 7:57:16 AM UTC-5, Lasse Reichstein Holst
Post by 'Lasse R.H. Nielsen' via Dart Misc
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
<https://www.dartlang.org/resources/dart-tips/dart-tips-ep-11>:


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.

Thanks
Dan
--
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+***@dartlang.org.
'Lasse R.H. Nielsen' via Dart Misc
2016-08-18 16:20:48 UTC
Permalink
Post by Daniel Davidson
On Thursday, August 18, 2016 at 7:57:16 AM UTC-5, Lasse Reichstein Holst
Post by 'Lasse R.H. Nielsen' via Dart Misc
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?
You don't need a factory *constructor* to create and cache instances. All
you need is a factory *function*.
The real reason for having factory constructors in Dart is that it allows
you to change from having a generative constructor (which always create a
new instance) to a factory constructor (which could be caching) without
changing the class API.

The problem is that it does change the class API wrt. extension because a
subclass must always call generative constructor of the superclass.
Changing from generative to factory is therefore a breaking change. The
other direction isn't, though, so you can always start out with only public
factory constructors.
Post by Daniel Davidson
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.
That is true. Again, you don't need a constructor for that, any static
function will do. You just don't get to (have to) write `new` in front of
it.

I'm not saying factory constructors are necessarily a bad idea. Personally,
I think it's the generative constructors that are the problem - if we
didn't have them, there would be no need for factory constructors either,
it'd all just be static functions.

Given that we do have constructors, factory constructors are useful in
order to get a kind of symmetry in the APIs, so similar functions are all
constructors or all functions, and not a mismatch were some are generative
constructors and some are static factory functions.

/L
--
Lasse R.H. Nielsen - ***@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 KÞbenhavn K
- Denmark - CVR nr. 28 86 69 84
--
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+***@dartlang.org.
tatumizer-v0.2
2016-08-18 18:29:59 UTC
Permalink
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 like
var myFooContructor=Foo.constructor; // for default constructor
var foo=myFooConstructor("bar", "baz");
var myFooConstructor1=Foo.someFactoryConstructor;
var foo1=myFooConstructor1("bar", "baz");
etc

IMO, 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)").
--
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+***@dartlang.org.
'Lasse R.H. Nielsen' via Dart Misc
2016-08-18 20:32:27 UTC
Permalink
Post by tatumizer-v0.2
As soon as "new" is gone, dart can support the view on constructor as
static function.
I tried to avoid that discussion, but yes.
If you don't have a syntactic difference between constructor calls and
non-constructor calls, then you don't need factory constructors. Factory
methods are completely equivalent (assuming generic methods).
Post by tatumizer-v0.2
All you need for that is to allow expressions like
var myFooContructor=Foo.constructor; // for default constructor
var foo=myFooConstructor("bar", "baz");
var myFooConstructor1=Foo.someFactoryConstructor;
var foo1=myFooConstructor1("bar", "baz");
etc
IMO, 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.

/L
--
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+***@dartlang.org.
tatumizer-v0.2
2016-08-18 20:48:37 UTC
Permalink
Post by 'Lasse R.H. Nielsen' via Dart Misc
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?
--
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+***@dartlang.org.
'Lasse R.H. Nielsen' via Dart Misc
2016-08-19 07:03:37 UTC
Permalink
Post by 'Lasse R.H. Nielsen' via Dart Misc
Post by 'Lasse R.H. Nielsen' via Dart Misc
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?
The only real problem I have is that whether something is a generative
constructor is a part of your API due to subclasses requiring it. Changing
it is a breaking change, independently of which syntax you use to call
constructors.
Post by 'Lasse R.H. Nielsen' via Dart Misc
super() calls can remain the same as they are now, what's wrong with that?
That super-calls in subclass constructors require a generative constructor
that is also publicly visible.
If we had protected generative constructors, then we could make the public
API independent of whether something is a generative constructor or not,
and change between them without breaking clients, as long as we keep the
protected constructor the same.

Right now your subclass API and your client API are mixed and that locks
you in to some choices that you have to make.

Adding a "static perspective" (as in the example above) doesn't seem to
Post by 'Lasse R.H. Nielsen' via Dart Misc
destroy anything, it's just an "extra", no?
The public client API of a class can easily be abstract, and that works
well.
There doesn't need to be any difference between static functions and
generative constructors from that perspective.

There do need to be a difference in the subclass API, and currently we
can't distinguish the two APIs because they are all public. That's my
problem.

/L
--
Lasse R.H. Nielsen - ***@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 KÞbenhavn K
- Denmark - CVR nr. 28 86 69 84
--
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+***@dartlang.org.
tatumizer-v0.2
2016-08-19 16:19:43 UTC
Permalink
Now I remember we discussed that, but I don't remember why simply prefixing
protected members with "protected" (e.g. protectedFoo, protectedBar,
Baz.protected for constructor etc) is not a good idea. Basically, this all
fits into the great discovery we made in a parallel thread (things are not
the same if you look from outside vs from inside). Those protected methods
can be kinda public, but analyzer will complain if used by somebody other
than subclass.

BTW, I don't think dart has much choice in that, b/c private members are
already distinguished by prefix _, so for protected we just need another
prefix, and it's better be BIG prefix (protected methods are rare).
--
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+***@dartlang.org.
Kasper Peulen
2016-08-18 14:39:40 UTC
Permalink
Not sure if I understand your point precisely. I'm taking an example, from
Emil's article.

This is how I would picture inheritance:

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);
}
}

So now you say, you loose the object state you would get by calling the
default static method? I guess that is a point.

You can maybe do this:

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);
}
}

where Super() is the default static method. I guess this can become very
painfull though, in super large classes.
Post by Kasper Peulen
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.
I 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 thing, 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;
}
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");
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,
https://groups.google.com/a/dartlang.org/forum/?fromgroups#!topic/misc/Lnj2sRQaITQ
class State {
@required String value;
@required int length;
bool show;
}
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.
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))
)
}
}
var point = Point(2, 3);
Now all the fields are always the things that you can set while creating a
new object. So it is just the input for the `new MyObject` function. If it
is not final, you can also change it later, or set the value later.
But what if you want a field, that you can not set in the initializer?
Well, you can make it private, and optionally create a getter for it.
I'm sure I have not thought about all the edge cases. Actually, I didn't
really think how this would work with inheritance.
But I do think that Dart's constructor syntax is just too messy, and too
much ways to do the same thing. Just putting in some ideas.
--
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+***@dartlang.org.
Loading...