marcov wrote:I only know Wirthian module systems, but some of the things I like about them:
- faster compilation (no infinite reparsing). Note that precompiled headers (like in commercial C compilers) can provide this too, but at substantially more work, and without the other benefits.
I don't believe this is true of FB, unless you create and use libraries which are linked in.
If I include a .bi, is an ascii sourcefile parsed? Or is something binary from a previous run loaded from disk?
.bi's belong to the total source size, and if you compile multiple files, and .bi's are read multiple times, they count multiple times.
- Compiler generates errors when compilation units don't match. compilation units don't meet only at the linker. The compiler has more information and an earlier opportunity to generate a decent error msg. (Undefined symbol "XX". Well ok, but why and where!??!)
FB is a single pass compiler so it will generate an error at the line. Whether it identifies the module I don't know.
Will it generate an error when a .bas doesn't contain an symbol declared in the .bi ?
I've thought about this since yesterday, and this is more a strong bond between a .bi and the corresponding implementation (.bas), so that no missing symbol is considered external unless explicitely declared as such.
- If you support nested scopes, the unit level (and importing in general) is just another one. The unit typically also provides a namespace. (*)
FB has namespace, Scope and End Scope as well as global, module and sub/func scope.
Is there a document how these scopes work? Is there a scope stack?
- Decentralized initialization and finalization code.
Yes in modules. Personally I haven't ever found this useful in FB or Pascal.
It is mainly useful for plugin like architectures on source level. Having modules register them somewhere central (e.g. register class types, strings or whatever).
If you have a module managing hardware, the hardware initializations and finalizations might also go there.
- The name mangling allows to have global variables in different modules with the same name. No endless renaming anymore if you piece code out of various origins together.
Namespaces cover this.
I know FB has some. I don't know exactly how it works.
- the compiler has knowledge about what module are used. This means that the compiler can autobuild and -link without much additional info. This reduces the need for makefiles and/or additional building information (FPC only needs to know what the main program is, and can compile the program by just "compiler <mainprogram>", and figures out the rest itself)
Since FB is a single pass compiler you can't get these types of tricks as you can in a multi-pass compiler.
I'm not sure what you mean here. Single pass (like e.g. Pascal) means that a sourcecode is only passed once (which is faster but requires all symbols to be declared before used). Multi pass (like e.g. C) means that you first scan to find all identifiers and their rough type. (struct or int etc), and then compile during the second pass.
Afaik it hasn't any relevance on multi-module systems, since both terms have relevance on a single piece of source.
I have heard the term "single issue" once for a compiler that compiles only one sourcefile at a time (and then shuts down). Maybe you mean that?
To make a very general comparison, FB modules are somewhat like Pascal units, and many of the same problems exist. You have to sometimes jumps through hoops in order to get different units/modules to work together.
This is why C dropped the notion of units/modules, because they get can get in the way, rather than help.
C never had them. The design predates modules by 7 years. (module was the buzzword anno 1980)
To be honest, I don't think you really know what you are talking about.
In C++ instead of unit/modules, the class was added to make code reuse much easier, to get some of the benefits of units/modules, but without all the hassles. There are some hassles with classes, they are not the end-all solution, but they have proven much more useful than units/modules in the long run.
C++ is not something to orient against. Even Java or C# would be better. C++ had such horrible design constraints (because of C backwards compat) that it should be made an example for any language design.
A class is a stronger concept for code reuse, but, unless you put it central to the importing mechanism like e.g. Java does (with his classes hierarchy) doesn't provide a substitute for modules.
C++ does neither and has no concept of how files come together in a controlled way to form a program at all, and like C relies on interpreting linker errors if something is wrong. Classes don't help there in the C++ case.
IOW in Java/C#, a light module concept has been added to the class, in C++ not. I don't like the Java solution, but at least it is a solution to the problem. C++ has none to my best knowledge, and relies on out-of-language tools for this (makefiles, non-standarized project systems that usually map to makefiles or something similar). But in fact it is manual, with patchy tools to help with it, not a system.
So to be honest, I have the feeling you have no clue at all what this part of a module system is about, and know only C/C++.
Now, the C++ model can be used in FB. FB supports objects and all the same features of C++ classes, except inheritance. So how does this enable code reuse?
This is how I do code reuse, and in my opinion, it is a much better solution to the problem.
To me your example shows some of the problems, like the need to wrap. (why would you need to if you have namespaces?)
Where do you import the namespace into your local namespace, or does FB always require you to prefix tableobj. ?
Again: I really think you don't understand at all what I'm hinting at. If you want to talk about it, I'm on IRC. I do think you intuitively are on the right track, otherwise you wouldn't have named the single vs multi-issue bit. But somehow you miss some of it.