Sunday, May 23, 2010

Re-thinking imports

Global Script has a short import syntax that looks like this:

  import m.f; -- > 'f = m.f;
  import type m.t -- > type 't = m.t;
  import module m.n -- > module 'n = module m.n;
I quite like this syntax; it has the nice bonus that, if you do need a string of imports, by formatting them this way:

   import xml.parser.attribute;
   import xml.parser.cdata;
   import xml.parser.element;
you can alphabetize the import list by piping the entire code segment by M-2 on |sort. As an added bonus, this respects module names as well. This is fairly straight-forward to parse: take a name after the import keyword, check that it has multiple components, split it into a module name and a field name on the final component division, check that the field name is a valid function name, and store the module name and function name separately. This syntax really only doesn't work for two cases:
  • Importing everything from a module, and
  • Importing a qualified name from a module.
For the second case, we can just say the programmer can suck it up and write:

  'n.f = m.n.f;
For the first case, we can use the fact that spaces are never legal in identifiers to permit a syntax like:

  import m ..;


  1. The problem is that if we see


    that might be followed by either a name or a module name. A better syntax would be

    import <name> (from <module name>)?;


    import m.f;

    is a more-convenient short-hand for

    import f from m;

    This solves the import-everything problem by allowing substitution of .. for f:

    import .. from m;

    We solve the import-multiples problem by allowing a comma-terminated list to be substitued for f:

    import f, g, h, from m;

  2. Strip the from keyword. Keywords are bad.

    import f, g, h m;

    The break in the commafication indicates that the next thing is a module to import. Or, better,

    import (f, g, h,) m;

    or just

    import f m;

    This lets us use standard ACNE sequences.