[comp.lang.ada] Ada functions versus arrays

hammondr@sunroof.crd.ge.com (Richard A Hammond) (03/01/90)

In article <598@software.software.org> blakemor@software.org (Alex Blakemore) writes:
>In article <184@trwacs.UUCP> epstein@trwacs.UUCP (Jeremy Epstein) writes:
>> ... look at how Ada overloads symbols.  For
>> example, parentheses are used for parameters as well as subscripts
>> (that's something that totally confuses me as an old-time C programmer).

>This is a strength of Ada not an inconsistency.  This way you can change
>between using an array and a function to provide some info  ...

>This is consistent with some formal proof methods (like Tony Hoare's)
>which treat array references as function calls. Logically they
>have the same effect.  Mathematically a function is essentially a table
>anyway.  Of course, there is a difference when you assign to an array
>element.

...

>C has some elegance but why should the programmer have to remember
>when to use [] or () ?  just to make the compiler easier to write ?

Last point first:  I think the reason is to give the programmer a cue
to what is going on.  Remember, the goal of C is to provide constructs
which map in a straightforward way to machine code.  Thus, the C
programmer is interested in the difference between an
array reference and a function call.  Besides, functions in C have the
attributes of Ada procedures and Ada functions, i.e. the Ada
function is more limited than a C function(no out or in/out parameters).
So in C: a = b(d,e) + f; could modify the value not just of a, but of
what d and/or e pointed to (if they were access types) or d/e themselves
if they are defined via macros as more complicated objects.

In fact, the argument that "an array ref" is the same as a "function call"
is true for mathematical functions but not Ada ones.  Ada functions can
have side effects, which is a software engineering deficiency in Ada.

For that reason, I'd want to know when a function call is being made.
Even a function without parameters, which is why I like C's "foo()" better
than Ada's "foo" for calling a parameterless function.
And why I'd like to distinguish between function calls and array refs.

Please, I'm trying to discuss Ada and not Ada versus C, except that
because C does some things wrong doesn't mean you can't steal the
good ideas.

Rich Hammond

blakemor@software.org (Alex Blakemore) (03/01/90)

I previously posted the next two lines AB
> >C has some elegance but why should the programmer have to remember
> >when to use [] or () ?  

In article <5619@crdgw1.crd.ge.com> hammondr@sunroof.crd.ge.com (Richard A Hammond) writes:
> ...  I think the reason is to give the programmer a cue
> to what is going on.  Remember, the goal of C is to provide constructs
> which map in a straightforward way to machine code.

That is not Ada's goal (as most compilers remind us :-)
The question is what you mean by "what is going on".
The important thing for the caller is the type and content of whatever
name (args) returns, not how/when it is computed.  (That is important too,
but the responsibility for that lies with the code providing the service.)

> The C programmer is interested in the difference between an
> array reference and a function call.

So are Ada programmers, no one is keeping that information from you.
You are free to go look in the package spec any time to see what exactly 
you are referencing.  And if you dont like the way it is implemented,
you can change it IN EXACTLY ONE PLACE. The meaning of calling programs
is not changed if the switch between array/function implements the same
abstract function.  Only their efficiency changes.

(i.e. Ada allows you do it right, there are still ways to mess it up such as ...)

> In fact, the argument that "an array ref" is the same as a "function call"
> is true for mathematical functions but not Ada ones.  Ada functions can
> have side effects, which is a software engineering deficiency in Ada.

I agree that side effects are best avoided - they definitely mess up this
scheme.  I assume the language designers left them in for the 
very few times when they are justifiable (e.g. next_random_number).
Quite possibly a language design error forced on them by C programmers :-)

At least this syntactic overloading is consistent with other Ada features,
such as private types.  One of the things I love about Ada is being able
to encapsulate the representation of a type or object using a private type.
Again, this doesnt mean the user of the type shouldn't know how it is
implemented.  It means he can confidently change the representation
in one place and easily reason about how that change will affect
the rest of the program (if at all).

--
-------------------------------------------------------------------------
Alex Blakemore             blakemore@software.org          (703) 742-7125
Software Productivity Consortium   2214 Rock Hill Road Herndon, VA  22070
------------------------   Eschew Obfuscation !!! -----------------------

firth@sei.cmu.edu (Robert Firth) (03/01/90)

In article <608@software.software.org> blakemor@software.org (Alex Blakemore) writes:

>I agree that side effects are best avoided - they definitely mess up this
>scheme.  I assume the language designers left them in for the 
>very few times when they are justifiable (e.g. next_random_number).
>Quite possibly a language design error forced on them by C programmers :-)

As I recall, we left them in for the same reason Algol-60 did: it is
impossible to rule out the bad uses without also ruling out the good
ones.  It is the responsibility of the programmer not to employ the
bad uses.

Let me give you a couple of examples that fall within the present
discussion.  You have to implement a mapping of some kind - call
it M.  The user then writes M(I) to apply the mapping to object I
in the domain of M.

Initially, this domain is small and compact, so you implement M
as an array.  During subsequent maintenance, it becomes rather
large, so you implement M as a virtual array, ie an array that is
held on backing store.  M is now a function that - shock! horror!
keeps an internal buffer cache and does some hairy I/O periodically.

This is a side effect that any rule would prohibit.  But it is a
good one: M appears to the user as a pure function; its implementation
is of no consequence and should not be visible to the invoker.  To
force M to be rewritten as a procedure pollutes the use context with
information about the implementation.

As a second example, consider a dictionary used by a spelling checker.
There is a function Check(W) that checks whether W is in the dictionary.
Many implementations of this function are adaptive: they use a temporary
cache of some kind that is dynamically reorganised so that words
occurring frequently in the document in question float to the front.
Over a long document, this can substantially speed the checking process.
Again, this is a benign and proper use of side effects within a function.

Robert Firth

mph@lion.inmos.co.uk (Mike Harrison) (03/02/90)

In article <608@software.software.org> blakemor@software.org (Alex Blakemore) writes:

>I agree that side effects are best avoided - they definitely mess up this
>scheme.  I assume the language designers left them in for the 
>very few times when they are justifiable (e.g. next_random_number).
>Quite possibly a language design error forced on them by C programmers :-)
>
Remember that preliminary Ada had procedures, functions *and* 'value-returning
procedures'. 
Functions were not allowed to have side-effects, value-returning procedures
were.

It's all a long time ago but, I talked to several members of the design team 
about this, and if my memory is correct, the problem was that detecting
side-effects in non-trivial functions (written in an imperative langauge) was
impracticable (if not impossible).
So they decided not to include in the language concepts which could not be 
enforced.
The same argument (about side-effects) also led to the removal of the ASSERT
statement.

Mike,


Michael P. Harrison - Software Group - Inmos Ltd. UK.
-----------------------------------------------------------
UK : mph@inmos.co.uk             with STANDARD_DISCLAIMERS;
US : mph@inmos.com               use  STANDARD_DISCLAIMERS;

mph@lion.inmos.co.uk (Mike Harrison) (03/02/90)

In article <6281@bd.sei.cmu.edu> firth@sei.cmu.edu (Robert Firth) writes:

>As a second example, consider a dictionary used by a spelling checker.
>There is a function Check(W) that checks whether W is in the dictionary.
>Many implementations of this function are adaptive: they use a temporary
>cache of some kind that is dynamically reorganised so that words
>occurring frequently in the document in question float to the front.
>Over a long document, this can substantially speed the checking process.
>Again, this is a benign and proper use of side effects within a function.

I question whether this is really a side-effect.
Clearly it is a side-effect at the level of the implementation, in that it
causes a change of state from a call of the function, but if you view the 
function as a mapping from elements of its domain to elements of its range
then there is no observable change at the appropriate level of abstraction.

This is not a disagreement with Robert's point, because the Ada code of the 
function body will clearly cause side-effects.
It is rather an attempt to point out that 'pernicious' side-effects are those
which are visible at the same level of abstraction as the function definition,
rather than its implementation.

The problem is writing a compiler which can recognise the distinction.

Mike,




Michael P. Harrison - Software Group - Inmos Ltd. UK.
-----------------------------------------------------------
UK : mph@inmos.co.uk             with STANDARD_DISCLAIMERS;
US : mph@inmos.com               use  STANDARD_DISCLAIMERS;

simpson@saturn.ind.trw.com (Scott Simpson) (03/03/90)

In article <6281@bd.sei.cmu.edu> firth@sei.cmu.edu (Robert Firth) writes:
>In article <608@software.software.org> blakemor@software.org (Alex Blakemore) writes:
>
>>I agree that side effects are best avoided - they definitely mess up this
>>scheme.  I assume the language designers left them in for the 
>>very few times when they are justifiable (e.g. next_random_number).
>>Quite possibly a language design error forced on them by C programmers :-)
>
>As I recall, we left them in for the same reason Algol-60 did: it is
>impossible to rule out the bad uses without also ruling out the good
>ones.  It is the responsibility of the programmer not to employ the
>bad uses.

Meyer summed this up much more beautifully I think in his book
Object-Oriented Software Construction when he said that side-effects
are harmless when they only affect the *concrete* state and not the
*abstract* state.  This division is important.  See section 7.7.3, page
135 of OOSC.
Scott Simpson    TRW Information Networks Division    simpson@trwind.trw.com

sommar@enea.se (Erland Sommarskog) (03/07/90)

I think the main reason that Ada does not use [] for array
indexing is that symbols like () are far easier to read
than using letters like C does. Of course Ada could have
used something like (..) as Pascal permit, but it feels
clumsy. And the flexibility aspect of being able to switch
between an array and a function is not to be disregarded.
-- 
Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se

jbg@sei.cmu.edu (John Goodenough) (03/08/90)

In article Re: Ada functions versus arrays (i.e. () vs [] ) of 6 Mar 90
19:13:21 GMT sommar@enea.se (Erland Sommarskog) writes:

>I think the main reason that Ada does not use [] for array
>indexing is that symbols like () are far easier to read
>than using letters like C does. Of course Ada could have
>used something like (..) as Pascal permit, but it feels
>clumsy. And the flexibility aspect of being able to switch
>between an array and a function is not to be disregarded.

All these are plausible reasons, but the real reason is appallingly mundane --
the requirements specification for Ada directed that all Ada programs be
representable in a small character set, the basic_characters, and this
character set does not include [ and ].  (Although the possible use of
brackets was discussed at at least one design review meeting, given the
character set requirement, the possibility was dismissed almost immediately.)


-- 
John B. Goodenough					Goodenough@sei.cmu.edu
Software Engineering Institute				412-268-6391