[LV2] Thoughts on a clearer atom forge API

David Robillard d at drobilla.net
Sun Jan 12 20:12:54 PST 2014


On Mon, 2014-01-13 at 02:49 +0000, Kaspar Emanuel wrote:
> On 12 January 2014 23:25, David Robillard <d at drobilla.net> wrote:
> > []
> >     a my:Message ;
> >     rdfs:label "A wild message appears!" ;
> >     my:intensity 9000 .
> >
> > this would get you something like:
> >
> > frame = forge.object(uris.my_Message);
> > frame.key(uris.rdfs_label);
> > frame.string("A wild message appears!");
> > frame.key(uris.my_intensity)
> > frame.value(9000)
> > frame.end();
> >
> 
> This looks quite nice (or am I just getting used to the terminology?).
> Would you really need the end() ? Then end is implied when you send
> no?

The end pops the frame.  If you have several nested frames, you need to
indicate when a child one is finished, e.g.

frame = forge.start_object(uris.my_Message);
frame.key(uris.my_list);
subframe = forge.start_list();
subframe.int(1);
subframe.int(2);
subframe.end();
frame.key(uris.my_intensity);
frame.value(9000);
frame.end();

Chaining seems to kind of fall apart for nesting, unfortunately.

> I suppose you are proposing this as C++ only. What could be done to
> make the C API more beginner friendly?

Not much that I can think of.  Things that would help something:

 * Returning a frame
 * property_head -> key
 * uniform use of start_* for things that start containers
 * "blank" and "resource" terminology with a single "object"

That last one has hairy ID implications, though, unless we just drop
blank IDs entirely and let 0 = blank (i.e. no URI).

> Following on from the Protobuf discussions we had in the other thread:
> my ideal at the moment would be if I could define my message in ttl
> with something like:
> 
> <my:Message>
>     a patch:Message ;
>     rdf:property [
>         a xsd:String;
>         lv2:name "label"
>         xsd:maxLength 256
>     ] , [
>         a xsd:Integer;
>         lv2:name "intensity"
>         lv2:maximum 9001
>         lv2:minum 0
>     ] ;

Note properties are keyed by URIs, not strings like "label".  That
aside:

While I think such a tool would be cool, honestly I don't think this
would help the situation much (socially).  The overwhelming majority of
plugin developers just want to write some C or C++ and get on with their
day.  Many of them want as little to do with Turtle as possible.

More fundamentally, it is inherently restricted to static objects with a
fixed number of properties.

As an alternative API and auxiliary tool it would be nice, but I think a
good universal atom API is required regardless.  Since LV2 itself
currently does not depend on any syntax libraries, it would have to be
developed elsewhere, for now.

> #include "MyMessage.h"
> MyMessage* msg = MyMessage_get();
> msg->label = "A wild message appears!";
> msg->intensity = 9000;

The problem here is... how does such a thing get sent?  How does the
code know the URIDs for label and intensity?  It would need to emit code
that needs to be initialized with the URI map.  Possible, but yes, a lot
of work, and quite a bit more generated code than just structure
definitions (some say that generated code is a code smell...).  The
effort:payoff ratio here doesn't seem very good, and honestly I'd be
surprised if anyone used it.  It's even more complex than current stuff,
though I guess it might get you out of having to map those URIs
yourself, assuming you don't need them elsewhere.

Honestly, unfortunately the more RDFey it seems the less popular it is.
People fear/hate what they do not understand.  I'm more shooting for
atoms to seem JSON-like: Dictionaries, lists, and some simple
primitives.  Nobody complains about JSON being cryptic and hard to
understand, because it isn't.  Neither are LV2 atoms, but the current
documentation/API/something is failing to give that impression...

Anyway, code generation from ttl is another option, though I'm afraid I
don't personally have the time to commit to implementing that.  Thanks
for the feedback,

-- 
dr





More information about the Devel mailing list