# Poll: \`Foo::new()\` vs \`Foo()\` as the default constructor

**URL:** <https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758>\
**Category:** libs\
**Created:** [November 6, 2014, 4:44pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758 "2014-11-06T16:44:09Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [November 7, 2014, 1:01am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/21 "2014-11-07T01:01:34Z")

</div>

Argh. I always forget that Discourse requires top-posting. All I was saying is that the original proposal involved no syntactic sugar.

---

<div class="post-metadata">

**Author:** ![pythonesque](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pythonesque/32/336_2.png) [@pythonesque](https://internals.rust-lang.org/u/pythonesque)\
**Post date:** [November 7, 2014, 2:36am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/22 "2014-11-07T02:36:19Z")

</div>

How are namespace conflicts handled, then? You often do want to use static methods on types other than the original constructor; would you have to use an alias and keep the function in its own module? Is that really simpler or easier, or am I missing a way in current Rust that this would be clean to resolve?

---

<div class="post-metadata">

**Author:** ![kennytm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kennytm/32/161_2.png) [@kennytm](https://internals.rust-lang.org/u/kennytm)\
**Post date:** [November 7, 2014, 7:17am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/23 "2014-11-07T07:17:16Z")

</div>

Under this proposal, how will this code work?

```rust
struct Foo(pub uint);

impl Foo {
    fn new(n: uint) -> Foo {
        Foo(1 << n) // <-- ?
    }
}

let foo = Foo(8); // <-- ?

```

---

<div class="post-metadata">

**Author:** ![P1start](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/p1start/32/23_2.png) [@P1start](https://internals.rust-lang.org/u/P1start)\
**Post date:** [November 7, 2014, 8:09am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/24 "2014-11-07T08:09:52Z")

</div>

This proposal doesn’t alter any language semantics, just conventions. So that example will operate in exactly the same way that it does today.

There appears to be a lot of confusion along these lines, so I’d like to clarify how I understand this proposal with an example. The current convention for the ‘main’ constructor function of a type is to define a static `new` method on it:

```rust
struct Foo {
    x: int,
}

impl Foo {
    fn new(x: int) -> Foo {
        Foo {
            x: x,
        }
    }
}

```

Under this proposal, the convention will be changed to defining a method in the same scope with the same name as the type:

```rust
struct Foo {
    x: int,
}

fn Foo(x: int) -> Foo {
    Foo {
        x: x,
    }
}

```

This is doable today, and is in fact used in some places (particularly in `rustc` itself, where conventions are somewhat ignored); for example, [`syntax::ptr::P`](http://doc.rust-lang.org/syntax/ptr/) uses this convention.

---

<div class="post-metadata">

**Author:** ![kennytm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kennytm/32/161_2.png) [@kennytm](https://internals.rust-lang.org/u/kennytm)\
**Post date:** [November 7, 2014, 9:33am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/25 "2014-11-07T09:33:05Z")

</div>

In that case a tuple-like struct cannot have such “constructors”.

```rust
struct Foo(uint, uint);
fn Foo(n: uint) -> Foo { // ← error: duplicate definition of value `Foo`
     Foo(n, 1 << n)
}

```

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [November 7, 2014, 11:05am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/26 "2014-11-07T11:05:35Z")

</div>

True, my view is that a tuple-struct already _has_ a default constructor, and if you want a different one, you should either use a struct with field-names.

---

<div class="post-metadata">

**Author:** ![dhardy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dhardy/32/2399_2.png) [@dhardy](https://internals.rust-lang.org/u/dhardy)\
**Post date:** [November 7, 2014, 5:05pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/27 "2014-11-07T17:05:10Z")

</div>

It annoys me that constructors in C++ don’t have easily searchable names (since obviously the class name gets used many times), besides which it isn’t obvious in a few cases that the constructor is being called. Typing a few extra letters to make that explicit with consistent notation is definitely worth it in my opinion.

---

<div class="post-metadata">

**Author:** ![dobkeratops](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dobkeratops/32/4577_2.png) [@dobkeratops](https://internals.rust-lang.org/u/dobkeratops)\
**Post date:** [November 9, 2014, 6:29pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/28 "2014-11-09T18:29:19Z")

</div>

Far, Far prefer this. it’s fine to have named functions for ‘alternative’/‘special case’/‘complex’ constructors, but I’ve always found ::new() to be redundant, unnecessary ugliness that stabs me in the eye. I used tuple-structs for vector maths purely because I dislike the idiomatic Vec3::new(x,y,z) convention. This proposed convention would allow you to move back & forth more easily. This is the kind of pointless refactoring issue we’re trying to escape from C++. “if you reverse this choice later, you have to change calling conventions …”

You can currently write struct Foo{} fn Foo()-\>Foo{} , and it is unambiguous both at call & definition site, hence still easy to search for. (grep `struct Foo{` vs `struct Foo(` vs `fn Foo` vs `Foo(` vs `Foo{` )

Don’t “Throw out the baby with the bathwater” when comparing to C++: C++‘s system is difficult because of many combined factors: header files, everything is overloaded, there are hidden conversions, and its hard to distinguish a definition from a use in a single line. Rusts’ lack of headers & simpler grammar (especially introducing types with “:” ) cut through many problems.

box Foo::new() also looks very redundant.

its’ also repurposing of the word ‘new’ compared to other languages which might cause confusion for people creating cross-langauge C wrappers.would people expect extern “C” Foo\_new() to really be a function that allocates and initialises, returning Foo\* ? opposite is Foo\_delete(Foo\*) ? Rust doesn’t exist in isolation.

Are there any details in language support, for example does `use foo::Bar` get _all_ symbols ‘Bar’ from foo (both the struct and the fn,if you make one)

---

<div class="post-metadata">

**Author:** ![bfops](https://avatars.discourse-cdn.com/v4/letter/b/50afbb/32.png) [@bfops](https://internals.rust-lang.org/u/bfops)\
**Post date:** [November 9, 2014, 6:54pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/29 "2014-11-09T18:54:06Z")

</div>

I totally misunderstood the original proposal. If it’s just about conventions, then my answer would be to not default to either, but to just choose whichever makes sense for your actual struct (or something else entirely)… For little things like `Vec3`, I’d definitely agree this seems nicer.

---

<div class="post-metadata">

**Author:** ![Manishearth](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/manishearth/32/50_2.png) [@Manishearth](https://internals.rust-lang.org/u/Manishearth)\
**Post date:** [November 10, 2014, 7:25pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/30 "2014-11-10T19:25:33Z")

</div>

This makes it clash with tuple struct constructors though. I prefer `Foo::new()` for user defined constructors, and `Foo()` for compiler provided tuple-like construction for variants/tuple structs.

---

<div class="post-metadata">

**Author:** ![nwin](https://avatars.discourse-cdn.com/v4/letter/n/4da419/32.png) [@nwin](https://internals.rust-lang.org/u/nwin)\
**Post date:** [November 10, 2014, 7:31pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/31 "2014-11-10T19:31:31Z")

</div>

I would strongly vote for consistency. As bstrie already wrote: Why should `::new` be special compared to `::with_capacity`?

Reminder: If this change comes, it also has to be ensured that `&Foo` returns a function pointer as `&Foo::new` does

---

<div class="post-metadata">

**Author:** ![Jurily](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jurily/32/212_2.png) [@Jurily](https://internals.rust-lang.org/u/Jurily)\
**Post date:** [November 11, 2014, 12:50am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/32 "2014-11-11T00:50:52Z")

</div>

My main problem is that it breaks the style. I don’t really like Rust’s default style, but at least it’s consistent.

I could live with `Foo::foo()` or non-method `foo()`.

---

<div class="post-metadata">

**Author:** ![bjadamson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjadamson/32/52_2.png) [@bjadamson](https://internals.rust-lang.org/u/bjadamson)\
**Post date:** [November 11, 2014, 3:03am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/33 "2014-11-11T03:03:04Z")

</div>

::new() is a huge improvement in consistency then introducing the idea of constructors. -1

---

<div class="post-metadata">

**Author:** ![ruuda](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ruuda/32/1870_2.png) [@ruuda](https://internals.rust-lang.org/u/ruuda)\
**Post date:** [November 11, 2014, 8:56am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/34 "2014-11-11T08:56:45Z")

</div>

`Type::new()` is one of the things that I immediately liked about Rust. It shows that the constructor is not special or magical in any way; it is just a function. Of course, when the constructor is a free function this is still the case, but this is not immediately obvious, especially for people coming from C++/C#/Java, where the constructor _is_ special. If `Vec()` would be the default constructor for `Vec`, then it could also be confusing that `Vec::with_capacity(c)` is a constructor as well. It might be more consistent with tuple structs and enum variants, but it is less consistent with non-default constructors.

The five extra characters do not bother me at all. Rust is already quite concise (e.g. `Rc` instead of C++’s `shared_ptr`).

---

<div class="post-metadata">

**Author:** ![eddyb](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/eddyb/32/8411_2.png) [@eddyb](https://internals.rust-lang.org/u/eddyb)\
**Post date:** [November 11, 2014, 5:56pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/35 "2014-11-11T17:56:14Z")

</div>

`&Foo` won’t produce a function pointer, but a reference to a function pointer - assuming `fn Foo(...) -> Foo {...}`, which is possible today, even if a type `Foo` is declared in the same module. That said, `Foo` is no different than `Foo::new`, or any other free function or static method.

---

<div class="post-metadata">

**Author:** ![naicode](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/naicode/32/2254_2.png) [@naicode](https://internals.rust-lang.org/u/naicode)\
**Post date:** [December 31, 2014, 11:24pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/36 "2014-12-31T23:24:47Z")

</div>

I real like the fact that rust does not have special constructors but just static methods witch initialise the object on POD basis.

Also the initialisation with `Enumval(...)` and `Foo {...}` shows clearly that it’s a POD initialisation where `Foo::new(..)` might do other stuff like data transformation, validity checks or even mutating mutable constants.

So -1 for this idea. Also the current convention is much clearer in regret to additional constructors like from\_…

---

<div class="post-metadata">

**Author:** ![strega-nil](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/strega-nil/32/13228_2.png) [@strega-nil](https://internals.rust-lang.org/u/strega-nil)\
**Post date:** [January 2, 2015, 5:21pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/37 "2015-01-02T17:21:01Z")

</div>

> [@dobkeratops](#):
>
> its' also repurposing of the word 'new' compared to other languages which might cause confusion for people creating cross-langauge C wrappers.would people expect extern "C" Foo\_new() to really be a function that allocates and initialises, returning Foo\* ? opposite is Foo\_delete(Foo\*) ? Rust doesn't exist in isolation.

As far as I can tell, at least in my own code, you would write

```
struct Foo *foo_alloc() {...}
void foo_free(struct Foo *foo) {...}

```

not

```
struct Foo *foo_new() {...}
void foo_delete(struct Foo *foo) {...}

```

`new` and `delete` just feel very "C++", not C. C uses `malloc` and `free`.

---

<div class="post-metadata">

**Author:** ![sivadeilra](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sivadeilra/32/7347_2.png) [@sivadeilra](https://internals.rust-lang.org/u/sivadeilra)\
**Post date:** [January 10, 2015, 11:12pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/38 "2015-01-10T23:12:02Z")

</div>

I much prefer `Vec::new()` over `Vec()`. I dislike method overloading, and I dislike using the type name for the constructor name in C++. Rust seems to get it right, to me. I also love the searchability of `::new(`. I can find many ctor calls just by searching for that string, unlike C++.

In C++, because you _can’t_ use a different name for ctor overloads, you are sometimes forced to add extra unused parameters to ctors, just so that you can abuse method overloading in order to choose the overload that you actually want. In Rust, you never have that problem.

Keep it the way it is.

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [January 11, 2015, 3:02pm UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/39 "2015-01-11T15:02:32Z")

</div>

In case it’s unclear, no such change is happening now that alpha has been released.

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [March 25, 2019, 8:23am UTC](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758/40 "2019-03-25T08:23:05Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

[Previous page](https://internals.rust-lang.org/t/poll-foo-new-vs-foo-as-the-default-constructor/758.md?page=1)
