On 11/7/2014 5:41 PM, Manu via Digitalmars-d wrote:
On 3 November 2014 19:55, Walter Bright via Digitalmars-d
This isn't anything to do with what I'm talking about. I'm not nervous
because I don't like the D template syntax, it's because I don't feel
it's a good idea for druntime (specifically) to have non-static
interfaces which may expose, or create dependencies on druntime
internals.
My point with the C macro interfaces is it's not the "template" that makes an
API design non-static, it's the way the API is designed. Such a determination
can only be made on a case by case basis, not a blanket templates-are-bad.
The only library I would use as comparison is the CRT, which is firmly
self-contained, with a well defined API.
Hardly. It still uses macros, and it's still quite sensitive to various struct
declarations which are in the corresponding .h files. If you don't agree, take a
look in druntime at all the conditional compilation for the various CRTs which
presumably have the same API.
Check out fileno(), for example. Or errno. Or heck, just grep for #define in the
C .h files, or grep for "struct{".
That's fine. But how is that the case here? Performing a string
conversion implies direct access to the data being converted. If the
function is a template, then my app is directly accessing internal
druntime data.
It all depends on how you design it. Recall that what defines an Output Range is
the existence of put(r,e). There's no dependency on internals unless you
deliberately expose it.
I don't like being classified as 'the offense', in fact, I'm really,
really tired of unfairly being assigned this position whenever I try
and make a stand for things that matter to me and my kind.
Sorry, I thought you'd find the metaphor amusing. I didn't mean it to be
offensive (!). Oops, there I go again!
which is excellent, but replacing it with indirect function calls
isn't awesome. This takes one problem and replaces it with a different
problem with different characteristics.
I think this is a misunderstanding of output ranges.
I would like to see an overload like the C lib; API receives memory,
writes to it. This may not be the API that most people use, but I
think it should exist.
I then suggested that this API may be crafted in such a way that the
higher-level goals can also be expressed through it. It could be
wrapped in a little thing that may request a memory expansion if the
buffer supplied wasn't big enough:
struct OutputBuffer
{
char[] buffer;
bool function(size_t size) extendBuffer; // <- user-supplied
(indirect) function that may expand the buffer in some app-specific
way.
}
toString writes to 'buffer', if it's not big enough, ONLY THEN make an
indirect function call to get more memory. API is the similar to the
synk callback, but only used in the rare case of overflow.
We're reinventing Output Ranges again.
I don't know exactly, other people have much more elaborate needs than
myself. I'm just saying I don't like where this API is headed. It
doesn't satisfy my needs, and I'm super-tired of being vilified for
having that opinion!
Well, my opinion that sink should be replaced with output range isn't very
popular here either, join the club.
* toString should be capable of receiving a pre-allocated(/stack)
buffer and just write to it
* indirect function calls should only happen only in the rare case
of output buffer overflow, NOT in all cases
Again, this is reinventing output ranges. It's exactly the niche they serve.
I don't think that's what's on offer here. If toString is a template
(ie, receives an OutputRange, which is a user-defined type), how can
it be that the user's instantiation would already be present in
druntime?
If one uses an output range that is imported from druntime, which is quite
likely, then it is also quite likely that the instantiation with that type will
already be present in druntime.