Announcing Dryverl: an Erlang-to-C binding compiler

Romain Lenglet <>
Sat May 27 05:04:06 CEST 2006


David Hopwood wrote:
> I don't see the point of this extra layer. (Actually, I don't
> see the point of trying to encode programming language code in
> XML, ever.)

This is the first time I see someone advocating for macros for 
solving complex problems, instead of a domain-specific language 
(such as Dryverl).

Dryverl doesn't encode a programming language in XML. Part of it 
is pure declarative XML, and part of it adds markup (i.e. new 
syntactic constucts) to existing languages (C and Erlang) to 
hide complex implementation details. This is different.

So, in your opinion, any language extension (such as jTom, or 
even the parse_transform/2 Erlang mechanism!) is useless, 
because it could be done using a pre-processor. That is the very 
meaning of what you wrote. And I don't agree.


The Dryverl compiler generates code that is about ten times the 
length (in number of lines) of a binding specification. If you 
prefer writing ten times more code, it is up to you. But I don't 
prefer that.
If you had ever tried to write a C port driver to bind a complex 
C library, you would see the point of a language that is 
higher-level than bare C and Erlang, even using a pre-processor.


> > Is that really more readable? Is that "a better way?"
>
> No, but I would be strongly inclined to write it as
>
> #include "dryverl.h"
> ...
>
> CCV(major_status) = gss_acquire_cred(
>                         &CCV(minor_status),
>                         CCV(desired_name),
>                         CCV(time_req),
>                         CCV(desired_mechs),
>                         CCV(cred_usage),
>                         &CCV(output_cred_handle),
>                         &CCV(actual_mechs),
>                         &CCV(time_rec));
>
> if (GSS_CALLING_ERROR(CCV(major_status))) {
>    
> dryverl_failure_atom(GSS_CALLING_ERROR_TO_STRING(CCV(major_sta
>tus))); }
>
> which is certainly more readable than either of the versions
> above -- and can be expanded to much the same thing just by
> running it through the C preprocessor.

Surely, macros work for this very simple *fragment of 
specification*.
This example above was *a simple example of a specification 
fragment to compare representations in both XML and Erlang 
terms*. It is clearly not representative of the complexity of a 
C port driver implementation.

You would also have to find another mechanism to generate the 
driver's init and stop functions, to generate automatically 
switch()es for the driver's port_output and call functions to 
dispatch calls, find a way to generate unique command 
identifiers and make them consistent between the generated C 
code and the generated Erlang code, find a way to hide the 
differences in implementation details between calls made through 
port_call/2 and port_command/2 to the same C code, hide the 
details when the output term is returned as a port_call/2's 
return value or using the emulator's driver_output function, as 
determined at runtime (all that *without having to modify or 
duplicate your binding code / specification*!!!), etc. etc.
I wish good luck to you and your pre-processor.
And I am convinced that your specifications would be much less 
readable than using Dryverl.

Another example: currently Dryverl generates the source code of 
two Erlang modules and two C files (one .h and one .c), for 
every set of bindings (i.e. from one spec. file). What you 
propose is to write and maintain those four files separately, 
and prey for them to be consistent (e.g. have consistent command 
identifiers).
Or please can you point me to a smart *C pre-processor* that 
allows to specify both Erlang and C code in a single file?

In EDTK and Dryverl, everything is specified in a single 
specification. What needs to be consistent is generated 
automatically. All the boring and error-prone code (unlike the 
trivial example above) is generated automatically, and is *not 
written by developers*. That is the whole point of defining a 
new language and a compiler.

So, *yes*, for the XML elements in the trivial *fragment* above, 
XML is overkill. But please take a look at Dryverl and at the C 
port driver APIs, and you would see that there is much more to C 
port driver development than this simple fragment.


> I would also try to get rid of the need for CCV() if at all
> possible (maybe by telling Dryverl any information it needs
> about a variable only at its declaration, rather than every
> use).

In Dryverl, I have defined new markup elements only when 
necessary, to hide implementation details.
What you don't understand from the above example taken out of 
context, is that call variables must be passed between the input 
decoding step, the body execution step and the output encoding 
step in a call. So they must be declared in a struct (they are 
*not* local variables!), of which an instance is allocated and 
is passed between the several C functions that implement the 
several steps in every binding. If the call is asynchronous, 
those functions must not call themselves directly, but instead 
through the emulator's dryver_async function.

So, once again, *yes* for this very trivial specification 
*fragment* above, XML and a new layer is overkill, but *not* for 
the code that is generated all around this code.



I am currently writing a tutorial and a simple example. It will 
make this discussion more concrete.

-- 
Romain LENGLET



More information about the erlang-questions mailing list