comp.lang.ada
 help / color / mirror / Atom feed
* Function call or variable?
@ 1993-03-05 23:31 Thomas Huynh
  1993-03-07 20:27 ` Alex Blakemore
  0 siblings, 1 reply; 7+ messages in thread
From: Thomas Huynh @ 1993-03-05 23:31 UTC (permalink / raw)


Given that the following lines are the only code in the
module, how can one determine if the identifier "func_or_var"
is a function call or variable?  Is it possible
to come any conclusion at all?  Assume that the identifier
"func_or_var" is defined in another module.

-- File starts here
with This_System;
use This_System;

procedure Validate(a, b : in out integer) is
begin
  if (func_or_var)
    a := b;
  end if;
end Validate;
-- End of file



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

* Re: Function call or variable?
  1993-03-05 23:31 Function call or variable? Thomas Huynh
@ 1993-03-07 20:27 ` Alex Blakemore
  1993-03-08  0:34   ` David Emery
  1993-03-13  0:39   ` Adam Beneschan
  0 siblings, 2 replies; 7+ messages in thread
From: Alex Blakemore @ 1993-03-07 20:27 UTC (permalink / raw)


In article <9303051531.aa21226@Paris.ics.uci.edu> lhuynh@siam.ICS.UCI.EDU (Thomas Huynh) writes:
> how can one determine if the identifier "func_or_var"
> is a function call or variable?
>   if (func_or_var) [then]

you cant tell by looking at the reference, but have to look at the definition.
that is IMHO a _very_ good thing.

it means that the implementation can change between parameterless function and
constant and variable and client code need not be modified.
similarly, you can change between a function and an array without changing
client code.  the semantics are the same, just the implementation has changed.

this doesnt mean that you shouldnt care about how something is implemented, but
that you should only record that design decision in one place instead of
propogating the info throughout the code.

the same principle that makes private types so useful.

if not convinced, consider this scenario, you have a constant or variable referenced
throughout your code - and as time goes on, the code to keep it set
correctly gets more and more complex and needs to be invoked from more
and more places.  In Ada, you can replace the variable with a function safely.
Code that only references the variable need not change at all.
in C, you would have to modify every caller.

this syntactic ambiguity allows better information hiding of implementation details.
the compiler needs to know the details, but the caller doesnt.
overloading is another example of a useful apparent ambiguity,
which the compiler resolves based on complete information from the definition.

for this reason, I really object to coding styles which try to distinguish
syntactically those things that the language intentionally does not.
such as using a space or not before left parens to tell distinguish
function calls from array references.  thats a bad idea.

-- 
---------------------------------------------------
Alex Blakemore alex@cs.umd.edu   NeXT mail accepted



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

* Re: Function call or variable?
  1993-03-07 20:27 ` Alex Blakemore
@ 1993-03-08  0:34   ` David Emery
  1993-03-13  0:39   ` Adam Beneschan
  1 sibling, 0 replies; 7+ messages in thread
From: David Emery @ 1993-03-08  0:34 UTC (permalink / raw)


You can always assign _to_ the variable.  More importantly, you cannot
tell the difference between a function and a *constant*.  After all,
the semantics of enumeration literals (for instance) is that they are
parameterless functions that return a value of the enumeration type.
				dave




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

* Re: Function call or variable?
  1993-03-07 20:27 ` Alex Blakemore
  1993-03-08  0:34   ` David Emery
@ 1993-03-13  0:39   ` Adam Beneschan
  1 sibling, 0 replies; 7+ messages in thread
From: Adam Beneschan @ 1993-03-13  0:39 UTC (permalink / raw)


In article <64872@mimsy.umd.edu> alex@cs.umd.edu (Alex Blakemore) writes:

> In article <9303051531.aa21226@Paris.ics.uci.edu> lhuynh@siam.ICS.UCI.EDU 
> (Thomas Huynh) writes:
> > how can one determine if the identifier "func_or_var"
> > is a function call or variable?
> >   if (func_or_var) [then]

> you cant tell by looking at the reference, but have to look at the
> definition.  that is IMHO a _very_ good thing.

> it means that the implementation can change between parameterless
> function and constant and variable and client code need not be
> modified.  similarly, you can change between a function and an array
> without changing client code.  the semantics are the same, just the
> implementation has changed.

The semantics aren't entirely the same---there are important
differences between constants and parameterless functions.  For
example, you can use a constant in a CASE selector, but not a
parameterless function.  There are other contexts in Ada where
constant expressions are required;  in this case, constant may appear
while parameterless functions may not.  The obvious difference between
variables, arrays, and function calls, is that you can put variables
and arrays on the left side of an assignment (or pass them as OUT or
IN OUT parameters).

> this doesnt mean that you shouldnt care about how something is
> implemented, but that you should only record that design decision in
> one place instead of propogating the info throughout the code.

> the same principle that makes private types so useful.

I agree that private types are extremely useful.  The difference here
is that with private types, you can change the definition of the type
any way you want, but the type identifier's class doesn't
change---i.e., the type remains a TYPE---and the rest of the program
won't have to change at all.  Changing from a parameterless function
to and from a constant doesn't have this property---the identifier's
class changes and some of the semantics change with it.

If a package makes a constant value publicly available, but the program
designer anticipates that the program may change later such that the
value won't be a constant any more, I would strongly argue that the
value should be implemented as a parameterless function from the
beginning.  The function's body will be trivial if the value is a
constant, but when the program is modified later, only the function
body needs to be changed.  The package spec won't change at all, and
this is the best way to guarantee that the remainder of the program
will not have to change just because the implementation of this one
value changes.  There won't be any loss of efficiency if you use
PRAGMA INLINE (and your compiler supports it).  This, I think, is the
logical parallel to private types.

> if not convinced, consider this scenario, you have a constant or
> variable referenced throughout your code - and as time goes on, the
> code to keep it set correctly gets more and more complex and needs
> to be invoked from more and more places.  In Ada, you can replace
> the variable with a function safely.  Code that only references the
> variable need not change at all.  in C, you would have to modify
> every caller.

Not necessarily.  You could use #define to ensure that the program is
changed in only one place.  I don't believe I've ever seen any C code
that's designed like this, though.

> [other stuff deleted]

Alex has made some pretty good arguments why parameterless functions
and variables/constants should have the same syntax, and I'm sure
there are good arguments the other way too.  What's a little amusing
about this is that, in my opinion, none of these design arguments were
actually factors in how the language syntax was decided on.  I don't
have any evidence to back this up, but I'm willing to bet that
parameterless procedures are the way they are in Ada because they were
that way in Ada's ancestors, Pascal and Algol.  C's syntax was
probably designed to make it easy for the compiler's parser.

Back in the early 80's, when Ada was in the design process, I remember
reading an article by someone who pointed out the advantages of having
function calls and array references have the same syntax---both use
parentheses, while in other languages array references use square
brackets.  However, this clearly had nothing to do with the real
reason array references use parentheses; the real reason is that
EBCDIC doesn't have square brackets.  This made the article seem like
a lame, after-the-fact rationalization, even though it did make some
valid points.

                                -- Adam



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

* Re: Function call or variable?
@ 1993-03-17 23:58 Robert I. Eachus
  1993-03-23 16:02 ` John English
  0 siblings, 1 reply; 7+ messages in thread
From: Robert I. Eachus @ 1993-03-17 23:58 UTC (permalink / raw)


   Adam Beneschan makes some good points, but a language lawyer like
me has to argue the details...

  > The semantics aren't entirely the same---there are important
  > differences between constants and parameterless functions.  For
  > example, you can use a constant in a CASE selector, but not a
  > parameterless function.  There are other contexts in Ada where
  > constant expressions are required;  in this case, constant may appear
  > while parameterless functions may not.

  Fooled you.  Enumeration and character literals ARE parameterless
functions which can appear as case selectors.  There are also
functions which have the form of an attribute, but they are not
parameterless.  i. e. T'LAST(2).

  > The obvious difference between variables, arrays, and function
  > calls, is that you can put variables and arrays on the left side of
  > an assignment (or pass them as OUT or IN OUT parameters).

  Gotcha again...  A function which returns an access value can appear
on the left hand side of an assignment statement:

   type R is record C: Character; I: Integer; end record;

   type RA is access R;

   V: R; -- a variable of type R.
   function F return RA; -- a function which returns an access value.
   ...
   
   V.I := 3; -- no surprise.
   F.C := 'V'; -- ain't Ada fun?

   The same is true with array types for subscripts and slices.

  > Changing from a parameterless function to and from a constant
  > doesn't have this property---the identifier's class changes and
  > some of the semantics change with it.

    The biggest change, which programmers tend to forget, is that
functions are overloadable, variables are not.  So you can have the
cases where as a result of changing a declaration in one package, a
function in another package is no longer directly visible.

  > If a package makes a constant value publicly available, but the program
  > designer anticipates that the program may change later such that the
  > value won't be a constant any more, I would strongly argue that the
  > value should be implemented as a parameterless function from the
  > beginning.  The function's body will be trivial if the value is a
  > constant, but when the program is modified later, only the function
  > body needs to be changed.  The package spec won't change at all, and
  > this is the best way to guarantee that the remainder of the program
  > will not have to change just because the implementation of this one
  > value changes.  There won't be any loss of efficiency if you use
  > PRAGMA INLINE (and your compiler supports it).  This, I think, is the
  > logical parallel to private types.

  Good idea.  Especially given the gotcha above.

  > Not necessarily.  You could use #define to ensure that the program is
  > changed in only one place.  I don't believe I've ever seen any C code
  > that's designed like this, though.

  No, no, no.  I have seen C code like this, and I have seen people
use #defines to change things.  And I have seen the code compile
cleanly and work in simple cases but break horribly later.  For
example, the code in the #define for example might use a local
variable, and you only get burned if the #define is used in a scope
where there is a variable of the same name.  But the burn occurs at
run time, and in the form of a wrong answer.

  > What's a little amusing about this is that, in my opinion, none of
  > these design arguments were actually factors in how the language
  > syntax was decided on.  I don't have any evidence to back this up,
  > but I'm willing to bet that parameterless procedures are the way
  > they are in Ada because they were that way in Ada's ancestors,
  > Pascal and Algol.  C's syntax was probably designed to make it easy
  > for the compiler's parser.

  You lose!  In Ada 80, parameterless functions did have empty
parentheses. June 80 RM, section 6.5:

  function_call ::=

    _function_name actual_parameter_part | _function_name ()

  This was changed during the ANSI standardization process.  Although
one argument if favor of the change was that the empty parentheses
were ugly, the telling arguments were the unification of the syntax,
and allowing the enumeration literals are function calls simplification.

  > Back in the early 80's, when Ada was in the design process, I remember
  > reading an article by someone who pointed out the advantages of having
  > function calls and array references have the same syntax---both use
  > parentheses, while in other languages array references use square
  > brackets.  However, this clearly had nothing to do with the real
  > reason array references use parentheses; the real reason is that
  > EBCDIC doesn't have square brackets.  This made the article seem like
  > a lame, after-the-fact rationalization, even though it did make some
  > valid points.

  Wrong again.  The allowed characters come from the Steelman
requirements and not from EBCDIC.  (Although they do trace to the IBM
029 card punches.)  If common to EBCDIC and ASCII had been the
requirement, there would have been lots of choices.  But the
justification was NOT a lame after the fact one.  It was a lot of
effort but strongly desired by those who had made exactly that change
in existing code in other programming languages.  (Embedded systems
often make this time/space tradeoff very late in the design process.
The intent in designing Ada was that 1) it not be an expensive change
to make and 2) to the greatest extent possible it should not be
necessary to change the code.  Thus inlining of function calls with
static arguments should be the same as doing the array reference in
place.
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...

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

* Re: Function call or variable?
  1993-03-17 23:58 Robert I. Eachus
@ 1993-03-23 16:02 ` John English
  1993-03-24  2:10   ` Robert I. Eachus
  0 siblings, 1 reply; 7+ messages in thread
From: John English @ 1993-03-23 16:02 UTC (permalink / raw)


eachus@spectre.mitre.org (Robert I. Eachus) writes:
:   > Not necessarily.  You could use #define to ensure that the program is
:   > changed in only one place.  I don't believe I've ever seen any C code
:   > that's designed like this, though.
: 
:   No, no, no.  I have seen C code like this, and I have seen people
: use #defines to change things.  And I have seen the code compile
: cleanly and work in simple cases but break horribly later.

These days any sensible C programmer uses "const", not "#define".
Avoids headaches without aspirin.
-- 
-------------------------------------------------------------------------------
John English                    | "There are basically two types of dicks,
Dept. of Computing              |  hard dicks and floppy dicks."
University of Brighton          |    -- from a student essay on storage media
E-mail: je@unix.brighton.ac.uk  | "Disks are divided into sex & tractors."
Fax:    0273 642405             |    -- from one of my lectures (on a bad day)
-------------------------------------------------------------------------------



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

* Re: Function call or variable?
  1993-03-23 16:02 ` John English
@ 1993-03-24  2:10   ` Robert I. Eachus
  0 siblings, 0 replies; 7+ messages in thread
From: Robert I. Eachus @ 1993-03-24  2:10 UTC (permalink / raw)



   John English by the way he quoted me seems to imply that I was
endorsing #define, when actually we are in violent argeement.  I also
agree that there exist sensible C programmers--not that there are many
of them. :-)

   However, const does come with a different set of potential
problems, it is just a much smaller set.  (The watch it! involves
consts included in different modules, whose values depend on
globals...  There is no guarentee that the const will evaluate the
same in every unit.  Another one of those C "features" where good
library management discipline is essential.)

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...



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

end of thread, other threads:[~1993-03-24  2:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1993-03-05 23:31 Function call or variable? Thomas Huynh
1993-03-07 20:27 ` Alex Blakemore
1993-03-08  0:34   ` David Emery
1993-03-13  0:39   ` Adam Beneschan
  -- strict thread matches above, loose matches on Subject: below --
1993-03-17 23:58 Robert I. Eachus
1993-03-23 16:02 ` John English
1993-03-24  2:10   ` Robert I. Eachus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox