Promised unit "paper"

Grant Jacobs gjacobs at bioinfotools.com
Mon Mar 10 01:34:28 CET 2003


Well, I promised that I'd write up a brief account of what I really 
meant. Unfortunately I'm going to have to let it slip a little as I 
am extremely busy. Hope this rushed effort make its clearer, not more 
confusing! Looking at it briefly, if anything its redundant as all 
this seems to have already been covered, but all the same... I did 
promise more examples, which I have to admit I'm out of time for... 
maybe another week.

Anyway, on with the show.

A. Layout.

Basically identical to BP units:

unit DemoUnit;

interface
    uses whatever;

    <export declaration part>
end.

implementation
   uses whatever, somemore;

   <definition part>
end.

The difference lies in the way the elements are used, not the syntax.

Because of this, I suspect if this were to be implemented, a compiler 
switch such as the one Chief suggested would be appropriate. No new 
keywords, Frank! ;-)

There are no different types of uses clauses; they always do the same 
thing: import stuff. The difference is what happens once the stuff is 
imported.

The implementation doesn't import the interface, it only checks 
against the interface's declaration part. So it has to import its own 
stuff for itself; more on that in a mo'.


B. Independence of action of the interface and implementation sections

Firstly, let's clarify the flow of information of interface and 
implementation sections as this seems to have caused confusion 
amongst some people. Conventional units effectively work such that 
the declarations in the interface are imported into the 
implementation section of the same unit.

Here, interface exports all of its contents to other units. Its 
declarations are *checked* against those of the implementation 
section. The implementation section has its own definitions; it does 
not import those from the interface for its use. As a consequence, it 
does not import the uses present in the interface section. Right?

You *could* have the declarations in the interface imported as in BP 
units, but I believe it works best - for these types of units - if 
the two are more-or-less independent, bar the checking of the 
declarations. If you do have the implementation import the stuff from 
the interface, you now are asking for trouble with the uses clauses.

Each section separately imports (uses) any other units that they 
need. This isn't checked across the interface/implementation 
boundary; only the declaration part is.

*Everything* in the interface is exported, including any imported 
units (via uses). One rule, no exceptions. The interface section is a 
container saying that "these things ought to be exported".

Everything in the implementation section is private.

An interface is free to import (and hence re-export) any unit it 
feels relevant. It could for example import a related unit which is 
not needed in the implementation of the current unit, but which is 
useful for the users of the current unit in some way.

The interface section will, of course, have to import the units 
needed to satisfy the declaration part of the interface. This has the 
effect that users of the current units get these dependencies "for 
free". This can work well, provided that developers of lower-level 
units don't place a lot of things into the interfaces that really 
aren't needed to be there - which they ought not to be doing anyway. 
Put in another way: the current unit's interface looks after the 
"required definitions" on behalf of any users of the current unit by 
exporting those that are needed. (To do this with more control - a 
good thing I think - you really need the ability to import only 
subsets of an interface.) We've already discussed how this can shield 
higher-level units from re-organisation of code in lower-level units.

The implementation is free to import units it needs that are not 
needed to satisfy the interface declaration part or needed by the 
user of the current unit. It could, for example, import units which 
are effectively private to the implementation of the current unit, 
such as one we decided to bundle all system-dependent elements into 
or a unit with some obscure internal manipulations which are 
necessary for the implementation but really ought to be hidden from 
higher-level units.

Because of the way things work, there will almost always be a uses in 
both the interface and the implementation, unlike in BP units where 
you can use only only one uses in the interface section and rely on 
the implementation section picking this up. Having the uses in the 
interface imported by the implementation imposes restrictions on the 
interface and if you left things that way the idea of re-exporting 
interfaces of imported units would awkward. I think this is where 
some people's early complaints of "re-exporting everything" come from 
(i.e. they are thinking of a single uses in the interface section 
importing everything needed for both the interface declarations and 
the implementation. I wouldn't want all the stuff for the 
implementation section re-exported either and with the two uses you 
don't have to.). You really need the interface and implementation 
sections to be more independent and you need a uses clause in both 
(so that they are independent) to make this work well.

You could mimick the equivalent of the BP uses situation, by allowing 
the result of a uses clause outside both the interface and 
implementation sections to be 'read-only' to both sections, but 
personally I think this could be confusing - ? (You might have 
problems if the interface and implementation are placed in two 
separate files - haven't got time to think about this right now.) I'm 
really not sure what to do about the possibility of a uses clause 
outside of both sections, but it strikes me as being inconsistent 
with the rest of the approach.

While you could introduce an export clause of some sort, they aren't 
really necessary under this scheme and it seems easier on the 
programmer to just remember that everything in the interface is 
exported, including what is brought in through uses. Its a simple 
enough rule. And no new syntactic elements, Frank! (But perhaps some 
of the behaviour differences are annoying instead?)

BTW, I don't have experience with use of several interfaces for one 
module as Frank mentioned in a earlier post (he says this is possible 
in EP). If anyone has any comments on this, I'd be happy to hear them.

Not recommended in general, but on rare occasion useful - you can 
allow users to optionally relax the type checking across the 
interface/implementation barrier (comparing the implementation's 
definitions to declaration part of the interface) to allow explicit 
recasting of types for the rare occasions this is useful. This isn't 
possible if the interface is imported into the interface section. Not 
exactly a feature to rest a debate on, though ;-) The inheritance is 
the key thing; this is just a minor aside.


C. Circular references.

Skating out on thin ice here...

If a unit's interface has already been imported, a re-importing of it 
is redundant (unless you allow importing only parts of an interface, 
but let's keep this simple for now). This ought to be able to break 
the deadlock -- ? Ditto for the initialisation code.



I have to get back to work, so this is where I stop. Sorry... or 
perhaps you're grateful?! ;-)


Cheers,

Grant
-- 
-------------------------------------------------------------------
Grant Jacobs Ph.D.                                     BioinfoTools
ph. +64 3 476 1820  (office, after 10am)               PO Box 6129,
or  +64 25 601 5917 (mobile)                               Dunedin,
gjacobs at bioinfotools.com                               NEW ZEALAND.
    Bioinformatics tools: deriving knowledge from biological data
Bioinformatics tools - software development - consulting - training
Check out the website for more details: http://www.bioinfotools.com

The information contained in this mail message is  confidential and
may  be legally privileged. Readers of this message who are not the
intended recipient are hereby notified that any use, dissemination, 
distribution or reproduction of this message is prohibited. If  you
have received this message in error please notify the sender immed-
iately and destroy the original message.  This applies also to  any
attached documents.




More information about the Gpc mailing list