Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [asciidoc-lang-dev] Avoiding Implementation Specifics Thoughts

I think from Dan and Davids replies I have not been clear in what I am proposing regarding extensions, let me try again.

TL;DR version, I'm proposing that the specification define the what, where and _how_ of extensions.

First the part we agree on, that "where" extensions are allowed in documents and "what" can be extended needs to be specified.

For "how" it seems to me a purely textual "macro" capability would address many use-cases and could easily be specified to be portable (the word "macro" is far too overloaded in computer programming and even in Asciidoc usage, I mean preprocessor macros like C).  As the originator of Asciidoc has noted in the past, this was not included in Asciidoc because its original environment was Unix where many such capabilities are available off the shelf as preprocessors for the Asciidoc input.  As a purely substitution capability it needs only to be similar to "multiline document attributes with parameters" substituted in the preprocessor, so easy to specify and easy to implement.

To explain my suggestion for the more complex and more interesting "how" requiring programming language capability, let me use the example of another project I'm involved in, the Geany IDE.  It is written in C and can have plugins in C, C++, Python, Lua and Ruby on the way.  Clearly the mechanisms of these are different, C/C++ plugins load DLLs and call C functions directly and Geany calls their exported functions directly, but Python, Lua and Ruby load plugins as source in those languages and there is a (fairly thick, partly automatically generated) shim that wraps Geany structures to/from the target language structures, and maps function calls from/to C and those languages.  But irrespective of the language mechanism, the API presented is the same, a C plugin has the same capabilities as a Ruby one.  Only the startup and loading mechanisms differ.  If there were more than one implementation of Geany in another language, so long as it presented the same API, it would allow it to be able to use plugins from the C implementation and vice versa.

For Asciidoc what I'm concerned with is not the mechanism, that is solvable, indeed solved, as shown in the Geany example.  What I am proposing is that an API to the DOM and to extension points, be specified using sufficiently common features so that plugins _are_ largely portable.  Whilst the loading and initialisation mechanisms may need to be implementation and language specific, being able to reuse the main body of the extension code would help prevent them being captive to one implementation and help grow the overall Asciidoc ecosystem through sharing.

So what I'm proposing is that the API be common and be specified in a form that is compatible with as many static, ahead of time compiled languages, dynamic interpreted languages, procedural, object oriented, and functional languages as reasonable.  That means being careful what features are used in the API.

Lack of object oriented features in procedural languages can make OO APIs difficult for those languages, similarly, dynamic languages can allow typing to be specified more loosely and make it difficult to interface to static typed languages.  Or multiple dispatch features can leave single dispatch object oriented languages floundering in the visitor pattern and other artifaces to simulate multiple dispatch.  Or dynamic languages allow redefinition of functionality (monkey patching I think its called in the Ruby community), but again that is not available to ahead of time compiled languages.  So the key is to use acceptably lowest common denominator features.

It would be best to specify the API in a human readable but still formal enough language to be machine readable.  So one of the formal procedure call IDLs.

Although I mentioned Corba IDL as a possible definition language, Wikipedia notes that it is object oriented and therefore difficult to use in C which has no object oriented capabilities, but in reality it is the features that the API uses that are key.  But the decision may be that procedural interfaces are too low and higher level features, say OO capabilities, should be the minimum, leaving purely procedural languages with a difficult (but not impossible) API.

But it is nowhere near the first thing to do in the specification, even the what and where and macro how come before the coding how, so no need to decide now.  Just keep the idea ticking over in the background and don't do anything that precludes it.  The point of raising it is so it is recorded and I won't forget it.


Back to the top