Topic: Nameless modules and importless imports


Author: "Ivan G." <nekotekina@gmail.com>
Date: Wed, 26 Sep 2018 07:56:54 -0700 (PDT)
Raw View
------=_Part_143_1685643132.1537973814982
Content-Type: multipart/alternative;
 boundary="----=_Part_144_201997619.1537973814982"

------=_Part_144_201997619.1537973814982
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hello, I thought about modules recently and some other problems which=20
bother me.Nameless (Anonymous) Modules Introduction=20

I want to start with asking an extremely na=C3=AFve question. Why, in order=
 to=20
use some standard library classes or functions, should I ever bother with #=
include=20
<...> of the corresponding standard header?

In existing header inclusion model, including is extremely costly for=20
obvious reason, so it definitely makes sense to include only necessary=20
things for performance reasons.

Modules aim to radically optimize the cost of includes by importing only=20
explicitly exported names instead. This is well described and sounds good.=
=20
And may also be able to answer the original question: just import std; and=
=20
use most standard components (if it's allowed).

I want to point to some problems with current Modules TS, in arbitrary=20
order:

   - Naming a module requires a programmer to perform a double work of=20
   naming modules in additional to naming the file containing the module. T=
his=20
   seems small, but it violates DRY (Don't Repeat Yourself) principle. It c=
an=20
   be a source of various problems.=20
   - Either importing or including, in general, requires a programmer to=20
   type the header or module, usually at the beginning of the source file.=
=20
   This is, in the best case, a distracting, annoying, repetitive work.=20
   - New keywords *import* and *module* will break outrageous amount of=20
   existing code. Changing the keywords is possible, but it will make thing=
s=20
   ugly. On the other hand, *export* keyword is already reserved and thus=
=20
   doesn't have this problem.=20

Maybe something useful can be implemented with only *export* keyword?
Brief proposal=20
  =20
   1. All C++ identifiers (namespaces, aliases, classes, functions, global=
=20
   variables, any templates, etc) marked with *export* keyword are=20
   automatically *visible in all translation units*. All exported names=20
   imply external linkage and don't allow internal linkage. Preprocessor=20
   defines cannot be exported. Exporting a namespace implies exporting all=
=20
   names in corresponding {} clause. Exporting an anonymous namespace does =
the=20
   same, and the linkage becomes external.=20
   2. Most standard components are exported by default. But not all of=20
   them, like assert macro still shall require #include <cassert>.=20
   3. Exporting a name creates an *anonymous module interface* for this=20
   very name. Each exported name essentially becomes at least a one anonymo=
us=20
   module.=20
   4. Optionally, specify another keyword to separate parts of the exported=
=20
   declaration from the interface. Or abuse *extern* keyword for this=20
   purpose. For example, if we don't want some inline class methods to beco=
me=20
   part of the interface, we declare them extern and they are excluded, but=
=20
   still can be implemented inline without separation. This can also be use=
ful=20
   to break circular dependencies.=20

Simplified process of code transition for existing projects:

   - Optionally, do nothing, and everything should still work as is.=20


   1. Marking all exported names with *export* keyword.=20
   2. Adding all header files (or all files which contain exports) to the=
=20
   build system as translation units. Optionally, hint the build system abo=
ut=20
   files which don't export, to optimize building the cache of exported nam=
es.=20
   3. Remove most #includes from all headers and translation units.=20

Motivation=20

Current Modules TS requires, in order to work, parse all files in the=20
project, extract all module names and map them internally. I will assume=20
this is supposed to be done automatically, because doing this manually=20
sounds horrible. This is also the object of criticism, for example:=20
https://izzys.casa/posts/millennials-are-killing-the-modules-ts.html

The idea is rather simple. If we need to parse all files to extract module=
=20
names, why not extract all the exported names instead? The count of them=20
matters? I don't think so. It's not the amount of names which makes current=
=20
header inclusion model slow. A lot can be cached and optimized.

=3D=3D=3D=3D=3D
Latest version can be found here:=20
https://gist.github.com/Nekotekina/26aaa605ad4be1c0ba169b705c2b9806
I would be glad to hear comments.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/05940a35-4a42-41f8-b0ad-8757b984dceb%40isocpp.or=
g.

------=_Part_144_201997619.1537973814982
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hello, I thought about modules recently and some othe=
r problems which bother me.<h1>Nameless (Anonymous) Modules</h1>
<h2>Introduction</h2>
<p>I want to start with asking an extremely na=C3=AFve question. Why, in=20
order to use some standard library classes or functions, should I ever=20
bother with <code>#include &lt;...&gt;</code> of the corresponding standard=
 header?</p>
<p>In existing header inclusion model, including is extremely costly for
 obvious reason, so it definitely makes sense to include only necessary=20
things for performance reasons.</p>
<p>Modules aim to radically optimize the cost of includes by importing=20
only explicitly exported names instead. This is well described and=20
sounds good. And may also be able to answer the original question: just <co=
de>import std;</code> and use most standard components (if it&#39;s allowed=
).</p>
<p>I want to point to some problems with current Modules TS, in arbitrary o=
rder:</p>
<ul>
<li>Naming a module requires a programmer to perform a double work of=20
naming modules in additional to naming the file containing the module.=20
This seems small, but it violates DRY (Don&#39;t Repeat Yourself) principle=
..
 It can be a source of various problems.</li>
<li>Either importing or including, in general, requires a programmer to=20
type the header or module, usually at the beginning of the source file.=20
This is, in the best case, a distracting, annoying, repetitive work.</li>
<li>New keywords <strong>import</strong> and <strong>module</strong>=20
will break outrageous amount of existing code. Changing the keywords is=20
possible, but it will make things ugly. On the other hand, <strong>export</=
strong> keyword is already reserved and thus doesn&#39;t have this problem.=
</li>
</ul>
<p>Maybe something useful can be implemented with only <strong>export</stro=
ng> keyword?</p>
<h2>Brief proposal</h2>
<ol>
<li>All C++ identifiers (namespaces, aliases, classes, functions, global va=
riables, any templates, etc) marked with <strong>export</strong> keyword ar=
e automatically <strong>visible in all translation units</strong>.
 All exported names imply external linkage and don&#39;t allow internal=20
linkage. Preprocessor defines cannot be exported. Exporting a namespace=20
implies exporting all names in corresponding {} clause. Exporting an=20
anonymous namespace does the same, and the linkage becomes external.</li>
<li>Most standard components are exported by default. But not all of them, =
like <code>assert</code> macro still shall require <code>#include &lt;casse=
rt&gt;</code>.</li>
<li>Exporting a name creates an <em>anonymous module interface</em> for thi=
s very name. Each exported name essentially becomes at least a one anonymou=
s module.</li>
<li>Optionally, specify another keyword to separate parts of the exported d=
eclaration from the interface. Or abuse <em>extern</em>
 keyword for this purpose. For example, if we don&#39;t want some inline=20
class methods to become part of the interface, we declare them extern=20
and they are excluded, but still can be implemented inline without=20
separation. This can also be useful to break circular dependencies.</li>
</ol>
<p>Simplified process of code transition for existing projects:</p>
<ul>
<li>Optionally, do nothing, and everything should still work as is.</li>
</ul>
<ol>
<li>Marking all exported names with <strong>export</strong> keyword.</li>
<li>Adding all header files (or all files which contain exports) to the=20
build system as translation units. Optionally, hint the build system=20
about files which don&#39;t export, to optimize building the cache of=20
exported names.</li>
<li>Remove most #includes from all headers and translation units.</li>
</ol>
<h2>Motivation</h2>
<p>Current Modules TS requires, in order to work, parse all files in the
 project, extract all module names and map them internally. I will=20
assume this is supposed to be done automatically, because doing this=20
manually sounds horrible. This is also the object of criticism, for=20
example: <a href=3D"https://izzys.casa/posts/millennials-are-killing-the-mo=
dules-ts.html" rel=3D"nofollow">https://izzys.casa/posts/millennials-are-ki=
lling-the-modules-ts.html</a></p>
<p>The idea is rather simple. If we need to parse all files to extract=20
module names, why not extract all the exported names instead? The count=20
of them matters? I don&#39;t think so. It&#39;s not the amount of names whi=
ch=20
makes current header inclusion model slow. A lot can be cached and=20
optimized.</p></div><div><br></div><div>=3D=3D=3D=3D=3D</div><div>Latest ve=
rsion can be found here: https://gist.github.com/Nekotekina/26aaa605ad4be1c=
0ba169b705c2b9806</div><div>I would be glad to hear comments.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/05940a35-4a42-41f8-b0ad-8757b984dceb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/05940a35-4a42-41f8-b0ad-8757b984dceb=
%40isocpp.org</a>.<br />

------=_Part_144_201997619.1537973814982--

------=_Part_143_1685643132.1537973814982--

.