June 05, 2014 Re: (git HEAD) std.datetime spewing deprecation messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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@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 | |||
June 06, 2014 Re: (git HEAD) std.datetime spewing deprecation messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brad Anderson | On Thu, 05 Jun 2014 18:42:29 -0400, Brad Anderson <eco@gnuk.net> wrote:
> On Thursday, 5 June 2014 at 22:06:02 UTC, monarch_dodra wrote:
>> On Thursday, 5 June 2014 at 08:49:18 UTC, Jonathan M Davis via Digitalmars-d
>>> long days;
>>> int seconds;
>>> short msecs;
>>> d.split!("days", "seconds", "msecs")(&days, &seconds, &msecs);
>>
>> Please don't use pass-by-pointer in D APIs. It makes it a real *nightmare* to ever use the code in a safe context. Besides, we have ref. The only arguments "for" pass by pointer afaik are:
>> - retain existing/C api (1)
>> - allow null pointers (2)
>>
>> (1) is not applicable, I think.
>> (2) would only make sense if split did not have a template parameter, and took "all" arguments, and only filled the non-null ones.
>>
>> So, please make these pass by ref.
>
> Even better than ref would be out which guarantees that the input parameter values do not affect the function.
I think that would be 'out'
-Steve
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply