On Monday, 27 August 2012 at 22:44:53 UTC, F i L wrote:
Era Scarecrow wrote:

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.

So it will intentionally ignore 'new' and instead just call the constructor and decide if it should be heap or not? Sounds both helpful and harmful to me.

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.

I think that's why the naming should be something that sounds easy to follow or follows a particular style. The following should have no trouble figuring out even without seeing any documentation. Mind you i'm throwing this out there without a specific class in min.

 File inputFile = File.createHandle("some file");
 inputFile.load();
 inputFile.close();

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.

Wrong. If you have it within a class, you know it comes FROM that class. There may be multiple 'Records' depending on different projects or having compatible types. In my own factory function it polymorphs based on the input, so knowing the root class makes sense to me.

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
    }

But now you're breaking consistency by not including a return type. maybe 'this this()' but that looks like a mistake or typo. If you're willing to use something without a return type, why not leave it 'this(this)'? Or rename it all together? 'this postblitz()'.

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.

Wasn't there already a way to specify (or going to be) what you wanted to use an allocator? I thought i remember seeing an example in TDPL.

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".

 Isn't that more an API issue?

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.

But new wouldn't be a constructor then would it? It would still be based on allocating memory that's optionally different. Constructor and allocation are two different steps; And for it to seamlessly go from one to another defaults to having a set default constructor. Let's assume...

 class Object {
   this new() {
   //allocate
     return defaultConstructor();
   }
   this defaultConstructor() {}
 }

Now in order to make a constructor (and then destructor) you either can:

A) overload or use 'defaultConstructor', which would be publicly known B) overload new to do allocation the same way and call a different constructor and specifically add a destructor to make sure it follows the same lines. C) overload new to call the default allocator and then call a different constructor

Now assuming you can make a different constructor by name, you then have to be able to specify a destuctor the same way for consistancy.

 class CustomType {
   this MyAwesomeConstuctor();
   void MyAwesomeDestructor();
 }

Same problem, how do you tell it ahead of time without completely rewriting the rules? leaving it as 'this' and '~this' are simple to remember and work with, and factory functions should be used to do a bulk of work when you don't want the basic/bare minimum.

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);

After reading a large chunk where Andrei spoke of the flaws of C++'s classes and inheritance and potential problems having stack/exact size allocated classes compared to leaving them on the heap is coming to mind. This would undo all of that.

 class Bar : Foo {
   float y, z;
 }

 auto foo = Foo.alloc();
 int isSafe;
foo = Bar.alloc(); //should implicity convert normally. But stack?

assert(isSafe == int.init); //or was the next variables overwritten??


In the cases where you don't overload anything would make the classes safe, in which case they don't polymorph, in which case you may as well use structs. Am I wrong on this?

Reply via email to