[M3devel] generics w/o explicit instantiation in build system?

Rodney M. Bates rodney_bates at lcwb.coop
Sun Sep 30 22:48:45 CEST 2012



On 09/27/2012 09:49 PM, Jay K wrote:
> Given GENERIC INTERFACE Vector(T);
>
>
> I'd like to say:
>
>
> TYPE Foo = REF RECORD ... END;
>
>
> VAR foo := NEW(Sequence(Foo));
>
>
> without messing around with any Quake code.
>
>
> Is this really so much to ask?
>
>
> Today instead I have to either mess around with Quake,
> or store REFANY and constantly NARROW them.
> Like storing a void* in a container, but safer and slower.
>

No, you are not limited to these two.  You can use generics
and instantiate without quake code.  See 2.5.5 for how.  The
one disadvantage to this is it requires a very small separate
compilation source file for every instantiation.  This is the
one and only way the language defines.

The Quake way is purely extra-linguistic and part of the
implementation only.  I am guessing the implementors thought
it would simplify things to be able to have instantiations
be one-liners and all in the same file, rather than each
one a separate file with maybe 3 lines or so. The Quake way
is defined and implemented by a translation into pure Modula-3
code.  You can do it either way.

Limiting generics and instantiations to be whole compilation
units is one of the ways Modula-3 drastically simplifies the
language, at the cost of minor annoyance.  Both C++ and Ada
amply demonstrate how it takes many pages to define the semantics
of generics and instantiations that are non-compilation-unit
and any of several kinds (functions. classes, etc.)  Modula-3's
are at least an order of magnitude simpler, and more powerful,
if not as syntactically sweet.

As for anonymous instantiations, I think they are just appalling.
Just take a look at what happens when somebody needs to compose
more than one generic abstraction (as you have been advocating
in STL).  Not only are the nested instantiations very hard to
read, but they have to be repeated over and over and over.

Moreover, the implementation is much more difficult, and calls for
far worse name mangling, which just makes your oft-stated goal
of a reasonable debugger experience using a debugger that is
not aware of your source language all the more difficult.

Would you advocate requiring every type definition be anonymous
and have to be repeated everywhere you need to use it, with
the language not allowing giving it a name in a type declaration
and then just using the name in all those places?

>
> C++, Java, and C# all provide about the same thing here.
>
>
>  From a language point of view, I think this is easy.
> The only complication is what name to give the thing internally.
> There are a few obvious choice:
>   Prepend/append the current module/interface.
>   This is easiest. But might lead to some bloat.
>
>   Prepend/append a hash. Or maybe nothing.
>   This provides for single instancing,
>   It either requires builder or linker cooperation.
>
>   Mark the code as "file level static" using whatever mechanism C does.
>   This is presumably easy and might lead to some bloat.
>   Given a 64bit Sequence(INTEGER), Sequence(LONGINT),
>   the Microsoft linker will automatically combine any resulting
>   code -- when optimization, it combines duplicate
>   code that is "the same" but has different names.
>   Note that it is easy to inhibit, e.g.:
>   int F1() { static int i; return ++i; }
>   int F2() { static int i; return ++i; }
>   are NOT the same, because they must reference different "i".
>   Thoughts?
>   - Jay
>




More information about the M3devel mailing list