Sat Dec 8 12:52:33 EST 2012

Tagged list tricks

Use callbacks instead of lists:

typedef void (*zl_zwindow_parsed_event_fn)(void *context, int nb_args, ...);
void zl_xwindow_for_parsed_events(zl_xwindow *xwin, zl_zwindow_event_fn handle, void *context);

Use const char to "simulate" interned symbols (hashed strings) for
tags known at compile time, without actually having to implement
dynamic symbol hashing.

Abstracting lists of tags (i.e. a "type definition") in a macro can
help here:

#define ZL_DISPLAY_EV_LIST(EV)           \
    EV(keypress)                         \
    EV(keyrelease)                       \
    EV(keyrelease)                       \

/* Declaration */
#define ZL_DISPLAY_EV_DECL(name) extern const char *ZL_DISPLAY_EV_#name;

/* Implementation */
#define ZL_DISPLAY_EV_IMPL(name) const char *zl_display_ev_#name ##name;

Some more info:


To bridge 2 programming systems, the real hurdle is in
impedance-matching the data types and memory model.

In ZL this is done by keeping a very simple basic data type: C
variable argument lists where tags are reprented using

typedef const char *zl_tag;

A. List representation

There are essentially 2 kinds of list in C that are easy to use inside
the language:

- Static data initializers.  This requires a union (optionally tagged)
  so has some syntactic overhead.  Works for global and local

- Variable argument lists.  This is a feature supported by the C
  standard and is very convenient to use as there is no notational

Often converted data is short-lived, allowing data conversion to be
implemented with nested C calls.  Both are able to side-step malloc()
when they are combined with some kind of callback mechanism.

B. List tagging

Using const char * as a tag type allows 2 things to be married in a
very elegant way:

- Pointer-based comparison in C without memory allocation overhead
  (all string memory allocation is static).

- Easy conversion to run-time interned symbols (hashed strings) for
  dynamic languages.