September 10, 2018
On 10/09/2018 9:11 PM, Kagamin wrote:
> On Saturday, 8 September 2018 at 08:32:58 UTC, Guillaume Piolat wrote:
>> There is no other choice when the runtime is disabled but to have @nogc.
>> It's a fantastic peace of mind for high-performance to be able to _enforce_ something will not allocate.
> 
> You can't have a working GC allocation with disabled runtime, can you?

Yes.

GC.disable
September 11, 2018
On Saturday, 8 September 2018 at 08:32:58 UTC, Guillaume Piolat wrote:
> Not Weka but we are happy with @nogc and without @nogc our job would be impossible.

There is one way to code without garbage collector somewhat practically without annotating @nogc, the way I use: Compile manually only those parts of runtime you need and have linker to link in only needed symbols (so there is no need to go stubbing the whole runtime). If you accidently allocate, you get linker errors.

Still, @nogc helps because it will tell right away where I called something I should not.

I wonder if having an option to compile DRuntime without support for thearding would simplify portability. I once read the implementation and got the impression that theards are by far the most platform-dependant part of it.
September 11, 2018
On Monday, 10 September 2018 at 09:11:38 UTC, Kagamin wrote:
> On Saturday, 8 September 2018 at 08:32:58 UTC, Guillaume Piolat wrote:
>> There is no other choice when the runtime is disabled but to have @nogc.
>> It's a fantastic peace of mind for high-performance to be able to _enforce_ something will not allocate.
>
> You can't have a working GC allocation with disabled runtime, can you?

Indeed and that's why you must ensure at compile-time that you have no `new` else you have a runtime crash, and one that might be difficult to test unless you have perfect coverage.
September 19, 2018
On Friday, 7 September 2018 at 17:01:09 UTC, Meta wrote:
> So it seems that it's never worked. Looking at the implementation, it uses a std.container.BinaryHeap, so it'd require a small rewrite to work with @nogc.

AFAICT, extending std.container with support for specifying you own @nogc (malloc-based) allocators is one way of making `topNCopy` not use the GC.
September 19, 2018
I've got plenty to say, but here is the long and the short of it: Use Mecca.

On 07/09/18 19:44, Peter Alexander wrote:
> 3. It was really frustrating that I had to make the compiler happy before I was able to run anything again. Due to point #1 I had to move code around to restructure things and wanted to make sure everything continued working before all GC allocations were removed.

mecca.lib.reflection has "as".
https://weka-io.github.io/mecca/docs/mecca/lib/reflection/as.html

Here is how you use it:
void fun() @nogc {
  as!"@nogc"( some code that is not @nogc );
}

> 
> 4. I used std.algorithm.topNCopy, which is not @nogc. The error just says "cannot call non-@nogc function [...]". I know there are efforts to make Phobos more @nogc friendly, but seeing this error is like hitting a brick wall. I wouldn't expect topNCopy to use GC, but as a user, what do I do with the error? Having to dig into Phobos source is unpleasant. Should I file a bug? What if it is intentionally not @nogc for some subtle reason? Do I rewrite topNCopy?
> 
> 5. Sometimes I wanted to add writeln to my code to debug things, but writeln is not @nogc, so I could not. I could have used printf in hindsight, but was too frustrated to continue.

mecca.log has logging facilities that are @nogc.

Now, to be fair, they are not actually @nogc, as by default it uses writeln. It is, however, annotated with @nogc, for precisely the reasons you encountered.

Shachar
September 19, 2018
On 08/09/18 11:07, Peter Alexander wrote:
> I'd love to know if anyone is making good use of @nogc in a larger code base and is happy with it. Weka.io?

No, sorry.

Actually, yes.

Well, sortof.

The main Weka codebase hardly uses any annotations of any kind. Not @nogc nor others. This is in the process of being amended, somewhat, but is not a high priority. We do use run-time detection of GC use. I.e. - we've modified the druntime to invoke a callback if a GC allocation takes place, and we then log that fact (with traceback). We then are able to search logs for GC allocations and remove them.

So that's the "no" part.

As pointed out, one of the main motivations for running Mecca was to clear up the strange solutions that have accumulated over the years. As such, the Mecca code does have @nogc in much more wide use.

So, yes.

There is a catch, though. Writing Mecca with @nogc required re-implementing quite a bit of druntime. Mecca uses its own exception allocations (mkEx, just saw it's not yet documented, it's under mecca.lib.exception). The same module also has "enforceNGC". We also have our own asserts. This is partially to support our internal logging facility, that needs a static list of formats, but it also solves a very important problem with D's @nogc:

void func() @nogc {
  assert(condition, string); // string is useless without actual info about what went wrong.
  assert(condition, format(string, arg, arg)); // No good - format is not @nogc
  ASSERT!"format"(condition, arg, arg); // @nogc and convenient
}

So, yes, we do use @nogc, but it took a *lot* of work to do it.

The good news is that mecca is available, and you can just dub it into your project and use it, so you don't have to repeat that whole set of work.

Mecca was advertised mostly around the reactor. While it is a piece of work I am very proud of, it is not the only part there, nor is it necessary to use mecca's reactor if you want just the library. In fact, nothing outside of mecca.reactor depends on the reactor running.

Hope this helps,
Shachar
September 19, 2018
On 9/19/18 1:13 PM, Shachar Shemesh wrote:

> There is a catch, though. Writing Mecca with @nogc required re-implementing quite a bit of druntime. Mecca uses its own exception allocations (mkEx, just saw it's not yet documented, it's under mecca.lib.exception). The same module also has "enforceNGC". We also have our own asserts. This is partially to support our internal logging facility, that needs a static list of formats, but it also solves a very important problem with D's @nogc:
> 
> void func() @nogc {
>    assert(condition, string); // string is useless without actual info about what went wrong.
>    assert(condition, format(string, arg, arg)); // No good - format is not @nogc
>    ASSERT!"format"(condition, arg, arg); // @nogc and convenient
> }
> 
> So, yes, we do use @nogc, but it took a *lot* of work to do it.

I'm running into this coincidentally right now, when trying to debug a PR. I found I'm getting a range error deep inside a phobos function. But because Phobos is trying to be pure @nogc nothrow @safe, I can do almost nothing to display what is wrong.

What I ended up doing is making an extern(C) hook that had the "right" attributes, even though it's not @nogc (let's face it, you are about to crash anyway).

But it got me thinking, what a useless interface to display errors we have! Inside Throwable, there is the function toString(someDelegate sink) which prints out the exception trace.

Near the front there is this:

        if (msg.length)
        {
            sink(": "); sink(msg);
        }

My, wouldn't it be nice to be able to override this! And forget about the whole msg BS. When an exception trace is printed, there are almost no restrictions as to what can be done. We should delay the generation of the message until then as well! Not to mention that if we can output things piecemeal through the sink, we don't even have to allocate at all.

I'm going to write up a more detailed post on this, but it's annoying to throw exceptions without any information EXCEPT what can be converted into a string at runtime at the time of exception. All that is missing is this hook to generate the message.

-Steve
September 19, 2018
On 19/09/18 21:35, Steven Schveighoffer wrote:
> On 9/19/18 1:13 PM, Shachar Shemesh wrote:
> 
>> There is a catch, though. Writing Mecca with @nogc required re-implementing quite a bit of druntime. Mecca uses its own exception allocations (mkEx, just saw it's not yet documented, it's under mecca.lib.exception). The same module also has "enforceNGC". We also have our own asserts. This is partially to support our internal logging facility, that needs a static list of formats, but it also solves a very important problem with D's @nogc:
>>
>> void func() @nogc {
>>    assert(condition, string); // string is useless without actual info about what went wrong.
>>    assert(condition, format(string, arg, arg)); // No good - format is not @nogc
>>    ASSERT!"format"(condition, arg, arg); // @nogc and convenient
>> }
>>
>> So, yes, we do use @nogc, but it took a *lot* of work to do it.
> 
> I'm running into this coincidentally right now, when trying to debug a PR. I found I'm getting a range error deep inside a phobos function. But because Phobos is trying to be pure @nogc nothrow @safe, I can do almost nothing to display what is wrong.
> 
> What I ended up doing is making an extern(C) hook that had the "right" attributes, even though it's not @nogc (let's face it, you are about to crash anyway).
> 
> But it got me thinking, what a useless interface to display errors we have! Inside Throwable, there is the function toString(someDelegate sink) which prints out the exception trace.
> 
> Near the front there is this:
> 
>          if (msg.length)
>          {
>              sink(": "); sink(msg);
>          }
> 
> My, wouldn't it be nice to be able to override this! And forget about the whole msg BS. When an exception trace is printed, there are almost no restrictions as to what can be done. We should delay the generation of the message until then as well! Not to mention that if we can output things piecemeal through the sink, we don't even have to allocate at all.
> 
> I'm going to write up a more detailed post on this, but it's annoying to throw exceptions without any information EXCEPT what can be converted into a string at runtime at the time of exception. All that is missing is this hook to generate the message.
> 
> -Steve

Then by all means, have a look at ASSERT inside mecca.lib.exception.
September 19, 2018
On 9/7/2018 10:35 AM, Eugene Wissner wrote:
> fill() uses enforce() which allocates and throws. 

The addition of -dip1008 stopped using the gc for throwing exceptions, but it's opt-in at the moment.
September 19, 2018
On 9/19/2018 10:13 AM, Shachar Shemesh wrote:
>    assert(condition, string); // string is useless without actual info about what went wrong.
>    assert(condition, format(string, arg, arg)); // No good - format is not @nogc

Another method:

  debug
    assert(condition, format(string, arg, arg));
  else
    assert(condition, string);

because @nogc is ignored in debug conditionals, just like purity is ignored in debug conditionals.