The CAPI Manifesto

Christophe Travert travert at phare.normalesup.org
Fri Oct 28 01:13:10 PDT 2011


Walter Bright , dans le message (digitalmars.D:146786), a écrit :
> If you want to add a layer on top of the C API, that would be fine. std.zlib is 
> an example of that.
> 
> But the idea of CAPI is NOT to add a layer. Not fix, extend, refactor, improve, etc.

I definitely agree with that, no attempt should be made to fix anything.

However, if you want only direct translation, the only way I see is to 
treat all defines as mixins. That mean all macro will become very 
tedious to use. Even there, there are choices to make (how do you 
translate multi-parameter macros ?). So I think a minimum of adaptation 
should be provided.

Here is an example of how this could be made:

#define square(x) ((x)*(x))

=>

// direct translation
mixin template!(string x)square
{
    enum square = '((' ~ x ~ ')*(' ~ x ~ '))';
}

// adapted version
T square(T)(T x) { return x*x; }


Which version should be added ?
Both do not do the same thing ! As you know, In the first one, if x is a 
function call, it is called twice, and it the other one, it is called 
only once.
So if I follow the rule: no fix, no extend, etc, I must include only the 
direct translation. But the CAPI library will not be as usable as the c 
one. Then I miss the purpose of CAPI: make d as usable as c when using 
c libraries.

So which version should be added: I think it is both:

// direct translation
mixin template!(string x)M_square
{
    enum M_square = '((' ~ x ~ ')*(' ~ x ~ '))';
}

// adapted version
T square(T)(T x) { return mixin M_square!q{x}; }


So this is what I propose:
Direct translation have to be provided. Adapted version can be provided 
alongside the direct translation of the d header. Adaptaded version must 
be a direct forward call to the direct version (note here that the 
adapted. Rules will have to be defined to avoid name clashes (for 
example, here, I used a the direct name for the usable version, and M_ 
prefix for the mixin version, but we could decide other rules).


Macros are a big issue.

And I think abvious translating, such as const char* to string, or 
pointer-length pairs to dynamic arrays is about the same problem.


double array_sum(double* a, size_t length);

=>
double array_sum(double* a, size_t length);
// AND
double array_sum(double[] a) { return array_sum(a.ptr, a.length); }


That is very little work. The direct translation is mandatory, and the 
adapted translation is not. But when the translation is obvious, there 
is no reason for everyone to make it on it's corner. Make it in the 
public header and share it!

I order to remain consistent, adaptation will have to obey to very 
precise rules, that have to be set. No fix, no extend, no refactor, no 
improve, etc. Just a forward call, to have, in addition to the C API, 
an API that use D's power: using enums, inline functions, for defines 
instead of the direct mixin translation. Using D's arrays instead of C 
arrays, etc. could be nice too.

What translation should be provided ? What rules to translate defines ? 
Is translation of pointer+length pair to array worth doing ? What about 
stringz and strings ? Where to draw the line ?


-- 
Christophe



More information about the Digitalmars-d mailing list