leafo/moonscript

Multiple import with name prefix and/or suffix to avoid name clashes

bpj opened this issue · 2 comments

bpj commented

Currently import doesn't allow you to modify the names
of imports, which means you can't use import if there
is a risk for name clashes. With the Lua standard libs
this happens with pack and unpack from both string
and table (which is not so serious since the string.[un]pack are little used), and with math.type vs. type vs. moon.type (which IMO is serious) and it can't be foreseen where this might happen with non-standard libs.

While import foo as bar from baz as proposed in #413 would help
it would not allow multiple renamed imports in one
statement. It would be better to (also) support adding a
prefix and/or suffix to imported names.
I'm thinking of three possible syntaxes for this (in order
from most to least preferred):

  1. Named parameters, where you in practice would hardly
    ever use both parameters, but you could conceivably add
    further parameters in the future like pattern: '^is_'
    to only import names which match a pattern which could
    be useful with some libs.

    import foo, bar from baz with prefix: 'b_', suffix:
    '_az'
  2. as with a "glob template" where * is replaced with
    the original name. This may obviously be preferred in
    order not to overload the with keyword, but isn't very
    self explaining

    import foo, bar from baz as b_*

    Alternatively you could use a string.format format
    with %s for the original name, but what happens if
    someone uses %d instead? Not a very good idea to use
    something which looks like it could be replaced with
    something else but couldn't.

  3. Dedicated with[_]prefix and with[_]suffix keywords,
    both a lot to type and not extensible...

    import foo, bar from baz withprefix 'b_' withsuffix
    '_az'

I think this could be implemented cleanly enough in Lua. The
compiler would need to construct the list of modified names
on LHS against the original names on RHS but I don't think
it would be too complicated, as you could use simple loops
over some arrays to construct the import (prefix .. name .. suffix or gsub(template, "%*", name)) and export (lib .. '.' .. name) names, then concat the results into
comma-separated lists and insert them into the lua code with
a local in front and an = in between so presumably only
one additional step over what is done now.

(Apologies if this is a duplicate. I did search the
existing issues for relevant keywords but there seemed not
to be anything similar.)

A workaround could be destructuring assignment:

{ foo: bar } = baz

which compiles to:

local bar
bar = baz.foo

About your issue, I'm not really sure if with should have a second meaning in the language other than chaining stuff.

bpj commented