comp.lang.ada
 help / color / mirror / Atom feed
* Better support for garbage collection
@ 2001-03-13 18:37 Nick Roberts
  2001-03-14  8:16 ` Florian Weimer
                   ` (4 more replies)
  0 siblings, 5 replies; 115+ messages in thread
From: Nick Roberts @ 2001-03-13 18:37 UTC (permalink / raw)


There follows a proposal that I intend to make to the ARG in the next few
days. I would appreciate comments and criticisms before doing so.

This is the first of many proposals that I shall be likely to make. The fact
that this one comes first is of no significance.

----------

I would like to make a proposal for the next revision of the language which
would provide standardised support for partially user-defined garbage
collection, and a standard mechanism for disposability.

I think these facilities should be defined in an optional annex.

RM95-13.11 defines a mechanism permitting a degree of user control over the
dynamic allocation and deallocation of storage for objects. This mechanism
is based on the abstract type Root_Storage_Pool, and defines the interface
for this type. However this interface is not sufficient for the provision
of a user-defined storage pool which supports garbage collection.

The following proposal defines a new abstract type, derived from
Root_Storage_Pool, which adds sufficient extra functionality to this
interface to facilitate user-defined garbage-collecting storage pools
(UDGCSPs). The new type is called Repositioning_Storage_Pool, from the
assumption that garbage collection will (generally) require the
repositioning of objects in memory.

The language should define the following package:

   package System.Storage_Pools.Repositioning is

      pragma Preelaborate(System.Storage_Pools.Repositioning);

      type Repositioning_Storage_Pool is
         abstract new Root_Storage_Pool with private;

      type Object_Token is new Address;

      procedure Allocate(
         Pool : in out Repositioning_Storage_Pool;
         Token : out Object_Token) is abstract;

      procedure Deallocate(
         Pool : in out Repositioning_Storage_Pool;
         Token : in Object_Token) is abstract;

      procedure Lock(
         Pool : in out Repositioning_Storage_Pool;
         Token : in Object_Token;
         Storage_Address : out Address) is abstract;

      procedure Unlock(
         Pool : in out Repositioning_Storage_Pool;
         Token : in Object_Token) is abstract;

      procedure Tidy(
         Pool : in out Repositioning_Storage_Pool) is abstract;

      function Max_Lock_Count(Pool : Repositioning_Storage_Pool)
         return Natural is abstract;

      Locking_Error: exception;

   private
      ... -- not specified by the language
   end System.Storage_Pools.Repositioning;

A type derived from Repositioning_Storage_Pool is a 'repositioning pool' (a
UDGCSP), whose operations are defined below.

These operations all work in a way which is 100% upwards-compatible with
Root_Storage_Pool, so that a compiler which does not support the extra
functionality implied by a repositioning pool will nevertheless work
correctly with the pool (although no garbage collection will be performed).

Each pool element is identified by a unique (within the pool) value of the
type Object_Token, called the element's 'token'. This value will never
change throughout the life (from its allocation to its deallocation) of the
element. The type Object_Token is the same size as System.Address (and will
typically actually be an address, hence the declaration which makes this
conversion convenient).

Each pool element has a 'lock count', of an unspecified integer (or
modular) subtype, whose range does not exceed that of Standard.Natural. The
element is said to be 'locked' if its lock count is a value other than 0.

The overloading of the Allocate procedure with a Storage_Address parameter
sets the lock count of the pool element it allocates to 1, reserves a token
for the element, and reserves a block of memory, whose address is passed
out to the Storage_Address parameter.

The overloading of the Allocate procedure with a Token parameter sets the
lock count of the pool element it allocates to 0, reserves a block of
memory, and reserves a token for the element, whose value is passed out to
the Token parameter.

Either Allocate procedure may raise Storage_Error as a result of having
insufficient memory for a block or for a token.

The Lock procedure increments (by 1) the lock count of a pool element. The
current address of the block of memory reserved for the element is passed
out in Storage_Address.

For any repositioning pool, there is a maximum value the lock count of any
of its elements can reach. The Max_Lock_Count function returns this
maximum. If a call is made to Lock for an element whose lock count equals
this value, the Locking_Error exception is raised (and the lock count is
not changed).

I suggest a recommendation (or perhaps a stipulation) that the maximum lock
count is never less than 15. (Although this recommendation will apply to
the user rather than the implementation, except for implementation-supplied
repositioning pools.)

The Unlock procedure decrements (by 1) the lock count of a pool element,
unless the element's lock count is already 0, in which case it raises the
Locking_Error exception instead.

The overloading of the Deallocate procedure which takes a Storage_Address
parameter raises the Locking_Error exception if the pool element's lock
count is not 1 (and does not deallocate the element).

The overloading of the Deallocate procedure which takes a Token parameter
raises the Locking_Error exception if the pool element's locking count is
not 0 (and does not deallocate the element).

The Tidy procedure carries out what is called 'compaction' or
'defragmentation' (the second stage of the garbage collection process) on a
pool. Blocks of memory reserved for objects are moved (their contents
copied to other locations in memory) so as to reduce (to a minimum) the
amount of memory which is effectively unusable (typically because many of
the gaps between the blocks have become too small). The block of memory
reserved for a pool element must not be moved if the element is locked (its
lock count is not 0).

The first stage of the garbage collection process is 'scavenging', the
recognition and deallocation of allocated objects which have become
'unreachable' (inaccessible by any degree of indirection). This stage needs
to be carried out by code specially generated by the compiler.

A 'disposable object' is a dynamically allocated object which an
implementation (of Ada) is permitted to deallocate at any time, if it needs
to do so in order to successfully complete the allocation of another
object.

The language should define a subtype in the package System:

   subtype Disposability_Level is
      Integer range 0..implementation_defined;

and an attribute Disposability, which applies to any pool-specific access
type, and has a static value of subtype Disposability_Level. A value other
than 0 indicates that objects referenced by access values of this access
type are disposable. The disposability level of the objects is the same as
the disposability level of the access type. The default value is 0, but may
be set by a representation clause. An implementation must never attempt to
dispose of an object with a certain disposability level if there exists
another object with a higher disposability level.

Disposal of a controlled object will cause finalization of the object as
normal.

The principles behind the above interface are explained briefly below.

Whenever an implementation makes an attempt to allocate an object in a
repositioning pool, and that attempt fails (Storage_Error being raised), it
can intervene by carrying out garbage collection (both stages) and then
attempting the allocation again. If the second attempt fails, the
implementation may attempt to deallocate a disposable object, and then try
once more. Eventually, on repeated failures, defeat must be conceded (and
the Storage_Error exception propagated as normal).

Additional calls to Tidy may be made, by the implementation or the user,
e.g. as part of an ongoing garbage collection strategy.

The imlementation must always lock a pool element before reading from it or
writing into it, in order to prevent it being moved at an inopportune
moment. On the other hand, the implementation should unlock elements as
frequently as possible (without overly reducing execution speed), so that
the Tidy procedure is not stymied by locked elements to the point of being
made ineffective.

I would suggest that an implementation should employ a strategy where it
unlocks any elements of a particular pool it has locked at every 'control
point', where a control point with respect to a pool is defined as being:

(1) just before any call to an allocator for an access value associated
with that pool;

(2) just before any call to a subprogram which may (or does) contain a
control point for that pool;

(3) any instance of pragma Inspection_Point (see RM95-H.3.2).

The same comments made in RM95-13.11(27-30), regarding tasking, would apply
to UDGCSPs. Locking, unlocking, and moving operations would need to be
atomic, for a task-safe pool.

The use of access values associated with UDGCSPs will, in general, be
inefficient compared to non-repositioning pools; this is a compromise
inherent in (full) garbage collection. It may be possible for compilers to
remove a great deal of locking and unlocking in the absence of (potential)
parallel task usage of a UDGCSP. Only calls to Tidy should ever move pool
elements; elements should remain statically positioned in memory otherwise
(regardless of their lock counts).

Garbage collection facilities for Ada tend to be rare at the moment. I
believe there are many situations where the availability of garbage
collection would be of genuine value to Ada programmers.

For example: students beginning to learn Ada, and wanting to be relieved of
the burden of storage management until later in their studies; anyone
writing a program which is likely to have a very short useful life, or who
for any reason requires speed of development more than speed of execution;
whenever an 'engine' of something else that requires garbage collection
(e.g. a Java Virtual Machine) is being implemented in Ada.

I think that a language definition of user-defined garbage-collecting
storage pools (UDGCSPs) would help in two ways towards making garbage
collection facilities more available to Ada programmers: first, it would
lessen the burden on the compiler writer, who would need only to be
concerned with the first stage of garbage collection (the second stage
being the province of UDGCSPs); second, it would open up a 'market' in
UDGCSPs, offering hopefully many variations with regard to price,
functionality, reliability, and efficiency.

Disposability is a facility provided by a variety of other languages, and
its use is an important technique for certain kinds of software (e.g. many
'artifical intelligence' applications). In addition, it is a facility that
can be very helpful for some kinds of commercial software, especially
programs which need to be able to cope gracefully with environments that
provide widely differing amounts of memory.

Even if an implementation supports repositioning pools, it should not be
required for any of its standard storage pools to be repositioning pools.
Every implementation must continue to support non-repositioning pools.

Finally, I believe the design I propose above would have the benefit that
UDGCSPs could still be used with implementations that did not specifically
support them (albeit without the garbage collection functionality), and
that it does not impose any difficulty on the programmer requiring -- e.g.
for speed reasons -- a non-repositioning pool.

----------

One question in my mind is whether the second parameter of the Unlock
procedure should be a token or an address. Might the latter enable compilers
to generate slightly better code?

Apologies for the length of the post!

--
Nick Roberts
http://www.AdaOS.org






^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-13 18:37 Better support for garbage collection Nick Roberts
@ 2001-03-14  8:16 ` Florian Weimer
  2001-03-14 18:52   ` Robert A Duff
  2001-03-14 19:29 ` Robert A Duff
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 115+ messages in thread
From: Florian Weimer @ 2001-03-14  8:16 UTC (permalink / raw)


"Nick Roberts" <nickroberts@callnetuk.com> writes:

> One question in my mind is whether the second parameter of the Unlock
> procedure should be a token or an address. Might the latter enable compilers
> to generate slightly better code?

IMHO, it's better to separate address-based storage pools from
token-based storage pools completely.  In addition, your proposal
doesn't analyze the interaction of such storage pools with the rest of
the language.  For example, subprogram calls with arguments allocated
in token-based storage pools can be implemented in two different ways
(caller locking and callee locking), with different results (less
locking overhead vs. short locking periods).

The general question regarding garbage collection and Ada is: With the
current Ada language, type safe, non-compacting garbage collection is
already possible.  Why don't typical Ada implementations (which
produce native code) support garbage collection?  There seem to be
many reservations about garbage collections, so I think the priority
issue is to provide an implementation of garbage collection which
demonstrates that better garbage collection 



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-14  8:16 ` Florian Weimer
@ 2001-03-14 18:52   ` Robert A Duff
  2001-03-14 19:40     ` Florian Weimer
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-14 18:52 UTC (permalink / raw)


Florian Weimer <fw@deneb.enyo.de> writes:

> The general question regarding garbage collection and Ada is: With the
> current Ada language, type safe, non-compacting garbage collection is
> already possible.

So is type-safe compacting garbage collection.

>...  Why don't typical Ada implementations (which
> produce native code) support garbage collection?  There seem to be
> many reservations about garbage collections, so I think the priority
> issue is to provide an implementation of garbage collection which
> demonstrates that better garbage collection 

...what?

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-13 18:37 Better support for garbage collection Nick Roberts
  2001-03-14  8:16 ` Florian Weimer
@ 2001-03-14 19:29 ` Robert A Duff
  2001-03-14 20:59   ` Brian Rogoff
                     ` (2 more replies)
  2001-03-14 22:05 ` Laurent Guerby
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-14 19:29 UTC (permalink / raw)


"Nick Roberts" <nickroberts@callnetuk.com> writes:

> I would like to make a proposal for the next revision of the language which
> would provide standardised support for partially user-defined garbage
> collection, and a standard mechanism for disposability.

If you're interested in garbage collection, you should get on the gc
mailing list (gclist-digest@iecc.com).  You should also read Jones and
Lins' excellent book called "Garbage Collection", if you haven't
already.

I too think it would be cool if GC for Ada were widely available.
But I think youll have a hard time convincing others.  After all, any
implementation is allowed to provide GC, but nobody has done so, except
when the GC is unavoidable (the Ada 83 implementation on top of the
Symbolics Lisp Machine, and the Ada 95 implementations on top of the
JVM).  Why not?

Robert Dewar would argue that it's because nobody wants it (at least,
nobody wants it enough to pay for it).  A more pessimistic take on this
is that all the folks who understand the glorious benefits of GC have
long since abandoned Ada in favor of "better" languages.

It is also possible to use Boehm's conservative collector with Ada.
Does anybody do so?

(I find the idea of conservative collection somewhat distasteful,
but it does seem to work in many cases.)

You seem to be saying that the user provides the compaction phase, and
the implementation provides the tracing phase.  But the tracing phase is
the hard part.  So how does this make GC so easy to implement that
implementers will do it when they haven't already?

Now to the technical points: I'm completely confused about what this
proposal means.  I don't see how the user can write the Tidy routine.
(Why not call it Compact?)  The Tidy routine needs to modify all the
pointers to objects in the repositioning pool -- how is it supposed to
find them?  It doesn't know the layout of all the records in the pool.
Also, it can't find all the pointers from outside the pool to objects in
the pool.

A sample implementation of package Repositioning would help me
understand.  Eg, what is the intended implementation of tokens?
(Or at least one possible implementation?)

Note that you can have pointers into the middle of objects -- these also
need to be adjusted when objects move around in memory.  (Pointers to
aliased components.  Renamings of components.  Components passed by
reference.)

Note that the tracing phase needs to trace the whole world (all stacks
and storage pools) whenever *any* repositioning pool is collected,
because you haven't proposed to restrict pointers from the outside.

You didn't say when the compiler is supposed to generate calls to the
Allocate and Deallocate routines (the ones with token parameter), so I
don't understand the point of them.

Note that it is not always known at compile time whether a given access
type's pool is a repositioning pool, so the code generated for "new" and
"Unchecked_Deallocation" must be as in the RM (eg, these can't call the
new Allocate).

>       procedure Allocate(
>          Pool : in out Repositioning_Storage_Pool;
>          Token : out Object_Token) is abstract;

> Each pool element has a 'lock count', of an unspecified integer (or
> modular) subtype, whose range does not exceed that of Standard.Natural. The
> element is said to be 'locked' if its lock count is a value other than 0.

Nonnegative, right?

> The overloading of the Allocate procedure with a Token parameter sets the
> lock count of the pool element it allocates to 0, reserves a block of
> memory, and reserves a token for the element, whose value is passed out to
> the Token parameter.

I don't see how it can reserve a block of memory, since it doesn't take
size and alignment parameters.  I'm confused as to what this routine is
for.

> I suggest a recommendation (or perhaps a stipulation) that the maximum lock
> count is never less than 15. (Although this recommendation will apply to
> the user rather than the implementation, except for implementation-supplied
> repositioning pools.)

I don't see the point of such a recommendation.

> The first stage of the garbage collection process is 'scavenging', the
> recognition and deallocation of allocated objects which have become
> 'unreachable' (inaccessible by any degree of indirection). This stage needs
> to be carried out by code specially generated by the compiler.

But that's not really how many (most?) GC's work.  The don't recognize
unreachable objects, and they don't deallocate them individually.  They
find all the *reachable* objects, and whatever's left over is garbage.
In a copying collector, the garbage need not be touched.  So the cost of
GC is proportional to the amount of reachable data.  If you have to
individually deallocate all the garbage objects, then it's proportional
to the size of the heap, which seems bad.

> A 'disposable object' is a dynamically allocated object which an
> implementation (of Ada) is permitted to deallocate at any time, if it needs
> to do so in order to successfully complete the allocation of another
> object.
> 
> The language should define a subtype in the package System:
> 
>    subtype Disposability_Level is
>       Integer range 0..implementation_defined;

Why "implementation_defined"?  It seems like a useless non-portability.

> and an attribute Disposability, which applies to any pool-specific access
> type, and has a static value of subtype Disposability_Level.

This is the first attribute of a non-scalar type that is static.

>... A value other
> than 0 indicates that objects referenced by access values of this access
> type are disposable.

It makes no sense to talk about the objects "referenced by access values
of this access type", because there can be many access values, of many
different types, all pointing to the same object.  Perhaps you mean
"allocated by allocators for this access type"?  (BTW, "designated" is
the Ada jargon -- not "referenced".)

> Whenever an implementation makes an attempt to allocate an object in a
> repositioning pool, and that attempt fails (Storage_Error being raised), it
> can intervene by carrying out garbage collection (both stages) and then
> attempting the allocation again. If the second attempt fails, the
> implementation may attempt to deallocate a disposable object, and then try
> once more. Eventually, on repeated failures, defeat must be conceded (and
> the Storage_Error exception propagated as normal).

Deallocating a disposable object can leave dangling pointers (which is
the whole point of GC to avoid).  Are you assuming the Finalize routine
will track them all down and do something about them (eg null them out)?
What happens if it doesn't.

You didn't mention anything about finalization of normal
(non-disposable) objects.  There are nasty interactions
there.  Eg, can the finalization routine resurrect the object
by creating a new pointer to it?  Java has an answer to this
(not a very good one, IMHO).

> Additional calls to Tidy may be made, by the implementation or the user,
> e.g. as part of an ongoing garbage collection strategy.
> 
> The imlementation must always lock a pool element before reading from it or
> writing into it, in order to prevent it being moved at an inopportune
> moment. On the other hand, the implementation should unlock elements as
> frequently as possible (without overly reducing execution speed), so that
> the Tidy procedure is not stymied by locked elements to the point of being
> made ineffective.

It seems like the compiler must generate a Lock before each call where a
movable object is passed by reference (or a part of such an object).
And it must remain locked throughout that call, because the called
procedure doesn't know whether it has a pointer into a repositioning
pool.  Doesn't sound very "frequent".

For that matter, it seems like it has to Lock even if the thing is
passed by copy, because the address of the actual is presumably saved at
the call site (at least in some cases).

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-14 18:52   ` Robert A Duff
@ 2001-03-14 19:40     ` Florian Weimer
  2001-03-15 13:18       ` Nick Roberts
  0 siblings, 1 reply; 115+ messages in thread
From: Florian Weimer @ 2001-03-14 19:40 UTC (permalink / raw)


Robert A Duff <bobduff@world.std.com> writes:

> > The general question regarding garbage collection and Ada is: With the
> > current Ada language, type safe, non-compacting garbage collection is
> > already possible.
> 
> So is type-safe compacting garbage collection.

Yes, you're right.  Silly me.

> >...  Why don't typical Ada implementations (which
> > produce native code) support garbage collection?  There seem to be
> > many reservations about garbage collections, so I think the priority
> > issue is to provide an implementation of garbage collection which
> > demonstrates that better garbage collection 
> 
> ...what?

Oops.

"is worth the additional complexity.  Until now, implementors and
large scale users have shown little interest in any type of garbage
collection."



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-14 19:29 ` Robert A Duff
@ 2001-03-14 20:59   ` Brian Rogoff
  2001-03-16 16:42     ` Robert A Duff
  2001-03-15  4:35   ` Nick Roberts
       [not found]   ` <87bsr46kxv.fsf@deneb.enyo.de>
  2 siblings, 1 reply; 115+ messages in thread
From: Brian Rogoff @ 2001-03-14 20:59 UTC (permalink / raw)


On Wed, 14 Mar 2001, Robert A Duff wrote:
> I too think it would be cool if GC for Ada were widely available.
> But I think youll have a hard time convincing others.  After all, any
> implementation is allowed to provide GC, but nobody has done so, except
> when the GC is unavoidable (the Ada 83 implementation on top of the
> Symbolics Lisp Machine, and the Ada 95 implementations on top of the
> JVM).  Why not?
> 
> Robert Dewar would argue that it's because nobody wants it (at least,
> nobody wants it enough to pay for it).  A more pessimistic take on this
> is that all the folks who understand the glorious benefits of GC have
> long since abandoned Ada in favor of "better" languages.

IMO, just tacking on GC to an existing language doesn't make it very 
much better. When the language designers design a language with the 
expectation of GC, they may then support some higher level features, 
like first class functions, which do make the language much better. 
Ada is far less leaky than C family languages, so the win of just 
adding a GC seems smaller for Ada. 

Of course, you still have designers who blow it by putting in GC and 
omitting such features, but then after a few years they realize they 
screwed up and hack in such things. Java and Eiffel are good examples 
of such screw ups (nested/anonymous classes and "agents"). 

> It is also possible to use Boehm's conservative collector with Ada.
> Does anybody do so?
> 
> (I find the idea of conservative collection somewhat distasteful,
> but it does seem to work in many cases.)

Maybe if it were called a "probabilistic garbage collector" you wouldn't 
mind? ;-)

Didn't Norman Cohen have a proposal for a storage pool extension that 
provided some support for garbage collection? I thought so, but my neural 
garbage collector seems to have reclaimed that hunk of my brain...

-- Brian





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-13 18:37 Better support for garbage collection Nick Roberts
  2001-03-14  8:16 ` Florian Weimer
  2001-03-14 19:29 ` Robert A Duff
@ 2001-03-14 22:05 ` Laurent Guerby
  2001-03-16 16:47   ` Robert A Duff
  2001-03-15 17:56 ` Better support for garbage collection Ray Blaak
  2001-03-21 16:15 ` Implementing C/C++ style #include bhazzard
  4 siblings, 1 reply; 115+ messages in thread
From: Laurent Guerby @ 2001-03-14 22:05 UTC (permalink / raw)


What I would like to see in Ada is to have an allocator where you pass
the pool object at allocation and deallocation. One pool per type is
not very flexible.

The advantages I see:

- If you know only one task access the given pool object, you need no
lock

- You can have an allocation / deallocation policy customized
to your local algorithm.

- You can use a strategy where you allocate very quiclky, and
deallocate only on destruction of the pool object.

Why did Ada 95 include pool objects only on a per type basis?

-- 
Laurent Guerby <guerby@acm.org>



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-14 19:29 ` Robert A Duff
  2001-03-14 20:59   ` Brian Rogoff
@ 2001-03-15  4:35   ` Nick Roberts
  2001-03-15 21:37     ` Randy Brukardt
                       ` (2 more replies)
       [not found]   ` <87bsr46kxv.fsf@deneb.enyo.de>
  2 siblings, 3 replies; 115+ messages in thread
From: Nick Roberts @ 2001-03-15  4:35 UTC (permalink / raw)


"Robert A Duff" <bobduff@world.std.com> wrote:

> If you're interested in garbage collection, you should get on the gc
> mailing list (gclist-digest@iecc.com).  You should also read Jones and
> Lins' excellent book called "Garbage Collection", if you haven't
> already.

Not another mailing list! I have visited the web site, and read much of
interest there. I haven't read Jones and Lins, but I have read up on the
subject.

> I too think it would be cool if GC for Ada were widely available.
> But I think youll have a hard time convincing others.  After all, any
> implementation is allowed to provide GC, but nobody has done so, except
> when the GC is unavoidable (the Ada 83 implementation on top of the
> Symbolics Lisp Machine, and the Ada 95 implementations on top of the
> JVM).  Why not?

Perhaps part of the reason is that no infrastructure for it has been
provided by the language standard. Anyway, I am proposing an optional
addition to the language; I don't expect many Ada vendors to support it, but
I feel a few might.

> Robert Dewar would argue that it's because nobody wants it (at least,
> nobody wants it enough to pay for it).  A more pessimistic take on this
> is that all the folks who understand the glorious benefits of GC have
> long since abandoned Ada in favor of "better" languages.

Don't you think it significant that so many other languages do incorporate
GC?

I must say, I get the impression, although I don't understand it, that
Robert, perhaps yourself, and a few others have an antipathy towards GC
which is not entirely objective or rational. It is not a sound argument to
say "Well, I don't want it, so nobody else does either."

The slowness of a GC environment can always be largely overcome, by using
techniques such a B-Tree's lumping data into blocks. The advantages of
having GC, especially from the point of view of software reliability, can be
very great. It is typical these days to hear advice such as "the best way to
maintain the efficiency of NT [the operating system] is to reboot it every
day". It is typical of application programs to leak memory like a sieve. I
suspect there are many Ada programs that commit the same sin, principally
because they do not have GC.

> You seem to be saying that the user provides the compaction phase, and
> the implementation provides the tracing phase.  But the tracing phase is
> the hard part.  So how does this make GC so easy to implement that
> implementers will do it when they haven't already?

If somebody refuses to dig a trench ten metres long, and I say, "Alright,
I'll dig one metre and you dig nine", they may still refuse, but then they
may not! I'm not saying my proposal will make the implementor's job
tremendously easy, just a little bit easier than it is now.

> Now to the technical points: I'm completely confused about what this
> proposal means.  I don't see how the user can write the Tidy routine.
> (Why not call it Compact?)  The Tidy routine needs to modify all the
> pointers to objects in the repositioning pool -- how is it supposed to
> find them?  It doesn't know the layout of all the records in the pool.
> Also, it can't find all the pointers from outside the pool to objects in
> the pool.

I agree with calling it "Compact" instead of "Tidy". The principle is that
this procedure does not need to modify any addresses pointing directly to
objects in the memory the pool controls. The implementation must ensure that
no pool element is ever in an unlocked state if and when Compact is (or
might be) called and moving the element is (or might be) unsafe, in that a
temporarily held address pointing into it may be used to read or write
within the (old position of the) element.

> A sample implementation of package Repositioning would help me
> understand.  Eg, what is the intended implementation of tokens?
> (Or at least one possible implementation?)

The difficult will take an hour. The impossible will take a little longer!
I'll try to cook up an example.

> Note that you can have pointers into the middle of objects -- these also
> need to be adjusted when objects move around in memory.  (Pointers to
> aliased components.  Renamings of components.  Components passed by
> reference.)

Again, it is the responsibility of the implementation to ensure that a pool
element is either locked or safely movable whenever Compact is (or might be)
called.

> Note that the tracing phase needs to trace the whole world (all stacks
> and storage pools) whenever *any* repositioning pool is collected,
> because you haven't proposed to restrict pointers from the outside.

Generally true (but not actually a problem). Perhaps I should rephrase my
proposal to make this clear.

> You didn't say when the compiler is supposed to generate calls to the
> Allocate and Deallocate routines (the ones with token parameter), so I
> don't understand the point of them.

A compiler which supports GC will use the ones with the Token parameter.
Compilers which do not support GC will (naturally) use the ones with the
Storage_Address parameter.

> Note that it is not always known at compile time whether a given access
> type's pool is a repositioning pool, so the code generated for "new" and
> "Unchecked_Deallocation" must be as in the RM (eg, these can't call the
> new Allocate).

In the unlikely case of an access type whose pool is specified by a dynamic
name, I think you are correct. The user would need to use a static name to
avoid this problem.

> > Each pool element has a 'lock count', of an unspecified integer (or
> > modular) subtype, whose range does not exceed that of Standard.Natural.
The
> > element is said to be 'locked' if its lock count is a value other than
0.
>
> Nonnegative, right?

As implied by the range being restricted by that of Standard.Natural, yes.

> > The overloading of the Allocate procedure with a Token parameter sets
the
> > lock count of the pool element it allocates to 0, reserves a block of
> > memory, and reserves a token for the element, whose value is passed out
to
> > the Token parameter.
>
> I don't see how it can reserve a block of memory, since it doesn't take
> size and alignment parameters.  I'm confused as to what this routine is
> for.

You are dead right. I missed these parameters out. Apologies. It should have
been:

      procedure Allocate(
         Pool : in out Repositioning_Storage_Pool;
         Token : out Object_Token;
         Size_in_Storage_Elements : in Storage_Elements.Storage_Count;
         Alignment : in Storage_Elements.Storage_Count) is abstract;

> > I suggest a recommendation (or perhaps a stipulation) that the maximum
lock
> > count is never less than 15. (Although this recommendation will apply to
> > the user rather than the implementation, except for
implementation-supplied
> > repositioning pools.)
>
> I don't see the point of such a recommendation.

The point is simply to prevent repositioning pools providing an inadequate
range, whilst not actually pinning them down to a specific, artificial,
figure.

> > The first stage of the garbage collection process is 'scavenging', the
> > recognition and deallocation of allocated objects which have become
> > 'unreachable' (inaccessible by any degree of indirection). This stage
needs
> > to be carried out by code specially generated by the compiler.
>
> But that's not really how many (most?) GC's work.  The don't recognize
> unreachable objects, and they don't deallocate them individually.  They
> find all the *reachable* objects, and whatever's left over is garbage.
> In a copying collector, the garbage need not be touched.

I didn't mean to give the impression that what I described is how many or
most garbage collectors work. All I meant was that what I described is how a
garbage collector would have to work to be compatible with my proposal.

> So the cost of
> GC is proportional to the amount of reachable data.  If you have to
> individually deallocate all the garbage objects, then it's proportional
> to the size of the heap, which seems bad.

I am assuming that implementors would implement a generational scheme that
would avoid the whole pool having to be scanned at each compaction. (I
suppose you'll want me to demonstrate this in my example too :-)

> >    subtype Disposability_Level is
> >       Integer range 0..implementation_defined;
>
> Why "implementation_defined"?  It seems like a useless non-portability.

Okay, what figure do you suggest?

> > and an attribute Disposability, which applies to any pool-specific
access
> > type, and has a static value of subtype Disposability_Level.
>
> This is the first attribute of a non-scalar type that is static.

Is this a problem?

> >... A value other
> > than 0 indicates that objects referenced by access values of this access
> > type are disposable.
>
> It makes no sense to talk about the objects "referenced by access values
> of this access type", because there can be many access values, of many
> different types, all pointing to the same object.  Perhaps you mean
> "allocated by allocators for this access type"?

What I said is perfectly logical, apart from using the wrong word ...

> (BTW, "designated" is the Ada jargon -- not "referenced".)

... Whoops! (Pardon me :-) ...

I really meant "all objects designated by access values of this type". It
doesn't matter if some of those objects (or any of their subcomponents) are
designated by access values of other types.

Perhaps I should add a specific note that if an object is designated by
several access values, of access types whose disposability levels are
different (but non-zero), the highest of those disposability levels applies.

> Deallocating a disposable object can leave dangling pointers (which is
> the whole point of GC to avoid).  Are you assuming the Finalize routine
> will track them all down and do something about them (eg null them out)?
> What happens if it doesn't.

I omitted to note that an object should only be disposed (deallocated
automatically by the implementation, even while being reachable) if it is
unlocked (or not in a repositioning pool). From the user's point of view, it
would be necessary for the Finalize procedure to signal to the rest of the
program that the object was no longer extant. I did toy with the idea of
providing a callback procedure to allow the program to be notified of
disposals.

> You didn't mention anything about finalization of normal
> (non-disposable) objects.  There are nasty interactions
> there.  Eg, can the finalization routine resurrect the object
> by creating a new pointer to it?  Java has an answer to this
> (not a very good one, IMHO).

I believe Java's 'answer' is a mess. My preference would be that
resurrection is simply disallowed (erroneous), thus the object is always
truly deallocated when Finalize returns.

> It seems like the compiler must generate a Lock before each call where a
> movable object is passed by reference (or a part of such an object).
> And it must remain locked throughout that call, because the called
> procedure doesn't know whether it has a pointer into a repositioning
> pool.  Doesn't sound very "frequent".

This is true, but if you look more closely at typical 'real-life'
situations, you will see that it actually causes very little problem in
practice.

> For that matter, it seems like it has to Lock even if the thing is
> passed by copy, because the address of the actual is presumably saved at
> the call site (at least in some cases).

Ditto.

> - Bob

I'm very grateful for your comments, Bob. Indeed, I'm grateful for the lack
of eerie silence that can attend my posts to this newsgroup sometimes.

The question that remains, to my mind, of what action for me to take next
reduces to three basic possibilities: (a) make the amendments suggested
herein, and send the proposal to the ARG (which e-mail address would be
best?); (b) continue discussing the proposal in this newsgroup (or
elsewhere?), and submit it later, after perhaps much refinement; (c) forget
it.

I MUST go now and get some sleep!

--
Nick Roberts
http://www.AdaOS.org
nickroberts@adaos.worldonline.co.uk

PS: Please note my correct email address above.






^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-14 19:40     ` Florian Weimer
@ 2001-03-15 13:18       ` Nick Roberts
  0 siblings, 0 replies; 115+ messages in thread
From: Nick Roberts @ 2001-03-15 13:18 UTC (permalink / raw)


"Florian Weimer" <fw@deneb.enyo.de> wrote in message
news:8766hc9m0m.fsf@deneb.enyo.de...
> > >...  Why don't typical Ada implementations (which
> > > produce native code) support garbage collection?  There seem to be
> > > many reservations about garbage collections, so I think the priority
> > > issue is to provide an implementation of garbage collection which
> > > demonstrates that better garbage collection
> >
> > ...what?
>
> Oops.
>
> "is worth the additional complexity.  Until now, implementors and
> large scale users have shown little interest in any type of garbage
> collection."

You are perhaps right, and maybe this is a flag that I will find almost
no-one saluting.

But consider this: I believe GC facilities would add to the language's (or a
particular implementation's) support of good software engineering
principles, providing the GC were used in the kind of programs for which it
is appropriate. Essentially, this is because GC removes the burden of
storage management from the application programmer, so eliminating a
notorious source of errors. This is what a lot of Ada's features are
supposed to be about, isn't it?

I suspect that if Ada had never had, for example, the automatic range
checking implied by sub-ranging a basic type, Florian's argument could be
applied just the same to someone trying introduce this feature at a later
stage ("No-one uses it, so it isn't needed, and it wouldn't be worth the
extra complexity, so nobody would ever implement it.").

Ada would no doubt be a much simpler language to implement, if it didn't
have all those nasty complex SE features. Of course it would! It would be C,
then!

--
Nick Roberts
http://www.AdaOS.org







^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
       [not found]   ` <87bsr46kxv.fsf@deneb.enyo.de>
@ 2001-03-15 14:18     ` Robert A Duff
  2001-03-15 16:36       ` Florian Weimer
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-15 14:18 UTC (permalink / raw)


Florian Weimer <fw@deneb.enyo.de> writes:

> This is solved by double indirection.  Access values are not
> addresses, but opaque handles.  The compiler is expected to lock the
> handle to obtain the actual address.

Ah, so it's sort of like the original implementation of Smalltalk-80 --
an array of addresses of "instances", and a pointer to an instance
actually contains the array index?

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-15 14:18     ` Robert A Duff
@ 2001-03-15 16:36       ` Florian Weimer
  0 siblings, 0 replies; 115+ messages in thread
From: Florian Weimer @ 2001-03-15 16:36 UTC (permalink / raw)


Robert A Duff <bobduff@world.std.com> writes:

> Florian Weimer <fw@deneb.enyo.de> writes:
> 
> > This is solved by double indirection.  Access values are not
> > addresses, but opaque handles.  The compiler is expected to lock the
> > handle to obtain the actual address.
> 
> Ah, so it's sort of like the original implementation of Smalltalk-80 --
> an array of addresses of "instances", and a pointer to an instance
> actually contains the array index?

I don't know about Smalltalk-80, but the same scheme was implemented
on Windows 2.x and 3.x. Of course, with the advent of the 286 and
especially the 386 and virtual memory management, nobody bothered to
unlock the local or global heap anymore.



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-13 18:37 Better support for garbage collection Nick Roberts
                   ` (2 preceding siblings ...)
  2001-03-14 22:05 ` Laurent Guerby
@ 2001-03-15 17:56 ` Ray Blaak
  2001-03-21 16:15 ` Implementing C/C++ style #include bhazzard
  4 siblings, 0 replies; 115+ messages in thread
From: Ray Blaak @ 2001-03-15 17:56 UTC (permalink / raw)


"Nick Roberts" <nickroberts@callnetuk.com> writes:
>       type Object_Token is new Address;

I would suggest something like this instead:

        type Object_Token is private;

        function AddressOf(Token : Object_Token) return System.Address;
        function TokenOf(Storage_Address : System.Address) return Object_Token;

That way you can still easily convert to addresses and back, and yet the
implementor has a lot more freedom in deciding how to represent a token.

Does a token represent the address of an object allocated with this pool? If
so, after a compaction, aren't all tokens for an object potentially invalid if
an object is moved? Perhaps some sort of indirection handle concept is needed.

Also, since regularly allocated objects can still refer to reposition-pool
objects, garbage collection will still need to interact all dynamically
allocated memory. If an object is still reachable by *any* path, then it
cannot be released yet.

If this is not the case, it seems to me that manual maintenance of
allocation/locking is still required, defeating the purpose of GC.

Given this, the utility of such a package is questionable to me. If GC is
present, it is either completely on or completely off. 

Perhaps all that is really needed is some way to invoke compaction/collection
directly, and the ability to lock/unlock objects explicitly, to allow for the
occasional manual intervention. Otherwise, the standard allocators and access
assignments can do all of the GC work, as they would need to do anyway.

-- 
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
blaak@infomatch.com                            The Rhythm has my soul.



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-15  4:35   ` Nick Roberts
@ 2001-03-15 21:37     ` Randy Brukardt
  2001-03-15 22:36     ` Stephen Leake
  2001-03-16 16:26     ` Robert A Duff
  2 siblings, 0 replies; 115+ messages in thread
From: Randy Brukardt @ 2001-03-15 21:37 UTC (permalink / raw)


Nick Roberts wrote in message
<98pgs1$32up7$1@ID-25716.news.dfncis.de>...
>> Note that it is not always known at compile time whether a given
access
>> type's pool is a repositioning pool, so the code generated for "new"
and
>> "Unchecked_Deallocation" must be as in the RM (eg, these can't call
the
>> new Allocate).
>
>In the unlikely case of an access type whose pool is specified by a
dynamic
>name, I think you are correct. The user would need to use a static name
to
>avoid this problem.

You don't know in generics, either, unless you plan to change the
matching rules for generic formal access types. Thus, this would
potentally contract-breaking. It certainly wouldn't work on any compiler
that uses universal generic code shared [i.e., Janus/Ada]. And, I think
that your attributes would have to be allowed on all access types, or
you would have contract model problems.

---

Personally, I don't think this proposal is worth pursuing, because it
doesn't propose a solution to the hard part of the problem (determining
what is reachable). Using your 10 foot trench analogy, I think you'll
have a lot better luck if you can figure out how dig 8 feet of the
trench, just leaving a little of it to the compiler.

                Randy Brukardt.







^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-15  4:35   ` Nick Roberts
  2001-03-15 21:37     ` Randy Brukardt
@ 2001-03-15 22:36     ` Stephen Leake
  2001-03-16 16:26     ` Robert A Duff
  2 siblings, 0 replies; 115+ messages in thread
From: Stephen Leake @ 2001-03-15 22:36 UTC (permalink / raw)


"Nick Roberts" <nickroberts@adaos.worldonline.co.uk> writes:

> <snip good stuff>
> 
> The question that remains, to my mind, of what action for me to take next
> reduces to three basic possibilities: (a) make the amendments suggested
> herein, and send the proposal to the ARG (which e-mail address would be
> best?); (b) continue discussing the proposal in this newsgroup (or
> elsewhere?), and submit it later, after perhaps much refinement; (c) forget
> it.

I suggest you actually implement it, and implement an example
application that benefits from garbage collection. 

Implementing the GC bodies will catch other mistakes like missing
function parameters.

Implementing an example application will help the rest of us
understand why we should support (or oppose :) this. In particular, it
should show why that application can't use what is already provided by
storage pools.

Then we can discuss it, and _then_ we can submit it to the ARG.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-15  4:35   ` Nick Roberts
  2001-03-15 21:37     ` Randy Brukardt
  2001-03-15 22:36     ` Stephen Leake
@ 2001-03-16 16:26     ` Robert A Duff
  2001-03-16 16:59       ` Brian Rogoff
  2001-03-19 18:24       ` Better support for garbage collection Tucker Taft
  2 siblings, 2 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-16 16:26 UTC (permalink / raw)


"Nick Roberts" <nickroberts@adaos.worldonline.co.uk> writes:

> "Robert A Duff" <bobduff@world.std.com> wrote:

> > Robert Dewar would argue that it's because nobody wants it (at least,
> > nobody wants it enough to pay for it).  A more pessimistic take on this
> > is that all the folks who understand the glorious benefits of GC have
> > long since abandoned Ada in favor of "better" languages.
> 
> Don't you think it significant that so many other languages do incorporate
> GC?

The most popular ones don't, though.  But I don't think popularity
implies goodness...

> I must say, I get the impression, although I don't understand it, that
> Robert, perhaps yourself, and a few others have an antipathy towards GC
> which is not entirely objective or rational. It is not a sound argument to
> say "Well, I don't want it, so nobody else does either."

Well, I said in my previous post, "I too think it would be cool if GC
for Ada were widely available" -- I don't see how you can interpret that
as "antipathy".  I think GC is a good idea in many situations.  I also
think other memory management strategies are appropriate in other
situations.  Robert also likes garbage collection, I believe.

But Robert and I are both in the business of making Ada compilers, and
we don't see a lot of demand for GC.

Tucker, by the way, is rather down on GC.  He thinks there must be some
better memory management approach yet to be invented (and we've
discussed some of his ideas along those lines).  We'll see.

> The slowness of a GC environment can always be largely overcome, by using
> techniques such a B-Tree's lumping data into blocks. The advantages of
> having GC, especially from the point of view of software reliability, can be
> very great. It is typical these days to hear advice such as "the best way to
> maintain the efficiency of NT [the operating system] is to reboot it every
> day". It is typical of application programs to leak memory like a sieve. I
> suspect there are many Ada programs that commit the same sin, principally
> because they do not have GC.

Memory leaks are indeed annoying.  GC can help a lot.  But it doesn't
completely cure the problem -- you still have to use your brain when
writing programs.  I've seen memory leaks in GC'ed programs.

I've also seen GC'ed programs that are horribly slow because of
overreliance on GC.  It's easy to get sloppy.

> The difficult will take an hour. The impossible will take a little longer!
> I'll try to cook up an example.

Or maybe just outline it.  I already understand what you're getting at
much better than I did at first.

> I didn't mean to give the impression that what I described is how many or
> most garbage collectors work. All I meant was that what I described is how a
> garbage collector would have to work to be compatible with my proposal.

> > >    subtype Disposability_Level is
> > >       Integer range 0..implementation_defined;
> >
> > Why "implementation_defined"?  It seems like a useless non-portability.
> 
> Okay, what figure do you suggest?

100.

> > > and an attribute Disposability, which applies to any pool-specific
> access
> > > type, and has a static value of subtype Disposability_Level.
> >
> > This is the first attribute of a non-scalar type that is static.
> 
> Is this a problem?

A little bit.  Think about how you would re-word the rules for static
expressions.  They're complicated enough as it is.

> > >... A value other
> > > than 0 indicates that objects referenced by access values of this access
> > > type are disposable.
> >
> > It makes no sense to talk about the objects "referenced by access values
> > of this access type", because there can be many access values, of many
> > different types, all pointing to the same object.  Perhaps you mean
> > "allocated by allocators for this access type"?
> 
> What I said is perfectly logical, apart from using the wrong word ...
> 
> > (BTW, "designated" is the Ada jargon -- not "referenced".)
> 
> ... Whoops! (Pardon me :-) ...
> 
> I really meant "all objects designated by access values of this type". It
> doesn't matter if some of those objects (or any of their subcomponents) are
> designated by access values of other types.
> 
> Perhaps I should add a specific note that if an object is designated by
> several access values, of access types whose disposability levels are
> different (but non-zero), the highest of those disposability levels applies.

Well, you need to say *something* -- the original proposal says that an
object can have multiple disposability levels, which doesn't make sense
(I still claim).  Don't you think it's simpler to define the level in
terms of the type used for allocation, so levels aren't changing willy
nilly as access type conversions occur?

> The question that remains, to my mind, of what action for me to take next
> reduces to three basic possibilities: (a) make the amendments suggested
> herein, and send the proposal to the ARG (which e-mail address would be
> best?); (b) continue discussing the proposal in this newsgroup (or
> elsewhere?), and submit it later, after perhaps much refinement; (c) forget
> it.

I guess it depends on how disappointed you'll be if your work is wasted.

I don't think your proposal has a very good chance with the ARG.

Another possibility is (d) get the sources of GNAT, implement garbage
collection (either using the scheme in your proposal, or some other
method).  Then try to get ACT to install your changes into the standard
version of the sources.

Maybe if GC were available, folks would use it, and other compiler
writers would have incentive to implement it.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-14 20:59   ` Brian Rogoff
@ 2001-03-16 16:42     ` Robert A Duff
  2001-03-17  6:13       ` Lao Xiao Hai
  2001-03-24  4:08       ` Brian Rogoff
  0 siblings, 2 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-16 16:42 UTC (permalink / raw)


Brian Rogoff <bpr@shell5.ba.best.com> writes:

> IMO, just tacking on GC to an existing language doesn't make it very 
> much better.

I think it does.  But anyway, Ada was originally designed with GC in
mind -- the original intent was that all implementations would of course
support GC.  But they didn't.  So implementing a GC for Ada isn't
"tacking on" in the language design sense.

Note that Unchecked_Deallocation is hidden away in chapter 13,
and given a jaw-breaking name -- if Ichbiah had wanted everybody to use
it, wouldn't he have called it "dispose" or "free", and made it a
built-in operation of some sort (like "new")?

>... When the language designers design a language with the 
> expectation of GC, they may then support some higher level features, 
> like first class functions, which do make the language much better. 

I don't see the huge advantage of first class functions.
I *do* see the advantage of downward closures.
Whenever I have asked for examples showing the usefulness of full
closures, most folks produce examples of downward closures.
(I've had this argument here, and also on functional language
newsgroups, where you would expect to find more knowledge about
closures.)

I also see a *disadvantage* of full closures: Information that is local
to a procedure can "escape", which seems to make code harder to
understand.  It seems to me that if you want to pass a function (plus
its environment) outward, you should instead explicitly create a tagged
object on the heap, to make it clear that this thing survives after the
end of the current procedure.

In any case, surely GC is useful independent of closures: it can go a
long way toward getting rid of dangling pointer bugs and storage leak
bugs.

> Ada is far less leaky than C family languages, so the win of just 
> adding a GC seems smaller for Ada. 

I would say "somewhat less leaky".

> Of course, you still have designers who blow it by putting in GC and 
> omitting such features, but then after a few years they realize they 
> screwed up and hack in such things. Java and Eiffel are good examples 
> of such screw ups (nested/anonymous classes and "agents"). 

Tell us about the Eiffel case.  The version of Eiffel I know had no such
thing.

> > It is also possible to use Boehm's conservative collector with Ada.
> > Does anybody do so?
> > 
> > (I find the idea of conservative collection somewhat distasteful,
> > but it does seem to work in many cases.)
> 
> Maybe if it were called a "probabilistic garbage collector" you wouldn't 
> mind? ;-)

;-)

> Didn't Norman Cohen have a proposal for a storage pool extension that 
> provided some support for garbage collection? I thought so, but my neural 
> garbage collector seems to have reclaimed that hunk of my brain...

I don't remember that.

I do remember Norm participating in the above "are full closures useful"
argument.  He's the only one I recall who produced an example that
wasn't "downward".  I was only half convinced by his example.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-14 22:05 ` Laurent Guerby
@ 2001-03-16 16:47   ` Robert A Duff
  2001-03-16 19:46     ` Laurent Guerby
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-16 16:47 UTC (permalink / raw)


Laurent Guerby <guerby@acm.org> writes:

> What I would like to see in Ada is to have an allocator where you pass
> the pool object at allocation and deallocation. One pool per type is
> not very flexible.

I agree.  I'm currently working on a tool that analyzes programs, and I
store the symbol table for each source file in a separate storage pool,
so I can deallocate them conveniently and efficiently as things become
obsolete and whatnot.  It's a pain in the neck to implement that in Ada,
and it's impossible to make it task safe (but I don't happen to need
tasks in that part of my tool).

> Why did Ada 95 include pool objects only on a per type basis?

I don't know.  Perhaps Tucker can tell us.

What syntax would you suggest?

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-16 16:26     ` Robert A Duff
@ 2001-03-16 16:59       ` Brian Rogoff
  2001-03-16 17:31         ` Robert A Duff
  2001-03-19 18:24       ` Better support for garbage collection Tucker Taft
  1 sibling, 1 reply; 115+ messages in thread
From: Brian Rogoff @ 2001-03-16 16:59 UTC (permalink / raw)


On Fri, 16 Mar 2001, Robert A Duff wrote:
> "Nick Roberts" <nickroberts@adaos.worldonline.co.uk> writes:
> > I must say, I get the impression, although I don't understand it, that
> > Robert, perhaps yourself, and a few others have an antipathy towards GC
> > which is not entirely objective or rational. It is not a sound argument to
> > say "Well, I don't want it, so nobody else does either."
> 
> Well, I said in my previous post, "I too think it would be cool if GC
> for Ada were widely available" -- I don't see how you can interpret that
> as "antipathy".  I think GC is a good idea in many situations.  I also
> think other memory management strategies are appropriate in other
> situations.  Robert also likes garbage collection, I believe.
> 
> But Robert and I are both in the business of making Ada compilers, and
> we don't see a lot of demand for GC.

The cynic may counter that one doesn't see a lot of demand for Ada either. 
Of course that says nothing about GC. 

> Tucker, by the way, is rather down on GC.  He thinks there must be some
> better memory management approach yet to be invented (and we've
> discussed some of his ideas along those lines).  We'll see.

I'd like to see some of those ideas. Tucker, care to elaborate?

I think there will never be a single approach which will work well for all 
cases. Even amongst "GC-ed" language advocates, you can see that there is
some realization that for embedded or hard real-time problems you may need 
other approaches. I'm thinking of the ML-Kit and it's region based memory 
manager, http://www.it-c.dk/research/mlkit/kit3/readme.html

Still, I program in a GCed language now and I have to admit that my 
"programming velocity" is better than it was with Ada (yeah, I know, who 
cares, readability, blah, blah, blah :) and even if GC isn't the main
reason it certainly helps. 

> Memory leaks are indeed annoying.  GC can help a lot.  But it doesn't
> completely cure the problem -- you still have to use your brain when
> writing programs.  I've seen memory leaks in GC'ed programs.

Static typing doesn't cure bugs either. 

> I've also seen GC'ed programs that are horribly slow because of
> overreliance on GC.  It's easy to get sloppy.

It's easy to get sloppy in Ada and write programs that are much slower
than C ones. How many times have people posted code in c.l.a. and made 
that same complaint?

My worry about GC in Ada would be that the bugs caused by the interaction 
of GC and unsafe features would be difficult. I guess if you use unsafe 
features all bets are off in any case...

-- Brian





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-16 16:59       ` Brian Rogoff
@ 2001-03-16 17:31         ` Robert A Duff
  2001-03-16 18:29           ` Brian Rogoff
  2001-03-17  2:30           ` Nick Roberts
  0 siblings, 2 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-16 17:31 UTC (permalink / raw)


Brian Rogoff <bpr@shell5.ba.best.com> writes:

> The cynic may counter that one doesn't see a lot of demand for Ada either. 
> Of course that says nothing about GC. 

If my company had money to burn, I would implement GC, and see if it
attracts more people to Ada.  But I wouldn't bet my own money on that.  ;-)

> I think there will never be a single approach which will work well for all 
> cases.

I strongly agree.

In fact, I think part of the reason GC didn't catch on for many years
(Java is really the first popular GC'ed language) is the overblown
claims of some GC zealots.

>... Even amongst "GC-ed" language advocates, you can see that there is
> some realization that for embedded or hard real-time problems you may need 
> other approaches. I'm thinking of the ML-Kit and it's region based memory 
> manager, http://www.it-c.dk/research/mlkit/kit3/readme.html

I've read various papers that claim to describe "real time" garbage
collection, only to be disappointed to find that its not so "hard" real
time after all (and have intolerable overheads for some programs).

> Still, I program in a GCed language now and I have to admit that my 
> "programming velocity" is better than it was with Ada (yeah, I know, who 
> cares, readability, blah, blah, blah :) and even if GC isn't the main
> reason it certainly helps. 

Which language?

> > Memory leaks are indeed annoying.  GC can help a lot.  But it doesn't
> > completely cure the problem -- you still have to use your brain when
> > writing programs.  I've seen memory leaks in GC'ed programs.
> 
> Static typing doesn't cure bugs either. 

Right, but there are fewer zealots making *that* claim.

> My worry about GC in Ada would be that the bugs caused by the interaction 
> of GC and unsafe features would be difficult.

I think I've heard Robert Dewar express that attitude (ie, perhaps GC is
inappropriate in a language that also has unsafe features).

>... I guess if you use unsafe 
> features all bets are off in any case...

That's *my* attitude.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-16 17:31         ` Robert A Duff
@ 2001-03-16 18:29           ` Brian Rogoff
  2001-03-17  2:30           ` Nick Roberts
  1 sibling, 0 replies; 115+ messages in thread
From: Brian Rogoff @ 2001-03-16 18:29 UTC (permalink / raw)


On Fri, 16 Mar 2001, Robert A Duff wrote:
> Brian Rogoff <bpr@shell5.ba.best.com> writes:
> 
> > The cynic may counter that one doesn't see a lot of demand for Ada either. 
> > Of course that says nothing about GC. 
> 
> If my company had money to burn, I would implement GC, and see if it
> attracts more people to Ada.  But I wouldn't bet my own money on that.  ;-)

I wouldn't bet my time or money on this either. I agree with your
last statement that modifying GNAT is the way to go. This is probably a 
good university project. 

> > I think there will never be a single approach which will work well for all 
> > cases.
> 
> I strongly agree.
> 
> In fact, I think part of the reason GC didn't catch on for many years
> (Java is really the first popular GC'ed language) is the overblown
> claims of some GC zealots.

Well, I doubt those claims had much to do with the success of GC one way
or the other. I think it's only relatively recently that huge numbers 
of programmers are working in "scripting" languages most of the time, and 
scripting languages generally don't have manual memory management. 

> >... Even amongst "GC-ed" language advocates, you can see that there is
> > some realization that for embedded or hard real-time problems you may need 
> > other approaches. I'm thinking of the ML-Kit and it's region based memory 
> > manager, http://www.it-c.dk/research/mlkit/kit3/readme.html
> 
> I've read various papers that claim to describe "real time" garbage
> collection, only to be disappointed to find that its not so "hard" real
> time after all (and have intolerable overheads for some programs).

Oh, I think you are actually already familiar with region based memory
management. It's really just a variation of "arenas" where you don't have
to match frees to allocs; you alloc from a region and free the entire
region in one call (like the pool in the Ada Rationale). So it's not like 
the pointer chasing algorithms I associate with real GC. 

 > > Still, I program in a GCed language now and I have to admit that
my 
> > "programming velocity" is better than it was with Ada (yeah, I know, who 
> > cares, readability, blah, blah, blah :) and even if GC isn't the main
> > reason it certainly helps. 
> 
> Which language?

OCaml (caml.inria.fr if you're interested), which I admit is hardly
popular. Yes, I've used Java at two jobs since it came out and I 
don't think it holds a candle to Ada *as a language*. OCaml has 
static typing, a good module system, and a great implementation. 
I'd think that Ada programmers should at least consider it as a 
scripting tool. Performance-wise it is impressive. 

> > > Memory leaks are indeed annoying.  GC can help a lot.  But it doesn't
> > > completely cure the problem -- you still have to use your brain when
> > > writing programs.  I've seen memory leaks in GC'ed programs.
> > 
> > Static typing doesn't cure bugs either. 
> 
> Right, but there are fewer zealots making *that* claim.

I guess you don't read comp.lang.functional. :-)

Anyways, I don't know any GC zealots. Most programmers think GC leads to
bloated slow programs, and while they were talking out their hats a few
years ago now they have Java as proof.

> > My worry about GC in Ada would be that the bugs caused by the interaction 
> > of GC and unsafe features would be difficult.
> 
> I think I've heard Robert Dewar express that attitude (ie, perhaps GC is
> inappropriate in a language that also has unsafe features).

Modula-3 is kind of the dual of a GC-ed Ada: GC is the default but it
supports an unsafe features in specially marked modules. 

-- Brian





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-16 16:47   ` Robert A Duff
@ 2001-03-16 19:46     ` Laurent Guerby
  2001-03-16 20:10       ` Robert A Duff
  0 siblings, 1 reply; 115+ messages in thread
From: Laurent Guerby @ 2001-03-16 19:46 UTC (permalink / raw)


Robert A Duff <bobduff@world.std.com> writes:
> Laurent Guerby <guerby@acm.org> writes:
> > What I would like to see in Ada is to have an allocator where you pass
> > the pool object at allocation and deallocation. One pool per type is
> > not very flexible.
> I agree.  I'm currently working on a tool that analyzes programs, and I
> store the symbol table for each source file in a separate storage pool,
> so I can deallocate them conveniently and efficiently as things become
> obsolete and whatnot.  It's a pain in the neck to implement that in Ada,
> and it's impossible to make it task safe (but I don't happen to need
> tasks in that part of my tool).

I'm even surprised it's possible to implement at all. How do you
manage to get one pool per file in Ada (I assume a dynamic number of
file)?

> > Why did Ada 95 include pool objects only on a per type basis?
> I don't know.  Perhaps Tucker can tell us.
> 
> What syntax would you suggest?

The obvious new T'(Pool_Object, Value) doesn't work unfortunately, so
may be:

new T'(Value) at Pool_Object -- may be replace "at" by use/of/with/in???

You also need a new version of Unchecked_Deallocation with an
additional parameter, but no new syntax needed here (and with
overloading, no new name).

I see no way to include the allocation part of this feature without
new syntax, due to the way 4.8 is written:

    4.7:
    qualified_expression ::=
       subtype_mark'(expression) | subtype_mark'aggregate

If other people have ideas.

-- 
Laurent Guerby <guerby@acm.org>



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-16 19:46     ` Laurent Guerby
@ 2001-03-16 20:10       ` Robert A Duff
  2001-03-17 13:14         ` Support for per allocation pool selection (was: Better support for garbage collection) Laurent Guerby
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-16 20:10 UTC (permalink / raw)


Laurent Guerby <guerby@acm.org> writes:

> I'm even surprised it's possible to implement at all. How do you
> manage to get one pool per file in Ada

My plan is to have a package that keeps track of the "current pool",
with a Set_Current_Pool operation, or some such.  And a storage pool
that redirects Allocate requests to the current pool.  This is somewhat
error prone.  It is also not task safe, and adding locks would be too
inefficient (I think).  If Ada had task-local storage, I could make it
task safe, but still error prone.

I haven't actually got this working -- I'm still designing.  I can
imagine other ways involving low-level tricks.

>... (I assume a dynamic number of
> file)?

Right.  However many source files are in the program being analyzed,
which changes over time.

> You also need a new version of Unchecked_Deallocation with an
> additional parameter, but no new syntax needed here (and with
> overloading, no new name).

U_D is a generic, and is a library unit, and overloading is not allowed
for generics, nor for lib units.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-16 17:31         ` Robert A Duff
  2001-03-16 18:29           ` Brian Rogoff
@ 2001-03-17  2:30           ` Nick Roberts
  2001-03-17 21:59             ` Robert A Duff
  2001-03-17 22:57             ` Static typing (Was Re: Better support for garbage collection) Brian Rogoff
  1 sibling, 2 replies; 115+ messages in thread
From: Nick Roberts @ 2001-03-17  2:30 UTC (permalink / raw)


"Robert A Duff" <bobduff@world.std.com> wrote in message
news:wcck85pr56b.fsf@world.std.com...
>
> In fact, I think part of the reason GC didn't catch on for many years
> (Java is really the first popular GC'ed language) is the overblown
> claims of some GC zealots.

Java? What about BASIC? Good old Microsoft BASIC (for the Z80 -- remember
those?), that fitted into 8K ROM, had GC, as did a variety of other BASICs
(some of them even tinier). And they were pretty popular for a period. I
think your statement might upset a lot of LISP enthusiasts, too. (Not to
mention Smalltalk, Prolog, xBASE, and probably many others ;-)

> > > Memory leaks are indeed annoying.  GC can help a lot.  But it doesn't
> > > completely cure the problem -- you still have to use your brain when
> > > writing programs.  I've seen memory leaks in GC'ed programs.
> >
> > Static typing doesn't cure bugs either.
>
> Right, but there are fewer zealots making *that* claim.

Maybe not in so many words, but actually there are a lot of people who claim
that a static typing system causes more trouble than it is worth. I am on
this side of that particular fence, but I see their point (e.g. it can
reduce the size of the source code by several times, which in itself, it
could be claimed, improves readability).

> > My worry about GC in Ada would be that the bugs caused by the
interaction
> > of GC and unsafe features would be difficult.
>
> I think I've heard Robert Dewar express that attitude (ie, perhaps GC is
> inappropriate in a language that also has unsafe features).

Actually, I think, with a bit of care, it is possible to design a (perfectly
good) GC system that defends quite effectively against the worst effects of
'damage'.

I think, in the end, I will take the advice of both Brian and Bob, and
simply implement GC myself (in my own compiler which I'm writing for AdaOS).
I just thought it would be preferable to have a widely agreed framework
within which to design it first.

--
Nick Roberts
http://www.AdaOS.org







^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-16 16:42     ` Robert A Duff
@ 2001-03-17  6:13       ` Lao Xiao Hai
  2001-03-24  4:08       ` Brian Rogoff
  1 sibling, 0 replies; 115+ messages in thread
From: Lao Xiao Hai @ 2001-03-17  6:13 UTC (permalink / raw)




Someone wrote:

>
>
> > Didn't Norman Cohen have a proposal for a storage pool extension that
> > provided some support for garbage collection? I thought so, but my neural
> > garbage collector seems to have reclaimed that hunk of my brain...

1)  John Barnes' newest edition has an excellent example of using the Storage
     Pools package to control garbage collection,

2) GNAT has a built in implementation of Storage Pools package that is easy to
use.

3) As noted by another post, garbage collection comes in many forms.  Which one
is
     the right one for Ada.  Probably none.   That is one reason to leave it
alone?

Richard Riehle




^ permalink raw reply	[flat|nested] 115+ messages in thread

* Support for per allocation pool selection (was: Better support for garbage collection)
  2001-03-16 20:10       ` Robert A Duff
@ 2001-03-17 13:14         ` Laurent Guerby
  2001-03-17 17:06           ` Robert A Duff
  2001-03-17 19:19           ` Florian Weimer
  0 siblings, 2 replies; 115+ messages in thread
From: Laurent Guerby @ 2001-03-17 13:14 UTC (permalink / raw)


Robert A Duff <bobduff@world.std.com> writes:
> My plan is to have a package that keeps track of the "current pool",
> with a Set_Current_Pool operation, or some such.  And a storage pool
> that redirects Allocate requests to the current pool.  This is somewhat
> error prone.  It is also not task safe, and adding locks would be too
> inefficient (I think).  If Ada had task-local storage, I could make it
> task safe, but still error prone.

Okay I see.

> > You also need a new version of Unchecked_Deallocation with an
> > additional parameter, but no new syntax needed here (and with
> > overloading, no new name).

> U_D is a generic, and is a library unit, and overloading is not
> allowed for generics, nor for lib units.

So new name needed ;-).

Note that close to your Set_Current_Pool idea, we can propose a pragma
to do so:

pragma Use_Pool_Object (T_Ptr, Pool_Object);

then all allocations (via new) of type T_Ptr use the given Pool_Object
in the current scope (and until the next pragma), no new syntax then.

No other people have expressed interest so far. Do you think if I
write down a proposal, it would be considered?

For reference:
> The obvious new T'(Pool_Object, Value) doesn't work unfortunately, so
> may be:
> 
> new T'(Value) at Pool_Object -- may be replace "at" by use/of/with/in???
> 
> [...] I see no way to include the allocation part of this feature without
> new syntax, due to the way 4.8 is written:
> 
>     4.7:
>     qualified_expression ::=
> 	 subtype_mark'(expression) | subtype_mark'aggregate
> 
> If other people have ideas.

-- 
Laurent Guerby <guerby@acm.org>



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Support for per allocation pool selection (was: Better support for garbage collection)
  2001-03-17 13:14         ` Support for per allocation pool selection (was: Better support for garbage collection) Laurent Guerby
@ 2001-03-17 17:06           ` Robert A Duff
  2001-03-17 19:19           ` Florian Weimer
  1 sibling, 0 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-17 17:06 UTC (permalink / raw)


Laurent Guerby <guerby@acm.org> writes:

> pragma Use_Pool_Object (T_Ptr, Pool_Object);
> 
> then all allocations (via new) of type T_Ptr use the given Pool_Object
> in the current scope (and until the next pragma), no new syntax then.

I'd prefer new syntax for "new".  But the pragma might be easier for
some folks to swallow.

> No other people have expressed interest so far. Do you think if I
> write down a proposal, it would be considered?

Yes, but I won't bet that it will actually happen.

By the way, this idea was considered (and rejected) during the Ada 9X
design.  I never understood why Tucker didn't like it, and we had too
much else to worry about at the time, so I never really got around to
asking.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Support for per allocation pool selection (was: Better support for garbage collection)
  2001-03-17 13:14         ` Support for per allocation pool selection (was: Better support for garbage collection) Laurent Guerby
  2001-03-17 17:06           ` Robert A Duff
@ 2001-03-17 19:19           ` Florian Weimer
  2001-03-17 21:10             ` Robert A Duff
  1 sibling, 1 reply; 115+ messages in thread
From: Florian Weimer @ 2001-03-17 19:19 UTC (permalink / raw)


Laurent Guerby <guerby@acm.org> writes:

> pragma Use_Pool_Object (T_Ptr, Pool_Object);
> 
> then all allocations (via new) of type T_Ptr use the given Pool_Object
> in the current scope (and until the next pragma), no new syntax then.

Are there other pragmas with a similarly scoped effect?



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Support for per allocation pool selection (was: Better support for garbage collection)
  2001-03-17 19:19           ` Florian Weimer
@ 2001-03-17 21:10             ` Robert A Duff
  0 siblings, 0 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-17 21:10 UTC (permalink / raw)


Florian Weimer <fw@deneb.enyo.de> writes:

> Are there other pragmas with a similarly scoped effect?

Pragma Supppress?

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-17  2:30           ` Nick Roberts
@ 2001-03-17 21:59             ` Robert A Duff
  2001-03-17 22:57             ` Static typing (Was Re: Better support for garbage collection) Brian Rogoff
  1 sibling, 0 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-17 21:59 UTC (permalink / raw)


"Nick Roberts" <nickroberts@adaos.worldonline.co.uk> writes:

> Java? What about BASIC? Good old Microsoft BASIC (for the Z80 -- remember
> those?), that fitted into 8K ROM, had GC, as did a variety of other BASICs
> (some of them even tinier). And they were pretty popular for a period. I
> think your statement might upset a lot of LISP enthusiasts, too. (Not to
> mention Smalltalk, Prolog, xBASE, and probably many others ;-)

Yeah, you're right about BASIC.  As to the others, I don't think they're
exactly "popular" (even if that upsets the folks who like them -- it
upsets *me* that C is more popular than Ada!).  But I can't quote any
facts and figures, so I could be very wrong.

> Maybe not in so many words, but actually there are a lot of people who claim
> that a static typing system causes more trouble than it is worth. 

I know, but those folks are wrong.  (Now I've *really* upset the Lisp
folks.  ;-) )

>...I am on
> this side of that particular fence, but I see their point (e.g. it can
> reduce the size of the source code by several times, which in itself, it
> could be claimed, improves readability).

> I think, in the end, I will take the advice of both Brian and Bob, and
> simply implement GC myself (in my own compiler which I'm writing for AdaOS).

We'll all be holding our collective breaths.  ;-) ;-)

> I just thought it would be preferable to have a widely agreed framework
> within which to design it first.

If there is at least one implementation of the framework, it has a
better chance of being implementable.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Static typing (Was Re: Better support for garbage collection)
  2001-03-17  2:30           ` Nick Roberts
  2001-03-17 21:59             ` Robert A Duff
@ 2001-03-17 22:57             ` Brian Rogoff
  2001-03-17 23:45               ` Robert A Duff
  1 sibling, 1 reply; 115+ messages in thread
From: Brian Rogoff @ 2001-03-17 22:57 UTC (permalink / raw)


On Sat, 17 Mar 2001, Nick Roberts wrote:
> "Robert A Duff" <bobduff@world.std.com> wrote in message
> > > Static typing doesn't cure bugs either.
> >
> > Right, but there are fewer zealots making *that* claim.
> 
> Maybe not in so many words, but actually there are a lot of people who claim
> that a static typing system causes more trouble than it is worth. I am on
> this side of that particular fence, but I see their point (e.g. it can
> reduce the size of the source code by several times, which in itself, it
> could be claimed, improves readability).

You're confusing static typing with *explicit* or *manifest* static
typing. Do yourself a favor and look at ML or Haskell. Better, here is a 
snippet from the OCaml top level

# let rec len l = match l with [] -> 0 | x::xs -> 1 + len xs;;

Hey, where are the types? Is this like Lisp? No, not really, here is what 
the top level says when I enter that

val len : 'a list -> int = <fun>

So the system *infers* the type, and a very general type, for that
function. It takes a list of anything to an integer. I didn't even need 
to instantiate a generic for that. Pretty spiffy, huh?

-- Brian





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-17 22:57             ` Static typing (Was Re: Better support for garbage collection) Brian Rogoff
@ 2001-03-17 23:45               ` Robert A Duff
  2001-03-18  0:58                 ` Brian Rogoff
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-17 23:45 UTC (permalink / raw)


Brian Rogoff <bpr@shell5.ba.best.com> writes:

> # let rec len l = match l with [] -> 0 | x::xs -> 1 + len xs;;
> 
> Hey, where are the types? Is this like Lisp? No, not really, here is what 
> the top level says when I enter that
> 
> val len : 'a list -> int = <fun>
> 
> So the system *infers* the type, and a very general type, for that
> function. It takes a list of anything to an integer. I didn't even need 
> to instantiate a generic for that. Pretty spiffy, huh?

No.  I don't find it spiffy to have to read down into the guts of that
function to find out that it returns an 'int'.  Nor do I find it spiffy
that the type of a literal is determined by what it looks like.  I think
the type of a literal should be determined from context.

I think type inference is spiffy within (small) expressions, but I think
interfaces should have explicitly declared types, including functions
like the above 'len'.

I understand that in ML you *can* declare signatures, *if you like*.
I don't know OCaml, unfortunately.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-17 23:45               ` Robert A Duff
@ 2001-03-18  0:58                 ` Brian Rogoff
  2001-03-19 15:24                   ` Robert A Duff
  0 siblings, 1 reply; 115+ messages in thread
From: Brian Rogoff @ 2001-03-18  0:58 UTC (permalink / raw)


On Sat, 17 Mar 2001, Robert A Duff wrote:
> Brian Rogoff <bpr@shell5.ba.best.com> writes:
> 
> > # let rec len l = match l with [] -> 0 | x::xs -> 1 + len xs;;
> > 
> > Hey, where are the types? Is this like Lisp? No, not really, here is what 
> > the top level says when I enter that
> > 
> > val len : 'a list -> int = <fun>
> > 
> > So the system *infers* the type, and a very general type, for that
> > function. It takes a list of anything to an integer. I didn't even need 
> > to instantiate a generic for that. Pretty spiffy, huh?
> 
> No.  I don't find it spiffy to have to read down into the guts of that
> function to find out that it returns an 'int'. 

If you have a problem with this, you have at least two options. 

(1) Use module interfaces and put the type of the function there. In
    "real" sized programs that's what I do. In OCaml, the type is 
    inferred and then checked against the explicit type. In Haskell, 
    the type is used in the checking, and this allows you to get  
    polymorphic recursion. Type inference is undecidable in the presence
    of PR, though Mercury does infer it and just has an iteration limit in
    the type checker. I think I like the Haskell approach better.  

(2) You can put the type declaration right there, like this 

let rec (len : 'a list -> int) = 
  fun l -> match l with [] -> 0 | x::xs -> 1 + len xs;;

So you can program entirely with explicit types in ML if you wish. 

Of course Nick's complaint is about all of the extra code with explicit 
types, and its that argument I responded to. While I agree with you that 
inference shouldn't be used everywhere, I think Ada goes way too far in 
having redundant types, and explicit instantiation everywhere. For all of 
its egregious flaws, I think C++ got this right with implicit
instantiation of templated functions. I think trying to duplicate the STL 
in Ada convinced me of that, though rather than go to C++ (which I find 
awful) or a dynamically typed language I started looking at ML and kin. 

> Nor do I find it spiffy that the type of a literal is determined by
> what it looks like. I think the type of a literal should be determined
> from context.

I don't understand what you mean. Are you complaining about the fact that 
'0' is an int, for instance?

> I think type inference is spiffy within (small) expressions, but I think
> interfaces should have explicitly declared types, including functions
> like the above 'len'.

Module interfaces do consist of explicitly declared types in ML. 

> I understand that in ML you *can* declare signatures, *if you like*.
> I don't know OCaml, unfortunately.

OCaml is a dialect of ML, so if you know SML it shouldn't be too hard to 
switch. 

My beef with {OCa,S}ML vis-a-vis Ada is the lack of overloading in ML 
dialects. Of course, many people will claim that overloading lessens 
readability. Haskell sort of has a kind of overloading (type classes) 
but it's not exactly the same. Mercury has overloading. Fergus Henderson 
used to post here, and Mercury is his project. Nice language, but I'm 
not familiar enough with logic programming to try and use it at work yet. 
While my manager acknowledges that Ada is much better than C++ or Java, 
it's a tough sell against a modern high level language.

-- Brian





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-18  0:58                 ` Brian Rogoff
@ 2001-03-19 15:24                   ` Robert A Duff
  2001-03-20  4:21                     ` Brian Rogoff
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-19 15:24 UTC (permalink / raw)


Brian Rogoff <bpr@shell5.ba.best.com> writes:

> So you can program entirely with explicit types in ML if you wish. 

Yeah, I know.  I just think it should be *required* at the interfaces.

> Of course Nick's complaint is about all of the extra code with explicit 
> types, and its that argument I responded to. While I agree with you that 
> inference shouldn't be used everywhere, I think Ada goes way too far in 
> having redundant types, and explicit instantiation everywhere. For all of 
> its egregious flaws, I think C++ got this right with implicit
> instantiation of templated functions. I think trying to duplicate the STL 
> in Ada convinced me of that, though rather than go to C++ (which I find 
> awful) or a dynamically typed language I started looking at ML and kin. 

I agree.

> I don't understand what you mean. Are you complaining about the fact that 
> '0' is an int, for instance?

Yes.  I think there should be many integer types (as in Ada),
so it makes no sense to say that '0' is an 'int' just because it looks
like an int.  The type of '0' is determined by context in Ada,
and I like that.

One thing I don't like in Ada is that '0' can't be a Float.
After all, when I write the rational number "one half" on
a piece of paper, I can write something like "1/2", and everybody knows
what I mean.  I don't write "1.0/2.0" -- the ".0" is superfluous.

Another thing I don't like is that if I write (for example), an
exact-rational-arithmetic package in Ada, I can't use literals --
literals are only allowed for the built-in kinds of types.

All of the above points are related: the context should determine the
type of a literal.  Then, after overload resolution has determined the
type of a literal, there should be a compile-time check that it is of
the right form -- the form should not *determine* the type.  Eg, if the
type of 1.2 turns out to be Integer, that should be illegal.  If the
type of 1.2 could be either Integer or Float, that should be ambiguous
and therefore illegal, whereas in Ada, it chooses Float.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-16 16:26     ` Robert A Duff
  2001-03-16 16:59       ` Brian Rogoff
@ 2001-03-19 18:24       ` Tucker Taft
  1 sibling, 0 replies; 115+ messages in thread
From: Tucker Taft @ 2001-03-19 18:24 UTC (permalink / raw)


Robert A Duff wrote:
> ...
> Tucker, by the way, is rather down on GC.  He thinks there must be some
> better memory management approach yet to be invented (and we've
> discussed some of his ideas along those lines).  We'll see.

There is actually a fair amount of academic research in
region-based storage management.  The most recent ACM TOPLAS
has an interesting, if a bit obstruse, article on that topic.

The general idea is to ensure there are no storage leaks
or dangling pointers, while also giving the programmer complete
control over where and when storage is allocated and freed.

The TOPLAS article is pretty heavy going, but the general
idea is to use multiple regions/heaps, and have the compiler
ensure that when a region is freed, there are no pointers still
referring to it.  Although they make no mention of it, Ada 83's
"typed" pointers, with local access "collections" are the beginnings
of this kind of thing.  However, they are clearly too limited.

I have been toying with a number of ideas that are more flexible
than Ada's "local" access types, but which are just as safe
and efficient.  Some day real soon now I will put out an Ada amendment
proposal I hope in this general area.

-- 
-Tucker Taft   stt@avercom.net   http://www.averstar.com/~stt/
Chief Technology Officer, AverCom Corporation (A Titan Company) 
Burlington, MA  USA (AverCom was formerly the Commercial Division of AverStar:
http://www.averstar.com/services/ebusiness_applications.html)



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-19 15:24                   ` Robert A Duff
@ 2001-03-20  4:21                     ` Brian Rogoff
  2001-03-21  1:32                       ` Ken Garlington
  2001-03-29 23:50                       ` Robert A Duff
  0 siblings, 2 replies; 115+ messages in thread
From: Brian Rogoff @ 2001-03-20  4:21 UTC (permalink / raw)


On Mon, 19 Mar 2001, Robert A Duff wrote:
> Brian Rogoff <bpr@shell5.ba.best.com> writes:
> > I don't understand what you mean. Are you complaining about the fact that 
> > '0' is an int, for instance?
> 
> Yes.  I think there should be many integer types (as in Ada),
> so it makes no sense to say that '0' is an 'int' just because it looks
> like an int.  The type of '0' is determined by context in Ada,
> and I like that.

Yes, I like that too. MLs kind of suck compared to Ada when it comes to 
scalars. Of course, since MLs don't have overloading (yes, SML has some 
fixed overloading but that's worse than no overloading IMO) you can't
really expect them to handle scalars as well. Even to get something like a 
Positives or Naturals you have to roll them yourself using the module
system. 

> One thing I don't like in Ada is that '0' can't be a Float.
> After all, when I write the rational number "one half" on
> a piece of paper, I can write something like "1/2", and everybody knows
> what I mean.  I don't write "1.0/2.0" -- the ".0" is superfluous.

Hmmm, that one never bothered me, but now that you mention it. 

> Another thing I don't like is that if I write (for example), an
> exact-rational-arithmetic package in Ada, I can't use literals --
> literals are only allowed for the built-in kinds of types.

Yes, *that* is a problem. There are quite a few places in Ada where I'd 
like to make user defined types have capabilities of builtins, but can't. 
It's also the case that if you wanted to make an STL inspired library have 
Ada-like iteration (over a range say) rather than C/C++ like iteration you
are also stuck. 

> All of the above points are related: the context should determine the
> type of a literal.  Then, after overload resolution has determined the
> type of a literal, there should be a compile-time check that it is of
> the right form -- the form should not *determine* the type.  Eg, if the
> type of 1.2 turns out to be Integer, that should be illegal.  If the
> type of 1.2 could be either Integer or Float, that should be ambiguous
> and therefore illegal, whereas in Ada, it chooses Float.

OK, I'm convinced. Maybe this next generation language should be named 
"Grace" or "Hopper" ;-)

-- Brian





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-20  4:21                     ` Brian Rogoff
@ 2001-03-21  1:32                       ` Ken Garlington
  2001-03-21 13:28                         ` Robert A Duff
  2001-03-29 23:50                       ` Robert A Duff
  1 sibling, 1 reply; 115+ messages in thread
From: Ken Garlington @ 2001-03-21  1:32 UTC (permalink / raw)


"Brian Rogoff" <bpr@shell5.ba.best.com> wrote in message
news:Pine.BSF.4.21.0103192012240.2056-100000@shell5.ba.best.com...

: > One thing I don't like in Ada is that '0' can't be a Float.
: > After all, when I write the rational number "one half" on
: > a piece of paper, I can write something like "1/2", and everybody knows
: > what I mean.  I don't write "1.0/2.0" -- the ".0" is superfluous.
:
: Hmmm, that one never bothered me, but now that you mention it.

Can't see why, since the terms "rational number" and "floating-point number"
are not the same. I think I'd be much more bothered by a floating-point
number without a (floating) point!





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-21  1:32                       ` Ken Garlington
@ 2001-03-21 13:28                         ` Robert A Duff
  2001-03-22  2:08                           ` Ken Garlington
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-21 13:28 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> writes:

> Can't see why, since the terms "rational number" and "floating-point number"
> are not the same. I think I'd be much more bothered by a floating-point
> number without a (floating) point!

Well, as it happens, "one half" is both a rational and (on most
machines) a floating point number.  Not to mention a fixed point
number. ;-)

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Implementing C/C++ style #include...
  2001-03-13 18:37 Better support for garbage collection Nick Roberts
                   ` (3 preceding siblings ...)
  2001-03-15 17:56 ` Better support for garbage collection Ray Blaak
@ 2001-03-21 16:15 ` bhazzard
  2001-03-21 16:45   ` Marin David Condic
                     ` (4 more replies)
  4 siblings, 5 replies; 115+ messages in thread
From: bhazzard @ 2001-03-21 16:15 UTC (permalink / raw)


A quick question...

Is there any way to implement c/c++ style
#ifdef pre-processor statements in Ada.

Do Ada compilers have a pre-processor ?

I am using Rational on an Sgi and Green Hills on a Sun... the manual set(s)
appear to have no reference to such things... This is what I want to do...
...
#ifdef TEST_MODE
#include "test_mode.a
#endif
...
a.make -D TEST_MODE -f *.a

Also... If you know this is IMPOSSIBLE a brief email  to that
effect would be useful....

Thanks before hand...

Brad Hazzard





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-21 16:15 ` Implementing C/C++ style #include bhazzard
@ 2001-03-21 16:45   ` Marin David Condic
  2001-03-22 15:13     ` Ira D. Baxter
  2001-03-21 18:07   ` Mark Lundquist
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 115+ messages in thread
From: Marin David Condic @ 2001-03-21 16:45 UTC (permalink / raw)


"bhazzard" <bhazzard@email.msn.com> wrote in message
news:OrZxgIisAHA.289@cpmsnbbsa09...
> A quick question...
>
> Is there any way to implement c/c++ style
> #ifdef pre-processor statements in Ada.
>
There is always a way. If you're willing to do the work yourself, you can
write a program to parse your Ada code to look for preprocessor directives &
output appropriate *new* Ada code before doing the compile. This is a lot of
work & I would be inclined to advise against it since most of the C/C++
style preprocessor directives are mostly a way to make more trouble for
yourself than you really want. (The conditional compilation, inclusion of
files, etc., is the source of *more* pain & horrible code than I care to
recall. It was considered and deliberately left out of Ada as a generally
agreed upon Bad Thing.)

There exists no standard way in Ada to have the sort of pre-processor
directives you mention since there are no language defined directives. Some
compilers (e.g. GNAT) may give you a means of invoking your own preprocessor
prior to compilation, but it is outside the language standard.


> Do Ada compilers have a pre-processor ?
>
They can, but its not part of the standard. Ask your vendor.


> I am using Rational on an Sgi and Green Hills on a Sun... the manual
set(s)
> appear to have no reference to such things... This is what I want to do...
> ...
> #ifdef TEST_MODE
> #include "test_mode.a
> #endif
> ...
> a.make -D TEST_MODE -f *.a
>
> Also... If you know this is IMPOSSIBLE a brief email  to that
> effect would be useful....
>
"Impossible" is a pretty strong word. Since there are no preprocessor
directives in Ada, you would have to roll your own. However, there is a
"pragma Debug" that is implemented by a number of compilers & this may get
you what you want. Basically, you can embed code within the pragma directive
& it is only compiled if you throw some debug switch on the compiler. How it
works (and if it exists!) will be implementation dependent. GNAT supports
this directive. I believe Aonix does as well. So might other compilers, but
you'll have to check.

For examples of how to use it, look on my web page under "Ada Programming"
and "GNAT Examples" - search that for "pragma debug" and you'll see how to
use it in the code. How to toggle it on/off will be up to your compiler.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/






^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-21 16:15 ` Implementing C/C++ style #include bhazzard
  2001-03-21 16:45   ` Marin David Condic
@ 2001-03-21 18:07   ` Mark Lundquist
  2001-03-22 12:50   ` Chris M. Moore
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 115+ messages in thread
From: Mark Lundquist @ 2001-03-21 18:07 UTC (permalink / raw)



bhazzard <bhazzard@email.msn.com> wrote in message
news:OrZxgIisAHA.289@cpmsnbbsa09...
> A quick question...
>
> Is there any way to implement c/c++ style
> #ifdef pre-processor statements in Ada.
>
> Do Ada compilers have a pre-processor ?

Some do (see below)... there's no standard preprocesor for Ada...

>
> I am using Rational on an Sgi and Green Hills on a Sun... the manual
set(s)
> appear to have no reference to such things... This is what I want to do...

Well, Rational *does* have an Ada preprocessor! :-)  If you're using Apex,
look in the online Ada Compiler Reference Guide -- there's a whole big
section on the Ada Preprocessor.

If you're using VADS you also have this same preprocessor, and I can't tell
you where to look in the docs, but I know it was documented in the manual
set.

The Rational Ada Preprocessor has an Ada-style syntax and is Ada-like in
spirit.  It's not cpp-compatible ("#ifdef", etc.).  It doesn't have a
cpp-style macro facility (judged to be too unsafe and non-Ada-like :-).  It
*does* support file inclusion (very useful for including files that contain
only preprocessor definitions).

Syntax example (*not* a suggested application! :-)

    # Mode : constant Text := "Know_It_All";
    .
    .
    .
    # if Mode = "Bonehead" then
    #    if Verbose'Defined and then Verbose = "Full" then
    .
    .
    .
    #    end if;
    # end if;


Hope this helps,

Mark Lundquist
Rational Software






^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-21 13:28                         ` Robert A Duff
@ 2001-03-22  2:08                           ` Ken Garlington
  2001-03-22 16:40                             ` Robert A Duff
  2001-03-27  2:39                             ` Andrew Berg
  0 siblings, 2 replies; 115+ messages in thread
From: Ken Garlington @ 2001-03-22  2:08 UTC (permalink / raw)


"Robert A Duff" <bobduff@world.std.com> wrote in message
news:wccelvrp7xk.fsf@world.std.com...
: "Ken Garlington" <Ken.Garlington@computer.org> writes:
:
: > Can't see why, since the terms "rational number" and "floating-point
number"
: > are not the same. I think I'd be much more bothered by a floating-point
: > number without a (floating) point!
:
: Well, as it happens, "one half" is both a rational and (on most
: machines) a floating point number.  Not to mention a fixed point
: number. ;-)

Actually, I think "one half" is a string. :)

More generally, of course, there are rational numbers that are not exactly
representable as floating point numbers, so I don't see why a compiler
should accept x/y as a floating-point literal.

:
: - Bob





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-21 16:15 ` Implementing C/C++ style #include bhazzard
  2001-03-21 16:45   ` Marin David Condic
  2001-03-21 18:07   ` Mark Lundquist
@ 2001-03-22 12:50   ` Chris M. Moore
  2001-03-22 14:30     ` Marin David Condic
  2001-03-22 15:02     ` Pat Rogers
  2001-03-26 16:13   ` Martin Dowie
  2001-03-26 22:55   ` Phaedrus
  4 siblings, 2 replies; 115+ messages in thread
From: Chris M. Moore @ 2001-03-22 12:50 UTC (permalink / raw)


On Wed, 21 Mar 2001 09:15:14 -0700, "bhazzard"
<bhazzard@email.msn.com> wrote:

>A quick question...
>
>Is there any way to implement c/c++ style
>#ifdef pre-processor statements in Ada.
>
>Do Ada compilers have a pre-processor ?
>
>I am using Rational on an Sgi and Green Hills on a Sun... the manual set(s)
>appear to have no reference to such things... This is what I want to do...
>...
>#ifdef TEST_MODE
>#include "test_mode.a
>#endif
>...
>a.make -D TEST_MODE -f *.a

package Debug is

  type Debug_Mode is (off, minimal, verbose);

  Mode : constant Debug_Mode := Verbose;  

end Debug;

...

with Debug; use Debug;
...
if Debug.Mode > Minimal then
  test_mode.test_code;
end if;

The compiler should optimise out the debug code when Mode = Off.  And
it's portable.

--
Chris M. Moore
Software engineer
speaking for myself



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 12:50   ` Chris M. Moore
@ 2001-03-22 14:30     ` Marin David Condic
  2001-03-22 21:15       ` singlespeeder
  2001-03-22 15:02     ` Pat Rogers
  1 sibling, 1 reply; 115+ messages in thread
From: Marin David Condic @ 2001-03-22 14:30 UTC (permalink / raw)


Lots of compilers will optimize away unreachable code thus making some
version of:

if (True) then
    Some_Debug_Code;
end if ;

a useful construct to take the place of preprocessor directives. There are a
couple of weaknesses: The most significant is that you can't use this within
a declarative part to conditionally create types and objects. The other is
that you can't easily toggle it on and off from the compiler command line
(or whatever the compiler environment provides.)

Still, I think it is a reasonable alternative for most of the things someone
wants to build in for debug code. The other alternative being the "pragma
Debug" which is more flexible if somewhat less portable.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/

"Chris M. Moore" <chris.m.moore@gecm.com> wrote in message
news:3ab9f314.13778993@news.geccs.gecm.com...
> On Wed, 21 Mar 2001 09:15:14 -0700, "bhazzard"
> <bhazzard@email.msn.com> wrote:
>
> >A quick question...
> >
> >Is there any way to implement c/c++ style
> >#ifdef pre-processor statements in Ada.
> >
> >Do Ada compilers have a pre-processor ?
> >
> >I am using Rational on an Sgi and Green Hills on a Sun... the manual
set(s)
> >appear to have no reference to such things... This is what I want to
do...
> >...
> >#ifdef TEST_MODE
> >#include "test_mode.a
> >#endif
> >...
> >a.make -D TEST_MODE -f *.a
>
> package Debug is
>
>   type Debug_Mode is (off, minimal, verbose);
>
>   Mode : constant Debug_Mode := Verbose;
>
> end Debug;
>
> ...
>
> with Debug; use Debug;
> ...
> if Debug.Mode > Minimal then
>   test_mode.test_code;
> end if;
>
> The compiler should optimise out the debug code when Mode = Off.  And
> it's portable.
>
> --
> Chris M. Moore
> Software engineer
> speaking for myself





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 12:50   ` Chris M. Moore
  2001-03-22 14:30     ` Marin David Condic
@ 2001-03-22 15:02     ` Pat Rogers
  2001-03-22 15:28       ` Marin David Condic
                         ` (2 more replies)
  1 sibling, 3 replies; 115+ messages in thread
From: Pat Rogers @ 2001-03-22 15:02 UTC (permalink / raw)


"Chris M. Moore" <chris.m.moore@gecm.com> wrote in message
news:3ab9f314.13778993@news.geccs.gecm.com...
<snip>
> package Debug is
>
>   type Debug_Mode is (off, minimal, verbose);
>
>   Mode : constant Debug_Mode := Verbose;
>
> end Debug;
>
> ...
>
> with Debug; use Debug;
> ...
> if Debug.Mode > Minimal then
>   test_mode.test_code;
> end if;
>
> The compiler should optimise out the debug code when Mode = Off.  And
> it's portable.

By what rule in the RM is the code removed?





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-21 16:45   ` Marin David Condic
@ 2001-03-22 15:13     ` Ira D. Baxter
  2001-03-22 15:23       ` Marin David Condic
  2001-03-23 17:39       ` Wes Groleau
  0 siblings, 2 replies; 115+ messages in thread
From: Ira D. Baxter @ 2001-03-22 15:13 UTC (permalink / raw)


One can take advantage of dead code optimization
to eliminate conditionally-compiled code.  So you
don't really need a preprocessor for that.

There isn't any standard in Ada for conditional compilation
of data declarations (or even pragmas!).  This
is probably enough to justify a preprocessor of some kind.

Building one out of conventional tools such as YACC
is probably pretty hard.  You can certainly hack
a simple one in PERL, if you want, by defining
it to operate on lines that start with #, say.

However, if you want one integrated with the Ada source,
you could do that pretty easily by augmenting
an Ada grammar with a few rules, and
using a transformation engine such as our DMS Reengineering Toolkit
(see http://www.semdesigns.com/Products/DMS/DMSToolkit.html).
DMS can be obtained with an Ada grammar.
Rewrite rules for simplifying boolean equations are pretty
easy, as are rules that eliminate conditionals conditioned by TRUE or FALSE.
Such rules coupled with boolean conditions would
give an Ada preprocessor with only small effort.

--
Ira D. Baxter, Ph.D. CTO Semantic Designs, Inc.
http://www.semdesigns.com

"Marin David Condic" <marin.condic.auntie.spam@pacemicro.com> wrote in
message news:99alrr$itf$1@nh.pace.co.uk...
> "bhazzard" <bhazzard@email.msn.com> wrote in message
> news:OrZxgIisAHA.289@cpmsnbbsa09...
> > A quick question...
> >
> > Is there any way to implement c/c++ style
> > #ifdef pre-processor statements in Ada.
> >
> There is always a way. If you're willing to do the work yourself, you can
> write a program to parse your Ada code to look for preprocessor directives
&
> output appropriate *new* Ada code before doing the compile. This is a lot
of
> work





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 15:13     ` Ira D. Baxter
@ 2001-03-22 15:23       ` Marin David Condic
  2001-03-25 15:45         ` Anton Gibbs
  2001-03-27  7:34         ` Ole-Hjalmar Kristensen
  2001-03-23 17:39       ` Wes Groleau
  1 sibling, 2 replies; 115+ messages in thread
From: Marin David Condic @ 2001-03-22 15:23 UTC (permalink / raw)


Dead code optimization was brought up in another sub-thread. I agree that
this is a good trick suitable for many of the things usually done by
preprocessors.

If one is willing to live with a rather primitive preprocessor, it might not
be that big a job to simply recognize some simple markers and
comment/uncomment code (or just remove it) as needed for test. Its just that
it usually isn't long before someone wants to have somewhat more
sophisticated features available.

Its like I said: How much work do you want to do? I don't think there are
enough benefits from a preprocessor to make it worth the time it would take
to develop one. I understand that your garden variety C/C++ programmer is
used to having one around and may want to lean on one for comfort while
moving into The Ada Way(tm). (Hacking C code in Ada syntax, as it were.)

I just distrust this sort of add-on to a language and I think Ada is rich
enough to get the job done without a preprocessor. If a programmer is used
to thinking in terms of lexical inclusion rather than semantic inclusion,
preprocessors behave more the way they are used to working. If you make the
mental shift into packages, generics, "with" statements, etc., you probably
won't feel the need to rely on preprocessors since you'll evolve mechanisms
to do the same job in The Ada Way.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Ira D. Baxter" <idbaxter@semdesigns.com> wrote in message
news:tbk5cb2rf5aef0@corp.supernews.com...
> One can take advantage of dead code optimization
> to eliminate conditionally-compiled code.  So you
> don't really need a preprocessor for that.
>
> There isn't any standard in Ada for conditional compilation
> of data declarations (or even pragmas!).  This
> is probably enough to justify a preprocessor of some kind.
>
> Building one out of conventional tools such as YACC
> is probably pretty hard.  You can certainly hack
> a simple one in PERL, if you want, by defining
> it to operate on lines that start with #, say.
>
> However, if you want one integrated with the Ada source,
> you could do that pretty easily by augmenting
> an Ada grammar with a few rules, and
> using a transformation engine such as our DMS Reengineering Toolkit
> (see http://www.semdesigns.com/Products/DMS/DMSToolkit.html).
> DMS can be obtained with an Ada grammar.
> Rewrite rules for simplifying boolean equations are pretty
> easy, as are rules that eliminate conditionals conditioned by TRUE or
FALSE.
> Such rules coupled with boolean conditions would
> give an Ada preprocessor with only small effort.
>
> --
> Ira D. Baxter, Ph.D. CTO Semantic Designs, Inc.
> http://www.semdesigns.com
>
> "Marin David Condic" <marin.condic.auntie.spam@pacemicro.com> wrote in
> message news:99alrr$itf$1@nh.pace.co.uk...
> > "bhazzard" <bhazzard@email.msn.com> wrote in message
> > news:OrZxgIisAHA.289@cpmsnbbsa09...
> > > A quick question...
> > >
> > > Is there any way to implement c/c++ style
> > > #ifdef pre-processor statements in Ada.
> > >
> > There is always a way. If you're willing to do the work yourself, you
can
> > write a program to parse your Ada code to look for preprocessor
directives
> &
> > output appropriate *new* Ada code before doing the compile. This is a
lot
> of
> > work
>
>





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 15:02     ` Pat Rogers
@ 2001-03-22 15:28       ` Marin David Condic
  2001-03-22 16:32       ` Chris M. Moore
  2001-03-22 16:57       ` Robert A Duff
  2 siblings, 0 replies; 115+ messages in thread
From: Marin David Condic @ 2001-03-22 15:28 UTC (permalink / raw)


There's obviously no ARM rule that demands dead code elimination. But so
what? You check to see that your compiler eliminates the code and if it
does, you're in like flynn. If it doesn't, you have to decide if having dead
code in your system matters to you. Unless you have very tight memory
constraints and/or very stringent testing requirements, it probably doesn't
matter. Semantically, its the same thing.

From a language lawyer perspective, there may be an issue here. From the
perspective of practical application, I don't think it matters. More of an
issue is the fact that you can't use this mechanism in declarative parts and
you can't toggle it on/off from the compiler command line.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Pat Rogers" <progers@NOclasswideSPAM.com> wrote in message
news:zuou6.1025$OX6.12643@nnrp1.sbc.net...
>
> By what rule in the RM is the code removed?
>
>





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 15:02     ` Pat Rogers
  2001-03-22 15:28       ` Marin David Condic
@ 2001-03-22 16:32       ` Chris M. Moore
  2001-03-22 16:57       ` Robert A Duff
  2 siblings, 0 replies; 115+ messages in thread
From: Chris M. Moore @ 2001-03-22 16:32 UTC (permalink / raw)


On Thu, 22 Mar 2001 09:02:54 -0600, "Pat Rogers"
<progers@NOclasswideSPAM.com> wrote:

>By what rule in the RM is the code removed?

Ok, you got me.  At least it's guaranteed to compile.

Alternatively Brad could use a debugger (commands on breakpoints).
This even saves the recompile.

--
Chris M. Moore
Software engineer
speaking for myself



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-22  2:08                           ` Ken Garlington
@ 2001-03-22 16:40                             ` Robert A Duff
  2001-03-25 16:21                               ` Ken Garlington
  2001-03-27  2:39                             ` Andrew Berg
  1 sibling, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-22 16:40 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> writes:

> More generally, of course, there are rational numbers that are not exactly
> representable as floating point numbers, so I don't see why a compiler
> should accept x/y as a floating-point literal.

You misunderstand my point.  Of course x/y is not a literal.
My claim is that you shouldn't have to write ".0" on a floating point
literal that happens to be an integer.  That is,

    X: Float := 0;
    Y: Float := 1/2;

should be legal.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 15:02     ` Pat Rogers
  2001-03-22 15:28       ` Marin David Condic
  2001-03-22 16:32       ` Chris M. Moore
@ 2001-03-22 16:57       ` Robert A Duff
  2 siblings, 0 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-22 16:57 UTC (permalink / raw)


"Pat Rogers" <progers@NOclasswideSPAM.com> writes:

> > if Debug.Mode > Minimal then
> >   test_mode.test_code;
> > end if;
> >
> > The compiler should optimise out the debug code when Mode = Off.  And
> > it's portable.
> 
> By what rule in the RM is the code removed?

He didn't say anything about the RM.  He said "The compiler
*should* ...", and I agree -- it should.
(And of course the RM doesn't say anything about "code" or "removal of
code", which was perhaps your point?)

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 14:30     ` Marin David Condic
@ 2001-03-22 21:15       ` singlespeeder
  2001-03-22 21:42         ` Marin David Condic
  0 siblings, 1 reply; 115+ messages in thread
From: singlespeeder @ 2001-03-22 21:15 UTC (permalink / raw)


I use a Trace package with two bodies, one which contains null stubs. Then
use the make script to select the right body to load into the Ada library
before compiling. Calls to the trace package don't have to be wrapped in
if-then-else's

with Trace;
...
Trace.Log_Line ("some text to log to file")
...

Nick





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 21:15       ` singlespeeder
@ 2001-03-22 21:42         ` Marin David Condic
  2001-03-23 14:43           ` Georg Bauhaus
  0 siblings, 1 reply; 115+ messages in thread
From: Marin David Condic @ 2001-03-22 21:42 UTC (permalink / raw)


That is yet another technique for building in debug code - again suitable
for a variety of things, but not necessarily a complete answer. (Can't
appear in a declarative part and is really a technique for logging output -
not a general means of encapsulating general code you'd like to use or not
use depending on configuration.)

One issue is the potential procedure call overhead - not a concern in most
apps, but in some. Possibly with judicious use of "pragma Inline" the
compiler may optimize it away. It also may create verification issues if
your project has some really tight testing constraints.

A bit of a narrower technique for getting some debug code into a program &
one I've used in a few situations. It is especially useful if you'd like to
keep the debug code in the production app and be able to toggle it on/off at
runtime.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"singlespeeder" <singlespeeder@32sixteen.com> wrote in message
news:99dpom$169$1@neptunium.btinternet.com...
> I use a Trace package with two bodies, one which contains null stubs. Then
> use the make script to select the right body to load into the Ada library
> before compiling. Calls to the trace package don't have to be wrapped in
> if-then-else's
>
> with Trace;
> ...
> Trace.Log_Line ("some text to log to file")
> ...
>
> Nick
>
>





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 21:42         ` Marin David Condic
@ 2001-03-23 14:43           ` Georg Bauhaus
  2001-03-23 18:51             ` Marin David Condic
  0 siblings, 1 reply; 115+ messages in thread
From: Georg Bauhaus @ 2001-03-23 14:43 UTC (permalink / raw)


Marin David Condic (marin.condic.auntie.spam@pacemicro.com) wrote:

: One issue is the potential procedure call overhead - not a concern in most
: apps, but in some. Possibly with judicious use of "pragma Inline" the
: compiler may optimize it away. It also may create verification issues if
: your project has some really tight testing constraints.

  pragma Debug (Trace.Log_Line ("some text to log to file"));

?-)

Georg




^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 15:13     ` Ira D. Baxter
  2001-03-22 15:23       ` Marin David Condic
@ 2001-03-23 17:39       ` Wes Groleau
  1 sibling, 0 replies; 115+ messages in thread
From: Wes Groleau @ 2001-03-23 17:39 UTC (permalink / raw)



> is probably enough to justify a preprocessor of some kind.
> 
> Building one out of conventional tools such as YACC
> is probably pretty hard.  ....

But why bother, when ACT offers an open source preprocessor?

   gnatprep.ads  &  gnatprep.adb

-- 
Wes Groleau
http://freepages.rootsweb.com/~wgroleau



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-23 14:43           ` Georg Bauhaus
@ 2001-03-23 18:51             ` Marin David Condic
  0 siblings, 0 replies; 115+ messages in thread
From: Marin David Condic @ 2001-03-23 18:51 UTC (permalink / raw)


pragma Debug was mentioned a handful of posts back. One of the issues
brought up about it was that it is not portable. (Not a standard pragma)

There are a lot of ways of dealing with debug code or multiple configuration
issues. Which you end up using depends on what you want to get out of it.
One of the down-sides of pragma Debug is that it is a static, compile-time
switch. You can't toggle the debug code on and off as you execute the
program. Sometmes that's a good thing and other times not. For workstation
apps that don't have speed/space/verification issues, I like to have the
debug stuff toggleable while running. For embedded systems or things with
stringent testing requirements (or timing issues, or memory issues, or....
:-) it is nice to get the code removed by the compilerwhen you're ready for
production.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Georg Bauhaus" <sb463ba@l1-hrz.uni-duisburg.de> wrote in message
news:99fnf7$o3a$1@a1-hrz.uni-duisburg.de...
>   pragma Debug (Trace.Log_Line ("some text to log to file"));
>
> ?-)
>
> Georg
>





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Better support for garbage collection
  2001-03-16 16:42     ` Robert A Duff
  2001-03-17  6:13       ` Lao Xiao Hai
@ 2001-03-24  4:08       ` Brian Rogoff
  1 sibling, 0 replies; 115+ messages in thread
From: Brian Rogoff @ 2001-03-24  4:08 UTC (permalink / raw)


Sorry for the late reply, there's just no telling when messages arrive on
my news server :-(

On Fri, 16 Mar 2001, Robert A Duff wrote:
> Brian Rogoff <bpr@shell5.ba.best.com> writes:
> > IMO, just tacking on GC to an existing language doesn't make it very 
> > much better.
> I think it does. 

I disagree, oh well. 

> >... When the language designers design a language with the 
> > expectation of GC, they may then support some higher level features, 
> > like first class functions, which do make the language much better. 
> 
> I don't see the huge advantage of first class functions.

How about the fact that I can build functions by partially parameterizing
a given function? I assume you know what I mean here, I have a function
with n arguments and I can build a new function by calling that function
with some arguments fixed? I do that all the time. I can use that trick to
defer evaluation and simulate lazy evaluation in an eager language. 

> I *do* see the advantage of downward closures.

Well, at least you're half right ;-).

> Whenever I have asked for examples showing the usefulness of full
> closures, most folks produce examples of downward closures.
> (I've had this argument here, and also on functional language
> newsgroups, where you would expect to find more knowledge about
> closures.)

The most mundane (and convincing) is just parameterization. I must have 
missed your posts on the FP newsgroups. 

> I also see a *disadvantage* of full closures: Information that is local
> to a procedure can "escape", which seems to make code harder to
> understand.  It seems to me that if you want to pass a function (plus
> its environment) outward, you should instead explicitly create a tagged
> object on the heap, to make it clear that this thing survives after the
> end of the current procedure.

I disagree again. This kind of heavyweight simulation dissuades anyone 
from using upward funargs at all!

> In any case, surely GC is useful independent of closures: it can go a
> long way toward getting rid of dangling pointer bugs and storage leak
> bugs.

Yes, I just said I didn't see "very much" gain from GC, not "no gain". 

> > Ada is far less leaky than C family languages, so the win of just 
> > adding a GC seems smaller for Ada. 
> 
> I would say "somewhat less leaky".

IME, *far* less leaky. 

> > Of course, you still have designers who blow it by putting in GC and 
> > omitting such features, but then after a few years they realize they 
> > screwed up and hack in such things. Java and Eiffel are good examples 
> > of such screw ups (nested/anonymous classes and "agents"). 
> 
> Tell us about the Eiffel case.  The version of Eiffel I know had no such
> thing.

ISE is still working on it. Check out their web page, look up "agents" and 
"iterators". 

> > > (I find the idea of conservative collection somewhat distasteful,
> > > but it does seem to work in many cases.)
> > 
> > Maybe if it were called a "probabilistic garbage collector" you wouldn't 
> > mind? ;-)
> 
> ;-)
> 
> > Didn't Norman Cohen have a proposal for a storage pool extension that 
> > provided some support for garbage collection? I thought so, but my neural 
> > garbage collector seems to have reclaimed that hunk of my brain...
> 
> I don't remember that.
> 
> I do remember Norm participating in the above "are full closures useful"
> argument.  He's the only one I recall who produced an example that
> wasn't "downward".  I was only half convinced by his example.

That was not a convining example (Ackerman?) though it was very pretty. 

-- Brian





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 15:23       ` Marin David Condic
@ 2001-03-25 15:45         ` Anton Gibbs
  2001-03-26 14:24           ` Ted Dennison
                             ` (2 more replies)
  2001-03-27  7:34         ` Ole-Hjalmar Kristensen
  1 sibling, 3 replies; 115+ messages in thread
From: Anton Gibbs @ 2001-03-25 15:45 UTC (permalink / raw)


In article <99d5dj$fi4$1@nh.pace.co.uk>, Marin David Condic <marin.condi
c.auntie.spam@pacemicro.com> writes

>I just distrust this sort of add-on to a language and I think Ada is rich
>enough to get the job done without a preprocessor. If a programmer is used
>to thinking in terms of lexical inclusion rather than semantic inclusion,
>preprocessors behave more the way they are used to working. If you make the
>mental shift into packages, generics, "with" statements, etc., you probably
>won't feel the need to rely on preprocessors since you'll evolve mechanisms
>to do the same job in The Ada Way.

I agree that Ada is rich enough to do the programming part of systems
development without the need for a pre-processor but my experience is
that a pre-processor can help enormously with configuration management.
For example, to be able to include or exclude specific functionality
according to a set of pre-processor options allowing different variants
of a system to be built whilst retaining the same essential
architecture. We even use this technique to cater for different target
execution environments (compiled using different compilers and, in fact,
different versions of Ada (83 vs. 95)).   

-- 
Anton Gibbs



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-22 16:40                             ` Robert A Duff
@ 2001-03-25 16:21                               ` Ken Garlington
  2001-03-25 16:56                                 ` Ken Garlington
  2001-03-25 22:31                                 ` Robert A Duff
  0 siblings, 2 replies; 115+ messages in thread
From: Ken Garlington @ 2001-03-25 16:21 UTC (permalink / raw)


"Robert A Duff" <bobduff@world.std.com> wrote in message
news:wccofutg3ku.fsf@world.std.com...
: "Ken Garlington" <Ken.Garlington@computer.org> writes:
:
: > More generally, of course, there are rational numbers that are not
exactly
: > representable as floating point numbers, so I don't see why a compiler
: > should accept x/y as a floating-point literal.
:
: You misunderstand my point.

No, I just disagree with it.

: Of course x/y is not a literal.
: My claim is that you shouldn't have to write ".0" on a floating point
: literal that happens to be an integer.  That is,
:
:     X: Float := 0;
:     Y: Float := 1/2;
:
: should be legal.

But if 1/2 is not a literal, then what is it? CW would say that it is a
division operation involving two integers; why should the result be a
floating-point number? If we are to have implicit casts of integers to
floating point values, why not then permit the more general:

Y : Float := ferble;

where "ferble" is a function that returns an integer (or, for that matter,
any fixed-point) type?

For that matter, why not Y : Float := "one half"; as you suggested
(unintentionally) in a separate post?

In general, I'm not a fan of DWIM compilers (PL/M being a favorite example
of mine).

:
: - Bob





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-25 16:21                               ` Ken Garlington
@ 2001-03-25 16:56                                 ` Ken Garlington
  2001-03-25 22:31                                 ` Robert A Duff
  1 sibling, 0 replies; 115+ messages in thread
From: Ken Garlington @ 2001-03-25 16:56 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> wrote in message
news:XVov6.54$aC3.6927396@newssvr16.news.prodigy.com...
: "Robert A Duff" <bobduff@world.std.com> wrote in message
: news:wccofutg3ku.fsf@world.std.com...

: : Of course x/y is not a literal.
: : My claim is that you shouldn't have to write ".0" on a floating point
: : literal that happens to be an integer.  That is,
: :
: :     X: Float := 0;
: :     Y: Float := 1/2;
: :
: : should be legal.

Just for the sake of completeness, I also want to point out that the second
declaration *can* be legal... if you use the following:

package Float_Away is

  function "/" (Left, Right: Standard.Integer) return Standard.Float;

end Float_Away;





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-25 16:21                               ` Ken Garlington
  2001-03-25 16:56                                 ` Ken Garlington
@ 2001-03-25 22:31                                 ` Robert A Duff
  2001-03-27  0:24                                   ` Ken Garlington
  1 sibling, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-25 22:31 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> writes:

> "Robert A Duff" <bobduff@world.std.com> wrote in message
> news:wccofutg3ku.fsf@world.std.com...
> : "Ken Garlington" <Ken.Garlington@computer.org> writes:
> :
> : > More generally, of course, there are rational numbers that are not
> exactly
> : > representable as floating point numbers, so I don't see why a compiler
> : > should accept x/y as a floating-point literal.
> :
> : You misunderstand my point.
> 
> No, I just disagree with it.

With all respect, I must insist that:  No, you don't disagree, you
misunderstand.  ;-) ;-)

You misunderstand what I mean by "literal" (which is exactly what the
Ada RM means by "literal", too).

> : Of course x/y is not a literal.
> : My claim is that you shouldn't have to write ".0" on a floating point
> : literal that happens to be an integer.  That is,
> :
> :     X: Float := 0;
> :     Y: Float := 1/2;
> :
> : should be legal.
> 
> But if 1/2 is not a literal, then what is it?

Certainly 1/2 is not a literal.  Not in Ada, and not by me.

>... CW would say that it is a
> division operation involving two integers; why should the result be a
> floating-point number?

I would say, it's a division operation involving two *literals*
(where literal implies no particular type).
The interpretation of those literals should be resolved by the context.

>... If we are to have implicit casts of integers to
> floating point values, why not then permit the more general:
> 
> Y : Float := ferble;
> 
> where "ferble" is a function that returns an integer (or, for that matter,
> any fixed-point) type?

Why not?  Because it makes no sense.  Converting type Standard.Integer
to Standard.Float probably makes no sense.  But implicitly converting
"1" to (say) Float *does* make sense.  I was only talking about
literals.

Note that Ada always converts literals to some particular type.

Note also that I'm not advocating all manner of implicit conversions.
Certainly no implicit conversions that might lose information.

> For that matter, why not Y : Float := "one half"; as you suggested
> (unintentionally) in a separate post?

You got me there!  ;-)

> In general, I'm not a fan of DWIM compilers (PL/M being a favorite example
> of mine).

Agreed (in general).

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-25 15:45         ` Anton Gibbs
@ 2001-03-26 14:24           ` Ted Dennison
  2001-03-26 15:00             ` Marin David Condic
  2001-03-26 14:49           ` Marin David Condic
  2001-03-26 16:12           ` Florian Weimer
  2 siblings, 1 reply; 115+ messages in thread
From: Ted Dennison @ 2001-03-26 14:24 UTC (permalink / raw)


In article <K$VNnBA+Jhv6Ewa4@zooks.demon.co.uk>, Anton Gibbs says...
>
>I agree that Ada is rich enough to do the programming part of systems
>development without the need for a pre-processor but my experience is
>that a pre-processor can help enormously with configuration management.

My experience is that the resultant source code is a maintanence nightmare. 

Apparently, I'm not the only one with that experience, as conditional
compilation was expressly forbidden from the original language design.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-25 15:45         ` Anton Gibbs
  2001-03-26 14:24           ` Ted Dennison
@ 2001-03-26 14:49           ` Marin David Condic
  2001-03-26 18:19             ` Stephen Leake
  2001-03-26 16:12           ` Florian Weimer
  2 siblings, 1 reply; 115+ messages in thread
From: Marin David Condic @ 2001-03-26 14:49 UTC (permalink / raw)


I guess I've just seen it done enough different ways that work as well or
better that I don't really see any necessity for a preprocessor to do this
job. Managing different configurations can be handled with package body
substitution, static elimination of code via normal "if" statements, pragma
Debug, available configuration management tools, etc. As a result, I think
that trying to include special pre-processor directives in the source and
going through an extra pre-compilation step (fraught with peril!) is
unnecessary and potentially dangerous. (Try looking at some older C code
that may have very convoluted "#include" chains, etc. if you need an example
of how dangerous this can get.) I've never once seen a case where you could
accomplish some goal with a preprocessor that you couldn't accomplish with a
less error prone technique. So why ask for the trouble?

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Anton Gibbs" <anton@zooks.demon.co.uk> wrote in message
news:K$VNnBA+Jhv6Ewa4@zooks.demon.co.uk...
> I agree that Ada is rich enough to do the programming part of systems
> development without the need for a pre-processor but my experience is
> that a pre-processor can help enormously with configuration management.
> For example, to be able to include or exclude specific functionality
> according to a set of pre-processor options allowing different variants
> of a system to be built whilst retaining the same essential
> architecture. We even use this technique to cater for different target
> execution environments (compiled using different compilers and, in fact,
> different versions of Ada (83 vs. 95)).






^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 14:24           ` Ted Dennison
@ 2001-03-26 15:00             ` Marin David Condic
  0 siblings, 0 replies; 115+ messages in thread
From: Marin David Condic @ 2001-03-26 15:00 UTC (permalink / raw)


"Ted Dennison" <dennison@telepath.com> wrote in message
news:giIv6.2807$fy.4181@www.newsranger.com...
> Apparently, I'm not the only one with that experience, as conditional
> compilation was expressly forbidden from the original language design.
>
And that which is not Forbidden, is Mandatory! :-) (Unless, of course, you
are a Commie Mutant Traitor and need to be turned into reactor shielding.
:-)

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/






^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-25 15:45         ` Anton Gibbs
  2001-03-26 14:24           ` Ted Dennison
  2001-03-26 14:49           ` Marin David Condic
@ 2001-03-26 16:12           ` Florian Weimer
  2001-03-26 17:34             ` David Starner
  2001-03-26 18:23             ` Stephen Leake
  2 siblings, 2 replies; 115+ messages in thread
From: Florian Weimer @ 2001-03-26 16:12 UTC (permalink / raw)


Anton Gibbs <anton@zooks.demon.co.uk> writes:

> I agree that Ada is rich enough to do the programming part of systems
> development without the need for a pre-processor but my experience is
> that a pre-processor can help enormously with configuration management.

Even for medium-sized projects, it doesn't.  For example, Linux kernel
development is quite difficult because no developer can build the
kernel in more than a few configurations, but there are more then
2**50 possible configurations.  As a result, it happens all the time
that one change breaks some special configurations, and there's really
no way to test automatically for such problems.



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-21 16:15 ` Implementing C/C++ style #include bhazzard
                     ` (2 preceding siblings ...)
  2001-03-22 12:50   ` Chris M. Moore
@ 2001-03-26 16:13   ` Martin Dowie
  2001-03-26 22:55   ` Phaedrus
  4 siblings, 0 replies; 115+ messages in thread
From: Martin Dowie @ 2001-03-26 16:13 UTC (permalink / raw)


you could just use the C pre-processor, but I've never really seen anything
that you
couldn't do in Ada - one trick I use is to always have a package called
'Project' which
contains the same details about a project as constants and let the compiler
then
work out which branches that can't be reached. For difference configurations
this
should be the one of the few files then needing changed.

e.g.

package Project is
  Name : constant String := "Blah";
  type An_Endian is (Little_Endian, Big_Endian):
  Byte_Endian : constant An_Endian := ...;
  type A_Processor is (X86, PowerPC, ARM);
  Processor : constant A_Processor := Power_PC;
  -- etc
end Project;

bhazzard <bhazzard@email.msn.com> wrote in message
news:OrZxgIisAHA.289@cpmsnbbsa09...
> A quick question...
>
> Is there any way to implement c/c++ style
> #ifdef pre-processor statements in Ada.
>
> Do Ada compilers have a pre-processor ?
>





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 16:12           ` Florian Weimer
@ 2001-03-26 17:34             ` David Starner
  2001-03-26 22:25               ` Florian Weimer
  2001-03-26 18:23             ` Stephen Leake
  1 sibling, 1 reply; 115+ messages in thread
From: David Starner @ 2001-03-26 17:34 UTC (permalink / raw)


On 26 Mar 2001 18:12:16 +0200, Florian Weimer wrote:
>Anton Gibbs <anton@zooks.demon.co.uk> writes:
>
>> I agree that Ada is rich enough to do the programming part of systems
>> development without the need for a pre-processor but my experience is that a
>> pre-processor can help enormously with configuration management.
>
>Even for medium-sized projects, it doesn't.  For example, Linux kernel
>development is quite difficult because no developer can build the kernel in
>more than a few configurations, but there are more then 2**50 possible
>configurations.  As a result, it happens all the time that one change breaks
>some special configurations, and there's really no way to test automatically
>for such problems.

Which has what to do with a pre-processor? The Linux kernel would be
able to be built in 2**50 possible configurations in any case, with or
without a pre-processor. 

-- 
David Starner - dstarner98@aasaa.ofe.org
Pointless website: http://dvdeug.dhis.org
"I don't care if Bill personally has my name and reads my email and 
laughs at me. In fact, I'd be rather honored." - Joseph_Greg



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 14:49           ` Marin David Condic
@ 2001-03-26 18:19             ` Stephen Leake
  2001-03-26 18:44               ` Pascal Obry
                                 ` (2 more replies)
  0 siblings, 3 replies; 115+ messages in thread
From: Stephen Leake @ 2001-03-26 18:19 UTC (permalink / raw)


"Marin David Condic" <marin.condic.auntie.spam@pacemicro.com> writes:

> I guess I've just seen it done enough different ways that work as well or
> better that I don't really see any necessity for a preprocessor to do this
> job. Managing different configurations can be handled with package body
> substitution, static elimination of code via normal "if" statements, pragma
> Debug, available configuration management tools, etc. 

Not this one:

   function Ada_Size_Of_Input is new 
      Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
#if GNAT_Compiler
   pragma Export (C, Ada_Size_Of_Input,
                  "ball_ct633_ada_size_of_input",  
                  "ball_ct633_ada_size_of_input");
#elsif ObjectAda_Compiler
   pragma Export (DLL_STDCALL, Ada_Size_Of_Input, 
                  "ball_ct633_ada_size_of_input", 
                  "ball_ct633_ada_size_of_input");
#end if;

The difference is in the name of the Convention. Preprocessing is, in
this case, the best way to handle it. I believe the only alternative
is to reproduce the entire package spec, and change this one value.
Surely you do not claim that is better from a maintenance point of
view? 

I can only assume you have not personally encountered a situation like
this. Until you have, you need to be a little more open :).

There are similar examples of needing to support a mix of Ada 83/95,
compiler vendors, and targets, where limited, structured,
well-designed use of pre-processing is the best way to go.

> As a result, I think that trying to include special pre-processor
> directives in the source and going through an extra pre-compilation
> step (fraught with peril!) is unnecessary and potentially dangerous.

"potentially dangerous" yes, just like Unchecked_Conversion and
Unchecked_Deallocation. "unecessary" no, just like
Unchecked_Conversion and Unchecked_Deallocation!

> 
> (Try looking at some older C code that may have very convoluted
> "#include" chains, etc. if you need an example of how dangerous this
> can get.) I've never once seen a case where you could accomplish
> some goal with a preprocessor that you couldn't accomplish with a
> less error prone technique. 

Have you seen the above case?

> So why ask for the trouble?

I'm not asking for "trouble", I'm asking for "expressive power".
"Trouble" I can handle with coding guidelines and project discipline.

Note that the gnat preprocessor does _not_ define "include", only
"if". And it does _not_ define macros.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 16:12           ` Florian Weimer
  2001-03-26 17:34             ` David Starner
@ 2001-03-26 18:23             ` Stephen Leake
  2001-03-26 22:34               ` Florian Weimer
  1 sibling, 1 reply; 115+ messages in thread
From: Stephen Leake @ 2001-03-26 18:23 UTC (permalink / raw)


Florian Weimer <Florian.Weimer@RUS.Uni-Stuttgart.DE> writes:

> Anton Gibbs <anton@zooks.demon.co.uk> writes:
> 
> > I agree that Ada is rich enough to do the programming part of systems
> > development without the need for a pre-processor but my experience is
> > that a pre-processor can help enormously with configuration management.
> 
> Even for medium-sized projects, it doesn't.  For example, Linux kernel
> development is quite difficult because no developer can build the
> kernel in more than a few configurations, but there are more then
> 2**50 possible configurations.  As a result, it happens all the time
> that one change breaks some special configurations, and there's really
> no way to test automatically for such problems.

On two of my current projects, I have a requirement to support at
least two different mixes of targets and/or compilers. My testing
procedure includes running _all_ possible variants _every_ _time_.

So yes, supporting a system like Linux, with thousands of variants, is
_hard_. But that does _not_ mean preprocessing is not useful on
systems with just a few variants, that can all be tested.

And anyway, what is the alternative for Linux? I guess structuring it
so the number of configurations is actually linear with the number of
targets, but is that really possible?

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 18:19             ` Stephen Leake
@ 2001-03-26 18:44               ` Pascal Obry
  2001-03-26 21:44                 ` Robert A Duff
  2001-03-26 19:18               ` Ted Dennison
  2001-03-26 19:35               ` Marin David Condic
  2 siblings, 1 reply; 115+ messages in thread
From: Pascal Obry @ 2001-03-26 18:44 UTC (permalink / raw)



Stephen Leake <stephen.a.leake.1@gsfc.nasa.gov> writes:

> Not this one:
> 
>    function Ada_Size_Of_Input is new 
>       Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
> #if GNAT_Compiler
>    pragma Export (C, Ada_Size_Of_Input,
>                   "ball_ct633_ada_size_of_input",  
>                   "ball_ct633_ada_size_of_input");
> #elsif ObjectAda_Compiler
>    pragma Export (DLL_STDCALL, Ada_Size_Of_Input, 
>                   "ball_ct633_ada_size_of_input", 
>                   "ball_ct633_ada_size_of_input");
> #end if;

I agree with you that in such a case a preprocessor could be usefull. Anothe
way to handle this is by writing a template and have the right spec generated
by a script.

   function Ada_Size_Of_Input is new 
      Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
   pragma Export (<OS_CONVENTION>, Ada_Size_Of_Input,
                  "ball_ct633_ada_size_of_input",  
                  "ball_ct633_ada_size_of_input");

This is even easier to maintain. Only one Export pragma. And if you have to
change/add new convention for new compiler you just need to add one token into
your script.

You can even configure prefix if you need so:

   function Ada_Size_Of_Input is new 
      Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
   pragma Export (<OS_CONVENTION>, Ada_Size_Of_Input,
                  "<COMP_PREFIX>_ada_size_of_input",  
                  "<COMP_PREFIX>_ada_size_of_input");

> 
> The difference is in the name of the Convention. Preprocessing is, in
> this case, the best way to handle it. I believe the only alternative
> is to reproduce the entire package spec, and change this one value.
> Surely you do not claim that is better from a maintenance point of
> view? 

Agree, but see above.

> I can only assume you have not personally encountered a situation like
> this. Until you have, you need to be a little more open :).

I have but in that case I use script.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|         http://perso.wanadoo.fr/pascal.obry
--|
--| "The best way to travel is by means of imagination"



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 18:19             ` Stephen Leake
  2001-03-26 18:44               ` Pascal Obry
@ 2001-03-26 19:18               ` Ted Dennison
  2001-03-27 18:51                 ` Anton Gibbs
  2001-03-26 19:35               ` Marin David Condic
  2 siblings, 1 reply; 115+ messages in thread
From: Ted Dennison @ 2001-03-26 19:18 UTC (permalink / raw)


In article <u7l1cgzpa.fsf@gsfc.nasa.gov>, Stephen Leake says...
>
>Not this one:
>
>   function Ada_Size_Of_Input is new 
>      Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
>#if GNAT_Compiler
>   pragma Export (C, Ada_Size_Of_Input,
>                  "ball_ct633_ada_size_of_input",  
>                  "ball_ct633_ada_size_of_input");
>#elsif ObjectAda_Compiler
>   pragma Export (DLL_STDCALL, Ada_Size_Of_Input, 
>                  "ball_ct633_ada_size_of_input", 
>                  "ball_ct633_ada_size_of_input");
>#end if;
>
>The difference is in the name of the Convention. Preprocessing is, in
>this case, the best way to handle it. I believe the only alternative
>is to reproduce the entire package spec, and change this one value.
>Surely you do not claim that is better from a maintenance point of
>view? 

If that's the only one, perhaps. But any time you are doing a pragma Import or
Export, odds are you are doing several of them (or more). In that case, it may
*still* be better from a maintenance point of view to have two copies of the
file.

Actually, this is one case where I'd like to see a minor language extension.
It'd be nice if the "Convention" parameter took a proper Ada data type of some
sort, so that it could be defined as a constant and placed in a convienent place
(like a system-dependant constants file). 

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 18:19             ` Stephen Leake
  2001-03-26 18:44               ` Pascal Obry
  2001-03-26 19:18               ` Ted Dennison
@ 2001-03-26 19:35               ` Marin David Condic
  2001-03-26 23:04                 ` Mark Lundquist
  2 siblings, 1 reply; 115+ messages in thread
From: Marin David Condic @ 2001-03-26 19:35 UTC (permalink / raw)


Well, you bring up a lot of points here. Let me see if I can at least hit on
the overall cases.

Yes, I've seen cases where you may need to maintain code for two different
compilers. You can't sneak the one version of code past the other compiler,
so you might be tempted to use preprocessing directives to eliminate it.
(Something that is itself possibly peculiar to one compiler and won't sneak
past another compiler, eh?) Why can't you burry this in a package body that
is maintained down a separate CM path? (Your example could be hidden in a
package body, no?)

While I admit the possibility of maintaining code for two different
compilers, I think it is kind of rare. More likely, you've got code for two
different platforms wherein some resources may be variant between the
platforms. (OS calls, devices, etc.) In either case, I'd prefer to either
isolate it in a package body and maintain two bodies down two different CM
paths or I'd control it with (static or dynamic) "if" checking that I would
change from a configuration package spec. I'd personally prefer these
choices to using a preprocessor.

As for being "open" - I think it was G. K. Chesterton who said "Having an
open mind is nothing. The object of opening the mind, as of opening the
mouth, is to shut it again on something solid." :-) Seriously, I've used
preprocessors (and still do by way of C/C++) and just remain unconvinced
that you can't get there by other means with fewer pitfalls.

Given the experience I have had, I just don't see it as being in the same
category as "Unchecked_Conversion" and I don't feel the need for that sort
of "expressive power". Some people may like a preprocessor and that's fine
by me. I personally would advise against it.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/



"Stephen Leake" <stephen.a.leake.1@gsfc.nasa.gov> wrote in message
news:u7l1cgzpa.fsf@gsfc.nasa.gov...
> "Marin David Condic" <marin.condic.auntie.spam@pacemicro.com> writes:
>
> > I guess I've just seen it done enough different ways that work as well
or
> > better that I don't really see any necessity for a preprocessor to do
this
> > job. Managing different configurations can be handled with package body
> > substitution, static elimination of code via normal "if" statements,
pragma
> > Debug, available configuration management tools, etc.
>
> Not this one:
>
>    function Ada_Size_Of_Input is new
>       Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
> #if GNAT_Compiler
>    pragma Export (C, Ada_Size_Of_Input,
>                   "ball_ct633_ada_size_of_input",
>                   "ball_ct633_ada_size_of_input");
> #elsif ObjectAda_Compiler
>    pragma Export (DLL_STDCALL, Ada_Size_Of_Input,
>                   "ball_ct633_ada_size_of_input",
>                   "ball_ct633_ada_size_of_input");
> #end if;
>
> The difference is in the name of the Convention. Preprocessing is, in
> this case, the best way to handle it. I believe the only alternative
> is to reproduce the entire package spec, and change this one value.
> Surely you do not claim that is better from a maintenance point of
> view?
>
> I can only assume you have not personally encountered a situation like
> this. Until you have, you need to be a little more open :).
>
> There are similar examples of needing to support a mix of Ada 83/95,
> compiler vendors, and targets, where limited, structured,
> well-designed use of pre-processing is the best way to go.
>
> > As a result, I think that trying to include special pre-processor
> > directives in the source and going through an extra pre-compilation
> > step (fraught with peril!) is unnecessary and potentially dangerous.
>
> "potentially dangerous" yes, just like Unchecked_Conversion and
> Unchecked_Deallocation. "unecessary" no, just like
> Unchecked_Conversion and Unchecked_Deallocation!
>
> >
> > (Try looking at some older C code that may have very convoluted
> > "#include" chains, etc. if you need an example of how dangerous this
> > can get.) I've never once seen a case where you could accomplish
> > some goal with a preprocessor that you couldn't accomplish with a
> > less error prone technique.
>
> Have you seen the above case?
>
> > So why ask for the trouble?
>
> I'm not asking for "trouble", I'm asking for "expressive power".
> "Trouble" I can handle with coding guidelines and project discipline.
>
> Note that the gnat preprocessor does _not_ define "include", only
> "if". And it does _not_ define macros.
>
> --
> -- Stephe





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 18:44               ` Pascal Obry
@ 2001-03-26 21:44                 ` Robert A Duff
  2001-03-27  3:02                   ` Andrew Berg
  2001-03-27 17:41                   ` Pascal Obry
  0 siblings, 2 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-26 21:44 UTC (permalink / raw)


Pascal Obry <p.obry@wanadoo.fr> writes:

> I agree with you that in such a case a preprocessor could be usefull. Anothe
> way to handle this is by writing a template and have the right spec generated
> by a script.
> 
>    function Ada_Size_Of_Input is new 
>       Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
>    pragma Export (<OS_CONVENTION>, Ada_Size_Of_Input,
>                   "ball_ct633_ada_size_of_input",  
>                   "ball_ct633_ada_size_of_input");

Your "script" is, in fact, a macro preprocessor.

Are macros more or less evil than #if things?
I've heard both opinions in this thread.  ;-)

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 17:34             ` David Starner
@ 2001-03-26 22:25               ` Florian Weimer
  2001-03-27  3:29                 ` David Starner
  0 siblings, 1 reply; 115+ messages in thread
From: Florian Weimer @ 2001-03-26 22:25 UTC (permalink / raw)


dvdeug@x8b4e53cd.dhcp.okstate.edu (David Starner) writes:

> >Even for medium-sized projects, it doesn't.  For example, Linux kernel
> >development is quite difficult because no developer can build the kernel in
> >more than a few configurations, but there are more then 2**50 possible
> >configurations.  As a result, it happens all the time that one change breaks
> >some special configurations, and there's really no way to test automatically
> >for such problems.
> 
> Which has what to do with a pre-processor? The Linux kernel would be
> able to be built in 2**50 possible configurations in any case, with or
> without a pre-processor. 

If you use a preprocessor, only the code which is activated in a given
configuration will be passed through the compiler.  Syntax errors,
type errors, name clashes, references to renamed identifiers in other
configurations won't be detected.

IMHO, that's the strongest argument against a preprocessor.  If you
don't use a preprocessor, you can be sure that your code compiles in
all configurations (if it works is another question, of course).



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 18:23             ` Stephen Leake
@ 2001-03-26 22:34               ` Florian Weimer
  0 siblings, 0 replies; 115+ messages in thread
From: Florian Weimer @ 2001-03-26 22:34 UTC (permalink / raw)


Stephen Leake <stephen.a.leake.1@gsfc.nasa.gov> writes:

> And anyway, what is the alternative for Linux? I guess structuring it
> so the number of configurations is actually linear with the number of
> targets, but is that really possible?

They try to isolate the configuration-specific code.  Once there was a
rule, 'no #ifdefs in actual code', but I don't know if it still
followed.  OTOH, it doesn't matter much if some configurations do not
compile.  The fix is pretty straightforward most of the time (even if
it breaks other configurations), and the usual configurations are
tested most, of course, so the probability they work is quite high.

Well, my experiences with the C preprocessor in much smaller projects
are quite bad as well.  I'm maintaining a fork of OpenSSH which adds
additional control over port forwarding (we use OpenSSH to implement
a poor man's VPN at the university because no other protocol/vendor
supports all the platforms we need), and the upstream authors use
#ifdefs in actual code.  Adding a few extra parameters to some
routines is quite annoying because of procedure calls hidden behind an
#ifdef.  For the next patching frenzy, I'm warned, but I'm convinced
as well that the C preprocessor is the source of major maintenance
headaches.



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-21 16:15 ` Implementing C/C++ style #include bhazzard
                     ` (3 preceding siblings ...)
  2001-03-26 16:13   ` Martin Dowie
@ 2001-03-26 22:55   ` Phaedrus
  2001-03-27  1:36     ` tmoran
  4 siblings, 1 reply; 115+ messages in thread
From: Phaedrus @ 2001-03-26 22:55 UTC (permalink / raw)


From your example, it looks like you just want to use the pre-processor to
maintain different code configurations.  Why not just tie the code differences
to one or two packages, and then keep different versions of them on the
different environments?
If that doesn't work for you (Yeah, I knew it wouldn't.  It never does.) then I
believe that both compilers come with a pragma that might suit your purposes.
Which one?  Uh, well, I can't quite remember, but I seem to vaguely remember
something of the kind.  What can I say, RTFM.  Sorry.

Phaedrus






^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 19:35               ` Marin David Condic
@ 2001-03-26 23:04                 ` Mark Lundquist
  2001-03-27 14:38                   ` Marin David Condic
  0 siblings, 1 reply; 115+ messages in thread
From: Mark Lundquist @ 2001-03-26 23:04 UTC (permalink / raw)



Marin David Condic <marin.condic.auntie.spam@pacemicro.com> wrote in message
news:99o5m6$6of$1@nh.pace.co.uk...
>
> As for being "open" - I think it was G. K. Chesterton who said "Having an
> open mind is nothing. The object of opening the mind, as of opening the
> mouth, is to shut it again on something solid." :-)

I think you're right, it was Chesterton.

> I personally would advise against it.

I'd disgree that there aren't instances where a preprocessor is the best
solution available.

Not my ideal solution, but my ideal doesn't exist today :-)
-- mark







^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-25 22:31                                 ` Robert A Duff
@ 2001-03-27  0:24                                   ` Ken Garlington
  2001-03-28 23:15                                     ` Robert A Duff
  0 siblings, 1 reply; 115+ messages in thread
From: Ken Garlington @ 2001-03-27  0:24 UTC (permalink / raw)


"Robert A Duff" <bobduff@world.std.com> wrote in message
news:wccr8zl4h0n.fsf@world.std.com...

: Certainly 1/2 is not a literal.  Not in Ada, and not by me.
:
: >... CW would say that it is a
: > division operation involving two integers; why should the result be a
: > floating-point number?
:
: I would say, it's a division operation involving two *literals*
: (where literal implies no particular type).
:
: The interpretation of those literals should be resolved by the context.

Note, however, that if these literals were "interpreted" as their "obvious"
floating-point context, and the function I posted earlier were introduced,
you'd have to decide if now (a) the literals were "more obviously" an
integer or (b) that the correct form could not be determined from context.
Either way would seem very awkward to me. Granted, you have that problem now
distinguishing different decimal representations, but I certainly wouldn't
want to make it any worse!

: >... If we are to have implicit casts of integers to
: > floating point values, why not then permit the more general:
: >
: > Y : Float := ferble;
: >
: > where "ferble" is a function that returns an integer (or, for that
matter,
: > any fixed-point) type?
:
: Why not?  Because it makes no sense.  Converting type Standard.Integer
: to Standard.Float probably makes no sense.

A conversion (or "interpretation", if you prefer) of a representation that
is numeric, but has an implied decimal point to the right of the last digit,
to a representation that has an explicit decimal point to the right of the
last digit, makes no sense? Then why do you want an Ada compiler to do it
for literals?

: But implicitly converting
: "1" to (say) Float *does* make sense.  I was only talking about
: literals.

Again, this makes about as much sense as insisting that 1 be implicitly
coverted to character, string... or, for that matter, "one half" to be
converted to some numeric type. After all, if you're going to object to the
"overhead" of adding .0, then why not object to adding quote marks for a
character or a single-word string (in the absence of some object with that
name)... isn't each "obvious in context"?

: Note that Ada always converts literals to some particular type.

Sure... some type that is *closest* to the representation *as entered*. If
you don't enter a decimal point, why would you expect it to be converted to
a representation that requires a decimal point (fixed or floating)?

: Note also that I'm not advocating all manner of implicit conversions.
: Certainly no implicit conversions that might lose information.

What about a conversion that adds *unintended* information?





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 22:55   ` Phaedrus
@ 2001-03-27  1:36     ` tmoran
  0 siblings, 0 replies; 115+ messages in thread
From: tmoran @ 2001-03-27  1:36 UTC (permalink / raw)


>maintain different code configurations.  Why not just tie the code differences
>to one or two packages, and then keep different versions of them on the
>different environments?
>If that doesn't work for you (Yeah, I knew it wouldn't.  It never does.)
  It works for Claw (150 KSLOC) on compilers from 4 different vendors.
The current public release of one compiler, however, has a bug that
requires a whole bunch of things to be moved from the private to the
public part of a spec.  Though that special version could be handled with
#if, it would really be ugly.  Presumably the next release of that
compiler will fix the problem and we can again have a single version, so
creating, and freezing, a special work-around version was probably less
trouble than inserting all the #if's and duplicated code.
  In the early days the compilers differed on Convention names, but a
specialized translator a la Pascal Obry's suggestion easily solved that.
  Having worked with C code that used the full power of the
preprocessor, I agree that's a fate worse than death. #.#



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-22  2:08                           ` Ken Garlington
  2001-03-22 16:40                             ` Robert A Duff
@ 2001-03-27  2:39                             ` Andrew Berg
  2001-03-27  3:33                               ` Ken Garlington
  1 sibling, 1 reply; 115+ messages in thread
From: Andrew Berg @ 2001-03-27  2:39 UTC (permalink / raw)



Ken Garlington wrote:
> 
> "Robert A Duff" <bobduff@world.std.com> wrote in message
> news:wccelvrp7xk.fsf@world.std.com...
> : "Ken Garlington" <Ken.Garlington@computer.org> writes:
> :
> : > Can't see why, since the terms "rational number" and "floating-point
> number"
> : > are not the same. I think I'd be much more bothered by a floating-point
> : > number without a (floating) point!
> :
> : Well, as it happens, "one half" is both a rational and (on most
> : machines) a floating point number.  Not to mention a fixed point
> : number. ;-)
> 
> Actually, I think "one half" is a string. :)
> 
> More generally, of course, there are rational numbers that are not exactly
> representable as floating point numbers, so I don't see why a compiler
> should accept x/y as a floating-point literal.

Okay, but then by that argument there are some decimal numbers that are
not exactly representable as floting point numbers, so I don't see why a
compiler should accept 0.1 as a floating-point literal.

After all, all 0.1 is is a silly way to write 1/10.  I'd myself like
better support for dealing with rational bignums, but that's a different
thing entirely.  And with enough time and operator overloading probably
would not require tons of compiler support, unless we want them to be
reasonably fast.  :(

-andrew



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 21:44                 ` Robert A Duff
@ 2001-03-27  3:02                   ` Andrew Berg
  2001-03-27  3:27                     ` Phaedrus
  2001-03-27 17:41                   ` Pascal Obry
  1 sibling, 1 reply; 115+ messages in thread
From: Andrew Berg @ 2001-03-27  3:02 UTC (permalink / raw)



Robert A Duff wrote:
> 
> Pascal Obry <p.obry@wanadoo.fr> writes:
> 
> > I agree with you that in such a case a preprocessor could be usefull. Anothe
> > way to handle this is by writing a template and have the right spec generated
> > by a script.
> >
> >    function Ada_Size_Of_Input is new
> >       Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
> >    pragma Export (<OS_CONVENTION>, Ada_Size_Of_Input,
> >                   "ball_ct633_ada_size_of_input",
> >                   "ball_ct633_ada_size_of_input");
> 
> Your "script" is, in fact, a macro preprocessor.
> 
> Are macros more or less evil than #if things?
> I've heard both opinions in this thread.  ;-)

As a full time C++ programmer, I'm going to have to side with Pascal
here.  Textual macros are dangerous, but a limited form of dangerous.  

#if's on the other hand are quite possibly the worst form of evil
imaginable, in that it is never really possible to know exactly what is
going on.  Even in simple cases it is bad, because when maintenance
happens they always get worse.  I suppose that if you are writing code
that will never get looked at they might not be so bad, but I have never
had that luxury.

Probably the only decent application of #if is '#if 0' as a way to
comment out multiple lines of code at once.  C's /* */ comments cannot
be nested and it gets really tedious to put //'s everywhere, so #if 0 is
a useful construct.

If you want an example of the kind of hell I am thinking of, go download
'stlport', a reasonably portable, reasonably compliant version of C++'s
STL.  Look at those header files for a while...

-andrew



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-27  3:02                   ` Andrew Berg
@ 2001-03-27  3:27                     ` Phaedrus
  0 siblings, 0 replies; 115+ messages in thread
From: Phaedrus @ 2001-03-27  3:27 UTC (permalink / raw)


Funny, I thought that C++ was the "worst form of evil imaginable".
No, scratch that...  Our software management is the worst form of evil
imaginable,
C++ is just number two.  Or maybe three, after taxes.  But it's a close race.

Pestilence?  Isn't that the same thing as C++?

Phaedrus

"Andrew Berg" <andrewb@votehere.net> wrote in message
news:3AC002AA.73118A89@votehere.net...
>
> Robert A Duff wrote:
> >
> > Pascal Obry <p.obry@wanadoo.fr> writes:
> >
> > > I agree with you that in such a case a preprocessor could be usefull.
Anothe
> > > way to handle this is by writing a template and have the right spec
generated
> > > by a script.
> > >
> > >    function Ada_Size_Of_Input is new
> > >       Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
> > >    pragma Export (<OS_CONVENTION>, Ada_Size_Of_Input,
> > >                   "ball_ct633_ada_size_of_input",
> > >                   "ball_ct633_ada_size_of_input");
> >
> > Your "script" is, in fact, a macro preprocessor.
> >
> > Are macros more or less evil than #if things?
> > I've heard both opinions in this thread.  ;-)
>
> As a full time C++ programmer, I'm going to have to side with Pascal
> here.  Textual macros are dangerous, but a limited form of dangerous.
>
> #if's on the other hand are quite possibly the worst form of evil
> imaginable, in that it is never really possible to know exactly what is
> going on.  Even in simple cases it is bad, because when maintenance
> happens they always get worse.  I suppose that if you are writing code
> that will never get looked at they might not be so bad, but I have never
> had that luxury.
>
> Probably the only decent application of #if is '#if 0' as a way to
> comment out multiple lines of code at once.  C's /* */ comments cannot
> be nested and it gets really tedious to put //'s everywhere, so #if 0 is
> a useful construct.
>
> If you want an example of the kind of hell I am thinking of, go download
> 'stlport', a reasonably portable, reasonably compliant version of C++'s
> STL.  Look at those header files for a while...
>
> -andrew
>





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 22:25               ` Florian Weimer
@ 2001-03-27  3:29                 ` David Starner
  0 siblings, 0 replies; 115+ messages in thread
From: David Starner @ 2001-03-27  3:29 UTC (permalink / raw)


On 27 Mar 2001 00:25:00 +0200, Florian Weimer <fw@deneb.enyo.de> wrote:
>IMHO, that's the strongest argument against a preprocessor.  If you
>don't use a preprocessor, you can be sure that your code compiles in
>all configurations (if it works is another question, of course).

If you use seperate packages for different configurations, you can't
be sure that the code compiles. Often, the point is that the code
doesn't compile (on MIPS/on Apex/with GNAT 3.72), and that different
code needs to be used there.

-- 
David Starner - dstarner98@aasaa.ofe.org
Pointless website: http://dvdeug.dhis.org
"I don't care if Bill personally has my name and reads my email and 
laughs at me. In fact, I'd be rather honored." - Joseph_Greg



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-27  2:39                             ` Andrew Berg
@ 2001-03-27  3:33                               ` Ken Garlington
  2001-03-27 14:23                                 ` Robert A Duff
  0 siblings, 1 reply; 115+ messages in thread
From: Ken Garlington @ 2001-03-27  3:33 UTC (permalink / raw)



"Andrew Berg" <andrewb@votehere.net> wrote in message
news:3ABFFD67.6EBDA7B@votehere.net...
:
: Ken Garlington wrote:
: >
: > "Robert A Duff" <bobduff@world.std.com> wrote in message
: > news:wccelvrp7xk.fsf@world.std.com...
: > : "Ken Garlington" <Ken.Garlington@computer.org> writes:
: > :
: > : > Can't see why, since the terms "rational number" and "floating-point
: > number"
: > : > are not the same. I think I'd be much more bothered by a
floating-point
: > : > number without a (floating) point!
: > :
: > : Well, as it happens, "one half" is both a rational and (on most
: > : machines) a floating point number.  Not to mention a fixed point
: > : number. ;-)
: >
: > Actually, I think "one half" is a string. :)
: >
: > More generally, of course, there are rational numbers that are not
exactly
: > representable as floating point numbers, so I don't see why a compiler
: > should accept x/y as a floating-point literal.
:
: Okay, but then by that argument there are some decimal numbers that are
: not exactly representable as floting point numbers, so I don't see why a
: compiler should accept 0.1 as a floating-point literal.

Because 0.1 is the exact "short-hand" notation for the rational number 1/10.
(How this is represented in a given*underlying hardware model* is, of
course, a different issue).

Class project: Type the rational number 1/3 in the same "short-hand"
notation (keeping the underlying assumption of base 10, of course).

(Of course, the issue is somewhat OBE, now that 1/2 is no longer "one half",
but is instead "1 divided by 2" :)

: After all, all 0.1 is is a silly way to write 1/10.

True. The more correct notation would be 0.1E0 (or, some would probably
argue, 1.0E-1). This would certainly make it easier to tell whether the
number was intended to be fixed-point or floating point.

: I'd myself like
: better support for dealing with rational bignums, but that's a different
: thing entirely.  And with enough time and operator overloading probably
: would not require tons of compiler support, unless we want them to be
: reasonably fast.  :(
:
: -andrew





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-22 15:23       ` Marin David Condic
  2001-03-25 15:45         ` Anton Gibbs
@ 2001-03-27  7:34         ` Ole-Hjalmar Kristensen
  2001-03-27 12:43           ` Dale Stanbrough
  2001-03-27 13:20           ` Preben Randhol
  1 sibling, 2 replies; 115+ messages in thread
From: Ole-Hjalmar Kristensen @ 2001-03-27  7:34 UTC (permalink / raw)


"Marin David Condic" <marin.condic.auntie.spam@pacemicro.com> writes:

If someone wants something like the C preprocessor, then just use the
C preprocessor. It works just as well (or bad) with Ada.


> Dead code optimization was brought up in another sub-thread. I agree that
> this is a good trick suitable for many of the things usually done by
> preprocessors.
> 
> If one is willing to live with a rather primitive preprocessor, it might not
> be that big a job to simply recognize some simple markers and
> comment/uncomment code (or just remove it) as needed for test. Its just that
> it usually isn't long before someone wants to have somewhat more
> sophisticated features available.
> 
> Its like I said: How much work do you want to do? I don't think there are
> enough benefits from a preprocessor to make it worth the time it would take
> to develop one. I understand that your garden variety C/C++ programmer is
> used to having one around and may want to lean on one for comfort while
> moving into The Ada Way(tm). (Hacking C code in Ada syntax, as it were.)
> 
> I just distrust this sort of add-on to a language and I think Ada is rich
> enough to get the job done without a preprocessor. If a programmer is used
> to thinking in terms of lexical inclusion rather than semantic inclusion,
> preprocessors behave more the way they are used to working. If you make the
> mental shift into packages, generics, "with" statements, etc., you probably
> won't feel the need to rely on preprocessors since you'll evolve mechanisms
> to do the same job in The Ada Way.
> 
> MDC
> --
> Marin David Condic
> Senior Software Engineer
> Pace Micro Technology Americas    www.pacemicro.com
> Enabling the digital revolution
> e-Mail:    marin.condic@pacemicro.com
> Web:      http://www.mcondic.com/
> 
> 
> "Ira D. Baxter" <idbaxter@semdesigns.com> wrote in message
> news:tbk5cb2rf5aef0@corp.supernews.com...
> > One can take advantage of dead code optimization
> > to eliminate conditionally-compiled code.  So you
> > don't really need a preprocessor for that.
> >
> > There isn't any standard in Ada for conditional compilation
> > of data declarations (or even pragmas!).  This
> > is probably enough to justify a preprocessor of some kind.
> >
> > Building one out of conventional tools such as YACC
> > is probably pretty hard.  You can certainly hack
> > a simple one in PERL, if you want, by defining
> > it to operate on lines that start with #, say.
> >
> > However, if you want one integrated with the Ada source,
> > you could do that pretty easily by augmenting
> > an Ada grammar with a few rules, and
> > using a transformation engine such as our DMS Reengineering Toolkit
> > (see http://www.semdesigns.com/Products/DMS/DMSToolkit.html).
> > DMS can be obtained with an Ada grammar.
> > Rewrite rules for simplifying boolean equations are pretty
> > easy, as are rules that eliminate conditionals conditioned by TRUE or
> FALSE.
> > Such rules coupled with boolean conditions would
> > give an Ada preprocessor with only small effort.
> >
> > --
> > Ira D. Baxter, Ph.D. CTO Semantic Designs, Inc.
> > http://www.semdesigns.com
> >
> > "Marin David Condic" <marin.condic.auntie.spam@pacemicro.com> wrote in
> > message news:99alrr$itf$1@nh.pace.co.uk...
> > > "bhazzard" <bhazzard@email.msn.com> wrote in message
> > > news:OrZxgIisAHA.289@cpmsnbbsa09...
> > > > A quick question...
> > > >
> > > > Is there any way to implement c/c++ style
> > > > #ifdef pre-processor statements in Ada.
> > > >
> > > There is always a way. If you're willing to do the work yourself, you
> can
> > > write a program to parse your Ada code to look for preprocessor
> directives
> > &
> > > output appropriate *new* Ada code before doing the compile. This is a
> lot
> > of
> > > work
> >
> >
> 
> 

-- 
Kabelsalat ist gesund.

Ole-Hj. Kristensen



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-27  7:34         ` Ole-Hjalmar Kristensen
@ 2001-03-27 12:43           ` Dale Stanbrough
  2001-03-27 14:40             ` Marin David Condic
  2001-03-27 15:01             ` Ted Dennison
  2001-03-27 13:20           ` Preben Randhol
  1 sibling, 2 replies; 115+ messages in thread
From: Dale Stanbrough @ 2001-03-27 12:43 UTC (permalink / raw)


Ole-Hjalmar Kristensen wrote:

> "Marin David Condic" <marin.condic.auntie.spam@pacemicro.com> writes:
> 
> If someone wants something like the C preprocessor, then just use the
> C preprocessor. It works just as well (or bad) with Ada.


No, it doesn't work with (some/all?) attributes. The preprocessor
really does understand -some- of C's syntax (or at least the low
level lexical details).


dale



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-27  7:34         ` Ole-Hjalmar Kristensen
  2001-03-27 12:43           ` Dale Stanbrough
@ 2001-03-27 13:20           ` Preben Randhol
  1 sibling, 0 replies; 115+ messages in thread
From: Preben Randhol @ 2001-03-27 13:20 UTC (permalink / raw)


On Tue, 27 Mar 2001 07:34:34 GMT, Ole-Hjalmar Kristensen wrote:
>"Marin David Condic" <marin.condic.auntie.spam@pacemicro.com> writes:
>
>If someone wants something like the C preprocessor, then just use the
>C preprocessor. It works just as well (or bad) with Ada.

But why somebody would want this I don't understand.

-- 
Preben Randhol ------------------- http://www.pvv.org/~randhol/ --
                 �For me, Ada95 puts back the joy in programming.�



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-27  3:33                               ` Ken Garlington
@ 2001-03-27 14:23                                 ` Robert A Duff
  2001-03-27 23:36                                   ` Ken Garlington
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-27 14:23 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> writes:

> True. The more correct notation would be 0.1E0 (or, some would probably
> argue, 1.0E-1). This would certainly make it easier to tell whether the
> number was intended to be fixed-point or floating point.

The "E" notation is legal for floating point, fixed point, and integer
literals.  Are you saying it should only be allowed for floating point?!

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 23:04                 ` Mark Lundquist
@ 2001-03-27 14:38                   ` Marin David Condic
  0 siblings, 0 replies; 115+ messages in thread
From: Marin David Condic @ 2001-03-27 14:38 UTC (permalink / raw)


I guess we'll just have to agree to disagree. I won't say that preprocessors
are the worst form of evil imaginable and I won't say that it is impossible
to write solid, reliable, comprehensible code with a preprocessor. Used
judiciously, I think you can produce good code. I just remain unconvinced
that there is anything someone can do with a preprocessor (with respect to
configuration issues) that can't be done with some other technique that is
less likely to be abused or fraught with peril.

MDC

--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Mark Lundquist" <mark@rational.com> wrote in message
news:8WPv6.628244$U46.19185300@news1.sttls1.wa.home.com...
>
> I'd disgree that there aren't instances where a preprocessor is the best
> solution available.
>
> Not my ideal solution, but my ideal doesn't exist today :-)
> -- mark
>
>
>
>





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-27 12:43           ` Dale Stanbrough
@ 2001-03-27 14:40             ` Marin David Condic
  2001-03-27 15:01             ` Ted Dennison
  1 sibling, 0 replies; 115+ messages in thread
From: Marin David Condic @ 2001-03-27 14:40 UTC (permalink / raw)


Just for the record... The quoted text below attributed to me is not mine.

MDC

--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/

"Dale Stanbrough" <dale@cs.rmit.edu.au> wrote in message
news:dale-FFC33C.22423927032001@m2.bigpond.net.au...
> Ole-Hjalmar Kristensen wrote:
>
> > "Marin David Condic" <marin.condic.auntie.spam@pacemicro.com> writes:
> >
> > If someone wants something like the C preprocessor, then just use the
> > C preprocessor. It works just as well (or bad) with Ada.
>
>
> No, it doesn't work with (some/all?) attributes. The preprocessor
> really does understand -some- of C's syntax (or at least the low
> level lexical details).
>
>
> dale





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-27 12:43           ` Dale Stanbrough
  2001-03-27 14:40             ` Marin David Condic
@ 2001-03-27 15:01             ` Ted Dennison
  1 sibling, 0 replies; 115+ messages in thread
From: Ted Dennison @ 2001-03-27 15:01 UTC (permalink / raw)


In article <dale-FFC33C.22423927032001@m2.bigpond.net.au>, Dale Stanbrough
says...
>
>Ole-Hjalmar Kristensen wrote:
>> If someone wants something like the C preprocessor, then just use the
>> C preprocessor. It works just as well (or bad) with Ada.
>
>No, it doesn't work with (some/all?) attributes. The preprocessor
>really does understand -some- of C's syntax (or at least the low
>level lexical details).

On the occasions I've done it (usually config files, not Ada source), I've used
"sed" or "awk". Those work just fine, and are available for just about every
possible development platform. If you really want to get sexy, I suppose you
could use m4, the GNU program specifically designed for preprocessing files,
which is also available for just about every possible development platform.

Of course technically you are also using a preprocessor if you use any of the
special RCS/CVS/SCCS symbols to insert the file name or revision history into
your sources. :-)

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 21:44                 ` Robert A Duff
  2001-03-27  3:02                   ` Andrew Berg
@ 2001-03-27 17:41                   ` Pascal Obry
  1 sibling, 0 replies; 115+ messages in thread
From: Pascal Obry @ 2001-03-27 17:41 UTC (permalink / raw)



Robert A Duff <bobduff@world.std.com> writes:

> Your "script" is, in fact, a macro preprocessor.

No. It is just text replacement too me. A macro preprocessor has marco in
it. You can do many things like convoluted #if, #define (with many levels).

Basicly what I does is a script for each configuration (for example Linux,
Windows...) and each script is a simple suite of sed commands. Nothing 
fancy :)

We are talking about different Export/Import directives here. For more complex
stuff I just duplicate the spec.

> Are macros more or less evil than #if things?

No macro as I said.

Pascal.



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Implementing C/C++ style #include...
  2001-03-26 19:18               ` Ted Dennison
@ 2001-03-27 18:51                 ` Anton Gibbs
  0 siblings, 0 replies; 115+ messages in thread
From: Anton Gibbs @ 2001-03-27 18:51 UTC (permalink / raw)


In article <YBMv6.2967$fy.4691@www.newsranger.com>, Ted Dennison
<dennison@telepath.com> writes
>In article <u7l1cgzpa.fsf@gsfc.nasa.gov>, Stephen Leake says...
>>
>>Not this one:
>>
>>   function Ada_Size_Of_Input is new 
>>      Interfaces_C_More.Storage_Unit_Size_Of (Input_Type);
>>#if GNAT_Compiler
>>   pragma Export (C, Ada_Size_Of_Input,
>>                  "ball_ct633_ada_size_of_input",  
>>                  "ball_ct633_ada_size_of_input");
>>#elsif ObjectAda_Compiler
>>   pragma Export (DLL_STDCALL, Ada_Size_Of_Input, 
>>                  "ball_ct633_ada_size_of_input", 
>>                  "ball_ct633_ada_size_of_input");
>>#end if;
>>
>>The difference is in the name of the Convention. Preprocessing is, in
>>this case, the best way to handle it. I believe the only alternative
>>is to reproduce the entire package spec, and change this one value.
>>Surely you do not claim that is better from a maintenance point of
>>view? 
>
>If that's the only one, perhaps. But any time you are doing a pragma Import or
>Export, odds are you are doing several of them (or more). In that case, it may
>*still* be better from a maintenance point of view to have two copies of the
>file.

From a maintenance point of view, I think encouraging duplication of
source files is a very dangerous path to take. It is never long before
skewed changes creep in...

One example of pre-processing we use concerns the reporting of unhandled
exceptions. For our Ada83 targets we use the Telesoft (aka Alsys aka
Aonix) vendor-specific System.Report_Error (there is nothing else); and
for our Ada95 Targets we use the standard Ada95 features plus a bit of
GNAT.Symbolic.Traceback (I think it is called). You cannot encapsulate
all this in a package/procedure because the Telesoft System.Report_Error
call has to be the first line in the exception handler. I would not
dream of allowing two separate copies of the source file to be made in
these circumstances.

-- 
Anton Gibbs



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-27 14:23                                 ` Robert A Duff
@ 2001-03-27 23:36                                   ` Ken Garlington
  0 siblings, 0 replies; 115+ messages in thread
From: Ken Garlington @ 2001-03-27 23:36 UTC (permalink / raw)


"Robert A Duff" <bobduff@world.std.com> wrote in message
news:wcc3dbze1ff.fsf@world.std.com...
: "Ken Garlington" <Ken.Garlington@computer.org> writes:
:
: > True. The more correct notation would be 0.1E0 (or, some would probably
: > argue, 1.0E-1). This would certainly make it easier to tell whether the
: > number was intended to be fixed-point or floating point.
:
: The "E" notation is legal for floating point, fixed point, and integer
: literals.  Are you saying it should only be allowed for floating point?!

I'm saying that if Ada did require the form <digit>.<digits>E<digits> for a
floating-point literal per the dictionary definition of the term, and reject
<digits>.<digits> as a floating-point literal as well as <digits> (as it
does now), then the user could indicate whether a floating-point literal was
really intended. However, I doubt the benefits would be sufficient for users
to go along with this idea (I know I wouldn't).

http://www.m-w.com/cgi-bin/dictionary?book=Dictionary&va=floating-point


:
: - Bob





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-27  0:24                                   ` Ken Garlington
@ 2001-03-28 23:15                                     ` Robert A Duff
  2001-03-29  5:02                                       ` Ken Garlington
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-28 23:15 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> writes:

> 
> "Robert A Duff" <bobduff@world.std.com> wrote in message
> news:wccr8zl4h0n.fsf@world.std.com...
> Note, however, that if these literals were "interpreted" as their "obvious"
> floating-point context, and the function I posted earlier were introduced,
> you'd have to decide if now (a) the literals were "more obviously" an
> integer or (b) that the correct form could not be determined from context.
> Either way would seem very awkward to me. Granted, you have that problem now
> distinguishing different decimal representations, but I certainly wouldn't
> want to make it any worse!

Sorry, I've lost track of which function you mean.  But certainly (a) is
Bad (if I understand what you mean) -- it introduces Beaujolais effects.

As to (b), once we have determined the type of a literal (ignoring its
form), we can then apply some rules to insist that its form is Good.
What I don't like is that the form helps determine the type.

> : >... If we are to have implicit casts of integers to
> : > floating point values, why not then permit the more general:
> : >
> : > Y : Float := ferble;
> : >
> : > where "ferble" is a function that returns an integer (or, for that
> matter,
> : > any fixed-point) type?
> :
> : Why not?  Because it makes no sense.  Converting type Standard.Integer
> : to Standard.Float probably makes no sense.
> 
> A conversion (or "interpretation", if you prefer) of a representation that
> is numeric, but has an implied decimal point to the right of the last digit,
> to a representation that has an explicit decimal point to the right of the
> last digit, makes no sense? Then why do you want an Ada compiler to do it
> for literals?

I see the two as completely different.  We shouldn't really be talking
about Integer and Float here.  We should be talking about, say:

    type Apple_Count is range 0..1_000;
    type Length_In_Meters is digits 7;

We don't want to implicitly convert a number-of-apples to a length,
because it doesn't make sense -- they're measuring different things.
This has nothing to do with the fact that one is float and the other
integer.  We wouldn't want to implicitly convert Apple_Count to
Orange_Count (two different integer types), either.

Literals, on the other hand, have no particular type.  The literal "1"
could be of any integer type (in Ada), and which type is determined by
context.  I say it should be "any type", and still determined by context
according to the usual overload resolution rules.

> : But implicitly converting
> : "1" to (say) Float *does* make sense.  I was only talking about
> : literals.
> 
> Again, this makes about as much sense as insisting that 1 be implicitly
> coverted to character, string... or, for that matter, "one half" to be
> converted to some numeric type. After all, if you're going to object to the
> "overhead" of adding .0, then why not object to adding quote marks for a
> character or a single-word string (in the absence of some object with that
> name)... isn't each "obvious in context"?

Of course it would be silly of me to make a big stink about having to
read an extra ".0" in the code.  I think it's silly, but it's obviously
not a big deal.

What I really object to is the general idea that the *form* of a literal
helps determine its type (during overload resolution).  For example,
suppose we have two procedures:

    procedure Mumble(X: Integer);
    procedure Mumble(X: Float);

Then in Ada, a call "Mumble(1);" will resolve to the first Mumble.  But
that's error prone.  A reasonable person might accidentally think it
refers to the other one (because, after all, the number one is a
perfectly reasonable floating-point number).  I claim that this call
should be ambiguous, and therefore illegal.  Likewise, "Mumble(1.0)"
could be mistaken to refer to the wrong one (because, after all, 1.0 is
an integer number).

If you want to require the ".0" in a call to the second one, as an extra
hint, I won't complain *too* much.  But I object to the ".0" being used
to help determine which Mumble we're talking about.

By the way, when I said "one half", I meant it as an English description
of a number.  Not as an Ada string literal.  I wanted to distinguish the
concept of numbers from the way they are written in Ada, so I could
complain about the latter clearly -- apparently it didn't work.  ;-)
So your point about converting "one half" is missing my point.

> : Note that Ada always converts literals to some particular type.
> 
> Sure... some type that is *closest* to the representation *as entered*. If
> you don't enter a decimal point, why would you expect it to be converted to
> a representation that requires a decimal point (fixed or floating)?

I don't understand why you think the form of a literal should have
something to do with the internal representation of the thing.  If that
were the case, we would be writing all numbers in binary, because that's
closer to their representation.  It seems to me that floating point is a
way of approximating the real numbers efficiently, at the expense of
some loss of precision.  Fixed point is a different way of doing the
same thing.  So it seems to me that the syntax for literals should
reflect the way we naturally write numbers, and not worry too much about
the internal representation.

> : Note also that I'm not advocating all manner of implicit conversions.
> : Certainly no implicit conversions that might lose information.
> 
> What about a conversion that adds *unintended* information?

I'm not sure what you mean by that.  Certainly if I say "it's about 10
miles from here to my house", you understand just as well as if I had
written "... 10.0 miles ...".  (In fact, I suppose 10.0 would confuse
you into thinking I was being overly precise -- but that's a whole
'nother issue.)  Leaving off the ".0" doesn't make you think miles are
discrete integer quantities, in English anyway.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-28 23:15                                     ` Robert A Duff
@ 2001-03-29  5:02                                       ` Ken Garlington
  2001-03-29  6:13                                         ` David Starner
  2001-03-29 23:46                                         ` Robert A Duff
  0 siblings, 2 replies; 115+ messages in thread
From: Ken Garlington @ 2001-03-29  5:02 UTC (permalink / raw)


"Robert A Duff" <bobduff@world.std.com> wrote in message
news:wccvgotscxo.fsf@world.std.com...

: As to (b), once we have determined the type of a literal (ignoring its
: form), we can then apply some rules to insist that its form is Good.
: What I don't like is that the form helps determine the type.

However, form would still be used to distinguish between numerics,
characters, and strings even if your proposal is adopted. Why is it harmful
in one context, but not another?

: > : >... If we are to have implicit casts of integers to
: > : > floating point values, why not then permit the more general:
: > : >
: > : > Y : Float := ferble;
: > : >
: > : > where "ferble" is a function that returns an integer (or, for that
: > matter,
: > : > any fixed-point) type?
: > :
: > : Why not?  Because it makes no sense.  Converting type Standard.Integer
: > : to Standard.Float probably makes no sense.
: >
: > A conversion (or "interpretation", if you prefer) of a representation
that
: > is numeric, but has an implied decimal point to the right of the last
digit,
: > to a representation that has an explicit decimal point to the right of
the
: > last digit, makes no sense? Then why do you want an Ada compiler to do
it
: > for literals?
:
: I see the two as completely different.  We shouldn't really be talking
: about Integer and Float here.

And, very importantly, I'm *not* talking about Integer and Float here. I'm
talking about integer, floating point, and fixed point *literals*.

: We should be talking about, say:
:
:     type Apple_Count is range 0..1_000;
:     type Length_In_Meters is digits 7;
:
: We don't want to implicitly convert a number-of-apples to a length,
: because it doesn't make sense -- they're measuring different things.
: This has nothing to do with the fact that one is float and the other
: integer.  We wouldn't want to implicitly convert Apple_Count to
: Orange_Count (two different integer types), either.
:
: Literals, on the other hand, have no particular type.  The literal "1"
: could be of any integer type (in Ada),

Right! To continue the thought - it *couldn't* be a string, a character,
etc... (where Ada includes "floating point" and "fixed point" value in the
"etc.").

: and which type is determined by
: context.  I say it should be "any type", and still determined by context
: according to the usual overload resolution rules.

I think you either meant (a) any *numeric* type, in which case you're
inconsistent, or (b) *any type*, which is now an internally consistent
position, but brings about some new problems. For example, how should the
following be interpreted?

X : constant String := 1_000;

Is the underscore retained?

: > : But implicitly converting
: > : "1" to (say) Float *does* make sense.  I was only talking about
: > : literals.
: >
: > Again, this makes about as much sense as insisting that 1 be implicitly
: > coverted to character, string... or, for that matter, "one half" to be
: > converted to some numeric type. After all, if you're going to object to
the
: > "overhead" of adding .0, then why not object to adding quote marks for a
: > character or a single-word string (in the absence of some object with
that
: > name)... isn't each "obvious in context"?
:
: Of course it would be silly of me to make a big stink about having to
: read an extra ".0" in the code.  I think it's silly, but it's obviously
: not a big deal.

My point is not that it's a trivial position (although it is), but that it's
an *inconsistent* position,. After all, we could just as easily say that Ada
should accept

X : constant Character := 0;

where the tick marks would be equally unnecessary. This would be much more
like a Do What I Mean compiler, which would annoy me no end.

: What I really object to is the general idea that the *form* of a literal
: helps determine its type (during overload resolution).  For example,
: suppose we have two procedures:
:
:     procedure Mumble(X: Integer);
:     procedure Mumble(X: Float);
:
: Then in Ada, a call "Mumble(1);" will resolve to the first Mumble.  But
: that's error prone.  A reasonable person might accidentally think it
: refers to the other one (because, after all, the number one is a
: perfectly reasonable floating-point number).

As noted earlier, not according to the dictionary definition of
"floating-point".

:  I claim that this call
: should be ambiguous, and therefore illegal.  Likewise, "Mumble(1.0)"
: could be mistaken to refer to the wrong one (because, after all, 1.0 is
: an integer number).

Not according to the dictionary definition of "integer".

: If you want to require the ".0" in a call to the second one, as an extra
: hint, I won't complain *too* much.  But I object to the ".0" being used
: to help determine which Mumble we're talking about.

Then, to be consistent, you have to object to these as well:

procedure Mumble("0");
procedure Mumble('0');
procedure Mumble("0.000");

and so forth.

: By the way, when I said "one half", I meant it as an English description
: of a number.

In order to deduce this, I would have had to look at the form of the
expression, now wouldn't I? :)

: Not as an Ada string literal.  I wanted to distinguish the
: concept of numbers from the way they are written in Ada, so I could
: complain about the latter clearly -- apparently it didn't work.  ;-)
: So your point about converting "one half" is missing my point.

But "one half" is an equally valid way of describing 0.5, 1/2, 1.0/2.0, etc.
using the informal notation you appear to have adopted... if not, why not?

: > : Note that Ada always converts literals to some particular type.
: >
: > Sure... some type that is *closest* to the representation *as entered*.
If
: > you don't enter a decimal point, why would you expect it to be converted
to
: > a representation that requires a decimal point (fixed or floating)?
:
: I don't understand why you think the form of a literal should have
: something to do with the internal representation of the thing.

I never used the word internal in the sentence above.

: If that
: were the case, we would be writing all numbers in binary, because that's
: closer to their representation.  It seems to me that floating point is a
: way of approximating the real numbers efficiently, at the expense of
: some loss of precision.

Oops! Now *you're* dealing in internal representations. Floating-point
numbers aren't an approximation of anything, according to Merriam-Webster.
It's a mathematical notation (a representation, in the dictionary's words)
for a real number. Any precision can be represented.

: Fixed point is a different way of doing the
: same thing.  So it seems to me that the syntax for literals should
: reflect the way we naturally write numbers, and not worry too much about
: the internal representation.
:
: > : Note also that I'm not advocating all manner of implicit conversions.
: > : Certainly no implicit conversions that might lose information.
: >
: > What about a conversion that adds *unintended* information?

Example: I write 4, meaning the integer value 4. You convert it to '4',
since that's the context in which I appeared to use it. You've added
information (4 can be a character) that I didn't intend.





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-29  5:02                                       ` Ken Garlington
@ 2001-03-29  6:13                                         ` David Starner
  2001-03-29 10:10                                           ` AG
  2001-03-29 14:28                                           ` Ken Garlington
  2001-03-29 23:46                                         ` Robert A Duff
  1 sibling, 2 replies; 115+ messages in thread
From: David Starner @ 2001-03-29  6:13 UTC (permalink / raw)


On Thu, 29 Mar 2001 05:02:56 GMT, Ken Garlington <Ken.Garlington@computer.org> wrote:
>: Then in Ada, a call "Mumble(1);" will resolve to the first Mumble.  But
>: that's error prone.  A reasonable person might accidentally think it
>: refers to the other one (because, after all, the number one is a
>: perfectly reasonable floating-point number).
>
>As noted earlier, not according to the dictionary definition of
>"floating-point".

I think it's a little flaky to depend on dictionary definitions. The
only dictionary I have that defines this (the Free On-line Dictionary
of Computing) defines it as "A number representation consisting of a
mantissa, M, an exponent, E, and an (assumed) radix (or base)" which
helps no one in this argument.

>:  I claim that this call
>: should be ambiguous, and therefore illegal.  Likewise, "Mumble(1.0)"
>: could be mistaken to refer to the wrong one (because, after all, 1.0 is
>: an integer number).
>
>Not according to the dictionary definition of "integer".

1.0 is either zero or an integer (in this case 0) plus or minus one.
So by the Free On-line Dictionary of Computing, it is an integer.
WordNet, and Webster's (1913) aren't as mathematically rigerous (an
integer is a number that isn't a fraction or a mixed number?). Again,
I don't see how the dictionary says that 1.0 is not an integer, and 
even if your's does, I don't see why that's definitive.

-- 
David Starner - dstarner98@aasaa.ofe.org
Pointless website: http://dvdeug.dhis.org
"I don't care if Bill personally has my name and reads my email and 
laughs at me. In fact, I'd be rather honored." - Joseph_Greg



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-29  6:13                                         ` David Starner
@ 2001-03-29 10:10                                           ` AG
  2001-03-29 14:28                                           ` Ken Garlington
  1 sibling, 0 replies; 115+ messages in thread
From: AG @ 2001-03-29 10:10 UTC (permalink / raw)



"David Starner" <dvdeug@x8b4e53cd.dhcp.okstate.edu> wrote in message
news:99ujqs$aai1@news.cis.okstate.edu...
<<<snip>>>
> I think it's a little flaky to depend on dictionary definitions.
But we do have to depend on *some* definitions, otherwise it's a bit hard to
talk:)
<<<snip>>>
> >Not according to the dictionary definition of "integer".
>
> 1.0 is either zero or an integer (in this case 0) plus or minus one.
Sorry, what? Either zero or an integer? So by what definition is zero no
longer considered an integer?
And is plus or minus one an integer or an entity on it's own?
> So by the Free On-line Dictionary of Computing, it is an integer.
Or maybe a zero?
<<<snip>>>
>Again,
> I don't see how the dictionary says that 1.0 is not an integer, and
> even if your's does, I don't see why that's definitive.
Well, because the normal convention in writing values like that is that the
actual value
is within 1/2 (or 0.5 or "one half" or whatever) of the last digit quoted.
So, 1.0 means
anything betwen 0.95 and 1.05 which is hardly an integer number by any
definition.
Of course it's not exactly a floating point either but at least it says
something about
the expected precision/error etc whereas just 1 is much more likely to be
(and be
construed as) an integer.





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-29  6:13                                         ` David Starner
  2001-03-29 10:10                                           ` AG
@ 2001-03-29 14:28                                           ` Ken Garlington
  1 sibling, 0 replies; 115+ messages in thread
From: Ken Garlington @ 2001-03-29 14:28 UTC (permalink / raw)



"David Starner" <dvdeug@x8b4e53cd.dhcp.okstate.edu> wrote in message
news:99ujqs$aai1@news.cis.okstate.edu...
: On Thu, 29 Mar 2001 05:02:56 GMT, Ken Garlington
<Ken.Garlington@computer.org> wrote:
: >: Then in Ada, a call "Mumble(1);" will resolve to the first Mumble.  But
: >: that's error prone.  A reasonable person might accidentally think it
: >: refers to the other one (because, after all, the number one is a
: >: perfectly reasonable floating-point number).
: >
: >As noted earlier, not according to the dictionary definition of
: >"floating-point".
:
: I think it's a little flaky to depend on dictionary definitions. : The
: only dictionary I have that defines this (the Free On-line Dictionary
: of Computing) defines it as "A number representation consisting of a
: mantissa, M, an exponent, E, and an (assumed) radix (or base)" which
: helps no one in this argument.

I usually use the Merriam-Webster online dictionary, which also defines
"floating-point." My hardcopy version of their Collegiate dictionary also
has a definition of "floating-point." I suspect many other dictionaries also
define the term.

IMHO it helps me *considerably* that there is a common meaning to the term,
and that that they all talk about a "representation" without necessarily
implying an *underlying hardware* representation. In fact, M-W is explicit
in this: "...in which a number is represented (as in a computer display)".
Therefore, there is support in general usage of form to determine if a
number is a floating-point number. If it's "flaky" to use traditions when
determining a "best" solution, then I guess I'm guilty as charged --
although, of course, the law would then be "flaky" as well, so I guess I
can't be convicted! ;)

As I noted in another post, if someone complained about Ada not requiring an
exponent as well as (or instead of) a decimal point, so that the literal
form would follow the "common" convention, I could understand that argument
(although it would be annoying to have to do this.)

: >:  I claim that this call
: >: should be ambiguous, and therefore illegal.  Likewise, "Mumble(1.0)"
: >: could be mistaken to refer to the wrong one (because, after all, 1.0 is
: >: an integer number).
: >
: >Not according to the dictionary definition of "integer".
:
: 1.0 is either zero or an integer (in this case 0) plus or minus one.

M-W says that it is one of the natural numbers, the negatives of these
numbers, or zero. A natural number is "the number 1 [not 1.0!]  or any
number (as 3, 12, 432) obtained by adding 1 to it one or more times: a
positive integer." (Zero is defined as "the arithmetic symbol 0".)

: So by the Free On-line Dictionary of Computing, it is an integer.

Actually, here's what FOLDOC says:

"integer: <mathematics> (Or 'whole number') One of the finite numbers in the
infinite set  ..., -3, -2, -1, 0, 1, 2, 3, ... An inductive definition of an
integer is a number which is either zero or an integer plus or minus one. An
integer is a number with no fractional part. If written in as a fixed-point
number, the part after the decimal (or other base) point will be zero.  A
natural number is a non-negative integer. "

Note that part about "if written in as [sic] a fixed-point number." What
this says to me is that an integer *is compatible with* a fixed-point
number, under certain circumstances. However, it clearly implies that we are
talking about two different "forms" of a number.

Just because in "the real world" we take short cuts doesn't change the fact
that these words have certain meanings. Generally, society encourages
non-rigorous usage of words, and since humans are interpreting them, it
works out OK (except, of course, that we often misunderstand each other as a
result). However, I believe that a language like Ada should pick a different
level of rigor in interpreting "words" (symbols), and that in particular I
wouldn't want it to be less rigorous than it is today.

: WordNet, and Webster's (1913) aren't as mathematically rigerous (an
: integer is a number that isn't a fraction or a mixed number?). Again,
: I don't see how the dictionary says that 1.0 is not an integer, and
: even if your's does, I don't see why that's definitive.

Well, I suppose you could argue that there are no definitive meanings to any
word, but I think there's a more generally-accepted notion in debate that
published works can be used to support an argument. Of course, you could
argue that it's "flaky" to use this concept in an argument. In fact, I think
the University of Texas did argue something similar, a few years ago.
(Actually, their argument was more expansive than that, IIRC...)





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-29  5:02                                       ` Ken Garlington
  2001-03-29  6:13                                         ` David Starner
@ 2001-03-29 23:46                                         ` Robert A Duff
  2001-03-30  3:41                                           ` Ken Garlington
  2001-03-30  9:16                                           ` Dmitry Kazakov
  1 sibling, 2 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-29 23:46 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> writes:

> "Robert A Duff" <bobduff@world.std.com> wrote in message
> news:wccvgotscxo.fsf@world.std.com...
> 
> : As to (b), once we have determined the type of a literal (ignoring its
> : form), we can then apply some rules to insist that its form is Good.
> : What I don't like is that the form helps determine the type.
> 
> However, form would still be used to distinguish between numerics,
> characters, and strings even if your proposal is adopted.

No, my proposal is that the form of a literal does not help determine
its type.  That applies to all kinds of literals.

As I said above, *after* overload resolution has determined the type of
a literal, we can apply rules that ensure the form of the literal is
appropriate for that type.  As you suggest, it's probably not a good
idea for:

    "12"

(with the quotes) to be allowed as an integer.

Exactly what those legality rules are is a fairly minor point.
You don't like 1 as a float, you would like to require 1.0, which
I think is silly, but either way, it's definitely a minor point.

I would eliminate the syntactic distinction between character literals
and string literals -- just use double quotes for both.  Then the
compiler has to determine whether "A" is a character or string from
context.

By the way, the "ulterior motive" in my ideas about literals is that
what I *really* want is user-defined literals.  I think the programmer
should be able to say "this type here has literals", and define which
forms are legal for that type, and what they mean.  But in order to
avoid chaos, we can't have the form of the literal affecting overload
resolution.

> And, very importantly, I'm *not* talking about Integer and Float here. I'm
> talking about integer, floating point, and fixed point *literals*.

I was trying to explain why the "interpretation" of a literal is
different from an implicit type conversion from (say) Integer to Float.
I wouldn't want to allow the implicit type conversion, because it
violates the type system.  But literals are different -- a literal, in
and of itself, is not of any particular type.  So you're not really
doing an "implicit conversion" in the usual sense (even though the RM
describes it that way).

> : We should be talking about, say:
> :
> :     type Apple_Count is range 0..1_000;
> :     type Length_In_Meters is digits 7;
> :
> : We don't want to implicitly convert a number-of-apples to a length,
> : because it doesn't make sense -- they're measuring different things.
> : This has nothing to do with the fact that one is float and the other
> : integer.  We wouldn't want to implicitly convert Apple_Count to
> : Orange_Count (two different integer types), either.
> :
> : Literals, on the other hand, have no particular type.  The literal "1"
> : could be of any integer type (in Ada),
> 
> Right! To continue the thought - it *couldn't* be a string, a character,
> etc... (where Ada includes "floating point" and "fixed point" value in the
> "etc.").

It's fine with me if 1 can't be a string, because it has no quotes (my
quoting conventions in English are confusing the issue here!).  But I
want that to be a post-resolution legality rule.  I don't want the lack
of quotes to help *determine* its type.

> : and which type is determined by
> : context.  I say it should be "any type", and still determined by context
> : according to the usual overload resolution rules.
> 
> I think you either meant (a) any *numeric* type, in which case you're
> inconsistent, or (b) *any type*, which is now an internally consistent
> position, but brings about some new problems. For example, how should the
> following be interpreted?

I really did mean "any type".

> X : constant String := 1_000;
> 
> Is the underscore retained?

Probably the right rule is that string literals must have quotes, so the
above is illegal.  Do you understand the rather subtle distinction
between letting the literal's form determine its type, versus making
certain forms illegal after having determined the type (clearly String,
in the above case)?

> : Of course it would be silly of me to make a big stink about having to
> : read an extra ".0" in the code.  I think it's silly, but it's obviously
> : not a big deal.
> 
> My point is not that it's a trivial position (although it is), ...

The whole trivial argument is an awful lot of fun, though!

>...but that it's
> an *inconsistent* position,. After all, we could just as easily say that Ada
> should accept
> 
> X : constant Character := 0;

I would require:

    X : constant Character := "0"; -- note double quotes

and also allow:

    X : constant String := "0";

because the context unambiguously determines the type of the literal in
each case.  But I would say just plain 0 without quotes would be a
malformed literal if it turns out to be a character or string literal.

I don't see any inconsistency.

> where the tick marks would be equally unnecessary. This would be much more
> like a Do What I Mean compiler, which would annoy me no end.
> 
> : What I really object to is the general idea that the *form* of a literal
> : helps determine its type (during overload resolution).  For example,
> : suppose we have two procedures:
> :
> :     procedure Mumble(X: Integer);
> :     procedure Mumble(X: Float);
> :
> : Then in Ada, a call "Mumble(1);" will resolve to the first Mumble.  But
> : that's error prone.  A reasonable person might accidentally think it
> : refers to the other one (because, after all, the number one is a
> : perfectly reasonable floating-point number).
> 
> As noted earlier, not according to the dictionary definition of
> "floating-point".

I don't think the dictionary definition you quoted is what Ada means by
floating point types.  In Ada, floating point is referring to an
internal representation, and the behavior of the operators -- not to the
display on the screen.

> :  I claim that this call
> : should be ambiguous, and therefore illegal.  Likewise, "Mumble(1.0)"
> : could be mistaken to refer to the wrong one (because, after all, 1.0 is
> : an integer number).
> 
> Not according to the dictionary definition of "integer".
> 
> : If you want to require the ".0" in a call to the second one, as an extra
> : hint, I won't complain *too* much.  But I object to the ".0" being used
> : to help determine which Mumble we're talking about.
> 
> Then, to be consistent, you have to object to these as well:
> 
> procedure Mumble("0");
> procedure Mumble('0');
> procedure Mumble("0.000");
> 
> and so forth.

Yes, and I do.  I would like to call those "ambiguous and therefore
illegal".

> : By the way, when I said "one half", I meant it as an English description
> : of a number.
> 
> In order to deduce this, I would have had to look at the form of the
> expression, now wouldn't I? :)

Well, English is like that.  A programming language ought to be less
susceptible to misunderstandings.

> : Not as an Ada string literal.  I wanted to distinguish the
> : concept of numbers from the way they are written in Ada, so I could
> : complain about the latter clearly -- apparently it didn't work.  ;-)
> : So your point about converting "one half" is missing my point.
> 
> But "one half" is an equally valid way of describing 0.5, 1/2, 1.0/2.0, etc.
> using the informal notation you appear to have adopted... if not, why not?

Too hard to describe precisely in the RM.  To hard to implement in
general.  Not worth the trouble.

The only reason I wrote "one half" is because it's a notation for
describing a number that is *not* allowed in Ada or any other
programming language I know -- hoping you would guess this is just an
English-language description of a particular number.

> : > : Note that Ada always converts literals to some particular type.
> : >
> : > Sure... some type that is *closest* to the representation *as entered*.
> If
> : > you don't enter a decimal point, why would you expect it to be converted
> to
> : > a representation that requires a decimal point (fixed or floating)?
> :
> : I don't understand why you think the form of a literal should have
> : something to do with the internal representation of the thing.
> 
> I never used the word internal in the sentence above.

OK.  So that wasn't quite fair of me.  Nonetheless, Ada floating point
is all about the internal representation, despite what your dictionary
says.

> : If that
> : were the case, we would be writing all numbers in binary, because that's
> : closer to their representation.  It seems to me that floating point is a
> : way of approximating the real numbers efficiently, at the expense of
> : some loss of precision.
> 
> Oops! Now *you're* dealing in internal representations. Floating-point
> numbers aren't an approximation of anything, according to Merriam-Webster.
> It's a mathematical notation (a representation, in the dictionary's words)
> for a real number. Any precision can be represented.
> 
> : Fixed point is a different way of doing the
> : same thing.  So it seems to me that the syntax for literals should
> : reflect the way we naturally write numbers, and not worry too much about
> : the internal representation.
> :
> : > : Note also that I'm not advocating all manner of implicit conversions.
> : > : Certainly no implicit conversions that might lose information.
> : >
> : > What about a conversion that adds *unintended* information?
> 
> Example: I write 4, meaning the integer value 4. You convert it to '4',
> since that's the context in which I appeared to use it. You've added
> information (4 can be a character) that I didn't intend.

OK, I see what you mean.  I didn't intend to allow that.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-20  4:21                     ` Brian Rogoff
  2001-03-21  1:32                       ` Ken Garlington
@ 2001-03-29 23:50                       ` Robert A Duff
  1 sibling, 0 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-29 23:50 UTC (permalink / raw)


Brian Rogoff <bpr@shell5.ba.best.com> writes:

> On Mon, 19 Mar 2001, Robert A Duff wrote:
> > All of the above points are related: the context should determine the
> > type of a literal.  Then, after overload resolution has determined the
> > type of a literal, there should be a compile-time check that it is of
> > the right form -- the form should not *determine* the type.  Eg, if the
> > type of 1.2 turns out to be Integer, that should be illegal.  If the
> > type of 1.2 could be either Integer or Float, that should be ambiguous
> > and therefore illegal, whereas in Ada, it chooses Float.
> 
> OK, I'm convinced. Maybe this next generation language should be named 
> "Grace" or "Hopper" ;-)

Why on Earth?!  G. Hopper, as far as I can tell, always thought all
these new-fangled languages (C, Ada, etc) are a waste of time -- we
should all go back to FORTRAN and COBOL.

;-)

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-29 23:46                                         ` Robert A Duff
@ 2001-03-30  3:41                                           ` Ken Garlington
  2001-03-30 21:21                                             ` Robert A Duff
  2001-03-30 21:29                                             ` Robert A Duff
  2001-03-30  9:16                                           ` Dmitry Kazakov
  1 sibling, 2 replies; 115+ messages in thread
From: Ken Garlington @ 2001-03-30  3:41 UTC (permalink / raw)


"Robert A Duff" <bobduff@world.std.com> wrote in message
news:wccofuk87gj.fsf@world.std.com...
: "Ken Garlington" <Ken.Garlington@computer.org> writes:
:
: > "Robert A Duff" <bobduff@world.std.com> wrote in message
: > news:wccvgotscxo.fsf@world.std.com...
: >
: > : As to (b), once we have determined the type of a literal (ignoring its
: > : form), we can then apply some rules to insist that its form is Good.
: > : What I don't like is that the form helps determine the type.
: >
: > However, form would still be used to distinguish between numerics,
: > characters, and strings even if your proposal is adopted.
:
: No, my proposal is that the form of a literal does not help determine
: its type.  That applies to all kinds of literals.

OK, that's at least internally consistent. However, the number of
ambiguities now is significantly expanded. For example:

J : constant := 1; -- legitimate named number, or did I mean to type

J : constant Character := 1;

Even better:

J: constant String := a; -- is this a literal "a", or a reference to
something that I forgot to import? Both are possible...

I'm not sure I want a language that has a design goal of catching faults to
be loosened in this regard. (I'm not sure I want it to be *tightened* either
in this regard, because I am still human, after all. :)

: As I said above, *after* overload resolution has determined the type of
: a literal, we can apply rules that ensure the form of the literal is
: appropriate for that type.  As you suggest, it's probably not a good
: idea for:
:
:     "12"
:
: (with the quotes) to be allowed as an integer.

I'm more worried about the _reverse_ case, where 12 is allowed as either a
string or an integer. However, why CAN'T "12" be an integer?

: I would eliminate the syntactic distinction between character literals
: and string literals -- just use double quotes for both.  Then the
: compiler has to determine whether "A" is a character or string from
: context.

However, this says that the form of the literal can be used to distinguish
between numerics and text. Why make a form-based distinction here, but not
within different forms of numerics?

:: By the way, the "ulterior motive" in my ideas about literals is that
: what I *really* want is user-defined literals.  I think the programmer
: should be able to say "this type here has literals", and define which
: forms are legal for that type, and what they mean.  But in order to
: avoid chaos, we can't have the form of the literal affecting overload
: resolution.

I'd have to understand the proposal better, but I don't see why abandoning
form is a good idea here. Assume a type

type X is (1, 2, 12.7);

function "/" (A, B: X) return X;

Q: X := 1/12.7;

how does form-assisted resolution hurt you?

: > And, very importantly, I'm *not* talking about Integer and Float here.
I'm
: > talking about integer, floating point, and fixed point *literals*.
:
: I was trying to explain why the "interpretation" of a literal is
: different from an implicit type conversion from (say) Integer to Float.
: I wouldn't want to allow the implicit type conversion, because it
: violates the type system.  But literals are different -- a literal, in
: and of itself, is not of any particular type.

You've contradicted this statement above, by distinguishing between numerics
and text.

:  So you're not really
: doing an "implicit conversion" in the usual sense (even though the RM
: describes it that way).
:
: > : We should be talking about, say:
: > :
: > :     type Apple_Count is range 0..1_000;
: > :     type Length_In_Meters is digits 7;
: > :
: > : We don't want to implicitly convert a number-of-apples to a length,
: > : because it doesn't make sense -- they're measuring different things.
: > : This has nothing to do with the fact that one is float and the other
: > : integer.  We wouldn't want to implicitly convert Apple_Count to
: > : Orange_Count (two different integer types), either.
: > :
: > : Literals, on the other hand, have no particular type.  The literal "1"
: > : could be of any integer type (in Ada),
: >
: > Right! To continue the thought - it *couldn't* be a string, a character,
: > etc... (where Ada includes "floating point" and "fixed point" value in
the
: > "etc.").
:
: It's fine with me if 1 can't be a string, because it has no quotes (my
: quoting conventions in English are confusing the issue here!).  But I
: want that to be a post-resolution legality rule.  I don't want the lack
: of quotes to help *determine* its type.

This says that you'd be willing to make quotes optional for text? Or not?

: > : and which type is determined by
: > : context.  I say it should be "any type", and still determined by
context
: > : according to the usual overload resolution rules.
: >
: > I think you either meant (a) any *numeric* type, in which case you're
: > inconsistent, or (b) *any type*, which is now an internally consistent
: > position, but brings about some new problems. For example, how should
the
: > following be interpreted?
:
: I really did mean "any type".
:
: > X : constant String := 1_000;
: >
: > Is the underscore retained?
:
: Probably the right rule is that string literals must have quotes, so the
: above is illegal.

Back to form of the literal contributing to its interpretation (*sigh*)

: Do you understand the rather subtle distinction
: between letting the literal's form determine its type, versus making
: certain forms illegal after having determined the type (clearly String,
: in the above case)?

If it's clearly String, why would 1_000 be an illegal string? If you can
explain that, then I might understand the distinction...

: > : Of course it would be silly of me to make a big stink about having to
: > : read an extra ".0" in the code.  I think it's silly, but it's
obviously
: > : not a big deal.
: >
: > My point is not that it's a trivial position (although it is), ...
:
: The whole trivial argument is an awful lot of fun, though!
:
: >...but that it's
: > an *inconsistent* position,. After all, we could just as easily say that
Ada
: > should accept
: >
: > X : constant Character := 0;
:
: I would require:
:
:     X : constant Character := "0"; -- note double quotes
:
: and also allow:
:
:     X : constant String := "0";
:
: because the context unambiguously determines the type of the literal in
: each case.  But I would say just plain 0 without quotes would be a
: malformed literal if it turns out to be a character or string literal.

I understand that you see it as a "malformed literal"... but WHY is it a
malformed literal, any more than

X : constant Float := 1;

would NOT be a malformed literal under your proposal? Isn't the desired
result "obvious" in each case?

I see BOTH of these as malformed literals, based on the commonly accepted
conventions for quoted text and floating-point values.

: I don't see any inconsistency.
:
: > where the tick marks would be equally unnecessary. This would be much
more
: > like a Do What I Mean compiler, which would annoy me no end.
: >
: > : What I really object to is the general idea that the *form* of a
literal
: > : helps determine its type (during overload resolution).  For example,
: > : suppose we have two procedures:
: > :
: > :     procedure Mumble(X: Integer);
: > :     procedure Mumble(X: Float);
: > :
: > : Then in Ada, a call "Mumble(1);" will resolve to the first Mumble.
But
: > : that's error prone.  A reasonable person might accidentally think it
: > : refers to the other one (because, after all, the number one is a
: > : perfectly reasonable floating-point number).
: >
: > As noted earlier, not according to the dictionary definition of
: > "floating-point".
:
: I don't think the dictionary definition you quoted is what Ada means by
: floating point types.  In Ada, floating point is referring to an
: internal representation, and the behavior of the operators -- not to the
: display on the screen.

OK... now, WHY do you believe this?

: > :  I claim that this call
: > : should be ambiguous, and therefore illegal.  Likewise, "Mumble(1.0)"
: > : could be mistaken to refer to the wrong one (because, after all, 1.0
is
: > : an integer number).
: >
: > Not according to the dictionary definition of "integer".
: >
: > : If you want to require the ".0" in a call to the second one, as an
extra
: > : hint, I won't complain *too* much.  But I object to the ".0" being
used
: > : to help determine which Mumble we're talking about.
: >
: > Then, to be consistent, you have to object to these as well:
: >
: > procedure Mumble("0");
: > procedure Mumble('0');
: > procedure Mumble("0.000");
: >
: > and so forth.
:
: Yes, and I do.  I would like to call those "ambiguous and therefore
: illegal".

OK, but then note that the following will (almost) always be illegal:

X : constant Float := 1/2;
X:  constant Integer := 1/2;
X: constant Float := 1.0/2.0;
X: constant Integer := 1.0/2.0;

because it's ambiguous which "/" operator is intended here (assuming one is
visible for both types). Currently, only two are illegal. Do we really want
to break existing programs in this manner?

: > : By the way, when I said "one half", I meant it as an English
description
: > : of a number.
: >
: > In order to deduce this, I would have had to look at the form of the
: > expression, now wouldn't I? :)
:
: Well, English is like that.  A programming language ought to be less
: susceptible to misunderstandings.

Exactly - it should have even *more* rules about interpretation, not less.
English often ignores form, expecting things to be resolved by context.

: > : Not as an Ada string literal.  I wanted to distinguish the
: > : concept of numbers from the way they are written in Ada, so I could
: > : complain about the latter clearly -- apparently it didn't work.  ;-)
: > : So your point about converting "one half" is missing my point.
: >
: > But "one half" is an equally valid way of describing 0.5, 1/2, 1.0/2.0,
etc.
: > using the informal notation you appear to have adopted... if not, why
not?
:
: Too hard to describe precisely in the RM.  To hard to implement in
: general.  Not worth the trouble.
:
: The only reason I wrote "one half" is because it's a notation for
: describing a number that is *not* allowed in Ada or any other
: programming language I know -- hoping you would guess this is just an
: English-language description of a particular number.

-- uncompiled: errors may abound
function To_Float (Fraction_Description : in String) return Float is
begin
  if Fraction_Description = "one half" then
    return 0.5;
  else ...

end To_Float;

X: = constant Float := To_Float("one half");

All you'd have to do is agree on common descriptions and have at it!

: > : > : Note that Ada always converts literals to some particular type.
: > : >
: > : > Sure... some type that is *closest* to the representation *as
entered*.
: > If
: > : > you don't enter a decimal point, why would you expect it to be
converted
: > to
: > : > a representation that requires a decimal point (fixed or floating)?
: > :
: > : I don't understand why you think the form of a literal should have
: > : something to do with the internal representation of the thing.
: >
: > I never used the word internal in the sentence above.
:
: OK.  So that wasn't quite fair of me.  Nonetheless, Ada floating point
: is all about the internal representation, despite what your dictionary
: says.

Actually, multiple dictionaries (see FOLDOC, for example). It *can* refer to
an internal representation, but it's not limited to that. Any evidence to
the contrary?

: > : If that
: > : were the case, we would be writing all numbers in binary, because
that's
: > : closer to their representation.  It seems to me that floating point is
a
: > : way of approximating the real numbers efficiently, at the expense of
: > : some loss of precision.
: >
: > Oops! Now *you're* dealing in internal representations. Floating-point
: > numbers aren't an approximation of anything, according to
Merriam-Webster.
: > It's a mathematical notation (a representation, in the dictionary's
words)
: > for a real number. Any precision can be represented.
: >
: > : Fixed point is a different way of doing the
: > : same thing.  So it seems to me that the syntax for literals should
: > : reflect the way we naturally write numbers, and not worry too much
about
: > : the internal representation.
: > :
: > : > : Note also that I'm not advocating all manner of implicit
conversions.
: > : > : Certainly no implicit conversions that might lose information.
: > : >
: > : > What about a conversion that adds *unintended* information?
: >
: > Example: I write 4, meaning the integer value 4. You convert it to '4',
: > since that's the context in which I appeared to use it. You've added
: > information (4 can be a character) that I didn't intend.
:
: OK, I see what you mean.  I didn't intend to allow that.
:
: - Bob





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-29 23:46                                         ` Robert A Duff
  2001-03-30  3:41                                           ` Ken Garlington
@ 2001-03-30  9:16                                           ` Dmitry Kazakov
  2001-03-30  9:51                                             ` Florian Weimer
                                                               ` (2 more replies)
  1 sibling, 3 replies; 115+ messages in thread
From: Dmitry Kazakov @ 2001-03-30  9:16 UTC (permalink / raw)


On Thu, 29 Mar 2001 23:46:04 GMT, Robert A Duff
<bobduff@world.std.com> wrote:

>"Ken Garlington" <Ken.Garlington@computer.org> writes:
>
>> "Robert A Duff" <bobduff@world.std.com> wrote in message
>> news:wccvgotscxo.fsf@world.std.com...

>By the way, the "ulterior motive" in my ideas about literals is that
>what I *really* want is user-defined literals.  I think the programmer
>should be able to say "this type here has literals", and define which
>forms are legal for that type, and what they mean.  But in order to
>avoid chaos, we can't have the form of the literal affecting overload
>resolution.

I strongly support your intention (user-defined literals and surely
user-defined aggregates), but I believe that the way is wrong. I would
say that a literal always has a type. And its type should be
determinable from the literal's form. I like the idea that, 1 is a
UNIVERSAL_INTEGER, 1.0 is a UNIVERSAL_FLOAT, 'a' is a
UNIVERSAL_CHARACTER etc. Then if I want to have 1 acceptable as a
value for MY_OWN_INTEGER, or for MY_OWN_FLOAT, or even for
MY_OWN_FILE_DESCRIPTOR, I (or the language, if the type is derived
etc) should simply provide a conversion from UNIVERSAL_INTEGER to my
type. Here you are.  IMO the actual problem is not inventing some
complex overloading rules, but supporting type conversions.

(For purists: there are type conversions in Ada, for instance there is
one from a derived type to its base)

Regards,
Dmitry Kazakov



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-30  9:16                                           ` Dmitry Kazakov
@ 2001-03-30  9:51                                             ` Florian Weimer
  2001-04-02  8:54                                               ` Dmitry Kazakov
  2001-03-30 16:13                                             ` Ken Garlington
  2001-03-30 20:44                                             ` Robert C. Leif, Ph.D.
  2 siblings, 1 reply; 115+ messages in thread
From: Florian Weimer @ 2001-03-30  9:51 UTC (permalink / raw)


dmitry@elros.cbb-automation.de (Dmitry Kazakov) writes:

> IMO the actual problem is not inventing some
> complex overloading rules, but supporting type conversions.

Type conversions do not mix very well with the extensive overloading
support provided by Ada (e.g. function overloading based on return
type).



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-30  9:16                                           ` Dmitry Kazakov
  2001-03-30  9:51                                             ` Florian Weimer
@ 2001-03-30 16:13                                             ` Ken Garlington
  2001-04-02 11:00                                               ` Dmitry Kazakov
  2001-03-30 20:44                                             ` Robert C. Leif, Ph.D.
  2 siblings, 1 reply; 115+ messages in thread
From: Ken Garlington @ 2001-03-30 16:13 UTC (permalink / raw)



"Dmitry Kazakov" <dmitry@elros.cbb-automation.de> wrote in message
news:3ac446f0.1707484@news.cis.dfn.de...
: On Thu, 29 Mar 2001 23:46:04 GMT, Robert A Duff
: <bobduff@world.std.com> wrote:
:
: >"Ken Garlington" <Ken.Garlington@computer.org> writes:
: >
: >> "Robert A Duff" <bobduff@world.std.com> wrote in message
: >> news:wccvgotscxo.fsf@world.std.com...
:
: >By the way, the "ulterior motive" in my ideas about literals is that
: >what I *really* want is user-defined literals.  I think the programmer
: >should be able to say "this type here has literals", and define which
: >forms are legal for that type, and what they mean.  But in order to
: >avoid chaos, we can't have the form of the literal affecting overload
: >resolution.
:
: I strongly support your intention (user-defined literals and surely
: user-defined aggregates), but I believe that the way is wrong. I would
: say that a literal always has a type. And its type should be
: determinable from the literal's form. I like the idea that, 1 is a
: UNIVERSAL_INTEGER, 1.0 is a UNIVERSAL_FLOAT,

Actually, 1.0 is a universal_real (see ARM 2.4:3).

: 'a' is a
: UNIVERSAL_CHARACTER etc.

Don't know exactly what a UNIVERSAL_CHARACTER is; it's an enumeration
literal of a character type (ARM 2.5:4). The only universal_types defined in
ARM 3.4.1:6 are universal_integer, universal_real, and universal_fixed.

: Then if I want to have 1 acceptable as a
: value for MY_OWN_INTEGER, or for MY_OWN_FLOAT, or even for
: MY_OWN_FILE_DESCRIPTOR, I (or the language, if the type is derived
: etc) should simply provide a conversion from UNIVERSAL_INTEGER to my
: type. Here you are.  IMO the actual problem is not inventing some
: complex overloading rules, but supporting type conversions.
:
: (For purists: there are type conversions in Ada, for instance there is
: one from a derived type to its base)
:
: Regards,
: Dmitry Kazakov





^ permalink raw reply	[flat|nested] 115+ messages in thread

* RE: Static typing (Was Re: Better support for garbage collection)
  2001-03-30  9:16                                           ` Dmitry Kazakov
  2001-03-30  9:51                                             ` Florian Weimer
  2001-03-30 16:13                                             ` Ken Garlington
@ 2001-03-30 20:44                                             ` Robert C. Leif, Ph.D.
  2001-04-02 11:29                                               ` Dmitry Kazakov
  2 siblings, 1 reply; 115+ messages in thread
From: Robert C. Leif, Ph.D. @ 2001-03-30 20:44 UTC (permalink / raw)
  To: comp.lang.ada

From: Bob Leif
To: Dmitry Kazakov et al.
Are you proposing that Universal_Integer, Universal_Float,
Universal_Character, etc. become visible types that can be explicitly used
in type conversions including where an object of a type like integer can be
converted to being of type Universal_Integer. Would it include subprograms
like:
function "+"   (Left : Integer'Base; Right : Universal_Integer) return
Integer'Base;

This would be very useful, since it would facilitate the use of private
numeric types. I have yet to be able to cleanly use a private type
Data_16_Type and directly add a literal to it.
I would like:
function To_Data_16_Type(The_Universal_Integer: Universal_Integer) return
Data_16_Type;

In essence these Universal_Types could now be used to explicitly specify the
classes of integers, floats, and characters. I can see the danger of
permitting programming with weakened types. However, these types could be
included in a separate package Standard.Universal and be subject to the
Pragma Restrictions or equivalent.


-----Original Message-----
From: comp.lang.ada-admin@ada.eu.org
[mailto:comp.lang.ada-admin@ada.eu.org]On Behalf Of Dmitry Kazakov
Sent: Friday, March 30, 2001 1:17 AM
To: comp.lang.ada@ada.eu.org
Subject: Re: Static typing (Was Re: Better support for garbage
collection)


On Thu, 29 Mar 2001 23:46:04 GMT, Robert A Duff
<bobduff@world.std.com> wrote:

>"Ken Garlington" <Ken.Garlington@computer.org> writes:
>
>> "Robert A Duff" <bobduff@world.std.com> wrote in message
>> news:wccvgotscxo.fsf@world.std.com...

>By the way, the "ulterior motive" in my ideas about literals is that
>what I *really* want is user-defined literals.  I think the programmer
>should be able to say "this type here has literals", and define which
>forms are legal for that type, and what they mean.  But in order to
>avoid chaos, we can't have the form of the literal affecting overload
>resolution.

I strongly support your intention (user-defined literals and surely
user-defined aggregates), but I believe that the way is wrong. I would
say that a literal always has a type. And its type should be
determinable from the literal's form. I like the idea that, 1 is a
UNIVERSAL_INTEGER, 1.0 is a UNIVERSAL_FLOAT, 'a' is a
UNIVERSAL_CHARACTER etc. Then if I want to have 1 acceptable as a
value for MY_OWN_INTEGER, or for MY_OWN_FLOAT, or even for
MY_OWN_FILE_DESCRIPTOR, I (or the language, if the type is derived
etc) should simply provide a conversion from UNIVERSAL_INTEGER to my
type. Here you are.  IMO the actual problem is not inventing some
complex overloading rules, but supporting type conversions.

(For purists: there are type conversions in Ada, for instance there is
one from a derived type to its base)

Regards,
Dmitry Kazakov





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-30  3:41                                           ` Ken Garlington
@ 2001-03-30 21:21                                             ` Robert A Duff
  2001-03-31 19:30                                               ` Ken Garlington
  2001-03-30 21:29                                             ` Robert A Duff
  1 sibling, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-03-30 21:21 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> writes:

> : > X : constant String := 1_000;
> : >
> : > Is the underscore retained?
> :
> : Probably the right rule is that string literals must have quotes, so the
> : above is illegal.
> 
> Back to form of the literal contributing to its interpretation (*sigh*)
> 
> : Do you understand the rather subtle distinction
> : between letting the literal's form determine its type, versus making
> : certain forms illegal after having determined the type (clearly String,
> : in the above case)?
> 
> If it's clearly String, why would 1_000 be an illegal string? If you can
> explain that, then I might understand the distinction...

This is key.  The reason why you don't understand my ideas (and think
I'm being self-contradictory) is that you don't understand this
distinction.  I'll try to clarify:

In the above example (in my proposal), the literal 1_000 is
*interpreted* as being of type String (because that's what the context
(quite obviously) requires).  This does *not* imply that it's legal --
there are additional rules that require literals of a type to be of a
certain form.  Those rules should be chosen to avoid confusion.  We both
agreed that it's confusing to leave off the quotes in this case, so I'm
imagining a rule making the above illegal.

In other words, there are two steps:

    1. Determine that 1_000 must be of type String (without noticing
       what the literal looks like).

    2. Check that 1_000 is a valid form for a literal of type String.

Of course the rules for what is valid form for a String are going to be
different then for Integer or Float.

I suppose there's actually:

    3. Given a valid literal, determine its value.

This is also type dependent.

> I understand that you see it as a "malformed literal"... but WHY is it a
> malformed literal, any more than
> 
> X : constant Float := 1;
> 
> would NOT be a malformed literal under your proposal? Isn't the desired
> result "obvious" in each case?

I find it obvious in this case, but not in the String case.  Shrug.
That's only a minor point.

> OK, but then note that the following will (almost) always be illegal:
> 
> X : constant Float := 1/2;
> X:  constant Integer := 1/2;
> X: constant Float := 1.0/2.0;
> X: constant Integer := 1.0/2.0;
> 
> because it's ambiguous which "/" operator is intended here (assuming one is
> visible for both types). Currently, only two are illegal. Do we really want
> to break existing programs in this manner?

No.  Again, you misunderstand how overload resolution works.  There is
only one "/" that returns Float, and that's the one chosen in the first
example.  Therefore, the two literals would also be interpreted as
Float.  Likewise, in the other three examples -- they would resolve just
fine.

> X: = constant Float := To_Float("one half");
> 
> All you'd have to do is agree on common descriptions and have at it!

I presume you're being sarcastic.  Writing down the rules for English
language descriptions of numbers (in words) would be a big job, and a
big waste of time.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-30  3:41                                           ` Ken Garlington
  2001-03-30 21:21                                             ` Robert A Duff
@ 2001-03-30 21:29                                             ` Robert A Duff
  1 sibling, 0 replies; 115+ messages in thread
From: Robert A Duff @ 2001-03-30 21:29 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> writes:

> OK, that's at least internally consistent. However, the number of
> ambiguities now is significantly expanded. For example:
> 
> J : constant := 1; -- legitimate named number, or did I mean to type
> 
> J : constant Character := 1;

Named numbers are a kludge.  I would eliminate them.  There are better
ways to achieve what named numbers can do.

By the way, note that all this talk about changing the rules for
literals, and eliminating named numbers is *not* meant as a serious
proposal for Ada -- I'm playing around with language design ideas.
Obviously, many of these ideas are incompatible with Ada.

> J: constant String := a; -- is this a literal "a", or a reference to
> something that I forgot to import? Both are possible...

The a is an identifier, not a literal, and I don't propose to change
that.

> I'm not sure I want a language that has a design goal of catching faults to
> be loosened in this regard. (I'm not sure I want it to be *tightened* either
> in this regard, because I am still human, after all. :)

My proposal does not "loosen" -- in fact (other than the minor ".0"
thing), my proposal makes more programs illegal -- it tightens.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-30 21:21                                             ` Robert A Duff
@ 2001-03-31 19:30                                               ` Ken Garlington
  2001-04-02 15:27                                                 ` Robert A Duff
  0 siblings, 1 reply; 115+ messages in thread
From: Ken Garlington @ 2001-03-31 19:30 UTC (permalink / raw)


"Robert A Duff" <bobduff@world.std.com> wrote in message
news:wccvgorkl54.fsf@world.std.com...

: > I understand that you see it as a "malformed literal"... but WHY is it a
: > malformed literal, any more than
: >
: > X : constant Float := 1;
: >
: > would NOT be a malformed literal under your proposal? Isn't the desired
: > result "obvious" in each case?
:
: I find it obvious in this case, but not in the String case.  Shrug.
: That's only a minor point.

Again, the inconsistency is rooted in an inability to articulate WHY it's
"obvious" in one case, but not in another. Presumably, we want to write the
language so that the expected result is "obvious" to the largest number of
people. For example, if I see

X: constant Float := 1/2;

I would intuitively expect this to have the same effect as if I wrote

A : constant Integer := 1;
B : constant Integer := 2;

X : constant Float := A/B;

If they both work, then I would also expect the following to work:

function Q (Z: in Float) return Float;

X : constant Float := Q(A);

and at this point we are talking about implicit casts, which I don't like.

Not being able to articulate the difference here is the same problem as
insisting that the term "floating-point" MUST be limited to hardware
representations... it's fine, so long as everyone shares your mindset (and
there's counter-evidence to that already). However, if someone believes
otherwise, then they may be confused and frustrated when the more widespread
definition is not supported by the language.

: > OK, but then note that the following will (almost) always be illegal:
: >
: > X : constant Float := 1/2;
: > X:  constant Integer := 1/2;
: > X: constant Float := 1.0/2.0;
: > X: constant Integer := 1.0/2.0;
: >
: > because it's ambiguous which "/" operator is intended here (assuming one
is
: > visible for both types). Currently, only two are illegal. Do we really
want
: > to break existing programs in this manner?
:
: No.  Again, you misunderstand how overload resolution works.  There is
: only one "/" that returns Float, and that's the one chosen in the first
: example.  Therefore, the two literals would also be interpreted as
: Float.  Likewise, in the other three examples -- they would resolve just
: fine.

However, if all four "resolve just fine," then that has to mean that both 1
and 1.0 are both reals and integers. Again, why have liberal rules for
numerics, but not for other literals?

In your other post, you said:

: My proposal does not "loosen" -- in fact (other than the minor ".0"
: thing), my proposal makes more programs illegal -- it tightens.

First, this seems to be a Bad Thing -- to make legal programs, that use a
more strict definition of literals, illegal.

Second, isn't this contradicted by the example above? GNAT says two of these
are illegal, you say all four are legal. Note that it's not limited to ".0";
all sorts of literal forms (exponents, based numbers, etc.) would now be
exchangable. All you have to do is leave off one digit (e.g. 1.00000E5
instead of 1.000001E5), and suddenly your floating-point value can be an
integer!

: > X: = constant Float := To_Float("one half");
: >
: > All you'd have to do is agree on common descriptions and have at it!
:
: I presume you're being sarcastic.  Writing down the rules for English
: language descriptions of numbers (in words) would be a big job, and a
: big waste of time.

What's the difference between that and having packages that define units of
measure (feet_per_second, etc.), which has been done more than once? You
wouldn't have to define every number, any more than "Furlongs_per_fortnight"
is required. The point is that the language supports it, and a compiler
vendor could include it if desired.

:> J: constant String := a; -- is this a literal "a", or a reference to
:> something that I forgot to import? Both are possible...

: The a is an identifier, not a literal, and I don't propose to change
: that.

Again, WHY is it a an identifier, if there's no identifier named A in my
program?

Note that you can't use the same argument for

J : constant String := 1;

since this is obviously not an identifier; therefore it must be a string
(just like 1/2 is obviously a floating point divide, not an integer divide,
if I assign it to a floating-point number).





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-30  9:51                                             ` Florian Weimer
@ 2001-04-02  8:54                                               ` Dmitry Kazakov
  0 siblings, 0 replies; 115+ messages in thread
From: Dmitry Kazakov @ 2001-04-02  8:54 UTC (permalink / raw)


On 30 Mar 2001 11:51:43 +0200, Florian Weimer <fw@deneb.enyo.de>
wrote:

>dmitry@elros.cbb-automation.de (Dmitry Kazakov) writes:
>
>> IMO the actual problem is not inventing some
>> complex overloading rules, but supporting type conversions.
>
>Type conversions do not mix very well with the extensive overloading
>support provided by Ada (e.g. function overloading based on return
>type).

It works for derived types, it would work for user-defined conversions
too. IMO a real argument against it always was (and it still holds)
that "skilfully" designed conversions may turn a program into a mess
(PL/1 disaster is an example). So the problem is how to limit
user-defined conversions.

Regards,
Dmitry Kazakov



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-30 16:13                                             ` Ken Garlington
@ 2001-04-02 11:00                                               ` Dmitry Kazakov
  0 siblings, 0 replies; 115+ messages in thread
From: Dmitry Kazakov @ 2001-04-02 11:00 UTC (permalink / raw)


On Fri, 30 Mar 2001 16:13:16 GMT, "Ken Garlington"
<Ken.Garlington@computer.org> wrote:

>"Dmitry Kazakov" <dmitry@elros.cbb-automation.de> wrote in message
>news:3ac446f0.1707484@news.cis.dfn.de...
>: On Thu, 29 Mar 2001 23:46:04 GMT, Robert A Duff
>: <bobduff@world.std.com> wrote:
>:
>: >"Ken Garlington" <Ken.Garlington@computer.org> writes:
>: >
>: >> "Robert A Duff" <bobduff@world.std.com> wrote in message
>: >> news:wccvgotscxo.fsf@world.std.com...
>:
>: >By the way, the "ulterior motive" in my ideas about literals is that
>: >what I *really* want is user-defined literals.  I think the programmer
>: >should be able to say "this type here has literals", and define which
>: >forms are legal for that type, and what they mean.  But in order to
>: >avoid chaos, we can't have the form of the literal affecting overload
>: >resolution.
>:
>: I strongly support your intention (user-defined literals and surely
>: user-defined aggregates), but I believe that the way is wrong. I would
>: say that a literal always has a type. And its type should be
>: determinable from the literal's form. I like the idea that, 1 is a
>: UNIVERSAL_INTEGER, 1.0 is a UNIVERSAL_FLOAT,
>
>Actually, 1.0 is a universal_real (see ARM 2.4:3).
>
>: 'a' is a
>: UNIVERSAL_CHARACTER etc.
>
>Don't know exactly what a UNIVERSAL_CHARACTER is; it's an enumeration
>literal of a character type (ARM 2.5:4). The only universal_types defined in
>ARM 3.4.1:6 are universal_integer, universal_real, and universal_fixed.

Surely. Though it was not about Ada, but about the idea how to deal
with a potentially unlimited set of literals. (We surely do not want
to *really* declare all 2**16 (24?) unicode characters and how many
strings? (:-))

Regards,
Dmitry Kazakov



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-30 20:44                                             ` Robert C. Leif, Ph.D.
@ 2001-04-02 11:29                                               ` Dmitry Kazakov
  2001-04-02 13:15                                                 ` Robert A Duff
  0 siblings, 1 reply; 115+ messages in thread
From: Dmitry Kazakov @ 2001-04-02 11:29 UTC (permalink / raw)


On Fri, 30 Mar 2001 12:44:57 -0800, "Robert C. Leif, Ph.D."
<rleif@rleif.com> wrote:

>From: Bob Leif
>To: Dmitry Kazakov et al.
>Are you proposing that Universal_Integer, Universal_Float,
>Universal_Character, etc. become visible types that can be explicitly used
>in type conversions including where an object of a type like integer can be
>converted to being of type Universal_Integer. Would it include subprograms
>like:
>function "+"   (Left : Integer'Base; Right : Universal_Integer) return
>Integer'Base;
>
>This would be very useful, since it would facilitate the use of private
>numeric types. I have yet to be able to cleanly use a private type
>Data_16_Type and directly add a literal to it.
>I would like:
>function To_Data_16_Type(The_Universal_Integer: Universal_Integer) return
>Data_16_Type;
>
>In essence these Universal_Types could now be used to explicitly specify the
>classes of integers, floats, and characters. I can see the danger of
>permitting programming with weakened types. However, these types could be
>included in a separate package Standard.Universal and be subject to the
>Pragma Restrictions or equivalent.

Yes and no. In my opinion instances of universal types may not exist
at run time. A universal_integer has an arbitrary length, its actual
representation is upon the compiler. So one may not have an object of
this type. In the end an instance of a universal type should be always
converted to some "legal" type. Yet with user-defined conversions one
will have an ability to explicitly add literals to a private type:

function <syntax-sugar> (Value : Integer) return Data_16_Type;

Then the following conversion path is applied:

123 (of universal_integer)->123 (of Integer)-> 123 (of Data_16_Type)

Further this issue is obviuosly relevant to another thread (where the
compile time routines are discussed). If such beasts were allowed then
one might have exactly what you mentioned:

function <syntax-sugar> (Value : Universal_Integer)
   return Data_16_Type;
??pragma <ensure-that-this-is-a-compile-time-function>;??

As for danger, it is immense, yet in modern times (take a look at
comp.object) strong-static-manifested typing is considered as an
evil?! (:-()

Regards,
Dmitry Kazakov




^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-04-02 11:29                                               ` Dmitry Kazakov
@ 2001-04-02 13:15                                                 ` Robert A Duff
  2001-04-03  8:57                                                   ` Dmitry Kazakov
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-04-02 13:15 UTC (permalink / raw)


dmitry@elros.cbb-automation.de (Dmitry Kazakov) writes:

> Yes and no. In my opinion instances of universal types may not exist
> at run time.

In Ada, there are actually some rare circumstances where
universal_integers can exist at run time.  For example:

if T1'Size > T2'Size then ...

where T1 and T2 are not static subtypes.  I suspect that the intent of
the original designers of Ada 83 was as you say (u_i is a compile time
concept), but there are a few minor holes in that idea.

Note that the above can raise Constraint_Error if one of the 'Sizes is
very large.

>... A universal_integer has an arbitrary length, its actual
> representation is upon the compiler. So one may not have an object of
> this type. In the end an instance of a universal type should be always
> converted to some "legal" type. Yet with user-defined conversions one
> will have an ability to explicitly add literals to a private type:
> 
> function <syntax-sugar> (Value : Integer) return Data_16_Type;
> 
> Then the following conversion path is applied:
> 
> 123 (of universal_integer)->123 (of Integer)-> 123 (of Data_16_Type)

You presumably need to require that this function be "pure", so the
compiler can evaluate calls at compile time.  (Note that Ada's pragma
Pure applies to whole packages, not to particular functions.)

Also, I suspect it's a bad idea to allow this function to have
machine-code inserts, or calls to foreign languages.  Especially if it's
a cross compiler!

Speaking of cross compilers, I suppose if the function does floating
point arithmetic, the compiler is required to simulate the target
hardware?  That's a fairly substantial burden...

> Further this issue is obviuosly relevant to another thread (where the
> compile time routines are discussed). If such beasts were allowed then
> one might have exactly what you mentioned:
> 
> function <syntax-sugar> (Value : Universal_Integer)
>    return Data_16_Type;
> ??pragma <ensure-that-this-is-a-compile-time-function>;??

I'm slightly confused at this point.  What rules do you propose that
ensure that the function is only called at compile time?  Are these
implicit conversions only allowed for literals?  Only for static
expressions?

> As for danger, it is immense, yet in modern times (take a look at
> comp.object) strong-static-manifested typing is considered as an
> evil?! (:-()

I've read part of that thread (until I got bored of "yes it is", "no
it's not" repeating indefinitely).  Actually, only *some* folks think
that strong-static-manifest typing is evil.  I think it's a sign of the
immaturity of "computer science" that practitioners can't agree on such
a fundamental issue.

Anyway, I don't understand why you like universal types with implicit
conversions better than the alternative I suggested.  (The alternative
is that the type of a literal is determined by context, and the value of
the literal is determined by evaluating a type-specific function at
compile time.)  What is the advantage of universal types?  They seem
kind of kludgy to me.

The original Green language said that integer literals are overloaded on
all integer types.  Universal integer was invented so that things like:

    if X = 1 then ...

where X is a named number, would not be ambiguous.  But I think named
numbers are a kludge anyway, so I don't buy the universal_integer
fiction.

By the way, you didn't mention a universal_access, which would
presumably be the type of "null".

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-03-31 19:30                                               ` Ken Garlington
@ 2001-04-02 15:27                                                 ` Robert A Duff
  2001-04-02 23:29                                                   ` Ken Garlington
  0 siblings, 1 reply; 115+ messages in thread
From: Robert A Duff @ 2001-04-02 15:27 UTC (permalink / raw)


"Ken Garlington" <Ken.Garlington@computer.org> writes:

> "Robert A Duff" <bobduff@world.std.com> wrote in message
> news:wccvgorkl54.fsf@world.std.com...
> 
> : > I understand that you see it as a "malformed literal"... but WHY is it a
> : > malformed literal, any more than
> : >
> : > X : constant Float := 1;
> : >
> : > would NOT be a malformed literal under your proposal? Isn't the desired
> : > result "obvious" in each case?
> :
> : I find it obvious in this case, but not in the String case.  Shrug.
> : That's only a minor point.
> 
> Again, the inconsistency is rooted in an inability to articulate WHY it's
> "obvious" in one case, but not in another.

I thought I articulated it already.  I'm basing my thinking on
fourth-grade maths, rather than on computer hardware.  In 4th grade
maths, the integers are a subset of the rational numbers.  The Ada
integers are a subset of the mathematical integers, and the Ada floats
are a subset of the rational numbers, but the number we refer to in
English as "one" is a member of both.  That's why I see nothing wrong
with denoting this number as 1, no matter what it's Ada type.

You claim I'm being inconsistent by not going further, and allowing
1_000 (without quotes) if the type is String.  Well, maybe that's
inconsistent, but so what.  I think we both agree that the rules about
what forms of literals are allowed should be different for different
types.

>... Presumably, we want to write the
> language so that the expected result is "obvious" to the largest number of
> people. For example, if I see
> 
> X: constant Float := 1/2;
> 
> I would intuitively expect this to have the same effect as if I wrote
> 
> A : constant Integer := 1;
> B : constant Integer := 2;
> 
> X : constant Float := A/B;
> 
> If they both work, then I would also expect the following to work:
> 
> function Q (Z: in Float) return Float;
> 
> X : constant Float := Q(A);
> 
> and at this point we are talking about implicit casts, which I don't like.

I don't like it either.  But I claim the two issues are different.  The
literal 1 is *not* inherently of type Integer.  The reason you can't
implicitly convert Integer to Float is the same reason you can't
implicitly convert My_Float to Float (even if My_Float has the same
'Digits as Float, and therefore the same underlying representation, and
the same mathematical properties).

> Not being able to articulate the difference here is the same problem as
> insisting that the term "floating-point" MUST be limited to hardware
> representations... it's fine, so long as everyone shares your mindset (and
> there's counter-evidence to that already). However, if someone believes
> otherwise, then they may be confused and frustrated when the more widespread
> definition is not supported by the language.

Perhaps I misspoke when I said something about hardware
representations.

The point is that floating point types in Ada (and all other programming
languages) are intended for doing certain kinds of approximate
calculations, which has little to do with the representation of these
things on the screen -- that is, every programming language disagrees
with all those dictionaries you quoted.

That's not too surprising -- after all, Ada uses the term "integer" to
refer to a rather small subset of the mathematical integers.  ;-)

> In your other post, you said:
> 
> : My proposal does not "loosen" -- in fact (other than the minor ".0"
> : thing), my proposal makes more programs illegal -- it tightens.
> 
> First, this seems to be a Bad Thing -- to make legal programs, that use a
> more strict definition of literals, illegal.

First, recall that I am not proposing to change Ada -- of course I agree
that such an incompatible change would be a Bad Thing.  I am talking
about what I would do if I were designing an Ada-like language, from
scratch, with no compatibility concerns.

> Second, isn't this contradicted by the example above? GNAT says two of these
> are illegal, you say all four are legal.

Sorry -- I was unclear.  In the "other post", I was saying that my rule
saying "the expected type for a literal is any type" is a *restriction*.
You are correct that allowing to leave off the ".0" is an *extension*.

>... Note that it's not limited to ".0";
> all sorts of literal forms (exponents, based numbers, etc.) would now be
> exchangable. All you have to do is leave off one digit (e.g. 1.00000E5
> instead of 1.000001E5), and suddenly your floating-point value can be an
> integer!

That's a good point.  I agree that it would be confusing for 1.00000E5
to be an allowed form for an integer literal.

> :> J: constant String := a; -- is this a literal "a", or a reference to
> :> something that I forgot to import? Both are possible...
> 
> : The a is an identifier, not a literal, and I don't propose to change
> : that.
> 
> Again, WHY is it a an identifier, if there's no identifier named A in my
> program?

Oh, come on!  I know that you know perfectly well that the a above is an
identifier, and not a literal -- this is the syntax defined in chap 2 of
the RM.  I never proposed to change that.

I think literals and identifiers should be syntactically
distinguishable, and I'm sure you agree.

- Bob



^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-04-02 15:27                                                 ` Robert A Duff
@ 2001-04-02 23:29                                                   ` Ken Garlington
  0 siblings, 0 replies; 115+ messages in thread
From: Ken Garlington @ 2001-04-02 23:29 UTC (permalink / raw)



"Robert A Duff" <bobduff@world.std.com> wrote in message
news:wccg0frz5hz.fsf@world.std.com...
: "Ken Garlington" <Ken.Garlington@computer.org> writes:
:
: > "Robert A Duff" <bobduff@world.std.com> wrote in message
: > news:wccvgorkl54.fsf@world.std.com...
: >
: > : > I understand that you see it as a "malformed literal"... but WHY is
it a
: > : > malformed literal, any more than
: > : >
: > : > X : constant Float := 1;
: > : >
: > : > would NOT be a malformed literal under your proposal? Isn't the
desired
: > : > result "obvious" in each case?
: > :
: > : I find it obvious in this case, but not in the String case.  Shrug.
: > : That's only a minor point.
: >
: > Again, the inconsistency is rooted in an inability to articulate WHY
it's
: > "obvious" in one case, but not in another.
:
: I thought I articulated it already.  I'm basing my thinking on
: fourth-grade maths, rather than on computer hardware.

What part of "4th grade maths" covers text?

:  In 4th grade
: maths, the integers are a subset of the rational numbers.  The Ada
: integers are a subset of the mathematical integers, and the Ada floats
: are a subset of the rational numbers, but the number we refer to in
: English as "one" is a member of both.

Which is irrelevant, since we both previously agreed that the imprecision of
English was insufficient, right?

: That's why I see nothing wrong
: with denoting this number as 1, no matter what it's Ada type.
:
: You claim I'm being inconsistent by not going further, and allowing
: 1_000 (without quotes) if the type is String.  Well, maybe that's
: inconsistent, but so what.  I think we both agree that the rules about
: what forms of literals are allowed should be different for different
: types.

If we both agree that "what forms of literals are allowed should be
different for different types," then you must agree that it is reasonable
for integer literals to be restricted to their dictionary form.

Of course, if you don't see inconsistency as an issue, then of course you
don't have to agree on anything :)

: >... Presumably, we want to write the
: > language so that the expected result is "obvious" to the largest number
of
: > people. For example, if I see
: >
: > X: constant Float := 1/2;
: >
: > I would intuitively expect this to have the same effect as if I wrote
: >
: > A : constant Integer := 1;
: > B : constant Integer := 2;
: >
: > X : constant Float := A/B;
: >
: > If they both work, then I would also expect the following to work:
: >
: > function Q (Z: in Float) return Float;
: >
: > X : constant Float := Q(A);
: >
: > and at this point we are talking about implicit casts, which I don't
like.
:
: I don't like it either.  But I claim the two issues are different.  The
: literal 1 is *not* inherently of type Integer.  The reason you can't
: implicitly convert Integer to Float is the same reason you can't
: implicitly convert My_Float to Float (even if My_Float has the same
: 'Digits as Float, and therefore the same underlying representation, and
: the same mathematical properties).

See previous post about the dangers of mixing specific Ada types (Integer,
Float) into the discussion, as well as machine representations.

: > Not being able to articulate the difference here is the same problem as
: > insisting that the term "floating-point" MUST be limited to hardware
: > representations... it's fine, so long as everyone shares your mindset
(and
: > there's counter-evidence to that already). However, if someone believes
: > otherwise, then they may be confused and frustrated when the more
widespread
: > definition is not supported by the language.
:
: Perhaps I misspoke when I said something about hardware
: representations.
:
: The point is that floating point types in Ada (and all other programming
: languages) are intended for doing certain kinds of approximate
: calculations, which has little to do with the representation of these
: things on the screen -- that is, every programming language disagrees
: with all those dictionaries you quoted.

Again, you're confusing the concept of a *type* with the much-narrower
concept of a *literal*. See the definition of type at www.foldoc.org for
more information.

: That's not too surprising -- after all, Ada uses the term "integer" to
: refer to a rather small subset of the mathematical integers.  ;-)

Which integer is not permitted in Ada as an integer literal (vs. an Integer
type)? Are you worried about line length limits?

: > In your other post, you said:
: >
: > : My proposal does not "loosen" -- in fact (other than the minor ".0"
: > : thing), my proposal makes more programs illegal -- it tightens.
: >
: > First, this seems to be a Bad Thing -- to make legal programs, that use
a
: > more strict definition of literals, illegal.
:
: First, recall that I am not proposing to change Ada -- of course I agree
: that such an incompatible change would be a Bad Thing.  I am talking
: about what I would do if I were designing an Ada-like language, from
: scratch, with no compatibility concerns.
:
: > Second, isn't this contradicted by the example above? GNAT says two of
these
: > are illegal, you say all four are legal.
:
: Sorry -- I was unclear.  In the "other post", I was saying that my rule
: saying "the expected type for a literal is any type" is a *restriction*.
: You are correct that allowing to leave off the ".0" is an *extension*.
:
: >... Note that it's not limited to ".0";
: > all sorts of literal forms (exponents, based numbers, etc.) would now be
: > exchangable. All you have to do is leave off one digit (e.g. 1.00000E5
: > instead of 1.000001E5), and suddenly your floating-point value can be an
: > integer!
:
: That's a good point.  I agree that it would be confusing for 1.00000E5
: to be an allowed form for an integer literal.

Now it starts to get really strange in that we have to introduce a new
literal form, presumably <sign><digits>.0, to allow as integers. Are we sure
we need this extra complexity?

: > :> J: constant String := a; -- is this a literal "a", or a reference to
: > :> something that I forgot to import? Both are possible...
: >
: > : The a is an identifier, not a literal, and I don't propose to change
: > : that.
: >
: > Again, WHY is it a an identifier, if there's no identifier named A in my
: > program?
:
: Oh, come on!  I know that you know perfectly well that the a above is an
: identifier, and not a literal -- this is the syntax defined in chap 2 of
: the RM.  I never proposed to change that.

This statement appears to parse as "it's not allowed because the ARM doesn't
allow it." In which case, your whole proposal is dead, since the ARM doesn't
allow it, either :)

You'll have to depend on a different line of argument -- if it's "obvious"
what was intended here, what's the problem with being consistent and
allowing this to be parsed?

: I think literals and identifiers should be syntactically
: distinguishable, and I'm sure you agree.

(1) You seem to be making a "proof by authority" here -- even if we both
agreed, at least one of us should be able to explain why.

(2) This still doesn't answer the case where the literal *is* syntactically
distinguishable, e.g.

X : constant String := 1;

: - Bob





^ permalink raw reply	[flat|nested] 115+ messages in thread

* Re: Static typing (Was Re: Better support for garbage collection)
  2001-04-02 13:15                                                 ` Robert A Duff
@ 2001-04-03  8:57                                                   ` Dmitry Kazakov
  0 siblings, 0 replies; 115+ messages in thread
From: Dmitry Kazakov @ 2001-04-03  8:57 UTC (permalink / raw)


On Mon, 2 Apr 2001 13:15:23 GMT, Robert A Duff <bobduff@world.std.com>
wrote:

>dmitry@elros.cbb-automation.de (Dmitry Kazakov) writes:
>
>> Yes and no. In my opinion instances of universal types may not exist
>> at run time.
>
>In Ada, there are actually some rare circumstances where
>universal_integers can exist at run time.  For example:
>
>if T1'Size > T2'Size then ...
>
>where T1 and T2 are not static subtypes.  I suspect that the intent of
>the original designers of Ada 83 was as you say (u_i is a compile time
>concept), but there are a few minor holes in that idea.
>
>Note that the above can raise Constraint_Error if one of the 'Sizes is
>very large.

An interesting example. You are right that in Ada universal types are
leaky (:-().

>>... A universal_integer has an arbitrary length, its actual
>> representation is upon the compiler. So one may not have an object of
>> this type. In the end an instance of a universal type should be always
>> converted to some "legal" type. Yet with user-defined conversions one
>> will have an ability to explicitly add literals to a private type:
>> 
>> function <syntax-sugar> (Value : Integer) return Data_16_Type;
>> 
>> Then the following conversion path is applied:
>> 
>> 123 (of universal_integer)->123 (of Integer)-> 123 (of Data_16_Type)
>
>You presumably need to require that this function be "pure", so the
>compiler can evaluate calls at compile time.  (Note that Ada's pragma
>Pure applies to whole packages, not to particular functions.)

There is no need for a user-defined conversion to be a compile-time
function. As a consequence, it is possible that

Devils_Number : constant Data_16_Type := 666;

is not static. It may look strange, but it is pretty consitent with
what we already have with enumeration literals and named constants
which are undistinguishabe from parameterless functions. Similarily,
in effect, 666 ::= Integer_To_Data_16_Type (666).

>Also, I suspect it's a bad idea to allow this function to have
>machine-code inserts, or calls to foreign languages.  Especially if it's
>a cross compiler!
>
>Speaking of cross compilers, I suppose if the function does floating
>point arithmetic, the compiler is required to simulate the target
>hardware?  That's a fairly substantial burden...

A conversion function should be treated like any other routine.

>> Further this issue is obviuosly relevant to another thread (where the
>> compile time routines are discussed). If such beasts were allowed then
>> one might have exactly what you mentioned:
>> 
>> function <syntax-sugar> (Value : Universal_Integer)
>>    return Data_16_Type;
>> ??pragma <ensure-that-this-is-a-compile-time-function>;??
>
>I'm slightly confused at this point.  What rules do you propose that
>ensure that the function is only called at compile time?  Are these
>implicit conversions only allowed for literals?  Only for static
>expressions?

The point is that IF (I am not sure here) universal types are allowed
as formal paramerters of some routine (no matter whether it is a
conversion function or not), THEN there should be a rule that prevents
this routine from being called at run time.

>Anyway, I don't understand why you like universal types with implicit
>conversions better than the alternative I suggested.  (The alternative
>is that the type of a literal is determined by context, and the value of
>the literal is determined by evaluating a type-specific function at
>compile time.)  What is the advantage of universal types?  They seem
>kind of kludgy to me.

Because with user-defined conversions you get user-defined literals
for free. Then the idea of user-defined conversions is a fundamental
ADT (or OO if you like) feature. If we consider how new types could be
built upon the existing types, we will find the following three major
approches:

1. Cloning: same functionality - unrelated type (type ... is new in
Ada). Used when we do not want to add apples to oranges.

2. Inheritance: same functionality - related type (type ... is new
with). This is what is usually called OO.

3. Masquerading (multiple representations): other functionality -
related type. This is what the user-defined conversions are supposedly
for. As an example, look at Ada string types and the plethora of "&"
functions one must have to interchangeable use instances of different
kinds of strings.

As for your idea, I feel it uncomfortable, when something is
undeterminable without a context. I accept it for many things, just
because we do not know how to do it better. But why such a simple
thing as 1 should have no type? IMO any thing in a language should
have a type.

>The original Green language said that integer literals are overloaded on
>all integer types.  Universal integer was invented so that things like:
>
>    if X = 1 then ...
>
>where X is a named number, would not be ambiguous.  But I think named
>numbers are a kludge anyway, so I don't buy the universal_integer
>fiction.

A nice fiction. Anyway 1 is also a fiction (or a science fiction?
(:-))

>By the way, you didn't mention a universal_access, which would
>presumably be the type of "null".

Surely. Moreover, in general there are lots of universal types, if you
want to build the type system consistently. This issue is definitely
related to the concept that, for instance, all numeric types should
have a common ancestor. Elaborating this idea, you will come to
universal record, array, index types too. Practically if you look into
a type you will find some universal fiction behind it.

Regards,
Dmitry Kazakov



^ permalink raw reply	[flat|nested] 115+ messages in thread

end of thread, other threads:[~2001-04-03  8:57 UTC | newest]

Thread overview: 115+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-03-13 18:37 Better support for garbage collection Nick Roberts
2001-03-14  8:16 ` Florian Weimer
2001-03-14 18:52   ` Robert A Duff
2001-03-14 19:40     ` Florian Weimer
2001-03-15 13:18       ` Nick Roberts
2001-03-14 19:29 ` Robert A Duff
2001-03-14 20:59   ` Brian Rogoff
2001-03-16 16:42     ` Robert A Duff
2001-03-17  6:13       ` Lao Xiao Hai
2001-03-24  4:08       ` Brian Rogoff
2001-03-15  4:35   ` Nick Roberts
2001-03-15 21:37     ` Randy Brukardt
2001-03-15 22:36     ` Stephen Leake
2001-03-16 16:26     ` Robert A Duff
2001-03-16 16:59       ` Brian Rogoff
2001-03-16 17:31         ` Robert A Duff
2001-03-16 18:29           ` Brian Rogoff
2001-03-17  2:30           ` Nick Roberts
2001-03-17 21:59             ` Robert A Duff
2001-03-17 22:57             ` Static typing (Was Re: Better support for garbage collection) Brian Rogoff
2001-03-17 23:45               ` Robert A Duff
2001-03-18  0:58                 ` Brian Rogoff
2001-03-19 15:24                   ` Robert A Duff
2001-03-20  4:21                     ` Brian Rogoff
2001-03-21  1:32                       ` Ken Garlington
2001-03-21 13:28                         ` Robert A Duff
2001-03-22  2:08                           ` Ken Garlington
2001-03-22 16:40                             ` Robert A Duff
2001-03-25 16:21                               ` Ken Garlington
2001-03-25 16:56                                 ` Ken Garlington
2001-03-25 22:31                                 ` Robert A Duff
2001-03-27  0:24                                   ` Ken Garlington
2001-03-28 23:15                                     ` Robert A Duff
2001-03-29  5:02                                       ` Ken Garlington
2001-03-29  6:13                                         ` David Starner
2001-03-29 10:10                                           ` AG
2001-03-29 14:28                                           ` Ken Garlington
2001-03-29 23:46                                         ` Robert A Duff
2001-03-30  3:41                                           ` Ken Garlington
2001-03-30 21:21                                             ` Robert A Duff
2001-03-31 19:30                                               ` Ken Garlington
2001-04-02 15:27                                                 ` Robert A Duff
2001-04-02 23:29                                                   ` Ken Garlington
2001-03-30 21:29                                             ` Robert A Duff
2001-03-30  9:16                                           ` Dmitry Kazakov
2001-03-30  9:51                                             ` Florian Weimer
2001-04-02  8:54                                               ` Dmitry Kazakov
2001-03-30 16:13                                             ` Ken Garlington
2001-04-02 11:00                                               ` Dmitry Kazakov
2001-03-30 20:44                                             ` Robert C. Leif, Ph.D.
2001-04-02 11:29                                               ` Dmitry Kazakov
2001-04-02 13:15                                                 ` Robert A Duff
2001-04-03  8:57                                                   ` Dmitry Kazakov
2001-03-27  2:39                             ` Andrew Berg
2001-03-27  3:33                               ` Ken Garlington
2001-03-27 14:23                                 ` Robert A Duff
2001-03-27 23:36                                   ` Ken Garlington
2001-03-29 23:50                       ` Robert A Duff
2001-03-19 18:24       ` Better support for garbage collection Tucker Taft
     [not found]   ` <87bsr46kxv.fsf@deneb.enyo.de>
2001-03-15 14:18     ` Robert A Duff
2001-03-15 16:36       ` Florian Weimer
2001-03-14 22:05 ` Laurent Guerby
2001-03-16 16:47   ` Robert A Duff
2001-03-16 19:46     ` Laurent Guerby
2001-03-16 20:10       ` Robert A Duff
2001-03-17 13:14         ` Support for per allocation pool selection (was: Better support for garbage collection) Laurent Guerby
2001-03-17 17:06           ` Robert A Duff
2001-03-17 19:19           ` Florian Weimer
2001-03-17 21:10             ` Robert A Duff
2001-03-15 17:56 ` Better support for garbage collection Ray Blaak
2001-03-21 16:15 ` Implementing C/C++ style #include bhazzard
2001-03-21 16:45   ` Marin David Condic
2001-03-22 15:13     ` Ira D. Baxter
2001-03-22 15:23       ` Marin David Condic
2001-03-25 15:45         ` Anton Gibbs
2001-03-26 14:24           ` Ted Dennison
2001-03-26 15:00             ` Marin David Condic
2001-03-26 14:49           ` Marin David Condic
2001-03-26 18:19             ` Stephen Leake
2001-03-26 18:44               ` Pascal Obry
2001-03-26 21:44                 ` Robert A Duff
2001-03-27  3:02                   ` Andrew Berg
2001-03-27  3:27                     ` Phaedrus
2001-03-27 17:41                   ` Pascal Obry
2001-03-26 19:18               ` Ted Dennison
2001-03-27 18:51                 ` Anton Gibbs
2001-03-26 19:35               ` Marin David Condic
2001-03-26 23:04                 ` Mark Lundquist
2001-03-27 14:38                   ` Marin David Condic
2001-03-26 16:12           ` Florian Weimer
2001-03-26 17:34             ` David Starner
2001-03-26 22:25               ` Florian Weimer
2001-03-27  3:29                 ` David Starner
2001-03-26 18:23             ` Stephen Leake
2001-03-26 22:34               ` Florian Weimer
2001-03-27  7:34         ` Ole-Hjalmar Kristensen
2001-03-27 12:43           ` Dale Stanbrough
2001-03-27 14:40             ` Marin David Condic
2001-03-27 15:01             ` Ted Dennison
2001-03-27 13:20           ` Preben Randhol
2001-03-23 17:39       ` Wes Groleau
2001-03-21 18:07   ` Mark Lundquist
2001-03-22 12:50   ` Chris M. Moore
2001-03-22 14:30     ` Marin David Condic
2001-03-22 21:15       ` singlespeeder
2001-03-22 21:42         ` Marin David Condic
2001-03-23 14:43           ` Georg Bauhaus
2001-03-23 18:51             ` Marin David Condic
2001-03-22 15:02     ` Pat Rogers
2001-03-22 15:28       ` Marin David Condic
2001-03-22 16:32       ` Chris M. Moore
2001-03-22 16:57       ` Robert A Duff
2001-03-26 16:13   ` Martin Dowie
2001-03-26 22:55   ` Phaedrus
2001-03-27  1:36     ` tmoran

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox