Bart <
bc@freeuk.com> wrote:
It is suitable for a vast number of programs. I'm sure it could be used
for multi-developer projects too. After all, don't your projects also
place all project-structure info into /one/ makefile? Which developer
has editing rights on that file?
There are _many_ possible organizations. Rather typical is one
Makefile _per directory_. Most 'make'-s seem to be able to do
file inclusion, so you may have a single main Makefile that
includes whatever pieces are necessary. For example, if somebody
wanted to add support for your language to gcc, that would need
creating a subdirectory and putting file called 'Make-lang.in'
inside. Make-lang.in is essentially Makefile for your language,
but it is processed to substitute crucial variable and included
as part of gcc Makefile. Of course, you will need more, but
this covers Makefile part.
Who decides what the modules are going to be? If one developer decided
they need a new module, what is the procedure to get that added to the
makefile?
In open source project normal thing is a patch or a Git pull
request. This specifies _all_ needed changes, including Makefile-s
if there is a need for new module it gets added where needed.
I one "my" project there can be multiple module in a file, so
a new module may go to existing file (if it is closely related
to other module in the file) or to a separate file. I also needs
changes to Makefile.
The above is technical part. Other is governace of a project.
If there are multiple developers, then there may be some form
of review. Or a developer may be declared to be maintainer of
given part and allowed changes without review. 'gcc' has several
"global maintainers", they can change each part and approve
all changes. There are maintainers for specific parts, they
can modify parts they are resposnible for and approve changes
there, for other parts they need approval. There are "write
after approval" people who propose changes but are allowed to
merge them only after approval from folks in the first two
groups. There is also a steering body which votes and
make decision after. Some project use some forms of democracy.
For example, all developers may be considerd equal, but
any change need aproval from another developer. In case of
objections there is a vote. Some projects have a "dictator"
of "lead developer" who has final say on anything project-related.
I have no experience in commercial setups, but IIUC normally
firms have rules and responsible persons. Person responible
for a project divides work and possibly delegates responsibility.
Firm or project rules may require review, so that other developer
looks at changes. There could be design meeting before
coding.
The design IS better in 100 ways, at least compared to C. Other modern,
higher level languages have 100 things I don't have, don't understand,
or would find impossible to use.
However a language at the level of C still appears to be extremely
popular. I guess people like something that is not so intimidating and
that they can feel in command of.
Hmm, the only language at C level that I know and is popular
is C. Ada, COBOL, Fortran, Modula 2, Pascal, PL/I are languages
that I consider to be at level similar to C. But AFAIK no of them
is really popular and in modern time they aim to be higher-level
than C. Forth is at lower level and really not that popular.
Can you name a language that is at level of C, is popular and
is not C?
No, it is not. You set PATH to the directories you want to use for
binaries - the OS does not search the entire disk or random additional
attached filesystems.
PATH is a collection of paths that are searched in turn. There it will
stop at the first match.
That's similar to my list of modules that are searched in turn. There it
will find all matches and report an ambiguity if more than one.
However, my list is private to my project, while PATH is common to every
command prompt and to whatever directory is current. Some programs could
even manipulate the contents of PATH.
Yes. In particular, depending on need program may put some specific
directory at start of the PATH or restrict PATH. I asked if you
can contol visibility in your system, you gave no aswer which for
me idicate that you can not. Of course, changing PATH is very
crude (is is essentially equvalent to what Forth is offering),
most languages have better ways. Do you know how Turbo Pascal
units worked? Or Modula 2?
No, your design is to /force/ "using namespace" - whether the programmer
wants it or not, and without the programmer even identifying the modules
to import. It's your choice - but it's a bad choice.
The programmer knows how the language works. They will have chosen the
modules that are grouped together.
The alternative is to have 50 modules of a project, where each module
contains its own subset of 0 to 49 imports. That's up to 950 possible
imports to maintain across up to 50 files. It sounds a maintenance
nightmare. A dependency graph would need a pretty big sheet of paper!
You discard posibility of re-export. Lazy programmer may write
"utility" module that imports every needed interface and re-exports
it. And then in each implementation import this single module.
Compared to your scheme overhead is essentially a single line
per implemention. Of course, lazy programmer gains nothing
compared to your scheme. Less lazy programmer may divide modules
into groups and only import groups that are needed, more lines
of code but also more control. Or programmer can specify imports
for each module which usually is not a big deal.
As as data point, I have system containing more than 1000 modules.
There are 1064 explicit import statements. Number of needed
imports is lowered by different features: there is possibility
of inheritance for interfaces and inheritance of implementation,
both do import as part of their function. There are also
calls using qualified name (probably more than 10000 such calls).
And yes, import statements need maintenance, IME it was not a
problem as import statements were small part of source. Normally
I would import a module if I need to use at least twice something
from the module and usually number of uses were higher.
And module import tended to change slower than normal code.
Would it even allow mutual imports? If not then that's another
nightmare, which is likely to generate lots of extra dummy modules which
only exist to get around the restriction.
I'm sorry, but I tried such a scheme, and decided it was awful.
One can do better than Turbo Pascal or Modula 2. But IME both
had quite resonable module systems. You may follow Oberon and
instead of separtate interface text just mark exported things.
But explictit imports, more precisely programmer ability to
restrict imports only to those which are explicitely specified
is essential.
Turbo Pascal and I think also Modula 2 distinguish import in
interface form import in implementation. Imports in interface
part must form a tree (no cycles allowed). Imports in
implementation part allow arbitrary dependencies. One could
allow weaker restrictions, for example during compilation you
may allow patially defined things and only require that there
are no cycles when you try to fill needed information.
For example module A could define a type depending on constant
from module B and module B could define a type depending on
module A. Compilation of type in A would look up in B which
would give value of the constant. Similarly, compilation of
type in B would look up in A. As long as all such chains
of lookups resoleve without cycles you can compile the whole
thing. But IME already simpler systems are adequate.
-- Waldek Hebisch