(git HEAD) std.datetime spewing deprecation messages

Artur Skawina via Digitalmars-d digitalmars-d at puremagic.com
Thu Jun 5 16:54:09 PDT 2014


On 06/06/14 00:15, Steven Schveighoffer via Digitalmars-d wrote:
> On Thu, 05 Jun 2014 17:54:49 -0400, Artur Skawina via Digitalmars-d <digitalmars-d at puremagic.com> wrote:
>> I'd say it is very C-ish and very unidiomatic.
>>
>> Why? Well, compare with:
>>
>>    struct D {
>>       // In real code these methods would do the work [1]:
>>       long days() @property { return 2012; }
>>       int seconds() @property { return 34; }
>>       short msecs() @property { return 567; }
>>
>>       auto split(string FIELDS)() @property {
>>          static struct Result {
>>             mixin(FIELDS.splitter(',').map!q{`typeof(D.`~stripLeft(a)~") "~a~";\n"}().join());
>>          }
>>          return mixin(`Result(`~FIELDS~`)`);
>>       }
>>    }
>>
>>    void main() {
>>       auto d = D();
>>       auto r = d.split!q{ days, seconds, msecs };
>>       import std.stdio;
>>       writeln(r, r.days, r.seconds, r.msecs);
>>    }
>>
>> No unnecessary declarations and redundancy.
> 
> auto r = d.split!("days", "seconds", "msecs")();
> writeln(r, r.days, r.seconds, r.msecs);

I'm not really sure what your point is.
I chose the DSL approach deliberately - specifically to avoid having to
work with individual names as separate strings. Both designs will work;
I prefer the simpler and terser one, that's all.

>> For cases where the target is already predeclared, a pseudo-destructuring
>> syntax can also be used:
>>
>>    template destr(A...) { void destr(S)(S s) @property { A = s.tupleof; } }
>>
>>    void main() {
>>       long days;
>>       int seconds;
>>       short msecs;
>>       auto d = D();
>>       destr!(days, seconds, msecs) = d.split!q{ days, seconds, msecs };
>>       import std.stdio;
>>       writeln(days, seconds, msecs);
>>    }
> 
> This requires odd machinery. Most people aren't used to writing code this way, and it would be difficult to explain. It's also not much different than the example above, and requires the compiler to inline a whole bunch of stuff in order to be efficient.

It only needs `destr` inlined. If `split` isn't inlined that should
only cause one extra copy (from RVO-struct-on-stack to final destination).

I don't really like this either, but it is equivalent to what the original
code did -- it's ugly because D does not have any built-in destructuring
syntax, but it's still better than the original -- because it avoids the
mutation-of-function-args issues. (yes, the address-of at call site is
better than the alternative (caller-invisible by-ref mutation), but it
is not good enough)
`res = call(...)` is always preferable to `call(..., &res)`; unlike in D, 
there were not many other choices available in C...

> Simple pointers to targets works very well. readf and getopt work this way, and are very effective.

I would not say "work very well". It's easy to mix them up, and the
compiler won't be able to catch the bug (when both pointers point
to the same basic type). Placing the outputs/side-effects among the
function args makes them more likely to be overlooked, especially
if the call happens in some conditionally taken path.
The compiler currently can not prevent escaping of the pointers,
so all callees have to be trusted.

> Respectfully disagree, the API looks very good to me. And decidedly not C-like.

No comment on the std.datetime API. I only responded because of the
it-is-idiomatic-D statement.

artur


More information about the Digitalmars-d mailing list