Topic: new module concept


Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 12 Dec 2002 21:32:05 +0000 (UTC)
Raw View
Ken Hagan wrote:
> So if your module uses a std::string in the interface,
> does a client using your module see the full declaration
> of std::string, a forward declaration or no declaration
> at all?

No declaration at all.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 12 Dec 2002 23:29:31 +0000 (UTC)
Raw View
MJ wrote:
> I would like to see a more concrete description of how you would
> realize modules in C++. Could you give an example?

Oh, I don't know that! If I did, my propsal would already
be out there. There will be all sorts of complicating
issues, such as namespaces and templates.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 12 Dec 2002 23:30:28 +0000 (UTC)
Raw View
nagle@animats.com (John Nagle) wrote
>     One of the biggest maintenance and build problems in C++
> comes from the fact that private parts of classes are visible
> in the include files needed by their users.  The effects of
> this are well-known - any change to the private part of a
> class declaration s forces recompilation of all its users.
> This warps program design; programmers tend to grow existing
> private member functions rather than adding new ones, and
> wrapper classes are created to get around the problem.

Such as the pImpl technique.

Note that private members aren't the only thing that causes this.
Change the definition of an inline member, and you have the same
problem.

> And, of course, it causes unneeded recompiles.

>      One first step worth considering is allowing the
> addition of private member functions to a class
> without declaring them in the class declaration.
> They'd only be visible within the current compilation
> unit.

One problem with this technique is that it's far too easy to break
encapsulation.

    #include "foo.h"
    // Need access to private member bar:
    int&Foo::AccessBar() { return bar; }
    void Baz(Foo &f) {
        f.AccessBar()++; // Increment private member
    }

>       Example:
>
> File foo.h:
>
>  class foo {
>  public:
>   void user_callable_fn();
>  private:
>   int state;  // need private data members
>   // void impl_function_1(); // no longer needed
>   // void impl_function_2(); // no longer needed
>  };
>
> File foo.cpp:
>
>  #include "foo.h"
>  static void foo::impl_function_1() // local to this file
>  { ... }
>  static void foo::impl_function_2() // local to this file
>  { ... }
>  void foo::user_callable_fn() // can call locals
>  { ...
>   impl_function_1();
>  }

But we can do this today, if you abandon member notation.

    // Foo.h
    class Foo {
        friend class FooImpl;
        int privatedata;
    public:
        int PublicFunc();
        // ..
    };

    // Foo.cpp
    #include "Foo.h"

    // This class is defined and used only here.
    // It implements all the "private" functions of Foo.
    class FooImpl {
        static bool PrivateFunc1(Foo&f);
        static int PrivateFunc2(Foo&f, std::string x);
    };

    class Foo {
        int PublicFunc() {
            if (FooImpl::PrivateFunc1(*this))
                return FooImpl::PrivateFunc2(*this,"yes");
            else
                return FooImpl::PrivateFunc2(*this,"no");
        }
    };

Note that if other client code attempts to access private data by
declaring it's own FooImpl class, this will violate the ODR and
will almost certainly cause link errors.

> With that change, many classes wouldn't need
> to declare their private member functions in the
> class declaration at all.  The internal workings of
> the class would be completely invisible at the header
> file level.

No, the total size of the class must still be known in order to
construct the object.

We could go a step further, and allow the header file to hide
the private data members as well -- but this would severely
limit what we can do with the class:
    * Can use only pointers to the object -- cannot embed the
      object in another class or derive from it, pass or return
      it by value, or even build one on the stack.
    * Can't call operator new directly -- need to get it called
      from a factory, or some other code that knows the whole
      implementation of the class.
This isn't much different than the pImpl method we can use without
any language changes at all.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Fri, 13 Dec 2002 01:38:41 +0000 (UTC)
Raw View
John Nagle wrote:
>    If we're really going to have modules, I'd like to suggest
> that a stronger effort be made to separate declarations from
> implementations.
>
>    One of the biggest maintenance and build problems in C++
> comes from the fact that private parts of classes are visible
> in the include files needed by their users.  The effects of
> this are well-known - any change to the private part of a
> class declaration s forces recompilation of all its users.
> This warps program design; programmers tend to grow existing
> private member functions rather than adding new ones, and
> wrapper classes are created to get around the problem.
> And, of course, it causes unneeded recompiles.
>
>     Any module concept should address this at least as
> well as Ada does.
>
>     One first step worth considering is allowing the
> addition of private member functions to a class
> without declaring them in the class declaration.
> They'd only be visible within the current compilation
> unit.  With that change, many classes wouldn't need
> to declare their private member functions in the
> class declaration at all.  The internal workings of
> the class would be completely invisible at the header
> file level.

I don't think we should change anything in C++ for that (except adding
modules).  I think the module system should handle it all.  In think the
module system should handle a part of the job programs like make does.
For example, for the following code:

class X
{
public:
    void foo();
private:
    void bar();
    int x_
};

For example, the module/package/whatever could
contain-and-remember-previous information about:
- Interface.
   - If you add public member functions, no need to recompile, except
with some cases with inlining.
- Size of object
   - If the size change, need recompile if it is used.
- Comments
   - No need to recompile if they are changed

It means modules would keep information about what they use and what
they expose.  A change to a not-used member function interface could
mean no recompilation at all for other modules (yes, I'm dreaming).  If
they are imported by C++ files translation units (instead of modules),
than any change would mean recompilation for them.  The fact that
modules would not expose what they import can really simplify more
efficient compilations.


>      From a programmer perspective, this means most
> of the private member function declarations leave
> the class declaration and move to the head of the
> file that implements them.  Header files become
> simpler, shorter, and show less implementation
> detail.

I would be more tempted by a java-like approach (one file).  Seems to me
there's no big need for .cpp files with modules.  You just compile a
module and it generates stuff to be imported.

Regards,

Nicolas Fleury

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 13 Dec 2002 01:39:06 +0000 (UTC)
Raw View
c141592653589@hotmail.com (MJ) wrote
> hyrosen@mail.com (Hyman Rosen) wrote
> > MJ wrote:
>  [...]
> > > the order of the importations
> >
> > There is no such thing as "order of importations".
> > Importing a module makes the names defined by that
> > module visible to the compiler and available for use.
> > All names within a module are looked up when the
> > module is compiled. They never depend on client code.
> >
>
> I would like to see a more concrete description of how you would
> realize modules in C++. Could you give an example?

Not speaking for Hyman, but here's my thought.

First, module names would translate into source code in an
implementation-defined way (but typically by searching for a file with
that name and a filetype of "Module". Perhaps it could check for another
file with the same name and filetype ".ModulePrecompiled", and if it
existed and was newer than the .Module file, use it...)

(A compiler could also store modules in some sort of dictionary,
similar to the way that an object-library works on almost all systems.
It would still be implementation defined, and outside the scope of the
language.)

Module imports must be done before any other processing on a translation
unit. If we can say that C++ compilers are single-pass with a straight
face, we would wish to continue that by requiring the import(1)
declarations to be at the top of the file, before any other code except
comments. (Yes, before namespace declarations as well.)

Second, and unlike header files, import modules are severely limited
in what they may contain. They can import other modules; they can
declare complete classes (perhaps including the definition of inline
functions, I haven't thought this through yet); they can declare
functions (and perhaps define them, if they are inline). Any of these
declarations can be inside a namespace. They must import any other
modules that they depend on(2); they ought not import any modules that
they don't depend on, but perhaps that might not be an error.

Modules must NOT define any preprocessor symbols (or maybe they can,
but these are automatically #undef'ed at the end of the module). Since
no code appears lexically before the modules are included, the code
cannot be affected by any symbols defined elsewhere(3), and therefore
the compiler can assume that the lexical content of modules is identical
from one compilation unit to the next. Unless I left something out,
these rules should prevent modules from including contextdependant code,
which should mean that such things as "pre-compiled modules" are possible.

Since modules must import any other module that they depend on, module
inclusion can nest -- however, this also guarantees that they are evaluated
in some valid order. Therefore, if the compiler encounters a directive
to include a module that it's already seen, it can safely be ignored.

Example:

    // Module Sale
    using module Customer;
    using module Product;
    namespace MyCompany {
       class Sale {
          Customer c;
          int ProductCount;
          Product *p;
          double TotalAmount;
          // etc.
       };
    }

    // Module Customer
    using module StandardString;
    namespace MyCompany {
       class Customer {
          std::string Name;
          std::string Address;
          double Balance, CreditLimit;
          // etc.
       };
    }

    // Module Product
    using module StandardString;
    namespace MyCompany {
        class Product {
           std::string Name;
           // use your imagination
        };
    }

    // Main.cpp
    using module Customer;
    using module Sale;
    using module StandardIO;
    int main() {
        Sale s;
        s.ReadFromDatabase(1);
        std::cout << "Our customer of the day is: "
                  << Sale.Customer.Name << std::endl;
    }

Main.cpp first imports Customer, which imports StandardString,
which is presumably functionally equivalent to #include <string>.
Perhaps the header file <string> simply contains
    using module StandardString

Next, Customer defines class Customer. Then Main.cpp imports Sale.
The directive "import module Customer" is ignored, because it has
already been imported. However, Sale also imports Product. Product
imports StandardString again, which is ignored because it's already
been imported. Product defines class Product, then Sale defines
class Sale.

After Main.cpp imports StandardIO, it defines function Main, which
can use all of the symbols that have been imported.

(1) I use "import module" here for exposition. The exact syntax of
    that declaration means nothing to me.

(2) One module depends on another if it uses any symbols defined in
    that other, even if it's only a pointer. If modules can be
    processed as quickly and easily as I hope, then the use of
    "forward" declarations would only be needed with co-dependant
    types (i.e. two classes that contain a pointer to each other).

(3) Unfortunately, this could also prevent conditional compilation,
    which would mean that we can't have one version of a function for
    one compiler and a different version for another compiler. Perhaps
    we could invent some other version of conditional compilation,
    which would have to be defined the same way for all translation
    units. Some compilers have "command line switches" to define
    preprocessor symbols before any source files are processed; perhaps
    we could allow these...?

    Or maybe, we could just relax this rule to say "macros may be
    defined (even with #include) before the first import, but no
    function-type macros, and all macros must be identical from one
    translation unit to the next." Or something to that effect --
    there has to be a better way to word that.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Fri, 13 Dec 2002 21:24:31 +0000 (UTC)
Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0212121512.4c73e806@posting.google.com>...
> nagle@animats.com (John Nagle) wrote
[...]
> >
> > File foo.h:
> >
> >  class foo {
> >  public:
> >   void user_callable_fn();
> >  private:
> >   int state;  // need private data members
> >   // void impl_function_1(); // no longer needed
> >   // void impl_function_2(); // no longer needed
> >  };
> >
[...]
> > With that change, many classes wouldn't need
> > to declare their private member functions in the
> > class declaration at all.  The internal workings of
> > the class would be completely invisible at the header
> > file level.
>
> No, the total size of the class must still be known in order to
> construct the object.
>

I think J. Nagle only wants to remove the requirement to declare
private member functions but not the requirement to declare private
data members. And the total size of the class does not depend on its
member functions, right?


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Fri, 13 Dec 2002 21:26:30 +0000 (UTC)
Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0212121558.5b2cc48@posting.google.com>...
> [...]
> First, module names would translate into source code in an
> implementation-defined way (but typically by searching for
> a file with that name and a filetype of "Module".
> Perhaps it could check for another file with the same name and
> filetype ".ModulePrecompiled", and if it existed and was newer
> than the .Module file, use it...)

a) I would add the following: If the ".ModulePrecompiled" was not
newer, generate a new one and compare it to the existing one. If
nothing has changed, don't recompile all units that depend on it.
The benefit would be that the comparison would be based on tokenized
information so that changes on whitespace (comments) would not require
recompilation.


> Module imports must be done before any other processing on a translation
> unit. If we can say that C++ compilers are single-pass with a straight
> face, we would wish to continue that by requiring the import(1)
> declarations to be at the top of the file, before any other code except
> comments. (Yes, before namespace declarations as well.)

b) I would support the idea to require import directives to be at the
top of the file, but rather because it would make the source more
readable for a human reader: The dependencies on other modules could
be seen easily.

But would it really prevent the compiler from being single-pass, if
the 'importation' were in the middle of the source as I have suggested
in earlier postings? Example:
   ...
   module1::varname x; // somewhere in the source
   // Referring to varname, which is supposed to be declared
   // in module1, would 'import' the module.

Wouldn't it still be possible to compile in a single-pass if the
importation were performed at the first appearance of a 'module
member'?


> Second, and unlike header files, import modules are severely limited
> in what they may contain. They can import other modules; they can
> declare complete classes (perhaps including the definition of inline
> functions, I haven't thought this through yet); they can declare
> functions (and perhaps define them, if they are inline).

c) I would define public and private sections for modules. The public
sections would have to obey to the rules that you describe.
The buffers containig the precompiled information (like in your
example .ModulePrecompiled) would be generated from the public
sections only.
Together with the algorithm described above (see paragraph a) it would
be provided that changes on the private sections wouldn't cause a
recompilation of all the units that depend on the given module.


> Any of these declarations can be inside a namespace.

d) I would tend to require a declaration for a namespace that is by
default identical with the file name (or an equivalent for the file
name in implementations that don't use files) and can optionally be
the global namespace.

Examples:

   // A.Module:
   module ns_name; // required element at the beginning
                   // of a module which determines the
                   // namespace (here: ns_name)

   // B.Module:
   module;         // selecting the file name
                   // (here: "B") as namespace;
                   // produces an error if the file
                   // name doesn't obey the rules
                   // for C++ names (e.g. "23~b.Module")

   // C.Module:
   module ::;      // selecting the global namespace
                   // (intentionally ugly syntax)


> They must import any other modules that they depend on(2); they ought
> not import any modules that they don't depend on, but perhaps that
> might not be an error.

e) But at least a warning would be very useful. Modules that are not
used could then be manually removed from the source.
So only the real dependencies on other modules would be 'documented'
within the code.


[...]
> Since modules must import any other module that they depend on, module
> inclusion can nest -- however, this also guarantees that they are evaluated
> in some valid order. Therefore, if the compiler encounters a directive
> to include a module that it's already seen, it can safely be ignored.
>
> Example:
>
>     // Module Sale
>     using module Customer;
>     using module Product;
>     namespace MyCompany {
>        class Sale {
>           Customer c;
>           int ProductCount;
>           Product *p;
>           double TotalAmount;
>           // etc.
>        };
>     }
>
>     // Module Customer
>     using module StandardString;
>     namespace MyCompany {
>        class Customer {
>           std::string Name;
>           std::string Address;
>           double Balance, CreditLimit;
>           // etc.
>        };
>     }
>
>     // Module Product
>     using module StandardString;
>     namespace MyCompany {
>         class Product {
>            std::string Name;
>            // use your imagination
>         };
>     }
>
>     // Main.cpp
>     using module Customer;
>     using module Sale;
>     using module StandardIO;
>     int main() {
>         Sale s;
>         s.ReadFromDatabase(1);
>         std::cout << "Our customer of the day is: "
>                   << Sale.Customer.Name << std::endl;
>     }

f) I think you missed to refer to the namespace defined in the
modules.
So Main.cpp should rather look like

   // Main.cpp
   using module Customer;
   using module Sale;
   using module StandardIO;
   int main() {
      MyCompany::Sale s;
      s.ReadFromDatabase(1);
      std::cout << "Our customer of the day is: "
                << s.Customer.Name << std::endl;
   }

or

   // Main.cpp
   using module Customer;
   using module Sale;
   using module StandardIO;

   using namespace MyCompany;

   int main() {
      Sale s;
      s.ReadFromDatabase(1);
      std::cout << "Our customer of the day is: "
                << s.Customer.Name << std::endl;
   }


If namespaces in modules would be declared as I suggested, e.g.
   // Sale.Module:
   module MyCompany;

   // Customer.Module:
   module MyCompany;

and it would be allowed to import modules by writing a namespace
directive of their associated namespace, then it would look like

   // Main.cpp
   using namespace MyCompany;
   using namespace std;

   int main() {
      Sale s;
      s.ReadFromDatabase(1);
      std::cout << "Our customer of the day is: "
                << s.Customer.Name << std::endl;
   }

which would avoid to write both, "using module ..." AND "using
namespace ...".


> Main.cpp first imports Customer, which imports StandardString,
> which is presumably functionally equivalent to #include <string>.
> Perhaps the header file <string> simply contains
>     using module StandardString
>

g) As modules ought to be defined such that they cannot export
preprocessor symbols, it would make sense to let #include
<standardheaderx> contain
   using module StandardHeaderX
PLUS the preprocessor '#define-s' that are traditionally 'exported' by
the header file "standardheaderx".


> After Main.cpp imports StandardIO, it defines function Main, which
> can use all of the symbols that have been imported.
>
> (1) I use "import module" here for exposition. The exact syntax of
>     that declaration means nothing to me.
>
> (2) One module depends on another if it uses any symbols defined in
>     that other, even if it's only a pointer. If modules can be
>     processed as quickly and easily as I hope, then the use of
>     "forward" declarations would only be needed with co-dependant
>     types (i.e. two classes that contain a pointer to each other).
>
> (3) Unfortunately, this could also prevent conditional compilation,
>     which would mean that we can't have one version of a function for
>     one compiler and a different version for another compiler. Perhaps
>     we could invent some other version of conditional compilation,
>     which would have to be defined the same way for all translation
>     units. Some compilers have "command line switches" to define
>     preprocessor symbols before any source files are processed;

h) I always thought that every compiler can have command line
switches.

>     perhaps we could allow these...?
>
>     Or maybe, we could just relax this rule to say "macros may be
>     defined (even with #include) before the first import, but no
>     function-type macros, and all macros must be identical from one
>     translation unit to the next." Or something to that effect --
>     there has to be a better way to word that.
>

i) There are some preprocessor symbols that are predefined by the
language (e.g. __cplusplus) that would have still to be supported, so
"command line switches" or something like that for defining
preprocessor symbols would be a simple solution.


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nagle@animats.com (John Nagle)
Date: Fri, 13 Dec 2002 23:08:06 +0000 (UTC)
Raw View
Allan W wrote:

> nagle@animats.com (John Nagle) wrote
>
>>    One of the biggest maintenance and build problems in C++
>>comes from the fact that private parts of classes are visible
>>in the include files needed by their users.  The effects of
>>this are well-known - any change to the private part of a
>>class declaration s forces recompilation of all its users.
>>This warps program design; programmers tend to grow existing
>>private member functions rather than adding new ones, and
>>wrapper classes are created to get around the problem.
>>
>
> Such as the pImpl technique.


    True, but that makes the programmer do a job the
compiler could be doing.   Similar code has to be
written and maintained in two places for every class
that uses that technique.

    Frequently, we see programmers making the data members
public so that they can use static functions with file scope
to work on class objects, which breaks encapsulation.  That's
the motivation for this proposal.


> One problem with this technique is that it's far too easy to break
> encapsulation.
>
>     #include "foo.h"
>     // Need access to private member bar:
>     int&Foo::AccessBar() { return bar; }
>     void Baz(Foo &f) {
>         f.AccessBar()++; // Increment private member
>     }


    The proposal is that you're declaring a private member function
with file scope, not a public one.  So you can't use it
to break encapsulation.  The usual protection of "private"
applies.


>>With that change, many classes wouldn't need
>>to declare their private member functions in the
>>class declaration at all.  The internal workings of
>>the class would be completely invisible at the header
>>file level.
>>
> No, the total size of the class must still be known in order to
> construct the object.


    Member functions don't take up space in objects.  This doesn't
even require constructing vtables in a different way.  Or are
you saying something else.


>
> We could go a step further, and allow the header file to hide
> the private data members as well -- but this would severely
> limit what we can do with the class:


     I'd like to do that, as Ada does, but major changes
to the language would be required to make that work.  What
I'm suggesting is far simpler, although not as far-reaching.

    John Nagle
    Animats

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Sun, 15 Dec 2002 00:26:39 +0000 (UTC)
Raw View
nid_oizo@yahoo.com_removethe_ (Nicolas Fleury) wrote in message news:<L29K9.5558$Ex6.1045383@news20.bellglobal.com>...

[...]
> For example, the module/package/whatever could
> contain-and-remember-previous information about:
> - Interface.
>    - If you add public member functions, no need to recompile, except
> with some cases with inlining.
> - Size of object
>    - If the size change, need recompile if it is used.
> - Comments
>    - No need to recompile if they are changed

I think, to inhibit recompilation if only a comment has changed or
whitespace is added/removed is quite easy to achieve (see my posting
http://groups.google.com/groups?selm=423c153c.0212130706.8537e7f%40posting.google.com
).

The other two compile time optimizations seem also realistic: The
compiler could keep track of the information that you suggested and
store it in the precompiled header (".ModulePrecompiled") for later
evaluation.


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nagle@animats.com (John Nagle)
Date: Sun, 15 Dec 2002 22:14:28 +0000 (UTC)
Raw View
MJ wrote:

> allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0212121512.4c73e806@posting.google.com>...
>
>>nagle@animats.com (John Nagle) wrote
>>
> [...]
> I think J. Nagle only wants to remove the requirement to declare
> private member functions but not the requirement to declare private
> data members. And the total size of the class does not depend on its
> member functions, right?


    That's right.  I'm making a conservative, easy to implement,
backwards compatible proposal.  A full separation between
the exposed interface and the implementation, like Ada, is
much tougher to accomplish, as it would require both new language
syntax and a different approach to compilation.

    John Nagle
    Animats

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Sun, 15 Dec 2002 22:21:21 +0000 (UTC)
Raw View
c141592653589@hotmail.com (MJ) wrote in message news:<423c153c.0212130706.8537e7f@posting.google.com>...
> allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0212121558.5b2cc48@posting.google.com>...
> > [...]
> > First, module names would translate into source code in an
> > implementation-defined way (but typically by searching for
> > a file with that name and a filetype of "Module".
> > Perhaps it could check for another file with the same name and
> > filetype ".ModulePrecompiled", and if it existed and was newer
> > than the .Module file, use it...)
>
> a) I would add the following: If the ".ModulePrecompiled" was not
> newer, generate a new one and compare it to the existing one. If
> nothing has changed, don't recompile all units that depend on it.
> The benefit would be that the comparison would be based on tokenized
> information so that changes on whitespace (comments) would not
> require recompilation.

[...]
> > Second, and unlike header files, import modules are severely limited
> > in what they may contain. They can import other modules; they can
> > declare complete classes (perhaps including the definition of inline
> > functions, I haven't thought this through yet); they can declare
> > functions (and perhaps define them, if they are inline).
>
> c) I would define public and private sections for modules. The public
> sections would have to obey to the rules that you describe.
> The buffers containig the precompiled information (like in your
> example .ModulePrecompiled) would be generated from the public
> sections only.
> Together with the algorithm described above (see paragraph a) it would
> be provided that changes on the private sections wouldn't cause a
> recompilation of all the units that depend on the given module.
>

>From the private sections there would be files generated which contain
'linkable' content. The generated files could for example be of
filetype ".ModuleLinkable".

That is to say, the private sections would be more or less equivalent
to cpp-files.

In cases where a module is kept in a single file, the
".ModuleLinkable" files would be similar to files which are on some
platforms of filetype ".obj".

In cases where a module is split over several files, the
".ModuleLinkable" files would be similar to files which are on some
platforms of filetype ".lib".

No extra tool for generating ".lib" files would be needed. A
differentiation between ".lib" and ".obj" filetypes would not be
necessary.

Example:

   // In this example I am assuming that it
   // would be legal to import modules by
   // writing a namespace directive of their
   // associated namespace.

   //-- file Sale.Module: --
   module MyLibrary; // identifies the
                     // module AND namespace

   public: // this public section contributes
           // for example to file
           // "MyLibrary.ModulePrecompiled"

     class Sale {
       Customer c;
       int ProductCount;
       Product* p;
       double TotalAmount;

     public:
       void ReadFromDatabase(int pos);
       // etc.
     };

   private: // this private section contributes
            // for example to file
            // "MyLibrary.ModuleLinkable"

     void Sale::ReadFromDatabase(int pos)
     {
       // implementation
     }
     // etc.


   //-- file Customer.Module: --
   module MyLibrary; // contributing to the
                     // same module as in
                     // file Sale.Module

   using namespace std; // importing standard
                        // library

   public: // contributing to file
           // "MyLibrary.ModulePrecompiled"

     class Customer {
       string Name; // standard library string
       string Address;
       double Balance, CreditLimit;
       // etc.
     };
   }

   private: // contributing to file
            // "MyLibrary.ModuleLinkable"

     // implementations


   //-- file Product.Module: --
   module MyLibrary; // contributing to the
                     // same module as in
                     // file Sale.Module and
                     // file Customer.Module

   using namespace std;

   public: // contributing to file
           // "MyLibrary.ModulePrecompiled"

     class Product {
       string Name;
       // use your imagination
     };
   }

   private: // contributing to file
            // "MyLibrary.ModuleLinkable"

     // implementations



   //-- file Main.cpp: --
   using namespace MyLibrary; // importing MyLibrary
   using namespace std;       // importing std library

   int main() {
     Sale s;
     s.ReadFromDatabase(1);
     cout << "Our customer of the day is: "
          << s.Customer.Name << endl;
   }



-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Mon, 16 Dec 2002 16:52:20 +0000 (UTC)
Raw View
nagle@animats.com (John Nagle) wrote in message news:<3DFBEAEB.7040104@animats.com>...

> I'm making a conservative, easy to implement, backwards compatible proposal.

But it would require something like modules. Without modules the
following would be possible ...

   file foo.h:
   ---
   class foo {
     // ...
   private:
     int state;
     // void impl_function();
   };

   file foo.cpp:
   ---
   #include "foo.h"
   static void foo::impl_function() // local to this file
   { ... }

   file bar.cpp:
   ---
   #include "foo.h"
   static void foo::impl_function() // local to this file too
   { ... }

... which would mean
a) private access to class foo could be
   gained in any cpp-file
b) each cpp-file could have its own, different
   version of an impl_function
if there were no extra rule which would forbid that.

I suppose that's why you see your proposed language extension related
to modules. The mentioned 'extra rule' would restrict the places where
it is legal to define impl_function to something like a module file
scope.


With the syntax used in posting
http://groups.google.com/groups?selm=423c153c.0212150540.77d6618a%40posting.google.com
it would look like

   file1.Module:
   ---
   module MyModule;

   public:

     class foo {
       // ...
     private:
       int state;
       // void impl_function();
     };

   private:

     void foo::impl_function()
       // supposed to be legal within this file only
       // ('static' not needed)


It would probably be a good idea to allow the definition of such a
function only within the same file.


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nagle@animats.com (John Nagle)
Date: Mon, 16 Dec 2002 20:25:56 +0000 (UTC)
Raw View
MJ wrote:

> nagle@animats.com (John Nagle) wrote in message news:<3DFBEAEB.7040104@animats.com>...
>>I'm making a conservative, easy to implement, backwards compatible proposal.
> But it would require something like modules. Without modules the
> following would be possible ...
>
>    file foo.h:
>    ---
>    class foo {
>      // ...
>    private:
>      int state;
>      // void impl_function();  // [NO, not for statics]
>    };
>
>    file foo.cpp:
>    ---
>    #include "foo.h"
>    static void foo::impl_function() // local to this file
>    { ... }

   That's not what I'm proposing.


    I'm proposing that if the function is static, it
can't (and doesn't have to) appear in the class declaration.
So you can only call it from within the same file, just
like non-static class functions.

    The general idea is that if you can implement your class
in one file, the file contains all the private functions
as statics, followed by the public functions.  None of the
private functions appear in the class header.  You can
then modify all the private code of the implementation,
adding static file-local member functions as needed,
without touching the include file that contains the
externally visible class declaration.

    The only really bad feature of this proposal is that
it creates another use for the keyword "static".


   John Nagle
   Animats

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Tue, 17 Dec 2002 02:20:39 +0000 (UTC)
Raw View
> > nagle@animats.com (John Nagle) wrote
> >>    One of the biggest maintenance and build problems in C++
> >>comes from the fact that private parts of classes are visible
> >>in the include files needed by their users.  The effects of
> >>this are well-known - any change to the private part of a
> >>class declaration s forces recompilation of all its users.
> >>This warps program design; programmers tend to grow existing
> >>private member functions rather than adding new ones, and
> >>wrapper classes are created to get around the problem.

> Allan W wrote:
> > Such as the pImpl technique.

>     True, but that makes the programmer do a job the
> compiler could be doing.   Similar code has to be
> written and maintained in two places for every class
> that uses that technique.
>
>     Frequently, we see programmers making the data members
> public so that they can use static functions with file scope
> to work on class objects, which breaks encapsulation.  That's
> the motivation for this proposal.

Sometimes, doing this is The Right Thing To Do(tm). Not every
C++ program is pure OOP, nor should it be.

FWIW, I sometimes use the handle of a screwdriver to pound on a nail
(if it's just a few nails, and my hammer isn't handy). That doesn't
mean we should require all nails to have slots for screwdrivers. (And
why can't they build a screwdriver set that includes a hammer? I've got
about 42 of the 50 bits that came with my screwdriver -- and not one of
them is any good on a nail!)

If that sounds sarcastic, I didn't mean it to be -- my point is one that's
often repeated here, in one form or another: just because you can misuse
a tool (in this case, for the sake of expedience) doesn't mean that the
tool is broken yet.

> >>With that change, many classes wouldn't need
> >>to declare their private member functions in the
> >>class declaration at all.  The internal workings of
> >>the class would be completely invisible at the header
> >>file level.
> >>
> > No, the total size of the class must still be known in order to
> > construct the object.
>
>     Member functions don't take up space in objects.  This doesn't
> even require constructing vtables in a different way.  Or are
> you saying something else.

Are you saying that you frequently add, delete, and change the
declaration of private member functions, but rarely do the same with
private data members? It seems to me that if you're changing the
private parts of the class, the data is just as likely to change as
the functions -- perhaps more. (I frequently find that if I design
the private data correctly, then most of the private functions are
trivial. YMMV.)

> > We could go a step further, and allow the header file to hide
> > the private data members as well -- but this would severely
> > limit what we can do with the class:
>
>      I'd like to do that, as Ada does, but major changes
> to the language would be required to make that work.

Big changes to the compiler implementation, yes. The effects on legacy
code might not be all that major, if we were very careful ... but it
would have run-time costs, so we wouldn't always want to use it, and
that would complicate things even more.

> What
> I'm suggesting is far simpler, although not as far-reaching.

Meaning no disrespect at all, but it seems to me that what you're
suggesting is a special case. I agree that it would improve build
speed (but not execute speed) at the cost of reducing encapsulation,
but I don't think it would help as much as you seem to think.

Also, how would this apply to private member classes? How would it
apply to proxy objects?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 11 Dec 2002 19:31:41 +0000 (UTC)
Raw View
Ken Hagan wrote:
> You still have to convince me that we can't get "close enough"

I don't know. What are your goals?

A module system controls names. Users of modules say
"with modulename", and that tells the compiler to make
the names available. Writers of modules can use whatever
implementation abilities they want, including #include,
macros, and anything else, and the result is a compiled
unit that makes only the public names visible. Compilers
know that they just need to look up the specification of
the module to find the names.

More analogies - it's the difference between templates
and generic.h.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nagle@animats.com (John Nagle)
Date: Thu, 12 Dec 2002 18:24:00 +0000 (UTC)
Raw View
    If we're really going to have modules, I'd like to suggest
that a stronger effort be made to separate declarations from
implementations.

    One of the biggest maintenance and build problems in C++
comes from the fact that private parts of classes are visible
in the include files needed by their users.  The effects of
this are well-known - any change to the private part of a
class declaration s forces recompilation of all its users.
This warps program design; programmers tend to grow existing
private member functions rather than adding new ones, and
wrapper classes are created to get around the problem.
And, of course, it causes unneeded recompiles.

     Any module concept should address this at least as
well as Ada does.

     One first step worth considering is allowing the
addition of private member functions to a class
without declaring them in the class declaration.
They'd only be visible within the current compilation
unit.  With that change, many classes wouldn't need
to declare their private member functions in the
class declaration at all.  The internal workings of
the class would be completely invisible at the header
file level.

      From a programmer perspective, this means most
of the private member function declarations leave
the class declaration and move to the head of the
file that implements them.  Header files become
simpler, shorter, and show less implementation
detail.

      From an implementation perspective, such
functions look a lot like static non-class
functions.  They have local linkage, they can
be expanded inline and optimized if desired, and
they don't need vtable entries.

      Example:


File foo.h:

 class foo {
 public:
  void user_callable_fn();
 private:
  int state;  // need private data members
  // void impl_function_1(); // no longer needed
  // void impl_function_2(); // no longer needed
 };

File foo.cpp:

 #include "foo.h"
 static void foo::impl_function_1() // local to this file
 { ... }
 static void foo::impl_function_2() // local to this file
 { ... }
 void foo::user_callable_fn() // can call locals
 { ...
  impl_function_1();
 }

      Comments?

    John Nagle
    Animats

MJ wrote:

> I would like to outline an extension to the current way of
> including 'modules' (#include ...). (For a motivation see below.)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 12 Dec 2002 19:35:05 +0000 (UTC)
Raw View
John Nagle wrote:
>     Any module concept should address this at least as
> well as Ada does.

Ada does it in the C++ way!

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Thu, 12 Dec 2002 19:50:19 +0000 (UTC)
Raw View
hyrosen@mail.com (Hyman Rosen) wrote in message news:<1039628304.471455@master.nyc.kbcfp.com>...
> MJ wrote:
[...]
> > the order of the importations
>
> There is no such thing as "order of importations".
> Importing a module makes the names defined by that
> module visible to the compiler and available for use.
> All names within a module are looked up when the
> module is compiled. They never depend on client code.
>

I would like to see a more concrete description of how you would
realize modules in C++. Could you give an example?


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: K.Hagan@thermoteknix.co.uk ("Ken Hagan")
Date: Thu, 12 Dec 2002 19:50:51 +0000 (UTC)
Raw View
Ken Hagan wrote:
> You still have to convince me that we can't get "close enough"

"Hyman Rosen" <hyrosen@mail.com> wrote...
>
> I don't know. What are your goals?

My goal is to do as little as possible. :)

> Writers of modules can use whatever
> implementation abilities they want, including #include,
> macros, and anything else, and the result is a compiled
> unit that makes only the public names visible.

So if your module uses a std::string in the interface,
does a client using your module see the full declaration
of std::string, a forward declaration or no declaration
at all?

The inclusion model would presumably expose all the declarations
in <string>, unless we created <stringfwd>. That's a fair number
of declarations that clients might not need, particularly if the
module in question only used strings in one rarely used function.

However, how often do these declarations actually cause problems?

> More analogies - it's the difference between templates
> and generic.h.

Or perhaps the difference between and exported template and
a non-exported one.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nicola.musatti@objectway.it ("Nicola Musatti")
Date: Wed, 11 Dec 2002 04:02:55 +0000 (UTC)
Raw View
"MJ" <c141592653589@hotmail.com> wrote in message
news:423c153c.0212070753.388657e3@posting.google.com
[...]
> That's close to what I was trying to say. I only wanted to forbid
> the global namespace.

I tend to dislike programming languages where decisions about what's
good for my projects are taken by the language designers. What goes in
which namespace should be decided on a program by program basis.

[...]
> A module concept based on namespaces similar to the one in C# could
> be interesting.

I don't know anything about C#, but if it's similar to Java packages, I
feel it's not the right solution.

> However, a difference between the languages is that C# does not
> have preprocessor macros. I wonder how preprocessor macros should
> interact with such a module concept. Should macros also be exportable
> from a module?

I'd say no. Preprocessing on an imported model should take place before
the actual importing. Macros on the other hand may influence what is
imported:

#define MODULE myModule

import MODULE;

Cheers,
Nicola Musatti


--
Posted via Mailgate.ORG Server - http://www.Mailgate.ORG

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: K.Hagan@thermoteknix.co.uk ("Ken Hagan")
Date: Wed, 11 Dec 2002 04:18:43 +0000 (UTC)
Raw View
Sorry, I still don't get the difference.

"Hyman Rosen" <hyrosen@mail.com> wrote...
>
> Header and source files are extra-linguistic elements that merely
serve
> as holders of code, and so are irrelevant to the module concept. A
"real
> module" contains a set of related types, data, and functions, rather
like
> a class or a namespace. The names declared by a module can generally
be
> imported through a single syntactic element requesting its use.

Ironically, to me this looks like you are getting hung up on the fact
that they are normally external files. They are only extra-liguistic
because you've said so, and because pre-processors traditionally run
separately from the compiler.

How is "#include <vector>" different from "using package vector" on a
system where C++ source code is held in a database, or on a system where
Ada packages happen to be held in files?

> A module system does away with things like the ODR, because contents
of a
> module are (at least conceptually) compiled only once. The C/C++
inclusion
> model is incredibly awkward by comparison.

If we could do away with all macros except for header guards (!), the
C/C++ inclusion model would be perfectly adequate. The ODR would be
irrelevant because of the guards; compilers could pre-compile such
modules because they didn't depend on or leak macro definitions; and the
C++ rules for name lookup already strive to ensure that the order of
declaration doesn't affect which name is chosen in a particular context.

As far as I can see, the language already allows this. It is legacy code
that spoils everything.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Wed, 11 Dec 2002 15:38:40 +0000 (UTC)
Raw View
hyrosen@mail.com (Hyman Rosen) wrote in message news:<cfWI9.756$5W.603@nwrddc02.gnilink.net>...
> llewelly wrote:
> > If they aren't, people will use #include to get them. Perhaps macros
> > should be exportable from a module, with semantics such that they
> > behave as if #defined at the point of the module's importation.
>
> No. As with everything else, the preprocessor will be completely
> independent of modules. Modules will be preprocessed like any other
> C++ code, and macros will come from #include as needed. Macros
> already don't understand templates, and there's a good chance they
> won't understand modules either if any fancy syntax is needed.
>

A module declaration could for example look like the following:

   module ns_name1 { // 'module' is a keyword
     // declarations, etc.
     struct any1 { ... };
     ...
   }

which would associate its items with a namespace, just like
declarations via 'namespace' and 'class' or 'struct'.

If modules could be 'imported' by referring to their items, e.g.

   ns_name1::any1 Any1;
   ...
   ns_name2::any2 Any2; // from another module

and macros from modules would be '#defined' at the point of the
module's importation then the result would depend on the order of the
importations, which is exactly what we want to avoid with modules, so
we better don't do that.



In the above examples modules don't have file nature, especially if we
further assume that the definition of a module can be split over
several files.

However, a system that supports modules which may use but don't export
macros, could be realized by putting all module declarations into
certain files that contain nothing but those module declarations.

The alternative - module declarations can appear anywhere in the
source code - is more difficult to accomplish if we want to keep the
macros under control. Example:

   filex.cpp:
   ---
   module ns_namex {
     #define add(arg1, arg2) ((arg1) + (arg2))

     ...
   }

   // macro 'add()' still valid here


Presupposed we do not want to fundamentally change the preprocessor's
behaviour, it seems that such module declarations can not appear
anywhere in the source if we want to keep the impact of macros to
within a module.


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Wed, 11 Dec 2002 09:56:51 CST
Raw View
nicola.musatti@objectway.it ("Nicola Musatti") wrote in message news:<2eadca86b46ba502617d94b88ddf4955_2394@mygate.mailgate.org>...

[...]
>
> I tend to dislike programming languages where decisions about what's
> good for my projects are taken by the language designers. What goes in
> which namespace should be decided on a program by program basis.
>

Ok, the programmer should have the option to decide what is good for
his program. But the language should offer reasonable defaults.


> > A module concept based on namespaces similar to the one in C# could
> > be interesting.
>
> I don't know anything about C#, but if it's similar to Java packages, I
> feel it's not the right solution.
>

What about Java packages would you dislike to have in C++, and why?


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 11 Dec 2002 10:09:33 CST
Raw View
In article <at4epu$bsc$1$8302bc10@news.demon.co.uk>, Ken Hagan
<K.Hagan@thermoteknix.co.uk> writes
>If we could do away with all macros except for header guards (!), the
>C/C++ inclusion model would be perfectly adequate. The ODR would be
>irrelevant because of the guards; compilers could pre-compile such
>modules because they didn't depend on or leak macro definitions; and the
>C++ rules for name lookup already strive to ensure that the order of
>declaration doesn't affect which name is chosen in a particular context.
>
>As far as I can see, the language already allows this. It is legacy code
>that spoils everything.

I do not think that it does, if I understand correctly. It isn't only
macros that are a problem but function declarations that are or are not
visible in a particular context.

--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 11 Dec 2002 16:38:22 +0000 (UTC)
Raw View
Ken Hagan wrote:
> They are only extra-liguistic because you've said so

No, they are extra-linguistic because the language says so.
Go read the eraly parts of 2 and 2.1.

> How is "#include <vector>" different from "using package vector"

First of all, modules are not just for the language implementors
but for all programmers. But mainly, the difference is that #include
builds up a translation unit by textual substitution (even when the
compiler can physically elide it in certain cases), and the included
text is completely arbitrary. Declaring the use of a package makes a
well-defined set of names, those declared by the package as public,
available, and only those names.

> If we could do away with all macros

Macros are irrelevant to this discussion.

> the C/C++ inclusion model would be perfectly adequate

I probably shouldn't do this, but here's an analogy.
In this newsgroup, when we quote from the Standard,
we use Chapter/Section/Paragraph notation, not page
number.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 11 Dec 2002 17:41:19 +0000 (UTC)
Raw View
MJ wrote:
> and macros from modules would be '#defined'

No. Modules do not contain macros. If someone wishes to
use macros and keep them in a separate file, then they
will be included using #include, as before. Macros are
orthogonal to modules. They are extra-linguistic in
every important sense. They are irrelevant.

> the order of the importations

There is no such thing as "order of importations".
Importing a module makes the names defined by that
module visible to the compiler and available for use.
All names within a module are looked up when the
module is compiled. They never depend on client code.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: K.Hagan@thermoteknix.co.uk ("Ken Hagan")
Date: Wed, 11 Dec 2002 18:22:27 +0000 (UTC)
Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote...
>
> First of all, modules are not just for the language implementors
> but for all programmers. But mainly, the difference is that #include
> builds up a translation unit by textual substitution (even when the
> compiler can physically elide it in certain cases), and the included
> text is completely arbitrary. Declaring the use of a package makes a
> well-defined set of names, those declared by the package as public,
> available, and only those names.

So if my #include contains only the well-defined set of names that I
want to publicise, then the choice is...

 a add it to the compilation unit by plugging the text into the
   source code at the point of #include. This will cause the
   compiler to parse the text and fill its symbol table with the
   new names.
 b add it to the compilation unit by compiling separately and
   plugging the compiled names into the symbol table

I suppose the difference then, is that all the names that were visible
in the global and anonymous namespaces of the original translation unit
at the point of #include are visible to the module declarations, and
that might be more than the module author expected.

Is this the key point?

However, if we avoid putting names in the global namespace, and import
modules before filling the anonymous namespace, there's not a fat lot
of difference between the two. Both look like fairly uncontroversial
recommendations to me.

> > If we could do away with all macros
>
> Macros are irrelevant to this discussion.
>
> > the C/C++ inclusion model would be perfectly adequate

You still have to convince me that we can't get "close enough" to
a module system just by avoiding some existing language features.
Macros are the most offensive of the things we have to avoid.

> I probably shouldn't do this, but here's an analogy.
> In this newsgroup, when we quote from the Standard,
> we use Chapter/Section/Paragraph notation, not page
> number.

But in the absence of section numbers, a page reference will do.
Isn't defining a module system "overkill" when the inclusion model
can be used in ways that don't depend on previously included
headers, don't add unnecessary names and don't leak macros?


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 9 Dec 2002 07:17:27 +0000 (UTC)
Raw View
Allan W wrote:
> You seem to be knowledgable about it... would you please explain how it
> works in Ada

Ada modules are named "packages" and are rather like a combination of
C++ classes and namespaces. An Ada program is built out of packages
and possibly out of free-standing subroutines. Packages have specifications,
which serve like the public declarations of class members. They may also
have private parts, where things needed only be the package itself are
declared. Finally, they have bodies, where the code goes. Packages are
fully block-scoped; you can declare packages inside others, and even
within subroutines. They can also be generic, like templates. There are
no "package objects", though. To declare that you wish to use a package,
you say "with PackageName;". To declare that you then want to use the
names from a package without qualifying them with their package name,
you say "use PackageName;"; this usage has its adherents and detractors,
who will fight fiercly about it.

I may have some of the above information mangled, since I'm no expert
in Ada. You can check out <http://adapower.com> for all sorts of reference
information.

 > and how it would be "adapted toward the needs of C++"?

Hard to say.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 9 Dec 2002 09:38:22 +0000 (UTC)
Raw View
llewelly wrote:
> If they aren't, people will use #include to get them. Perhaps macros
> should be exportable from a module, with semantics such that they
> behave as if #defined at the point of the module's importation.

No. As with everything else, the preprocessor will be completely
independent of modules. Modules will be preprocessed like any other
C++ code, and macros will come from #include as needed. Macros
already don't understand templates, and there's a good chance they
won't understand modules either if any fancy syntax is needed.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: K.Hagan@thermoteknix.co.uk ("Ken Hagan")
Date: Mon, 9 Dec 2002 18:22:32 +0000 (UTC)
Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote...
>
> Ada modules are named "packages" and are rather like a combination of
> C++ classes and namespaces.

The question that your subsequent description brings to mind is "How is
a package specification different from a C++ header file and a package
implementation different from a C++ source file?".

I've never really understood what proponents of a "real module system"
want, apart from a world where pre-processor macros can't run amok from
one module to another. Well I expect we'd all like that, and we could
have it if only someone would rewrite all header files to avoid using
macros at all. Would "doing that re-write for the standard library"
meet people's expectations of a "real module system", or is there some
language feature that we are still missing?


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Mon, 9 Dec 2002 18:22:56 +0000 (UTC)
Raw View
c141592653589@hotmail.com (MJ) wrote in message news:<423c153c.0212070753.388657e3@posting.google.com>...
> nicola.musatti@objectway.it ("Nicola Musatti") wrote in message news:<f1c10a6a595662b96a43e6d9b5345768_2394@mygate.mailgate.org>...
> > "MJ" <c141592653589@hotmail.com> wrote in message
> > news:423c153c.0212020427.403004d8@posting.google.com
> >


> A module concept based on namespaces similar to the one in C# could
> be interesting.
>

For example: If there were a way do 'add' modules to a C++ project so
that the declarations etc. from the 'interface part' of the modules
would be accessible in every cpp file, then the modules would be
'imported' by just refering to their namespaces. E.g.:

   file1.cpp:
   ---
   std::string s1;

or

   file2.cpp:
   ---
   using namespace std;
   string s2;


So it wouldn't be necessary to write '#include ...' any more.


For compatibility, empty header files could be provided. E.g.:

   file3.cpp:
   ---
   #include <string>  // empty file

   std::string s3;




-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 6 Dec 2002 20:33:24 +0000 (UTC)
Raw View
usenet@phatbasset.com ("Hillel Y. Sims") wrote
> Has anyone examined Ada's module facilities, particularly GNAT's (the free
> GNU Ada95 compiler) file-based implementation?

Nope -- nobody has.  :-)

> Could something like that be
> appropriate and adapted toward the needs of C++?

No, uh-uh, impossible, that would... well, wait a minute, I just admitted
that nobody has actually examined it.

You seem to be knowledgable about it... would you please explain how it
works in Ada, and how it would be "adapted toward the needs of C++"?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Sat, 7 Dec 2002 22:31:00 +0000 (UTC)
Raw View
nicola.musatti@objectway.it ("Nicola Musatti") wrote in message news:<f1c10a6a595662b96a43e6d9b5345768_2394@mygate.mailgate.org>...
> "MJ" <c141592653589@hotmail.com> wrote in message
> news:423c153c.0212020427.403004d8@posting.google.com
>

[...]

> [...]
> > 6.) Names from an import file shall always belong to a
> > (non-global) namespace.
>
> No. Names should be imported in the namespace in which they are
> defined within the imported module.
[...]

That's close to what I was trying to say. I only wanted to forbid
the global namespace.



[...]
> The import mechanism should work regardless of the way modules
> are named, and no transformations should be performed on their
> names.
[...]

I agree. The suggestion in my posting was too much stuck to the
mechanism via '#include'.

A module concept based on namespaces similar to the one in C# could
be interesting.

However, a difference between the languages is that C# does not
have preprocessor macros. I wonder how preprocessor macros should
interact with such a module concept. Should macros also be exportable
from a module?


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: llewelly.@@xmission.dot.com (llewelly)
Date: Sun, 8 Dec 2002 07:56:06 +0000 (UTC)
Raw View
c141592653589@hotmail.com (MJ) writes:

[bsnip]
> However, a difference between the languages is that C# does not
> have preprocessor macros. I wonder how preprocessor macros should
> interact with such a module concept. Should macros also be exportable
> from a module?
[snip]

If they aren't, people will use #include to get them. Perhaps macros
should be exportable from a module, with semantics such that they
behave as if #defined at the point of the module's importation.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Mon, 9 Dec 2002 00:34:52 +0000 (UTC)
Raw View
hyrosen@mail.com (Hyman Rosen) wrote in message news:<9ZgH9.33293$ic6.19933@nwrddc01.gnilink.net>...
> MJ wrote:
> > Why would it be a grave mistake?
>
> A module is a logical entity, rather like a namespace.
> There's no particular reason it should be bound to a
> single file. Let the implementation maintain the mapping
> of filenames to modules or pieces thereof.
>

Agreed. Modules that aren't bound directly to files allow for a better
abstraction.


A file based module inclusion like
  #include "directory1/directory2/filex.h"

carries out the file mapping within the source code, which does not
only make it depend on a certain directory structure, it leads to
portability problems as one has to care for things that depend on the
present file system (e.g. uppercase/lowercase naming; or the directory
separator: "/" or "\" or ":", etc.).
Such dependancies should not have to be maintained within the source
code.


C# has a module system based on namespaces. May be a similar system
could be introduced to C++.


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Mon, 9 Dec 2002 18:42:48 +0000 (UTC)
Raw View
K.Hagan@thermoteknix.co.uk ("Ken Hagan") writes:

| "Hyman Rosen" <hyrosen@mail.com> wrote...
| >
| > Ada modules are named "packages" and are rather like a combination of
| > C++ classes and namespaces.
|
| The question that your subsequent description brings to mind is "How is
| a package specification different from a C++ header file and a package
| implementation different from a C++ source file?".

I guess you don't get "ADL + exported template" being evil supposed
gotcha :-)

--
Gabriel Dos Reis,       gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 9 Dec 2002 20:23:33 +0000 (UTC)
Raw View
Ken Hagan wrote:

> The question that your subsequent description brings to mind is "How is
> a package specification different from a C++ header file and a package
> implementation different from a C++ source file?".
>
> I've never really understood what proponents of a "real module system" want


Header and source files are extra-linguistic elements that merely serve
as holders of code, and so are irrelevant to the module concept. A "real
module" contains a set of related types, data, and functions, rather like
a class or a namespace. The names declared by a module can generally be
imported through a single syntactic element requesting its use.

A module system does away with things like the ODR, because contents of a
module are (at least conceptually) compiled only once. The C/C++ inclusion
model is incredibly awkward by comparison.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: comp.std.c++_2002-12-04@nmhq.net (Niklas Matthies)
Date: Thu, 5 Dec 2002 07:07:56 +0000 (UTC)
Raw View
On 2002-12-04 16:52, "Nicola Musatti" <nicola.musatti@objectway.it> wrote:
> "MJ" <c141592653589@hotmail.com> wrote:
[...]
>> The 'area' within the import file(s) shall not be affected by
>> anything from outside. (I don't know how to say this in good
>> english - what I mean is that the import file(s) shall not 'see'
>> any code from outside.)
>
> I think I understood. Importing is *not* meant to be a simple textual
> inclusion. The definitions contained in an imported module should be
> made available after they have been parsed.

This is actually a feature. If some module B imports module std::string
because it uses std::string it in its interface, and module A imports
module B but also uses std::string independently of its use of the B
facilities, it _should_ import module std::string in its own right.

With includes, much too often this isn't done properly when the
respective facilities are already introduced by way of some other
header, even if that header is otherwise totally unrelated.

In particular, even if one strives to directly include all the headers
that conceptually should be, it is generally quite hard or tedious to
determine this set of headers because, of course, the compiler doesn't
complain when one is missing if it's already been included indirectly.

However, with the 'import' approach, an additional 'export' directive
would be advisable that lets a module export the interface of some other
module, so that one can write modules that "forward" the interface of
one or more other modules to the importing module. E.g.:


   /* module C */

   export "A";
   export "B";


   /* module D */

   import "C";    // equivalent to 'import "A"; import "B";'


-- Niklas Matthies

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: usenet@phatbasset.com ("Hillel Y. Sims")
Date: Thu, 5 Dec 2002 18:14:40 +0000 (UTC)
Raw View

"Hyman Rosen" <hyrosen@mail.com> wrote in message
news:9ZgH9.33293$ic6.19933@nwrddc01.gnilink.net...
>
> A module is a logical entity, rather like a namespace.
> There's no particular reason it should be bound to a
> single file. Let the implementation maintain the mapping
> of filenames to modules or pieces thereof.
>

Has anyone examined Ada's module facilities, particularly GNAT's (the free
GNU Ada95 compiler) file-based implementation? Could something like that be
appropriate and adapted toward the needs of C++?

hys

--
(c) 2002 Hillel Y. Sims
FactSet Research Systems
hsims AT factset.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Mon, 2 Dec 2002 16:33:10 +0000 (UTC)
Raw View
I would like to outline an extension to the current way of
including 'modules' (#include ...). (For a motivation see below.)


1.) A declaration like

   import "file1";

shall be called 'import declaration'. (At least in this text. Any
other suggestions??; would it, strictly speaking, be a declaration??)

After the keyword 'import' follows a non-empty comma separated list
of 'import files'. (Example: import "file1", <file2>, "file3";)

The 'area' within the import file(s) shall not be affected by
anything from outside. (I don't know how to say this in good
english - what I mean is that the import file(s) shall not 'see'
any code from outside.)




2.) Parts _subsequent_ to the import declaration shall 'see'
all code from the import file(s).

Subsequent import files are not considered as '_subsequent_'
in this sense.

(So the order of the import files would not matter.)

(But: Subsequent header files would 'see' the import file.
Example: import   "file1";
         #include "file2.h"
File2 would 'see' file1!)



3.) It shall be possible to write more than one import
declaration, e.g.

   import "file1";
   import "file2";

This would be necessary for allowing to include import
declarations via header files. Example:

   header1.h:
   ---
   ... import "file1"; ...

   header2.h:
   ---
   ... import "file2"; ...

   unit1.cpp:
   ---
   #include "header1.h"
   #include "header2.h"



4.) It shall not be necessary to prevent multiple inclusion of
import files.
In other words: Another improvement would be to remove the
necessity to write the 'include guards' like in header files.

Example:

   headerfile.h
   ---
   #ifndef headerfile_H
   #define headerfile_H
   ...
   #endif

For import files this shall be done automatically by the
compiler (... but without automatic definition of a preprocessor
symbol like "headerfile_H"!).



5.) The import file shall implicitly refer to a file with the
same name plus an extension ".i".
Example:

   import "file1";

This is supposed to import code from a file named "file1.i".
(Letter 'i' stands for 'import file'.),

similarly:
   import <file2>;
imports code from a file named "file2.i".


A file extension different from ".h" is useful because
otherwise an import file might be confused with a header
file which would lead to a problem if there are no
'include guards' in the import file.
This problem could be prevented if the 'include guards'
would be written in every import file, but then item 4
would not be needed.
In cases where an interface provided by header files is
needed (for compatibility or so) the following could be
written:

   shared.h:
   ---
   ... (ordinary header)

   shared.i:
   ---
   #include "shared.h"

   oldstyle.cpp:
   ---
   #include "shared.h"

   newstyle.cpp:
   ---
   import "shared";



6.) Names from an import file shall always belong to a
(non-global) namespace.

(For declarations in the global namespace "#include ..."
can still be used.)

A way to determine to which namespace the names of a
certain import file belong, shall be provided by some
mechanism within the import file.

To avoid typing like the following

   import "file1", "file2";
   ...
   using namespace file1;
   using namespace file2;

there shall be a short form. For example:

   import using namespace "file1", "file2";



                    ~~~~



Motivation:

The total compile time for a program can be significantly reduced
by buffering the intermediate compilation results of the headers
("precompiled headers"). At least two popular compilers for the
windows platform do this.

During the compilation process those compilers can make use of
previously compiled headers if the included header files in a cpp-file
are the same and in the same order as found in other cpp-files before.
What one has to do to make use of the buffering mechanism is write
code like this:

   // cpp-file 1:
   #include "header1.h"
   #include "header2.h"
   #include "header3.h"
   #pragma hdrstop

   #include "header4.h"

   // cpp-file 2:
   #include "header1.h"
   #include "header2.h"
   #include "header3.h"
   #pragma hdrstop

   #include "header5.h"

(The directive "#pragma hdrstop" tells the compiler to ignore
subsequent header files for buffering.)

I suppose the reason for having to write the headers in exactly the
same order is, that the headers have to be re-evaluated by the
compiler if found in a different order.

So this seems to be a matter of the C++ language definition: If the
module concept of C++ would be designed in a way that the compilation
result would not depend on the order in which the modules are listet,
then it would be easier to maintain the code - not only in terms
of compile time!

I think an enhanced 'module concept' would be a useful extension for
the C++ language.

[started in comp.lang.c++.moderated]




-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 2 Dec 2002 18:35:18 +0000 (UTC)
Raw View
MJ wrote:

> 1.) A declaration like
>    import "file1";


This is immediately heading off in the wrong direction.
Modules have nothing to do with files, and it would be
perpetuating a grave mistake to treat them as such.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c141592653589@hotmail.com (MJ)
Date: Tue, 3 Dec 2002 22:08:38 +0000 (UTC)
Raw View
hyrosen@mail.com (Hyman Rosen) wrote in message news:<1038848731.830120@master.nyc.kbcfp.com>...
> MJ wrote:
>
> > 1.) A declaration like
> >    import "file1";
>
>
> This is immediately heading off in the wrong direction.
> Modules have nothing to do with files, and it would be
> perpetuating a grave mistake to treat them as such.
>

Why would it be a grave mistake? Could you explain that a bit more
detailed?
And what would you suggest instead?

What I would like to have is some alternative to header files where
the order of appearance doesn't matter.


-- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 4 Dec 2002 16:50:51 +0000 (UTC)
Raw View
MJ wrote:
> Why would it be a grave mistake?

A module is a logical entity, rather like a namespace.
There's no particular reason it should be bound to a
single file. Let the implementation maintain the mapping
of filenames to modules or pieces thereof.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nicola.musatti@objectway.it ("Nicola Musatti")
Date: Wed, 4 Dec 2002 16:52:59 +0000 (UTC)
Raw View
"MJ" <c141592653589@hotmail.com> wrote in message
news:423c153c.0212020427.403004d8@posting.google.com

[...]
> 1.) A declaration like
>
>    import "file1";
>
> shall be called 'import declaration'. (At least in this text. Any
> other suggestions??; would it, strictly speaking, be a declaration??)

An import directive

> After the keyword 'import' follows a non-empty comma separated list
> of 'import files'. (Example: import "file1", <file2>, "file3";)

I agree with Hyman Rosen here. Modules do not necessarily have to be
files. An integrated version control/compiler system might make the
modules directly available to the compiler as in-memory data streams.

> The 'area' within the import file(s) shall not be affected by
> anything from outside. (I don't know how to say this in good
> english - what I mean is that the import file(s) shall not 'see'
> any code from outside.)

I think I understood. Importing is *not* meant to be a simple textual
inclusion. The definitions contained in an imported module should be
made available after they have been parsed.

> 2.) Parts _subsequent_ to the import declaration shall 'see'
> all code from the import file(s).
>
> Subsequent import files are not considered as '_subsequent_'
> in this sense.
>
> (So the order of the import files would not matter.)

Note however that this might make it necessary at times to import the
same module both in the original source file and in some of the modules
it imports.

> (But: Subsequent header files would 'see' the import file.
> Example: import   "file1";
>          #include "file2.h"
> File2 would 'see' file1!)

I.e. the import mechanism does not modify how inclusion works.

[...]
> 4.) It shall not be necessary to prevent multiple inclusion of
> import files.

[...]
> For import files this shall be done automatically by the
> compiler (... but without automatic definition of a preprocessor
> symbol like "headerfile_H"!).

I see this as an inevitable consequence of the mechanism you described
above.

> 5.) The import file shall implicitly refer to a file with the
> same name plus an extension ".i".
> Example:
>
>    import "file1";

No. The import mechanism should work regardless of the way modules are
named, and no transformations should be performed on their names.

[...]
> 6.) Names from an import file shall always belong to a
> (non-global) namespace.

No. Names should be imported in the namespace in which they are defined
within the imported module. The effect you describe can easily be
achieved with:

namespace MyNamespace
{
import MyModule;
}

[...]
I've long felt that C++ would benefit from the addition of a proper
module mechanism. While the importance of dependency management is
generally understood, a lot of effort must be put into it. Modules would
be a great help in dealing with this problems.

While I don't agree with some of the details of your proposal, I do
support its general aim.

Cheers,
Nicola Musatti


--
Posted via Mailgate.ORG Server - http://www.Mailgate.ORG

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]