[comp.lang.ada] proposal for Ada preprocessor

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (12/14/89)

From arny@cbnewsl.ATT.COM (arny.b.engelson):
> You can argue for or against such a thing based on philosophical reasons,
> but if experienced, competent programmers are going as far as using cpp, 
> we really ought to create a standard Ada preprocessor.

   A standard preprocessor would have the advantage of being standardized,
   but would suffer the disadvantage that compiler optimizations are not
   possible where the compiler has no knowledge of high-level semantics,
   which is a major reason not to simply codify the preprocessing practice. 

   One example of where this would appear inappropriate would be Classic 
   Ada, a preprocessor used to generate Ada code which implements the 
   object-oriented mechanisms of inheritance and dynamic binding.  It
   would seem that substantial optimizations could be performed if the
   compiler had knowledge of the inheritance graph, but not if this 
   knowledge is kept hidden from the compiler by a preprocessor. 

   In addition, a compiler can simply have a "preprocessing" pass as its
   first phase if it so chooses; it would therefore seem that we would lose
   nothing by defining our features as part of the language rather than as 
   part of the input to a separate preprocessor.

   These are of course "philosophical" arguments, but I really think the 
   use of preprocessors should be limited to:

      - those who are doing programming language research

      - cases in which a language's revision cycle is so lengthy
          that important advances are not incorporated within a
          reasonable period of time (and this is certainly the 
          case with the present Ada 10-year revision cycle, which
          I would like to see cut in half). 
         

From emery@D74SUN.MITRE.ORG (David Emery):
> Bill Wolfe sez:
> >  [standardization of symbols like the enumerations in SYSTEM.NAME 
> >   should be ]
> >   Appropriately handled in the package which provides the binding to
> >   the operating system involved.  OS bindings must also be standardized,
> >   and this is taking place; e.g., the IEEE 1003.5 Ada binding to Posix.
>   
> First, there are often options in a program which are not bound to the
> operating system.  One example that I've seen used very effectively
> occurs in the C source for Nethack, where features may be included or
> excluded at compile time by defining or undefining certain symbols.
> These features include things like different types of monsters, as
> well as support for system things, such as compressing save files. 

   I'm not familiar with Nethack (in fact, I try to stay away from
   anything remotely associated with hacking), but it would seem that
   you could do this simply by designing the software system to "with"
   a "Options_Desired" package specification which would be edited by
   the user to reflect the desired optional features; this would keep
   the definitions concentrated in a standard place.

   It seems offhand that the effect of testing whether symbols are
   defined or undefined can be automatically accomplished by defining
   an enumerated type containing all the symbol names, creating a boolean
   array indexed by that enumerated type, and initializing it with the
   appropriate values by named association.  Then the user would simply
   edit the named associations to set desired options to True and others
   to False.  Perhaps you had more in mind than just checking for "defined"?

> Second, as Technical Editor for IEEE 1003.5 POSIX Ada Binding, I see
> several instances in our binding where conditional compilation would
> be very useful to an applications programmer, particularly one trying
> to write portable software.  This is particularly true of the
> execution time symbolic constants, such as the C symbols
> _POSIX_NO_TRUNC and _POSIX_VDISABLE (defined in IEEE P1003.1-1988),
> and depending on the application, may also be true of the compile time
> symbolic constants, such as _POSIX_JOB_CONTROL.

   Again, it seems to me that by a suitable definition of the binding,
   these things could be accomplished using an existing mechanism.

   Assuming that, for example, POSIX_NO_TRUNC is a boolean variable
   whose value changes at run-time and depends on the identity of the
   process requesting its value, why not simply provide a function
   in the binding which finds out the identity of the caller (being 
   an operating system binding, it should be able to do this) and 
   returns the appropriate value to the caller? 

   (Disclaimer: not being the Technical Editor of the Posix binding,
    it's entirely possible that there are major flaws in my suggestion;
    I'm simply trying to isolate the fundamental reasons involved...)

> "Ultimate standardization", even of operating system names, is a long
> way away.  I don't see anyone racing around trying to standardize such
> things, either.  

   Tell me about it.  One particularly ludicrous example: one would think
   that compiler vendors would want to make it easy for you to write
   software which is portable across THEIR line of Ada compilers, if
   not anyone else's.  Therefore, one would expect the compiler vendors
   to supply definitions of SYSTEM.NAME which enumerate all the hardware
   platforms for which compilers exist in the vendor's product line, so
   that developers could write software which targets all the platforms
   for which that vendor markets Ada compilers.  If the vendor wanted to
   frustrate moving to another vendor's compiler environment, the exact
   names used in the enumeration could differ from those used by all other
   known vendors.  I know of at least two major compiler vendors, with 
   product lines spanning dozens of platforms, whose definition of 
   SYSTEM.NAME enumerates exactly one platform: the machine on which 
   the compiler at hand happens to run!!!
 
> I don't believe that it's worth waiting for,
> particularly since it won't solve all the problems.

   I'll agree that it's not worth *waiting* for... it's worth *PUSHING* for!!!

   Still trying to isolate why it "won't solve all the problems", though...


   Bill Wolfe, wtwolfe@hubcap.clemson.edu

   P.S. I could kick myself for not putting in a 9X suggestion that
        the rule about all field names being distinct be set up such 
        that one can do variant records whereby each of the mutually
        exclusive variants are identically named...  that rule makes 
        us add contrived suffixes to the field names just to get them 
        past the compiler, which would appear to be very nonproductive.

tynor@prism.gatech.EDU (Steve Tynor) (12/14/89)

In article <7423@hubcap.clemson.edu> billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu writes:
...
>   It seems offhand that the effect of testing whether symbols are
>   defined or undefined can be automatically accomplished by defining
>   an enumerated type containing all the symbol names, creating a boolean
>   array indexed by that enumerated type, and initializing it with the
>   appropriate values by named association.  Then the user would simply
>   edit the named associations to set desired options to True and others
>   to False.  Perhaps you had more in mind than just checking for "defined"?

What about the cases where disabling a feature should prevent 'with'ing a
package? (e.g. don't 'with' a DEBUG_TRACE package in a released version) -
Your method will prevent calls to the trace procedures, but the DEBUG_TRACE
package would still be linked in to the executable (ignoring potential linker
optimizations that might recognize that none of that package's code is actually
called).

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Never put off until tomorrow what you can avoid altogether.   
                     
    Steve Tynor
    Georgia Tech Research Institute
    Artificial Intelligence Branch
    tynor@prism.gatech.edu

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (12/15/89)

From tynor@prism.gatech.EDU (Steve Tynor):
> What about the cases where disabling a feature should prevent 
> 'with'ing a package? (e.g. don't 'with' a DEBUG_TRACE package 
> in a released version) - Your method will prevent calls to the 
> trace procedures, but the DEBUG_TRACE package would still be 
> linked in to the executable (ignoring potential linker optimizations 
> that might recognize that none of that package's code is actually called).

   No, in fact these linker optimizations are relied upon very heavily
   in Ada.  Consider a generic abstract data type -- the idea is to 
   provide as much functionality in that ADT as can reasonably be 
   expected to ever be required by any of the users.  Any functionality 
   which can be expressed generically is an excellent candidate to be
   included in the package.  Now if we could not rely upon these linker
   optimizations, then ADT developers would go crazy trying to keep
   5000 variations of the same package and ADT users would go crazy
   trying to select the package having exactly the set of operations
   they will use and no more.  Obviously this is ridiculous -- both
   developer and user rely instead upon the fact that the compiler/
   linker/etc will automatically trim away anything not referenced 
   by the user.  To assume otherwise is inconceivable.


   Bill Wolfe, wtwolfe@hubcap.clemson.edu