Plans for the Future
====================

This is just a simple bullet list of things that are on my (long term) TODO
list. Comments are welcome, as usual.

* Check whether it makes sense to let users specify the communication
  (request) type. This is currently baked-in to be inferred from the
  variable's type as specified in the program text. 
  Another twist would be to allow to use the native type and convert
  on the seq side. The question is if this
  brings any actual benefit, considering that sequencer and database
  typically run on the same IOC. It might be convenient, sometimes.

* Add optional timeout argument for pvGet and pvPut to override the
  hard-coded default of 10 seconds.

* pvGetComplete should support additional arguments for arrays of multiple
  PVs, just like pvPutComplete.

* It would be nice to be able to use foreign types in SNL declarations.
  However, supporting typedefs exactly as in C is problematic:
  at the place where an identifier is *used*, the context-free grammar cannot
  decide whether it is a type or a variable. So we would need to assign
  different tokens to typedefs and other identifiers. And the
  lexer would have to look up the identifier in the symbol table to see
  what kind of token to produce. Effectively, we need to feed information
  from the parser back into the lexer. This is all horrible and error
  prone. Instead, I am flirting
  with the idea to borrow C++'s typename keyword, so one could write e.g. ::

    %%#include <stdio.h>
    typename FILE *f;

  in SNL code. The "typename" would of course not be included in the
  generated C code.

  We could also allow to use named struct, union, or enum types, e.g. ::

    struct epicsTimeStamp ts = pvTimestamp(var);

  In all these cases, the keyword (typename, struct, union, enum)
  cleanly disambiguates the grammar, so we can keep lexing and parsing
  as separate stages.

* Raw ideas:

  - Allow parameterized state sets (like a function). Then allow to "jump"
    from one state set to another one. The "caller" i.e. the original state
    set must wait for the "callee" to finish. The idea here is to avoid
    dynamic creation of threads, as this could be implemented as a simple
    procedure call. Needs more thought.

  - Better support for enumerations i.e. PVs with native request type DBR_ENUM.
    The idea is that the programmer can use identifiers to name the choices,
    but does not have to know in advance which integer value corresponds
    to which choice.

    Maybe something very simple suffices, like a built-in function ::

      int pvChoice(var, char *choice_name);

    This requires support for DBR_GR_ENUM in the pv layer (so realistically
    has to wait until the pv layer is demolished).

  - Invent a new syntax for pv "assign". My current favourite::

      pv int x = 0;                   /* single anonymous scalar pv */
      pv "name" int x;                /* single named scalar pv */
      pv int x[2] = {1,2};            /* single anonymous array[2] pv */
      pv "name" int x[2] = {1,2};     /* single named array[2] pv */
      pv {} int x[2];                 /* multiple(2) anonymous scalar pvs */
      pv {"n1", "n2"} int x[2];       /* multiple(2) named scalar pvs */
      pv {} int x[2][100];            /* multiple(2) anonymous array[100] pvs */
      pv {"n1", "n2"} int x[2][100];  /* multiple(2) named array[100] pvs */

  - Go even further and invent a syntax for assign, monitor, sync, etc.
    The idea is to provide an alternative to the usual macros. Every
    SNL programmer uses her own self-made macros to simplify declaration blocks
    like ::

      int x;
      assign x to "bla";
      monitor x;
      sync x to ef_x;

    The challenge here is to come up with something that is light-weight,
    can be easily specialized, and seamlessly fits into the existing syntax.

* Convert everything under test to use epicsUnitTest. Add more regression tests.

* Clarify the situation of a pvPut/pvGet to array variable that
  has been connected to separate PVs. Currently this puts/gets the first element,
  but wouldn't it be nice if it meant to put/get all (connected) elements?
  Write to tech-talk and ask (since it breaks compatibility)?

* Not sure what to do with devSequencer. It is ugly, accesses sequencer
  internals, and does not work if programs are instantiated more than once.

* Need to go over the introductory chapters in the docs, remove out-dated
  information.

* Götz suggested to allow the monitor clause inside a state set, even if the
  variable is global. This would mean automatic variable updates affect only
  those state sets which contain the monitor clause, while others do not get
  updates. Can combine this with state set local event flags and sync clauses.

  This could be useful in situations where one state set writes to the variable
  and others only read. The writer would no need the monitor, thus would see
  his local copy in a consistent way.

  Implementation: need to have monitor flags for each state set; must also
  change interface to snc (monitored becomes a bitmask with numSS bits).
