July 29, 2014
On Tuesday, 29 July 2014 at 05:11:33 UTC, Dicebot wrote:
> (sorry for being a bit late, was distracted)
>
> std.logger proposal by Robert Schadek enters voting period which will last two weeks starting from now.
>
> Discussion thread : http://forum.dlang.org/post/zhvmkbahrqtgkptdlcvh@forum.dlang.org
>
> This voting will be somewhat different from previous ones because it will be done with std.experimental in mind. Because of that please reply with a bit more structured votes:
>
> 1) Yes / No for inclusion into std.experimental

Yes.

>
> At this point please consider if module has functionality you want to see in standard library in general and if implementation is not fundamentally broken. This is a simple sanity check.
>
> 2) Yes / No for inclusion into Phobos in its current state

Yes. A lot of reusable components need warnings (hence: logging).


> This is where you should summarize your concerns raised during review if there are any and make decision if existing API / architecture are promising enough to be set in stone via Phobos inclusion.
>
> 3) If you have answered "No" for (2) :  list of mandatory changes that are needed to make you vote "Yes"
>
> 4) Any additional comments for author.
>

Thanks.

July 29, 2014
On Tuesday, 29 July 2014 at 17:15:22 UTC, Andrei Alexandrescu
wrote:
> NO.
>
> We put something in std.experimental when we can't imagine what other work is to be done on the module. (Inevitably a little more work is prompted by usage, which is the point of it all.) We don't put in std.experimental stuff that has already a known backlog of work to do.
>
>
> Andrei

Spawned separate discussion thread :
http://forum.dlang.org/post/icumpyexlsneievlmfex@forum.dlang.org
July 29, 2014
Yes, assuming Andrei's non-negotiable issues are addressed first.
July 29, 2014
On Tuesday, 29 July 2014 at 17:20:58 UTC, Andrei Alexandrescu wrote:

I should have the overload approach done by tonight
July 29, 2014
> Second, the way I look at it, you can read the methods like this:
>
>     write - write
>     writef - write formatted
>     log - log
>     logf - log formatted
>     logc - log conditionally
>     logcf - log conditionally and formatted

Andrei is Romanian; not Hungarian.
And a Romanian is AFAIK also not a reverse Hungarian.
So no need to arouse him by proposing a Hungarian Api. :)
better being concise and precise.
July 29, 2014
On Tuesday, 29 July 2014 at 17:31:27 UTC, Robert burner Schadek wrote:
> On Tuesday, 29 July 2014 at 17:20:58 UTC, Andrei Alexandrescu wrote:
>
> I should have the overload approach done by tonight

Have a look at https://github.com/linkrope/log/blob/master/src/log.d#L55-66 for the overloading.

It's much cleaner than the 'static if' sequences.
July 29, 2014
On Tuesday, 29 July 2014 at 22:15:18 UTC, linkrope wrote:
> Have a look at https://github.com/linkrope/log/blob/master/src/log.d#L55-66 for the overloading.
>
> It's much cleaner than the 'static if' sequences.

of course, because you are doing much less
July 29, 2014
On Tuesday, 29 July 2014 at 06:09:25 UTC, Andrei Alexandrescu wrote:
>
> My vote is a qualified "yes" contingent upon fixes that I'll give detail on below. In the current form my vote is "no" seeing as the module makes a number of unforced tactical errors. Overall I think the goods are there, and are easy to put in acceptable form.

> Here's my list:
>
> 1. Minimal logging level must be selected statically in addition to the current dynamic selection. Static settings preclude dynamic settings. This is not negotiable.

I'm not sure how you except log(LogLevel.xxxx, "Hello world") to be disabled at compile time if LogLevel.xxxx is a runtime value? Or do I misunderstood you?

you can choose to disable name based logging like trace("Hello trace") at CT with the current release

>
> 2. All logging code must be rigorously eliminated if below the static logging level. More precisely, there must be a front-end optimization that eliminates all code dedicated to a "lazy" variable that's not used by a generic function. This would be a fantastic redeeming of the "lazy" keyword, which has been of marginal utility until now. The challenge here is cooperating with someone on the compiler team to make sure that front-end improvement gets implemented, and writing unit tests that make sure there's no regression later. This is not negotiable.

If you disabled one on the names logging functions at CT other prototypes will be used that have no lazy in it. You said that empty functions with lazy parameter are not optimized away. So there are no empty functions with lazy parameter if you disable these functions. As soon as the compiler can kill empty functions with lazy arguments this branching can be removed without any user code adjustment.

>
> 3. The suffix notations must be replaced with overloads. The only acceptable suffix is "f" for formatting. Everything else must be achieved via overloads with the help of template constraints. Robert's answer http://goo.gl/FehDVh suggests he didn't consider using template constraints. We can't let that slip become a feature of the library for millenia to come.
>
> The overloads must be:
>
> // just log stuff
> log(T...)(lazy T stuff) if (!is(T[0] : const LogLevel));
> // log with format
> logf(S, T...)(lazy S fmt, lazy T stuff) if (isSomeString!Str);
> // log conditional with format
> logf(S, T...)(lazy bool cond, lazy S fmt, lazy T stuff) if (isSomeString!Str);
>
> These three overloads should be repeated for all logging functions (info, trace etc). The functions don't evaluate their arguments if the respective log level is disabled.
>
> The following functions will NOT be repeated for all logging functions:
>
> // just log stuff at some level
> log(T...)(LogLevel lvl, lazy T stuff) if (!is(T[0] : const LogLevel));
> // log with format
> logf(S, T...)(LogLevel lvl, lazy S fmt, lazy T stuff) if (isSomeString!Str);
> // log conditional with format
> logf(S, T...)(LogLevel lvl, lazy bool cond, lazy S fmt, lazy T stuff) if (isSomeString!Str);
>
> These overloads always evaluate their first argument eagerly to determine the required logging level. Depending on it they may or may not evaluate their other arguments.
>
> This is not negotiable.

Overloads are implemented in the current version. They behave as you described.

>
> 4. Replace defaultLogger with theLog. "Logger" is a word, but one that means "lumberjack" so it doesn't have the appropriate semantics. The use is generally acceptable as a nice play on words and as a disambiguator between the verb "to log" and the noun "log". When we actually want to talk about the current log in an application, we should, however, call it "the log". This is negotiable.

I really don't care how a global Logger instance is called. Anyone else has an opinion on this? Otherwise Andrei wins.

>
> 5. I was hoping for a resolution on throttling. However, now I realize that conditional logging plus throttling functions that return true once in a while should work acceptably well. Higher-order functions taking lambdas that log would also be a nice possibility. So... no request here.

Creating a std.logger.conditions module is on my todo, std.logger.(stderr,stdout) will be cut because of being to noisy. I'm thinking of
* anyN
* anyNmillisec
* firstN
* ...


>
> 6. I'm still hoping for RefCounted as the storage for the class backend. I realize users can do their own management but log objects are unlikely to contain cycles and other liabilities for reference counting, and at some point if we want to use reference counting where appropriate we got to start somewhere with a few solid precedents. This is negotiable, but I plan to fight for it.

IMO something is wrong in the users code if the GC working on Logger instances is slowing the code done. The Logger instances properly stay around for the length of the programs execution. If you create Logger in a tight loop RC will properly slow you down as well.

>
>> 4) Any additional comments for author.
>
> Don't let any of the above discourage you. This is great work and is already one foot in. Let's get this done and done. Don't forget - it's all about Deutsche Gründlichkeit!
>
>
> Andrei

Hope this brings you closer to a "yes"
Robert

July 29, 2014
On Tue, Jul 29, 2014 at 11:09:27PM +0000, Robert burner Schadek via Digitalmars-d wrote:
> On Tuesday, 29 July 2014 at 06:09:25 UTC, Andrei Alexandrescu wrote:
[...]
> >4. Replace defaultLogger with theLog. "Logger" is a word, but one that means "lumberjack" so it doesn't have the appropriate semantics. The use is generally acceptable as a nice play on words and as a disambiguator between the verb "to log" and the noun "log". When we actually want to talk about the current log in an application, we should, however, call it "the log". This is negotiable.
> 
> I really don't care how a global Logger instance is called. Anyone else has an opinion on this? Otherwise Andrei wins.
[...]

I propose 'stdlog'.


T

-- 
There's light at the end of the tunnel. It's the oncoming train.
July 29, 2014
On 7/29/14, 4:16 PM, H. S. Teoh via Digitalmars-d wrote:
> On Tue, Jul 29, 2014 at 11:09:27PM +0000, Robert burner Schadek via Digitalmars-d wrote:
>> On Tuesday, 29 July 2014 at 06:09:25 UTC, Andrei Alexandrescu wrote:
> [...]
>>> 4. Replace defaultLogger with theLog. "Logger" is a word, but one
>>> that means "lumberjack" so it doesn't have the appropriate semantics.
>>> The use is generally acceptable as a nice play on words and as a
>>> disambiguator between the verb "to log" and the noun "log". When we
>>> actually want to talk about the current log in an application, we
>>> should, however, call it "the log". This is negotiable.
>>
>> I really don't care how a global Logger instance is called. Anyone
>> else has an opinion on this? Otherwise Andrei wins.
> [...]
>
> I propose 'stdlog'.

I thought of the same but then rejected it - stdlog looks like offering the same interface as stdout and stderr. Nevertheless it's a sensible choice, too. -- Andrei