Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make const / new optional #18241

Closed
DartBot opened this issue Apr 15, 2014 · 17 comments
Closed

Make const / new optional #18241

DartBot opened this issue Apr 15, 2014 · 17 comments
Assignees
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-not-planned Closed as we don't intend to take action on the reported issue type-enhancement A request for a change that isn't a bug

Comments

@DartBot
Copy link

DartBot commented Apr 15, 2014

This issue was originally filed by @seaneagan


issue #4046 is about making the "const" / "new" modifier optional within const expressions, defaulting it to "const".

This could be generalized to make "const" / "new" optional everywhere, for both consistency and to add the following capabilities:

In const constructor initializers, leaving off "const" would allow the constness to be determined by the constructor call site, which would mean you could call other const constructors for example.

It would allow for the existence of const functions, and const factory constructors. And finally, leaving off "const" / "new" from any other call sites, would default it to "new", which would make it no longer necessary to expose top-level functions (extra API surface, lack of generic type support) whose sole purpose is to allow the call site to omit "new " when creating an instance

Example:

class Foo {
  final int x;
  const Foo(this.x);
  const factory Foo.bar(x) => Bar(x, []);
}

class Bar extends Foo {
  final List list;
  const Bar(int x, this.list) : super(x);
}

const foo(x) => Foo(x);

Then the following equivalencies would hold:

a) const foo(x) -> const Foo(x)
b) foo(x) -> new Foo(x)
c) const Foo(x) -> const Bar(x, const [])
d) new Foo(x) -> new Bar(x, [])
e) Foo(x) -> foo(x)

Examples const functions would be the top-level functions in dart:math. And package:matchers could expose matchers as const constructors instead of top-level methods, which would allow them to be used in both annotations, and test code, without needing "new" / "const" in either case, and the matchers would then also be able to support generic type arguments. See:

https://groups.google.com/a/dartlang.org/forum/#!topic/misc/0_DXEjQSoiU

@kevmoo
Copy link
Member

kevmoo commented Apr 15, 2014

Removed Type-Defect label.
Added Type-Enhancement, Area-Language, Triaged labels.

@DartBot
Copy link
Author

DartBot commented May 5, 2014

This comment was originally written by @seaneagan


To expand on const methods, in addition to regular methods, they could also support:

// getters
const int get foo => new Foo(x);
static const Foo get foo => new Foo(x);

// final instance fields (implied instance getters)
const Foo foo;

// operators
const operator + (int other) => int value;

This would remove all the special cases from the language spec about what can be considered a constant, and instead that can be seen directly in the api docs of dart:core, and any other lib which wants to define const methods.

@DartBot
Copy link
Author

DartBot commented Jun 4, 2014

This comment was originally written by grant.js...@gmail.com


Would it not be great if, instead of using:
new Foo(x);
to create/instantiate a constant object
const Foo(x);
was used instead.
Swapping out out the "new" keyword with "const" keyword for instantiation will immediately communicate that we are creating a constant.

@DartBot
Copy link
Author

DartBot commented Jun 4, 2014

This comment was originally written by @zoechi


Thats how is is currently.

@gbracha
Copy link
Contributor

gbracha commented Aug 26, 2014

Const was very carefully limited in Darr,by design. We chose not to introduce const methods/getters etc. with notions of constness propagating. This is always subtle (well, a rat hole really). The cases where things are constant are explicitly defined in the spec and we want it that way.


Set owner to @gbracha.
Added WontFix label.

@DartBot
Copy link
Author

DartBot commented Aug 28, 2014

This comment was originally written by @seaneagan


Hi Gilad,

The limitedness of the const feature in dart currently limits the ability to use (and predict when one will be able to use) the dependent language features of metadata, default values, and canonicalization.

This issue proposes two simple, and backward compatible extensions that together pretty much completely solve this problem in my opinion:

  1. Make const (and new) optional at call sites, inferring constness from the top-level call-site. This at the very least adds the ability to reference other "potential constants" from the initialization list of the only current declaration allowed to be defined as constant, i.e. generative constructors, which is a pretty big pain point currently. An added bonus is terseness of constructor call-sites.

  2. Allow other things besides generative constructors, i.e. normal methods, getters, and factory constructors which merely return an expression (using =>) and instance fields to be explicitly declared const so that users can have the same luxury to define constants as the core libraries do (by virtue of being explicitly specified in the language spec). Note that it is then very easy to determine when constness should propogate here, i.e. when calling an explicitly declared const method, getter, or field. An added bonus is simplification of the spec, and documentation of constness directly at the declaration site (as opposed to the spec) which makes it easier to integrate into tooling such as API docs and refactoring.

Can you please address both of these extensions separately, and also why you consider them a rat hole, i.e. what cases do they leave unaddressed? Why is restricting the ability to define constants a goal?

Thanks!

@DartBot
Copy link
Author

DartBot commented Aug 28, 2014

This comment was originally written by @zoechi


To 1) I wonder if it's possible in this case to see (as a developer) when const is used. What when I know something should be const but something not obvious at callers site prevents it? When I can't explicitly declare it const I can't get a warning.

When something can be const but I don't want it to be const because I want to change it later, how can I prevent that? Just because something can be used in a const context doesn't mean I always want to.

@DartBot
Copy link
Author

DartBot commented Aug 28, 2014

This comment was originally written by @seaneagan


Yes, so when you declare something to be const (currently only constructors
support this) you are not declaring that it must always be invoked as a
constant, i.e. callers can use "new" as well. So thus the calls you make
from that constant declaration (currently only constructor initialization
list items) should not use "new" or "const" (and thus constructors
including [] and {} can't currently be used at all), since we don't know
whether the call-site of the current invocation of the thing we are
declaring is using "new" or "const", so if we leave it out, then it can
just be inferred. It would work the same way with 2) i.e. const methods,
getters, operators, factory constructors, and fields.

@gbracha
Copy link
Contributor

gbracha commented Aug 28, 2014

I think there already is a separate issue for (1).

As for extending the number of constructs that can be marked const (item 2). It is a slippery slope. The demands never end. Can I make an instance method constant, and if not, why not (we already had this debate for instance variables)? And now we need to execute arbitrary code at compile time. What if it contains loops? Just restrict them to expressions? Can they be recursive? Directly or indirectly? Can they use conditionals? For every limitation, someone comes up with a use case, an example that looks plausible in isolation.

There are answers to all these things, but complexity is a bad thing. Ultimately we make a judgement call as to how far we should go and which directions are worth investing in.

@Zectbumo
Copy link

Are you thinking of issue #5680 ? That's to remove new. I want it optional to keep the new crowd happy but program in peace for myself withoutnew.

@DartBot
Copy link
Author

DartBot commented Aug 28, 2014

This comment was originally written by @seaneagan


Great questions:

Can I make an instance method constant, and if not, why not (we already had this debate for instance variables)?

Yes, const instance method calls would only be considered const when the receiver and all arguments are const of course. It would be at least a warning if not error when the class does not have a const constructor:
    
    class Foo {

      const int x;

      const Foo(this.x);
      
      const m(int y) => x + y;
    }
    //...
    print(const Foo(1).x); // Same as 1
    print(const Foo(1).m(2)); // Same as 3

Notice that both the instance variable and method must be explicitly marked const.

And now we need to execute arbitrary code at compile time. What if it contains loops? Just restrict them to expressions?

Yes, just expressions. That would solve any use case I've ever had.

Can they be recursive?

I guess if you do allow recursion, then you'd need to detect infinite recursion during compilation by setting a max stack depth. I'm curious if anywhere else in dart already requires this.

@gbracha
Copy link
Contributor

gbracha commented Aug 28, 2014

I rest my case.

You should be able to see how far from trivial or straightforward the issues are, and how vast the gap is between showing an example and actually working out what the rules are and implementing it. This clearly qualifies as a rathole.

@Zectbumo
Copy link

const may be a rathole but can we at least make new optional?
Shall I open a new issue on this?

@lrhn
Copy link
Member

lrhn commented Aug 29, 2014

"optional new" was http://dartbug.com/18241 - it's closed as WontFix.

@Zectbumo
Copy link

That's this same issue. But it includes making const optional which appears to be a mess to change. I'm talking about only making new optional and leave const the way it is.

@DartBot
Copy link
Author

DartBot commented Aug 29, 2014

This comment was originally written by @richardeakin


re optional new:

I think Gilad is clearly not interested, as it has been debated to quite some extent, though I would urge the dart team to reconsider based on popular voice. I for one think that many expressions would be much clearer if the weren't plagued with new statements for simple objects, but I come from a C++ background where new is rarely used.

const, well I like const too but that is a different topic altogether! It should be discussed separately.

@Zectbumo
Copy link

I created a new discussion for new at issue #20750

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-not-planned Closed as we don't intend to take action on the reported issue type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

5 participants