147

The new keyword in languages like Java, Javascript, and C# creates a new instance of a class.

This syntax seems to have been inherited from C++, where new is used specifically to allocate a new instance of a class on the heap, and return a pointer to the new instance. In C++, this is not the only way to construct an object. You can also construct an object on the stack, without using new - and in fact, this way of constructing objects is much more common in C++.

So, coming from a C++ background, the new keyword in languages like Java, Javascript, and C# seemed natural and obvious to me. Then I started to learn Python, which doesn't have the new keyword. In Python, an instance is constructed simply by calling the constructor, like:

f = Foo()

At first, this seemed a bit off to me, until it occurred to me that there's no reason for Python to have new, because everything is an object so there's no need to disambiguate between various constructor syntaxes.

But then I thought - what's really the point of new in Java? Why should we say Object o = new Object();? Why not just Object o = Object();? In C++ there's definitely a need for new, since we need to distinguish between allocating on the heap and allocating on the stack, but in Java all objects are constructed on the heap, so why even have the new keyword? The same question could be asked for Javascript. In C#, which I'm much less familiar with, I think new may have some purpose in terms of distinguishing between object types and value types, but I'm not sure.

Regardless, it seems to me that many languages which came after C++ simply "inherited" the new keyword - without really needing it. It's almost like a vestigial keyword. We don't seem to need it for any reason, and yet it's there.

Question: Am I correct about this? Or is there some compelling reason that new needs to be in C++-inspired memory-managed languages like Java, Javascript and C# but not Python?

Tom Au
  • 893
  • 7
  • 17
Channel72
  • 2,475
  • 5
  • 27
  • 28
  • 13
    The question is rather why any language has the `new` keyword. Of course I want to create a new variable, stupid compiler! A _good_ language would in my opinion have a syntax like `f = heap Foo()`, `f = auto Foo()`. –  Oct 31 '11 at 15:25
  • 8
    A very important point to consider is how familiar a language looks to new programmers. Java was explicitly designed to look familiar to C/C++ programmers. –  Oct 31 '11 at 18:59
  • 4
    @Lundin: It's really a result of compiler technology. A modern compiler wouldn't even need hints; it would figure out where to put the object based on your actual use of that variable. I.e. when `f` doesn't escape the function, allocate stack space. – MSalters Nov 01 '11 at 09:52
  • @MSalters: A compiler can't know whether a variable should have static storage duration or dynamic storage duration, however. I guess my wish-list language should have a `f = static Foo()` as well. And `f = const Foo()`. And of course treat `f = Foo()` as auto by default. –  Nov 01 '11 at 13:53
  • 3
    @Lundin: It can, and in fact modern JVM's do. It's merely a matter of proving that the GC can collect object `f` when the enclosing function returns. – MSalters Nov 01 '11 at 15:13
  • Class is on the heap and struct is on the stack in C#, but both use new; although it is optional for a struct, it does save the trouble of having to initialize all fields before being used. – JeffO Oct 30 '12 at 12:39
  • 1
    It's not constructive to ask why a language is designed the way it is, particularly if that design asks us to type four extra characters for no obvious benefit? What am I missing? – Tyler Jan 30 '13 at 03:40
  • @JeffO that's not always true http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx – Andy Jan 03 '15 at 14:59
  • Its interesting to note that a number of newer languages have dropped the `new` keyword, Swift and Go for example – mcfedr Nov 07 '16 at 12:26
  • @MatrixFrog Usually, the answer to *why things were designed the way they were* is: "history". That is pretty much the whole answer, and delving deeper is usually a waste of time. You might very well get a lovely answer, and it might be satisfying to you, but it will not change either the past or the future, and probably won't help anyone else either. If you intensely dislike how something was designed, you could come up with a different design. And if someone asked you *why it was designed that way*, you could enlighten them. Still would not help anyone though. "Why" is basically useless. –  May 26 '17 at 13:43
  • Re, "...At first, this seemed a bit off to me" Maybe it seemed "a bit off" to Java's designers as well. And once they made their decision... (see no comprende's comment, immediately above.) – Solomon Slow Nov 28 '17 at 15:52
  • Of course it is not constructive. However, you might be lucky and get an answer to a question like this, from someone who actually have heard the motivation. It is always interesting to know what kind of mushroom a bunch of really intelligent people have been eating to come up with something like this. Something quite verbose and practically useless. Well sometimes it is interesting to get the history of thing as well, when you are too tired to learn something new :). – patrik Jun 20 '18 at 22:22

15 Answers15

100

Your observations are correct. C++ is a complicated beast, and the new keyword was used to distinguish between something that needed delete later and something that would be automatically reclaimed. In Java and C#, they dropped the delete keyword because the garbage collector would take care of it for you.

The problem then is why did they keep the new keyword? Without talking to the people who wrote the language it's kind of difficult to answer. My best guesses are listed below:

  • It was semantically correct. If you were familiar with C++, you knew that the new keyword creates an object on the heap. So, why change expected behavior?
  • It calls attention to the fact that you are instantiating an object rather than calling a method. With Microsoft code style recommendations, method names start with capital letters so there can be confusion.

Ruby is somewhere in between Python and Java/C# in it's use of new. Basically you instantiate an object like this:

f = Foo.new()

It's not a keyword, it's a static method for the class. What that means is that if you want a singleton, you can override the default implementation of new() to return the same instance every time. It's not necessarily recommended, but it's possible.

Berin Loritsch
  • 45,784
  • 7
  • 87
  • 160
  • 6
    The Ruby syntax looks nice and consistent! The _new_ keyword in C# is also used as a [generic type constraint](http://msdn.microsoft.com/en-us/library/sd2w2ew5%28v=vs.80%29.aspx) for a type with a default constructor. – Steven Jeuris Feb 14 '11 at 16:28
  • 3
    Yes. We won't talk about generics though. Both Java and C#'s version of generics are very obtuse. Not saying C++ is much easier to understand though. Generics really are only useful for statically typed languages. Dynamically typed languages like Python, Ruby, and Smalltalk just don't need them. – Berin Loritsch Feb 14 '11 at 17:30
  • 2
    Delphi has a similar syntax to Ruby, except that constructors are usually (but only bhy convention) called Create (`f := TFoo.Create(param1, param2...)' – Gerry Feb 14 '11 at 20:16
  • In Objective-C, the `alloc` method (roughly the same thing as Ruby's `new`) is also just a class method. – mipadi Feb 15 '11 at 18:02
  • 5
    From language design perspective, keywords are bad for many reasons, mainly you cannot change them. On the other hand reusing the concept of method is easier, but needs some attention while parsing and analysing. Smalltalk and its kin use messages, C++ and itskin on the other hand keywords – Gabriel Ščerbák Feb 16 '11 at 11:10
  • +1 for "expected behaviour." - with negative value to the language. – ocodo Oct 28 '11 at 00:02
  • @mipadi: Actually, the `alloc` method in Objective-C is equivalent to the `allocate` method in Ruby, not `new`. `new` in Ruby is just a convenience method that first calls `allocate` to create a new object, then calls `initialize` on that object, *exactly* the same way you call `alloc` and `init` in Objective-C. – Jörg W Mittag Feb 27 '13 at 01:26
  • Python actually does the same thing, but pushed under the hood. It's unobtrusive but can provide some gotchas in certain cases. Instead of just `Foo.new(args)` you'd use `Foo.__new__(args)`. – a p Jun 25 '14 at 21:36
  • eeeeew. The Ruby `new()` looks like a factory. `new Object()` bilds the semantics that you are creating a **new `Object`**. The `new` keyword may even be thought of as an abstraction for memory allocation cases. – Simon Kuang Aug 13 '14 at 01:40
  • So there are no constructors in Ruby ? – Jarvis Jan 30 '16 at 03:03
  • It's called an initializer, but it does exist. – Berin Loritsch Jan 30 '16 at 17:16
89

In short, you are right. Keyword new is superfluous in languages like Java and C#. Here are some insights from Bruce Eckel who was a member of C++ Standard Comitee in 1990s and later published books on Java: http://www.artima.com/weblogs/viewpost.jsp?thread=260578

there needed to be some way to distinguish heap objects from stack objects. To solve this problem, the new keyword was appropriated from Smalltalk. To create a stack object, you simply declare it, as in Cat x; or, with arguments, Cat x("mittens");. To create a heap object, you use new, as in new Cat; or new Cat("mittens");. Given the constraints, this is an elegant and consistent solution.

Enter Java, after deciding that everything C++ is badly done and overly complex. The irony here is that Java could and did make the decision to throw away stack allocation (pointedly ignoring the debacle of primitives, which I've addressed elsewhere). And since all objects are allocated on the heap, there's no need to distinguish between stack and heap allocation. They could easily have said Cat x = Cat() or Cat x = Cat("mittens"). Or even better, incorporated type inference to eliminate the repetition (but that -- and other features like closures -- would have taken "too long" so we are stuck with the mediocre version of Java instead; type inference has been discussed but I will lay odds it won't happen. And shouldn't, given the problems in adding new features to Java).

Nemanja Trifunovic
  • 6,815
  • 1
  • 26
  • 34
  • 2
    Stack vs Heap... insightful, never would have thought of it. – WernerCD Feb 15 '11 at 00:25
  • 1
    "type inference has been discussed but I will lay odds it won't happen.", :) Well, the development of Java still goes forward. Interesting that this is the only flagship for Java 10 though. The `var` keyword is nowhere close as good as `auto` in C++, but I hope it will improve. – patrik Jun 20 '18 at 22:26
15

There's two reasons I can think of:

  • new distinguishes between an object and a primitive
  • The new syntax is a bit more readable (IMO)

The first is trivial. I don't think it's any harder to tell the two apart either way. The second is an example of the OP's point, which is that new is sort of redundant.

There could be namespace conflicts, though; consider:

public class Foo {
   Foo() {
      // Constructor
   }
}

public class Bar {
   public static void main(String[] args) {
      Foo f = Foo();
   }

   public Foo Foo() {
      return Foo();
   }
}

You could, without too much stretching of the imagination, easily end up with an infinitely recursive call. The compiler would have to enforce a "Function name same as object" error. This really wouldn't hurt, but it is far simpler to use new, which states, Go to the object of the same name as this method and use the method that matches this signature. Java is a very simple language to parse, and I suspect this assists in that area.

Michael K
  • 15,539
  • 9
  • 61
  • 93
  • 1
    How is this any different to any other infinite recursion? – DeadMG Oct 28 '11 at 12:37
  • That's a fairly good illustration of a bad thing that could happen, although the developer that does that would have some serious mental issues. – Tjaart Oct 30 '12 at 12:32
11

In JavaScript you need it because the constructor looks like a normal function, so how should JS know that you want to create a new object if it wasn't for the new keyword?

Invoking a JavaScript function with the new operator results in different behavior than invoking a function without the new operator.

For example:

Date()       //Returns a string

new Date()   //Returns a Date object
function foo() {};

foo()        //Returns `undefined`

new foo()    //Returns an empty object
georgeawg
  • 101
  • 3
user281377
  • 28,352
  • 5
  • 75
  • 130
10

Java, for one, still has the dichotomy of C++: not quite everything is an object. Java has built-in types (e.g., char and int) that don't have to be allocated dynamically.

That doesn't mean that new is really necessary in Java though -- the set of types that don't need to be allocated dynamically is fixed and known. When you define an object, the compiler could know (and, in fact, does know) whether it's a simple value that char or an object that has to be allocated dynamically.

I'll refrain (yet again) from opining on what this means about the quality of Java's design (or lack thereof, as the case may be).

Jerry Coffin
  • 44,385
  • 5
  • 89
  • 162
  • More to the point, the primitive types don't need any constructor call at all – they either are written as a literal, come from an operator, or from some primitive-returning function. You actually also create strings (which are on the heap) without a `new`, so this isn't really the reason. – Paŭlo Ebermann Sep 23 '19 at 22:26
4

Interestingly, VB does need it - the distinction between

Dim f As Foo

which declares a variable without assigning it, the equivalent of Foo f; in C#, and

Dim f As New Foo()

which declares the variable and assigns a new instance of the class, the equivalent of var f = new Foo(); in C#, is a substantive distinction. In pre-.NET VB, you could even use Dim f As Foo or Dim f As New Foo - because there was no overloading on constructors.

Richard Gadsden
  • 737
  • 5
  • 12
  • 4
    VB doesn't *need* the shorthand version, it's just an abbreviation. You can also write the longer version with type and constructor Dim f As Foo = New Foo() . With Option Infer On, which is the nearest thing to C#'s var, you can write Dim f = New Foo() and the compiler infers the type of f. – MarkJ Oct 29 '12 at 07:56
  • 2
    ...and `Dim f As Foo()` declares an *array* of `Foo`s. Oh joy! :-) – Heinzi Oct 30 '12 at 12:56
  • @MarkJ: In vb.net, the shorthand is equivalent. In vb6, it wasn't. In vb6, `Dim Foo As New Bar` would effectively make `Foo` a property that would construct a `Bar` if it was read while (i.e. `Nothing`). This behavior wasn't limited to happening once; setting `Foo` to `Nothing` and then reading it would create another new `Bar`. – supercat Mar 13 '14 at 04:03
4

I like a lot of answers and would just like to add this:
It makes the reading of code easier
Not that this situation would happen often, but consider you wanted a method in the name of a verb that shared the same name as a noun. C# and other language naturally have the word object reserved. But if it were not then would Foo = object() be the result of the object method call or would it be instantiating a new object. Hopefully said language without the new keyword has protections against this situation, but by have the requirement of the new keyword before the calling of a constructor you allow the existence of a method with the same name as an object.

Kavet Kerek
  • 1,141
  • 8
  • 13
3

In C# it allows types visible in contexts where they might otherwise be obscured by a member. The allows you to have a property with same name as a its type. Consider the following,

class Address { 
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

class Person {
    public string Name { get; set; }
    public Address Address { get; set; }

    public void ChangeStreet(string newStreet) {
        Address = new Address { 
            Street = newStreet, 
            City = Address.City,
            State = Address.State,
            Zip = Address.Zip
        };
    }
}

Note the use of new allows it to be clear that Address is the Address type not the Address member. This allows a member to have the same name as its type. Without this you would need to prefix the name of the type to avoid the name collision, such as CAddress. This was very intentional as Anders never liked hungarian notation or anything similar and wanted to C# to be usable without it. The fact it was also familiar was a double bonus.

chuckj
  • 546
  • 5
  • 6
  • w00t, and Address could then derive from an interface called Address.. only, no it can't. So its not much of a benefit, being able to reuse the same name and decrease from the general readability of your code. So by keeping the I for interfaces, but removing the C from classes, they just created a nasty smell for no practical benefit. – gbjbaanb Oct 31 '12 at 12:12
  • I wonder that they don't use "New" instead of "new". Somebody could tell them there are also lowercase letters, which sort of solve this problem. – maaartinus Oct 17 '13 at 01:36
  • All reserved words in C derived languages, such as C#, are lower case. The grammar requires a reserved word here to avoid ambiguity thus the use of "new" instead of "New". – chuckj Oct 17 '13 at 22:16
  • @gbjbaanb There is no smell. It is always utterly clear whether you're referring to a type or a property/member or a function. The real smell is when you name a namespace the same as a class. MyClass.MyClass – Stephen May 20 '15 at 23:50
3

There's a lot of vestigial stuff in many programming languages. Sometimes it's there by design (C++ was designed to be as compatible as possible with C), sometimes, it's just there. For a more egregious example, consider how far the broken C switch statement propagated.

I don't know Javascript and C# well enough to say, but I see no reason for new in Java except that C++ had it.

David Thornley
  • 20,238
  • 2
  • 55
  • 82
  • I think JavaScript was designed to "look just like Java" as much possible, even when it's doing something particularly un-Java-like. `x = new Y()` in JavaScript doesn't *instantiate* the `Y` class, because JavaScript doesn't *have* classes. But it *looks* like Java so it carries the `new` keyword forward from Java, which of course carried it forward from C++. – Tyler Oct 31 '11 at 16:05
  • +1 for the broken switch (in the hope you repair it :D). – maaartinus Oct 17 '13 at 01:38
0

Interestingly, with the advent of perfect forwarding, non-placement new isn't required at all in C++ either. So, arguably, it's no longer needed in any of the mentioned languages.

DeadMG
  • 36,794
  • 8
  • 70
  • 139
  • 4
    What do you forward _to_? Ultimately, `std::shared_ptr foo();` will have to call `new int` somehow. – MSalters Nov 01 '11 at 09:56
0

I'm not sure whether Java designers had this in mind but when you think of objects as recursive records, then you could imagine that Foo(123) doesn't returns an object but a function whose fixpoint is the object being created (ie. function that would return the object if it's given as argument the object being constructed). And the purpose of new is to "tie the knot" and return that fixpoint. In other words new would make the "object-to-be" aware of its self.

This kind of approach could help formalizing inheritance for example: you could extend an object-function with another object-function and finally provide them with common self by using new:

cp = new (Colored("Blue") & Line(0, 0, 100, 100))

Here & combines two object-functions.

In this case new could be defined as:

def new(objectFunction) {
    actualObject = objectFunction(actualObject)
    return actualObject
}
Aivar
  • 301
  • 2
  • 4
  • 12
-2

To allow 'nil'.

Along with heap based allocation, Java embraced the use of nil objects. Not just as an artifact, but as a feature. When objects can have a nil state, then you have to separate declaration from initialisation. Hence the new keyword.

In C++ a line like

Person me;

Would instantly call the default constructor.

Kris Van Bael
  • 1,358
  • 6
  • 10
  • 4
    Um, what's wrong with `Person me = Nil` or having `Person me` be Nil by default and using `Person me = Person()` for non-Nil? My point is that it doesn't seem that Nil was a factor in this decision... – Andres F. Oct 30 '12 at 13:15
  • You have a point. Person me = Person(); would work equally well. – Kris Van Bael Oct 30 '12 at 23:51
  • @AndresF. Or even simpler with `Person me` being nil and `Person me()` invoking the default constructor. So you'd *always* need parentheses in order to invoke anything, and thus get rid of one C++ irregularity. – maaartinus Aug 03 '14 at 19:49
-2

The reason why Python does not need it is because of its type system. Fundamentally, when you see foo = bar() in Python, it doesn't matter what whether bar() is a method that is being invoked, a class that is being instantiated, or a functor object; in Python, there is no fundamental difference between a functor and function (because methods are objects); and you could even argue that a class being instantiated is a special case of a functor. Thus, there is no reason to create an artifical difference in what is happening (especially since memory management is so extremely hidden in Python).

In a language with a different typing system, or in which methods and classes are not objects, there is the possibility of a stronger conceptual difference between creating an object and calling a function or functor. Thus, even if the compiler/interpreter does not need the new keyword, it is understandable that it might be maintained in languages that haven't broken all the boundaries that Python has.

Kazark
  • 1,810
  • 1
  • 17
  • 37
-4

Actually in Java there is a difference when using Strings:

String myString = "myString";

is different from

String myString = new String("myString");

Supposing the string "myString" has never been used before, the first statement creates a single String object in the String pool (a special area of the heap) while the second statement creates two objects, one in the normal heap area for objects and other in String pool. It is pretty obvious that the second statement is useless in this particular scenario, but is allowable by the language.

This means that new assures that the object is created in that special area of the heap, allocated for normal object instantiation, but there may be other ways of instantiating objects without it; the above one is an example, and there is room left for extensibility.

Random42
  • 10,370
  • 10
  • 48
  • 65
  • 3
    But this wasn't the question. The question was "why not `String myString = String("myString");`?" (note the absence of the `new` keyword) – Andres F. Jan 29 '13 at 21:42
  • @AndresF. Kind of obvious imho... it is legal to have a method named String that returns a String in a String class and there has to be a difference between calling it and calling the constructor. Something like `class MyClass { public MyClass() {} public MyClass MyClass() {return null;} public void doSomething { MyClass myClass = MyClass();}} //which is it, constructor or method?` – Random42 Jan 29 '13 at 22:03
  • 3
    But it's not obvious. First, having a regular method named `String` goes against Java style conventions, so you can just assume any method starting with uppercase is a constructor. And second, if we aren't constrained by Java, then Scala has "case classes" where the constructor looks exactly like I said. So where is the problem? – Andres F. Jan 29 '13 at 23:11
  • Oh, right. C# has different conventions. To be fair, your example was Java. And anyway, my Scala example shows it's not important even then. – Andres F. Jan 29 '13 at 23:19
  • @AndresF. The code conventions have absolutely nothing to do with the syntax and semantics of the language; the current syntax does allow something like that (as does C, from which it was inherited) so calling `String s = String("s");` is ambiguous in Java if it weren't `new`; the syntax has to be very clear, it shouldn't make room for assumptions. Scala has different syntax that does not respect so much the C syntax; it has `val, def, var` which are unknown even for a Java programmer. – Random42 Jan 30 '13 at 15:56
  • 2
    Sorry, I don't follow your argument. You are effectively arguing _syntax_, not semantics, and anyway the question was about `new` for _managed languages_. I have shown that `new` is not at all needed (e.g. Scala doesn't need it for case classes) and also that there is no ambiguity (since you absolutely cannot have a method named `MyClass` in class `MyClass` anyway). There is _no ambiguity_ for `String s = String("hello")`; it cannot be anything else but a constructor. And finally, I disagree: code conventions are there to enhance and clarify the syntax, which is what you're arguing about! – Andres F. Jan 30 '13 at 16:17
  • @AndresF. I have told you why you cannot have `String s = String("s");` in Java for instantiating an object. You cannot remove `new` without altering the syntax&semantics; if you alter the syntax&semantics and do not allow methods named as the class, then you would not have backwards compatibility. What did you not understand here? – Random42 Jan 30 '13 at 17:10
  • 1
    So that's your argument? "Java designers needed the `new` keyword because otherwise Java's syntax would have been different"? I'm sure you can see the weakness of that argument ;) And yes, you keep discussing syntax, not semantics. Also, **backwards compatibility** with what? If you are designing a new language, such as Java, you are already incompatible with C and C++! – Andres F. Jan 30 '13 at 17:51
  • @AndresF. I was considering the idea of renouncing `new` now, not how Java would have been if... Java was designed to be as much as possible alike with C and C++; it was addressed to C++ programmers and it would have been harder from them to move to Java if things were different in ways like creating objects on heap in other way (not with new) or not allowing to have a method with the name of the class. Anyway, most objects are instantiated via factories so new is not so much of a burden. – Random42 Jan 30 '13 at 19:14
-8

In C# new is important to distinguish between objects created on the stack vs. the heap. Frequently we create objects on the stack for better performance. See, when a object on the stack goes out of scope, it disappears immediately when the stack unravels, just like a primitive. There is no need for the garbage collector to keep track of it, and there is no extra overhead of the memory manager to allocate the necessary space on the heap.

pds
  • 1