[comp.std.c++] foo

krste@ICSI.Berkeley.EDU ( Krste Asanovic) (08/03/90)

Suggestion: If a function can be called with no arguments, then it
should be possible to call it without using the superfluous empty
parenthesis. E.g.

class A
{ public:
    A(int i = 0) { val = i; };
    int value() { return val; };
  private:
    int val;
};

main()
{
    A a;
    int b;

    b = a.value;
    b = a.value(); // Still legal of course.
}

It would appear that this would be a fairly minor change. It is
illegal to declare a variable and function with the same name in the
same scope, so there should be no ambiguity (or am I missing something
subtle in the parser?). This allows the user to ignore whether a data
member like object is implemented as a data member or as a member
function.  It also saves a lot of ugly parens in code such as:

foo.bar().far().boo()  = foo2.bar3().far4().boo5()

which might be written as

foo.bar.far.boo = foo2.bar3.far4.boo5

Something similar already occurs in constructors, e.g. the definition
of "a" in main above.





    

    

eapu034@orion.oac.uci.edu (Carl F. Edman) (08/03/90)

In article <26717@pasteur.Berkeley.EDU> krste@ICSI.Berkeley.EDU ( Krste Asanovic) writes:
>Suggestion: If a function can be called with no arguments, then it
>should be possible to call it without using the superfluous empty
>parenthesis. E.g.
>
>class A
>{ public:
>    A(int i = 0) { val = i; };
>    int value() { return val; };
>  private:
>    int val;
>};
>
>main()
>{
>    A a;
>    int b;
>
>    b = a.value;
>    b = a.value(); // Still legal of course.
>}
>
>It would appear that this would be a fairly minor change. It is
>illegal to declare a variable and function with the same name in the
>same scope, so there should be no ambiguity (or am I missing something
>subtle in the parser?). This allows the user to ignore whether a data
>member like object is implemented as a data member or as a member
>function.  It also saves a lot of ugly parens in code such as:
>
>foo.bar().far().boo()  = foo2.bar3().far4().boo5()
>
>which might be written as
>
>foo.bar.far.boo = foo2.bar3.far4.boo5
>
>Something similar already occurs in constructors, e.g. the definition
>of "a" in main above.
>
A nice idea which I,too, have thought about before. It would f.e. let
you define a second complex type in which the internal representation
is in polar, not in cartesian coordinates. If you then decide that
some comples variables in your program are almost exclusively multiplied
and thus a polar representation would be more efficient, all you need
to do is to change the declaration of the variable.
Unfortunately, I do not think that this idea will ever be implemented,
as foo.bar , where bar is a member function, already has a meaning.
It denotes a pointer to the member function. Any programm which
uses this (possibly not many) would break, if your suggestion were
realized.

	Carl Edman

Theorectial Physicist,N.:A physicist whose   | Send mail
existence is postulated, to make the numbers |  to
balance but who is never actually observed   | cedman@golem.ps.uci.edu
in the laboratory.                           | eapu034@orion.oac.uci.edu

ark@alice.UUCP (Andrew Koenig) (08/03/90)

In article <26717@pasteur.Berkeley.EDU>, krste@ICSI.Berkeley.EDU ( Krste Asanovic) writes:

> Suggestion: If a function can be called with no arguments, then it
> should be possible to call it without using the superfluous empty
> parenthesis.

C++ inherits from C the notion that the unadorned name of a function
can be quietly converted to the address of that function.  Allowing
your suggestion would therefore introduce ambiguities.  For example:

	void f(int);
	void f(int (*)());

	int g();

	main()
	{
		f(g);		// what does this do?
	}

As C++ stands now, g can only be interpreted as a pointer to a function
returning int with no arguments.  Under your suggestion, it would
be permitted to call g() as well, thus introducing an amgibuity.
-- 
				--Andrew Koenig
				  ark@europa.att.com

scott@bbxsda.UUCP (Scott Amspoker) (08/03/90)

In article <26717@pasteur.Berkeley.EDU> krste@ICSI.Berkeley.EDU ( Krste Asanovic) writes:
>Suggestion: If a function can be called with no arguments, then it
>should be possible to call it without using the superfluous empty
>parenthesis. E.g.
>
>[some of example deleted]
>
>    b = a.value;
>    b = a.value(); // Still legal of course.
>
>It would appear that this would be a fairly minor change. It is
>illegal to declare a variable and function with the same name in the
>same scope, so there should be no ambiguity (or am I missing something
>subtle in the parser?). This allows the user to ignore whether a data
>member like object is implemented as a data member or as a member
>function.  It also saves a lot of ugly parens in code such as:

I believe Objective C allows this as does Pascal.  It is a nice
feature but I don't see it as a minor change.  How does one take
the address of a function?
 
       function_pointer = &funcname

Some parsing methods could easily choke on this.  Is *is* consistent
with the notion of "hiding" implementation details of an object
class from the programmer (who should not need to know whether a
particular member is data or a function).

-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232
unmvax.cs.unm.edu!bbx!bbxsda!scott

mcgrath@paris.Berkeley.EDU (Roland McGrath) (08/04/90)

If the reason people want the expression "foo" to mean "foo()" (which I think
is a bad idea, since "foo" already means "&foo"), is to make it possible to
hide whether something is a member or a method, why not instead implicitly
define functions for members?

For example,

class foo
  {
    public:
    int member;
  };

would be equivalent to:

class foo
  {
    public:
    int member;
    int member(void) { return member; }
  };

I don't particularly favor this proposal, but it's better than incompatibly
redefining what a function name by itself means.

My solution to this problem would simply be to have all members private, with
public methods to access them.  This is commonly done in Smalltalk (where it is
the only way to do it, since all instance variables are private).  It is a bit
more code to write (another line per member), but not a lot.
--
	Roland McGrath
	Free Software Foundation, Inc.
roland@ai.mit.edu, uunet!ai.mit.edu!roland

hg@tsisj1.UUCP (Heinrich Gantenbein) (08/04/90)

In article <26717@pasteur.Berkeley.EDU> krste@ICSI.Berkeley.EDU ( Krste Asanovic) writes:
>Suggestion: If a function can be called with no arguments, then it
>should be possible to call it without using the superfluous empty
>parenthesis. E.g.

>    b = a.value;
>    b = a.value(); // Still legal of course.

This one of the nice features (my opinion) of C over Pascal. It
makes it very clear at each point if it is a function call or a
reference to a variable.

I think this should be kept exactly as is.
--
Heinrich Gantenbein, Software Consultant:   I'd rather be sailing.
hg@tsisj1.uucp
..!apple!ditka!tsisj1!hg  ...!mips!daver!ditka!hg

rfg@NCD.COM (Ron Guilmette) (08/04/90)

In article <26717@pasteur.Berkeley.EDU> krste@ICSI.Berkeley.EDU ( Krste Asanovic) writes:
>Suggestion: If a function can be called with no arguments, then it
>should be possible to call it without using the superfluous empty
>parenthesis.

The parens which follow a function designator are definitely *NOT*
superfluous.  If `f' is a function, then:

	x = f;

says to assign the address of f to the variable x, whereas:

	x = f ();

says to call the function whose designator is f and then assign its return
value to the variable x.

>It would appear that this would be a fairly minor change. It is
>illegal to declare a variable and function with the same name in the
>same scope, so there should be no ambiguity (or am I missing something
>subtle in the parser?).

No, but you did miss something which has been a part of the standard
semantics of C and C++ from day one.  (Perhaps you are just learning C.)

>This allows the user to ignore whether a data
>member like object is implemented as a data member or as a member
>function.

The people who developed Ada had this same idea, and it did in fact wind
up in standard Ada.  In Ada, if F is a function, and you say:

	X := F;

The function gets called.  They (the people who developed Ada) though that
this was a swell feature because now users could switch back and forth
between F being a variable and F being a (zero-argument) function without
changing all the code that makes use of F.  Likewise, this was their excuse
(oh... sorry... I meant "rationale" :-) for having the same kind of
delimiters for either argument lists or subscript lists.  In Ada:

	NUM_NUTS (37)

could be either a function call or a array element reference (or even some
other things that you don't want to know about).  Thus, you could "change
implementation" from an array to a function without changing any of the
points at which NUM_NUTS was used... or at least that was how the theory
was stated back in the early days of Ada.

Of course this theoretical mumbo-jumbo introduced by Ada is all nonsense, and
fails to take into account the long-understood value of redundancy in
languages.  Adding explicit (and strictly-speaking "unnecessary") redundancy
into a language can make it easier to implement and easier to read.  For
instance, if I am reading some Ada code, and I see:

	X := Y;

I haven't a clue what Y is,  whereas in C or C++, if I see:

	x = y;

I at least know that y is either some kind of a data object (either a variable
or a constant) or perhaps (rarely) it is the name of a function, which gets
implicitly converted into a (pointer-to-function) data value according to
the rules of the language.  This fact makes C and C++ code easier to read
than Ada code.

Let's keep it that way.

P.S.  For historians, I should note that there have been those who have charged
that Ada *actually* avoided using [] for subscripting because of the political
clout of some of the really big players of those times (e.g. IBM, CDC, and
Honeywell) whose individual "standard" character sets didn't include things
like [].  The fact that politics was beating out reason in the design of
Ada (it has been claimed) then needed to be covered up.  That's when this
cockamaimy theory about easily changing implementations arose.

Disclaimer: The above rumors & inuendos do not reflect the views of NCD, it's
management, employees, customers, accountants, lawyers, or even me.  As a
matter of fact, I didn't even write this.

needed to be 
-- 
// Ron Guilmette
// C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.

krste@ICSI.Berkeley.EDU ( Krste Asanovic) (08/08/90)

As the originator of the suggestion, I thought I ought to wrap up this
discussion.

Interestingly, people were divided over whether the idea was desirable
in the first place. My suggestion was prompted by a desire for

1) Better implementation hiding. You shouldn't care whether foo is a
   public data member or a function.

2) Neater code. Empty().parentheses().are().often().unwanted().litter() .

Thanks to everybody who pointed out that a.foo, where foo is a member
function, already has a meaning (address of foo). Most people
(including me now) agree that this would be too great a change to make
to C++/C, so unless someone can spot a neat way of adding this I guess
we should drop the subject from the group.