'new' class method

KennyTM~ kennytm at gmail.com
Sat Oct 25 02:23:56 PDT 2008


Bill Baxter wrote:
> On Sat, Oct 25, 2008 at 2:04 AM, KennyTM~ <kennytm at gmail.com> wrote:
> 
>>>  auto a = Class();  // heap   (default)
>>>  auto a = Struct(); // stack   (default)
>>>
>>>  auto a = Class.new(stack)(); // stack
>>>  auto a = Struct.new(stack)(); // stack
>>>
>>>  auto a = Class.new(heap)(); // heap
>>>  auto a = Struct.new(heap)(); // heap
>>>
>>>   void *addr;
>>>   auto a = Class.new(addr)(); // placement
>>>   auto a = Struct.new(addr)(); // placement
>>>
>> I strongly *oppose* using stack and heap as keywords because there are also
>> (partly irrelevant) data structures called stack and heap, even though
>> according to the guideline these class/structs should be named Stack and
>> Heap.
> 
> Right, that's why both Benji and I proposed making them *context*
> keywords.  Just like "Windows" is a keyword only in the context of
> extern( ).  This would make heap and stack keywords only in the
> context of new(  ).
> 

I see. But with the your new(...) syntax this can't be done because it 
is ambiguous with

   void* stack = allocate();
   auto C = Class.new(stack)();

The placement new syntax should use some other syntax.

>> And I think we can include the meaning that "scope" attribute always
>> allocate on stack (Currently 4 conditions need to be met for so), but I'm
>> afraid this may break something (otherwise the other 3 conditions won't be
>> there?). Maybe some experts can comment on this?
>>
> 
>> And I suggest keeping the "new" syntax for heap ("return a pointer")
>> allocation. So,
> 
> Well, Andrei was looking at getting rid of this "new blah" syntax for
> other reasons already, so that's why I tacked in on as a pseudomethod
> of classes and structs.
> 

I know. My suggestion is not to get rid of all the new syntax but make 
it appear less frequently.

>> auto c = Class(...);   // default on heap
>> auto s = Struct(...);  // default on stack (compatible with current syntax)
>>
>> scope c = Class(...);  // on stack
>> scope s = Struct(...); // on stack (compatible with current syntax)
> 
> The main thing I don't like about this syntax is that it makes it
> impossible to create a class temporary on the stack in an expressoin.
> It means you always have to declare it and give it a name if you want
> to avoid the heap.  It's just not orthogonal in that way.  As in it
> entangles construction with declaration, when those two are usually
> separate concerns.
> 
> Specifically as an example, say you have some object that does
> comparisions and you want to pass it to a sort function then uniq it .
>   First you wrote this:
> 
>      T[] array; ...
>      T[] filtered = uniq(sorted(MyComparator.new, array)));
> 
> Then you decided the heap alloc was unnecessary there, so now you have
> to change it all around
> 
>      T[] array; ...
>      {   // made a block here so that theComparator goes away after sorting
>         scope theComparator = MyComparator.new;
>         T[] filtered = uniq(sorted(theComparator, array)));
>      }
> 
> Instead of just sticking "(stack)" in there and being done with it:
> 
>      T[] array; ...
>      T[] filtered = uniq(sorted(MyComparator.new(stack), array)));
> 

I see. So seems we must stick with method calls.

>> auto c = new Class(...);  // on heap (compatible with current syntax)
>> auto s = new Struct(...); // on heap (compatible with current syntax)
>>
>> auto c = new(...) Class(...);  // placement (compatible with current syntax)
>> auto s = new(...) Struct(...); // placement (compatible with current
>> syntax?)
>>
>>
>> /* if you want symmetry, do it like this:
>>
>> new c = Class(...);
>> new(...) c = Class(...);
>> kinda strange for me. */
> 
> Yeh, me too.  I definitely don't want any more of this sillyness of
> mixing up construction with declaration.
> 
>> These will cause minimum change while eliminating the "new" for most cases.
>> This won't free the "new" keyword though.
> 
> I don't particularly think it needs to be freed up.  A better case may
> be made for, delete, though because there's less that's special about
> how it works.
> 
>>> Yeah! I noticed it. And I like it. In fact, I thought to myself "that's
>>> almost the same as my idea".
> 
> (To Benji now) Yep, it was!
> 
>>> Generally, I'm not a fan of the consecutive
>>> sequence of parentheses (especially that templates already make for double
>>> parens; I can't imagine I'd want triple parens for a templatized
>>> consttructor call).
> 
> Well, the idea is that the versions that use "new" will be fairly
> rare.  I'm certainly open to other ideas.  I suggested using [] just
> for new args in another post.  Like
>      MyClass.new[scope](foo,bar)
> It just seems odd to me to use that in this one place and no other.  I
> think the parens would work, which is why I went back to parens.
> 
> Another possibility might be to introduce some syntax for heap vs
> stack and only use () for placement new -- like this:
> 
>      Class.*new(construct_args);   // stack (like *foo is dereferenced
> foo pointer)
>      Struct.*new(construct_args);  // stack
> 
>      Class.new(construct_args); // heap
>      Struct.new(construct_args); // heap
> 
>      Class.new@(new_args)(construct_args);  // placement
>      Struct.new@(new_args)(construct_args); // placement
> 
>>> For non-template chained calls, I'm not quite sure which I prefer:
>>>
>>>  auto a = Foo.new(heap)(Bar.new(stack)());
>>>
>>>  auto a = on(heap) Foo(on(stack) Bar());
> 
> I think Andrei is gunning to get rid of the dangling prefix words in
> the grammar.  That's why I put .new at the end.  I think he would also
> be happy with a regular function-like syntax, too, but what I've seen
> of that looks ugly.  When you do 'new' there always a class or struct
> involved, so why not make it a pseudo property of every class and
> struct, just like .init or .tupleof?
> 
> --bb



More information about the Digitalmars-d mailing list