December 31, 2013
On Monday, 30 December 2013 at 23:38:39 UTC, Walter Bright wrote:
> And people don't do that with C++. That's the whole problem with GLOBAL state.

Well, it should work ok for autoreleasepools (delete all objects at once) even under bad circumstances, I think.

>> But isn't this exactly what the proposed allocation system linked above enables?
>
> ??

Maybe I misunderstand, but isn't the purpose of std.allocator to set up allocators that new can call into?

December 31, 2013
On Tuesday, 31 December 2013 at 00:21:21 UTC, Ola Fosheim Grøstad wrote:
> Maybe I misunderstand, but isn't the purpose of std.allocator to set up allocators that new can call into?

No, it'll be a standard library interface.

I really think the built-in new should be discouraged - it has a lot of disadvantages over using a library setup, and not many advantages.
December 31, 2013
On Mon, 30 Dec 2013 16:45:50 -0800, Adam D. Ruppe <destructionator@gmail.com> wrote:

> On Tuesday, 31 December 2013 at 00:21:21 UTC, Ola Fosheim Grøstad wrote:
>> Maybe I misunderstand, but isn't the purpose of std.allocator to set up allocators that new can call into?
>
> No, it'll be a standard library interface.
>
> I really think the built-in new should be discouraged - it has a lot of disadvantages over using a library setup, and not many advantages.

Kind of like unique_ptr/shared_ptr but better. IIRC the GC is supposed to be just another allocator, which is fine by me and won't be unfamiliar to C++ guys. As a note though. Regular new is what the Java/C# guys will be used, they don't use allocators routinely.

-- 
Adam Wilson
IRC: LightBender
Project Coordinator
The Horizon Project
http://www.thehorizonproject.org/
December 31, 2013
Adam D. Ruppe:

> I really think the built-in new should be discouraged - it has a lot of disadvantages over using a library setup, and not many advantages.

It's hard to discourage the usage of a syntactically short and quite accessible feature of the language.

Bye,
bearophile
December 31, 2013
On Tuesday, 31 December 2013 at 00:45:51 UTC, Adam D. Ruppe wrote:
> I really think the built-in new should be discouraged - it has a lot of disadvantages over using a library setup, and not many advantages.

Huuuge +1 from me. A while ago, I heard someone state that allocation and object construction should be separate concepts and "new" kind of clobbers the two concepts together. Over time I've started recognizing that this as well and I've really started thinking that a "new" operator is actually a bad thing, despite it being a short and convenient way to do that process.

Once you start thinking of allocators as "objects" you start realizing that using the "new" operator is like you've been using global variables all over the place (which isn't necessarily a bad thing, but it's pretty shocking that no one really made the conscious choice to do so and most languages have made the choice too transparent when it actually matters quite a lot).
December 31, 2013
Chris Cain:

> A while ago, I heard someone state that allocation and object construction should be separate concepts and "new" kind of clobbers the two concepts together. Over time I've started recognizing that this as well and I've really started thinking that a "new" operator is actually a bad thing,

I remember time ago some people discussing about the idea of deprecating the "new" in D, not just "delete".

Bye,
bearophile
December 31, 2013
On Tuesday, 31 December 2013 at 00:45:51 UTC, Adam D. Ruppe wrote:
> I really think the built-in new should be discouraged - it has a lot of disadvantages over using a library setup, and not many advantages.

A flexible new and good compiler level memory management support that cannot be overridden gives the compiler some optimization opportunities. E.g. putting objects on the stack, allocating a single chunk for multiple objects, delaying init and perhaps avoiding allocation.

So I am personally sceptical of pushing libraries over advanced compiler support. Leaving more room for analysis is usually a good thing. The issue I have with library level allocation is that the compiler does not know that the code is doing allocation?
December 31, 2013
Am Mon, 30 Dec 2013 13:52:28 +0000
schrieb "ponce" <contact@gam3sfrommars.fr>:

> > http://www.reddit.com/r/programming/comments/1tzk5j/the_m_error_model/

> As compared with D:
> 
> - unrecoverable errors crash immediately like they should. I like it since the most sensible reason to catch Error in D is to crash anyway (in eg. C callbacks).

  »Unrecoverable errors are designed for conditions that can’t
  really be handled appropriately from within a software
  component. [...] Null dereferences, out-of-bounds array
  accesses, bad downcasts, out-of-memory, contract/assertion
  violations…«

  »[...] all failures are recoverable, but the granularity is
  much coarser grained than in traditional systems.«

As far as I can tell he is talking about tearing down a failing
component (e.g. a library or plugin), not the whole program. I
can only assume that he didn't look into bringing C code into
the mix.
This is different from D where you typically either get an access
violation or an attempt at stack unwinding down to D main().

  »if one component fails in an unrecoverable way, an external
  component can observe and/or recover from the failure of
  that component.«

> - hence, unrecoverable errors exception hierarchy not represented.

Personally I think it is useful to be able to check the type of unrecoverable error to handle out of memory situations or checks in test cases and unit tests.

> - a throws keyword instead of nothrow. I expect it will lessen M# support for code made in a hurry (something that D shines particularly).

Can both co-exist? E.g. use case 1) "doesn't throw anything ever", use case 2) "throws UtfException when the date string is not valid UTF-8 and DateException when the day of month is out of range", use case 3) no keyword since we are in a hurry.

> - same remark about the "try" keyword at call-site when calling a function which throw recoverable errors.

  »In fact, if you call a method that might raise a
  recoverable error, the call must be annotated to indicate
  that it might throw (the keyword we use is “try”).«

I'm not quite sure if that means "directly at the call-site" or "somewhere up in the call stack". What do you think?

-- 
Marco

December 31, 2013
On Tuesday, 31 December 2013 at 00:45:51 UTC, Adam D. Ruppe wrote:
> On Tuesday, 31 December 2013 at 00:21:21 UTC, Ola Fosheim Grøstad wrote:
>> Maybe I misunderstand, but isn't the purpose of std.allocator to set up allocators that new can call into?
>
> No, it'll be a standard library interface.
>
> I really think the built-in new should be discouraged - it has a lot of disadvantages over using a library setup, and not many advantages.

I suspect it will still be fine to use in situations where a loose aliasing policy is required (so GC-exclusive characteristics are depended on), such as scripts and certain other application code. The same goes for using the concatenation operators, over `Appender` et al. with a pluggable allocator.

For libraries though - definitely should be a red flag.
December 31, 2013
On Tuesday, 31 December 2013 at 06:28:40 UTC, Ola Fosheim Grøstad wrote:
> A flexible new and good compiler level memory management support that cannot be overridden gives the compiler some optimization opportunities. E.g. putting objects on the stack, allocating a single chunk for multiple objects, delaying init and perhaps avoiding allocation.
>
> So I am personally sceptical of pushing libraries over advanced compiler support. Leaving more room for analysis is usually a good thing.

Well, that's certainly a good point. There's _probably_ some extra optimizations that could be done with a compiler supported new. Maybe it could make some significantly faster code, but this assumes many things:

1. The compiler writer will actually do this analysis and write the optimization (my bets are that DMD will likely not do many of the things you suggest).
2. The person writing the code is writing code that is allocating several times in a deeply nested loop.
3. Despite the person making the obvious critical error of allocating several times in a deeply nested loop, he must not have made any other significant errors or those other errors must also be covered by optimizations.
4. The allocation isn't passed around too much to avoid the analysis or isn't actually kept around sometimes for some reason

This makes the proposed optimization _very_ situational. If the situation does occur, it's possible that the user can use something like "std.allocator.StackAllocator" to do what he needs. Manual optimization in this case isn't too unreasonable. Considering the drawbacks of new and the advantages of a library allocation, this additional _potential_ advantage of new isn't enough to suggest its usage over a library solution here. Again, it's not a bad point, but it's just not compelling enough.

That all said,

> The issue I have with library level allocation is that the compiler does not know that the code is doing allocation?

_Technically_ the compiler could also do some analysis in functions and figure out that it will be allocating in there somewhere and using that allocation later on. Think of replacing library calls when it's noticed that it's an allocate function. It's pretty dirty and won't actually happen nor do I suggest it should happen, but it's actually still also _possible_.