Modules

Hans-Dieter.Dreier@Materna.DE Hans-Dieter.Dreier@Materna.DE
Mon, 10 May 1999 15:51:47 +0200


--U2ADyElC4amfFKEsxlqTOPThSD8WH9pE
Content-type: text/plain; charset="ISO-8859-1"
Content-transfer-encoding: quoted-printable

>Hans-Dieter Dreier wrote:
>
>>> Why would you want to know that something is conditionally compiled?  I=
f
>>> I use a normal if, it can optimise it out or not, it doesn't affect me
>>> for the most part.
>> If I see an #if (and know its value) I know definitely which way control
>will
>> flow.If it is a normal if, I can't be so sure - I first have to check
>whether its
>> value is constant and known.
>
>Well, you don't definitely know which way it will flow, you only know
>that it will definitely be known at compile time.  You can't see that
>from an if, instead you have to understand what the identifier
>represents.  But the constancy should usually be obvious from the name,
>e.g. IS_UNIX.

I see. Good point. How about having the editor color-code the affected part=
s of the source code, according to the current value of the #if? Wouldn't t=
hat be nice?

>>> (b) To require the programmer to specify redundant information about
>>> what they intend to use?
>> No, too much hassle. What would be gained?
>
>Well, the same as any redundant information - to try and prevent errors
>by catching inconsistent programming.

Sure, but why not let the editor/compiler state what it thinks about it? If=
 the programmer sees that it is what he/she intended, everything is OK. Oth=
erwise the editor/compiler's info also provides a hint to what has gone wro=
ng. I'm not at all against having extra information available, I just want =
to avoid having to type it myself.

>>> (d) If included in types, could be used to restrict what elements a
>>> defined method can implicitly access.
>> What should that be good for?
>
>It could be used to prevent it from calling certain methods.  It's
>basically like a sandbox, ie a set of policies about what other elements
>a element can access and in what ways.

So it's sort-of "private the other way round" (ie seen from the server inst=
ead of the client)?

>A sandbox is usually only applied to loaded/generated classes, although
>it could become a language entity.  Whether this would be worthwhile, I
>don't know.  And how sophisticated to make it would also be a question.

I think the sandbox is particularly useful for environments like Java where=
 code comes from different sources and security as well as "mixability" is =
a major issue. I'm not sure whether this will be the case for a typical Ult=
ra environment.

>>> That's a good point - the code may change outside of the editor.  If
>>> it's read-only, it's OK, but if you can write to the code, we could get
>>> problems.  If we have a lock facility to make it read-only if someone
>>> else is editing it, that would work, but what about if not?
>>> We probably should attempt to ensure files are not saved if they aren't
>>> edited, although this might not be easy given my desire to make them
>>> kind of implicit.  Or it might be dead easy.

If each includeable entity (feature, class, ...) knows its source file, it =
shouldn't be difficult.

>> Every decent editor does it.

The real challenge comes if we attempt to mix changes. Until recently I wou=
ld have shuddered at the mere thought of it, but now I've seen what a marve=
llous job can be done even mixing C++ source files as long as the common ba=
se line is known. Actually, that was one of the sparse moments where I thou=
ght "That must be magic": To just hit "perform automated merge" and it gets=
 it right in 99% of all cases.

>It's probably quite doable.  We just have to make sure that when a
>change is made through a view, which would usually not care about
>modules, the editor determines which file this affects and marks it as
>changed since save.  The complication is that a normal editor usually
>only shows a file per window, whereas I'd prefer it in one window.

So do I.

>That does lead me to comment though that a nice view option would be to
>restrict a view to only showing one module.

Of course - although being able to restrict the display property-wise (ie j=
ust showing the parameters and leaving out everything else) might be even m=
ore usable. BTW: In database-speak the former would be a "restriction" (sho=
wing only some records), the latter a "projection" (showing only some field=
s). Maybe we should adopt these terms for brevity.

>> Actually, the standard file format (binary) saves a copy of all the incl=
uded
>parts
>> along with the top-level module.
>
>Do you mean the code from other modues, or just all the information
>necessary to generate the code?

All the source code from other modules is always included. Whether compiled=
 (binary) parts are included depends on when you save: If you save after a =
compile, the generated code will be included. If you save after editing, bu=
t before compiling, only the source will be included. =


>> This results in extremely fast load/save cycles (and in huge files as we=
ll,
>> but who cares?) and has the added benefit that you need only transfer on=
e
>> file if you wish to copy a project. If the included files are not presen=
t
>> at the copy location, the load function will simply complain and continu=
e
>> to use the existing copy. Otherwise it would have checked the file dates=
 to
>> see whether a refresh was due.
>
>Well it seems like it could be useful to be able to work in the absence
>of the other files, but would you need this often in practice?

I found it conventient when I used to transfer code between my office and m=
y home, on diskette. But maybe now it isn't that important anymore (as long=
 as you don't have to transfer a zoo of different file types where some are=
 needed and some big ones are not, like in VC++).

>I'm actually not aware of any compilers that do inheritance
>optimisations, but they seem to me to be a very useful if they can be
>done.

Maybe it's because they decided it's not worth the effort?

> By this I mean things like merging two impls together if the
>parent impl is only used by one subimpl, doing the same for types, and
>removing multiple inheritance where it's unneeded.
>
>These are based on the premiss that you might have separate entities for
>good reason, but in one particular program they might not need to be
>separate.  And yes, they would usually need to be inter-module.
>
>As an example take the following (implementation) inheritance hierachy.
>
>      Abstract A      Abstract B
>     /          \    /
>Concrete C    Concrete D
>
>Consider this to be closed, ie we're guaranteed nothing else will extend
>these implementations.  Note the impl MI on D.
>
>Since B is only used by D, we know that Bs methods will only be used in
>D.  Hence, any methods not used by D can be eliminated, and anything
>used by D can be inlined into the body of D, or become Ds methods if
>they are inherited but not overridden (which is really a simple case of
>inlining), and then eliminated from B.  Once all of the methods of B are
>eliminated, B can be eliminated.  Hence there is one less element in the
>system, and there is no MI.

You would need to recompile B's methods to reflect the different impl layou=
t of their new environment (D). In effect, this is what C++ template classe=
s do: Sort-of textual merge.

But I think the gain in execution speed would be pretty small, maybe one in=
direction per method call or so (whatever MI takes as its toll). The reduct=
ion in code size could be significant, though. BTW, >90% of the possible im=
provement could be gained by just deleting the superfluous code and NULLing=
 out any references to it, without changing instance layout or vtable layou=
t. That would save of lot of fix-ups.

>Types are probably a little more complicated, since they can be used
>both in variable declarations, impl declarations and type declarations
>rather than just creations and impl declarations.

You mean because of inheritance, which is possible for types but not impls?=
 But I'm not entirely convinced that having a strict impl/type separation i=
s so beneficial that it is justified to have it enforced by rules like lang=
uage syntax...

>An alternative system for doing submodules would be more conventional. =

>That is, a particular subtree is specified to be in another module, eg
>
>/
>| Module A
>| =

>|  /
>|  | Module C
>|  \
>\
>
>/
>| Module B
>\
>
>The modules can nest to arbitrary depths, and there is no "detaching". =

>Again, you would want to modular boundaries to be visible or not
>according to user preference.  It gets a little trickier, since it is no
>longer a matter of specifying a list of modules, but rather you have to
>say C goes into A - kind of like mount points in Unix if you're familiar
>with them.

Wouldn't that imply that a *whole* module is inserted at *one* place?
That would prevent the user from creating something like a debug or trace p=
ackage that would extend *several existing* classes: The included source wo=
uld need to be splitted up.


--

Regards,

Hans-Dieter Dreier
(Hans-Dieter.Dreier@materna.de)=

--U2ADyElC4amfFKEsxlqTOPThSD8WH9pE
Content-type: text/plain; charset="ISO-8859-1"
Content-transfer-encoding: quoted-printable

IDENTIFIKATIONSANGABEN:
a21106a.txt IA5 DX-MAIL X.400 User Agent=

--U2ADyElC4amfFKEsxlqTOPThSD8WH9pE--