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

Remove the 'new' keyword for invoking constructors #5680

Closed
justinfagnani opened this issue Oct 5, 2012 · 17 comments
Closed

Remove the 'new' keyword for invoking constructors #5680

justinfagnani opened this issue Oct 5, 2012 · 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

@justinfagnani
Copy link
Contributor

I keep wishing that Dart didn't have new keyword when I'm writing code. Especially when using simple value classes like Uri or Point, 'new' is noise that I just don't want to type or look at, and it may even discourage people from using nicely typed values over strings, lists and maps because those literal values are so much shorter.

Consider calling a function that takes points, with and without 'new':

  1. drawRect(new Point(0, 0), new Point(100, 200));

  2. drawRect([0, 0], [100, 200]);

  3. drawRect(Point(0, 0), Point(100, 200));

(1) is just terribly noisy to me, especially with syntax highlighting. (2) is the cleanest looking, and common in JavaScript, but we should discourage that because having a mixture of Points and lists floating around various APIs would be a messy pain. (3) isn't that bad really, much better than with 'new', in my opinion.

@munificent
Copy link
Member

Another data point to consider: Lasse recently moved parseInt and parseDouble into the int and double classes, respectively. So it's int.parse() and double.parse(). He made them static methods. If we actually like the new keyword, shouldn't those be named constructors?

@lrhn
Copy link
Member

lrhn commented Oct 6, 2012

I thought hard about int/double.parse, but in the end, a constructor just didn't feel right. Even if we have constructors in other places, we don't have them on int or double, and you don't think of the parse function as creating a new number, but more like finding an already existing number object.

Dart is designed to be "familiar", which is one reason for having constructors and the "new" keyword. The only real difference between factory constructors and static methods is that the former can take type parameters and has a fixed return type.
The language needs to evolve to the point where normal functions can be generic too before we can really remove the "new" keyword (and even then, we might not want to for stylistic reasons).


Removed Type-Defect label.
Added Type-Enhancement label.

@DartBot
Copy link

DartBot commented Nov 4, 2012

This comment was originally written by sigma...@gmail.com


-1 for this proposal, as I did express on the mailing list, too. The expression new Person()' provides a ready \_visual_ clue that a constructor is being invoked. Removingnew' as a keyword (without introducing some disambiguation) makes the reader pause needlessly. Remember that not every Dart user comes from Python background.

Alternatively, we could make `.new()' the default generative constructor. That will at least solve Justin's syntax highlighting problem. It is a big change though!

@DartBot
Copy link

DartBot commented Nov 4, 2012

This comment was originally written by chiahau...@gmail.com


I think, avoiding using new to call the constructor will enable people to change between a constructor call and a normal function without changing code. Thus reducing problems with dependencies. But there would still be a problem with named constructors.

@DartBot
Copy link

DartBot commented Nov 4, 2012

This comment was originally written by sig...@gmail.com


chiahau200 : I find this argument ... interesting. How often have you required such a change? How much is the corresponding gain?

In the current scenario, one can simply grep the source tree for ` new ' to identify all allocation locations, across all classes. The proposed modification eliminates that simple felicity.

@DartBot
Copy link

DartBot commented Nov 4, 2012

This comment was originally written by chiaha...@gmail.com


to be honest not much. Because we have factories.

I believe the gain here is that, we can eliminate or at least lessen the need for factory constructors. Thus making the language simpler. or at least give people an option to choose between using a function or a factory constructor.

Its true that you can use "new" to identify where "new" is used and thats about it. It doesn't represent allocation locations as calling new doesn't always create a new instance of a class. You could just be pulling something from cache.

@gbracha
Copy link
Contributor

gbracha commented Nov 7, 2012

I have a lot of sympathy for this. Personally, I don't see any point to new. However, familiarity counts for a lot in Dart, so I do not expect this to change. Also, there are issues around type arguments and parsing.


Set owner to @gbracha.
Added Accepted label.

@justinfagnani
Copy link
Contributor Author

Thanks for taking a look Gilad.

I understand the familiarity argument, but personally it isn't so strong to me without some data to back it up. For usability and adoption, which parts of the language need to be familiar? How familiar? How can we tell? Do Python users count?

I do see that trying to explain when type parameters can appear on what looks like a function call could be confusing, however I would argue that that's another good reason for generic functions.

@DartBot
Copy link

DartBot commented Nov 13, 2012

This comment was originally written by raku...@gmail.com


I would like to see 'new' go away, or at least be optional.
The reason is const.
I would like const to be infections to subexpressions.
It is tedious to have to write 'const' on subexpressions.

Annotations are top-level implicitly const but you have to put 'const' on all the subexpressions.
This is unpleasantly inconsistent.

class S {
  final e;
  const S(this.e);
}

@s(const S(const [1])) int foo; // can't say const at the top level and must say const deeper.

If const was infectious, I could write:

@s(S([1])) int foo;

This makes for a much cleaner embedded compile-time annotation language.

Now if I can omit 'const', I should be able to omit 'new' too.

@DartBot
Copy link

DartBot commented Jan 2, 2013

This comment was originally written by lasc...@gmail.com


I think google is one of the few companies that has the ability to create innovative things that are accepted by the mere fact of coming from google. I agree that Dart has to be a familiar language but not go so far as to copy Java / Javascript. I do not think removing "new" do less familiar language. I vote for removal.

Sorry for my English

@DartBot
Copy link

DartBot commented May 9, 2013

This comment was originally written by @davidB


+1 for remove usage of 'new' in caller side.
+1 for "Don't repeat classname in factory, constructor" and to use reserved name (factory, init, _, new,...)

vs it's "familiar" (for java audience) :

* I'm using Java since 1996. But I learn Python for a project no 'new' keyword and no duplicate of the name in the constructor was something I quickly appreciate. Idem about 'case class' in scala : it was a selling point for me (quick, readable and DRY way to create structure like).

  • Why so many language try to be sugar over java, if syntax of java is so nice ? Why 'modern' syntax try to follow this way ?
  • existing form of constructor isn't familiar to target (may be C++) :
      * use of 'this' in argument
      * use of init block (I don't know the name) 'X(arg1): <init> {...}'
      * use of 'factory'

vs it's an indicator of 'allocation':

* wrong, case of factory that can provide a singleton or use cache, pool,...

  • what about function that do 'allocation' transitively, should we used 'new' (I used new in my factory function that are out of the class) ?

vs tools take care of rename :

* only heavy ide

  • why having more work for
      * human reader (need to translate variable name of the class as it's a constructor)
      * tools, parser should know the name of class like human reader
      * tools, renamer should take care of rename

complementary discussion at
https://groups.google.com/a/dartlang.org/forum/?fromgroups=#!topic/misc/KtQlRHEaPTY

To copy the proposal from discussion (I'm not fan of all point, but seems a better way)

class Point0 {
  int x;
  int y;
  new(int x = 0, int y = 0) { this.x = x; this.y = 0; }
  new.fromString(String s) { ... }
}

class Point1 {
  int x;
  int y;
  _new({this.x = 0, this.y = 0});
  factory(int x, int y)=>_Point1(x,y)
  factory.fromString(String){... }
}

Sorry for my long comment in French-glish

@DartBot
Copy link

DartBot commented May 9, 2013

This comment was originally written by @davidB


I forgot a point (sorry)

I'm working on a dart game, where context (level, entities) is defined via "declaration", removing 'new' will be more 'homogeneous' :

extract :

  Entity newChronometer(int millis, timeout) => _newEntity([
    new Chronometer(millis),
    new Animatable()
      ..add(new Animation()
        ..onTick = (e, t, t0) {
          e.getComponent(chronometerCT).millis = millis + (t - t0).toInt();
          return (millis >= 0) || (e.getComponent(chronometerCT).millis <= 0);
        }
        ..onEnd = timeout
      )
  ]);

  Entity newCamera(music) => _newEntity([
    new PlayerFollower(new vec3(0, -25, 30)),
    new Transform.w3d(new vec3(0, -25, 30)).lookAt(new vec3(0,0,0)),
    Factory_Renderables.newCamera(),
    new AudioDef()..add(music)..isAudioListener = true
  ], group : GROUP_CAMERA);

  Entity newLight(vec3 pos, vec3 lookAt) => _newEntity([
    new Transform.w3d(pos).lookAt(lookAt),
    Factory_Renderables.newLight()
  ]);

  Entity newAmbientLight(color) => _newEntity([
    new Transform.w3d(new vec3(0.0, 0.0, 10.0)),
    Factory_Renderables.newAmbientLight(color)
  ]);

@DartBot
Copy link

DartBot commented May 9, 2013

This comment was originally written by gp789...@gmail.com


I see no benefit in using "new" for constructor calls either.

There is no reason to replace static methods, .i.e. int.parse(), by constructors.

One can easily discover and detect constructor calls (= class name) without new.

Programming in Dart is already so much different from programming Javascript and Java.
Any claimed intention to keep familiarity and superficial resemblance and is not only meaningless but misleading and disappointing by making the programmer believe Dart is like Java with a library for the web or like Javascript with type annotations.
And by now, I would not compete with Typescript by playing the familiarity card.

@DartBot
Copy link

DartBot commented May 9, 2013

This comment was originally written by kevinc184...@gmail.com


The 'familiar' argument is sound. No smalltalk/haskell syntactic innovations.
But some familiar things breed contempt - 'new' is one of them. Another is named constructors.

It's a stone in the shoe. Who wants to a new pair of shoes with a 'new' stone glued beneath the sole.
Unless there's a technical VM level reason why 'new' is required?

Also, I think there's a language where:
var p = Point(0,0);
is sugar for:
var p = Point.new(0,0);
Either can be used - which isn't bad.

The sweet spot for syntax is succinct - but non-magical - and reflects the core Dart semantics cleanly. Which will appeal to pioneers/early adopters. And enough familiarity for jobbing programmers to pick it up easily.

@gbracha
Copy link
Contributor

gbracha commented Oct 14, 2013

Added WontFix label.

@Zectbumo
Copy link

One thing I really like about Dart is that it does a fantastic job in pleasing both worlds in other cases such as int vs var and optionally specifying a return type for functions. I would like to see the same choice made in this case.

If new is truly "noise" then make new optional.

You like using new? Great, use it. Don't? Great, don't use it. Dart works fine either way.

@DartBot
Copy link

DartBot commented Aug 23, 2014

This comment was originally written by @seaneagan


You will want to star issue #18241 (Make const/new optional)

@justinfagnani justinfagnani added Type-Enhancement area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Aug 23, 2014
@kevmoo kevmoo added 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 and removed resolution-wont_fix labels Mar 1, 2016
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

7 participants