Announcing Dryverl: an Erlang-to-C binding compiler
Romain Lenglet
rlenglet@REDACTED
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