Era Scarecrow wrote:
I'm sure in C# that all structs and classes are heap allocated (It takes after C++ very likely) that's the simplest way to do it. You can do that in C++ as well, but other than having to declare it a pointer first. In C++ they made structs 'classes that are public by default' by it's definition I believe. Considering how C++ is set up that makes perfect sense.

C# structs are allocated on the stack when they can be. In certain cases (they're class fields, they're boxed, etc..) they're heap allocated.


By looking at newFoo I'd say a class; But if like in C# I'm sure you can't tell the difference (But C++ with the pointer you can).

the 'auto' keyword kind negates the 'Type*' distinction. My point here is that you pretty much have to look up the type definition (or a tooltip) to understand what you're working with when factory functions are involved.


And for factory functions I'd put them inside the struct/class, unless I had a compelling reason not to.

  class Record {
    static Record newRecord(string options) {
      Record rec = new Record();
      // stuff building the complex record
      return rec;
    }
  }

The result is the same weather they're inside or outside a class, because, when used, all the coder sees is the function name to know about what it's returning.

In D there is a difference between structs and classes beyond what's in C++. The 'new' keyword helps us understand what kind of object is being created, and I enjoy that. However, my argument is in favor of consistency because right now factory-functions, which _are_ used a lot, completely hide that distinction on top of being inconsistent with "normal" type construction.


And a postblits would end up being...? The extra 'this' makes it look like an obvious typo or a minor headache.

 this this(this){} //postblitz?

I'm sure this case has an easy solution. How about:

    struct Foo {
        this new() { ... } // constructor
        this() { ... } // postblit
    }


Only if you start getting creative can it begin to get confusing;

And I have to completely disagree with you here. Memory Pools are used everywhere in performance-critical code which needs a dynamic array of objects. At least half of all the "allocation" in game engines is done through factory functions that recycle objects.

And for overload distinction (new vs load), which is an issue beyond Memory Pools and effects and even larger codebase. There needs to be a consistent way to distinguish (by name) a constructor that loads from a file, and one that creates the object "manually".


If we take your approach and suggestion, which one should the compile assume?

 Something globalSomething;

 class Something {
   this defaultConstructor();
   this duplicate(); //or clone
   this copyGlobalSomething();
   this constructorWithDefault(int x = 100);
 }

By signature alone... Which one? They are all legal, they are uniquely named, and they are all equal candidates. Order of functions are irrelevant.

It could work identically to how D functions today. A 'new()' constructor would be part of the root Object classes are derived of, and structs would have an implicit 'new()' constructor.

This could work in our favor, because instead of 'new' we could use 'alloc' (or something like that) while still encouraging 'new'. Which means structs could provide a parameter-less new() constructor:

    class Foo {
        float x;
        // no constructor
    }

    auto f = Foo.alloc();
    assert(f.x == float.nan);

    ---

    struct Point {
        float x, y;
        this new() { x = 0; y = 0; }
        this new(float x, float y) { ... }
    }

    auto a = Point.new();
    auto b = Point.new(1, 2);
    assert(a.x == 0.0f);

Reply via email to