From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Subject: Re: C++ already *has* nested functions SO WHAT'S THE BEEF?
Keywords: nested functions, dumb ideas
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Date: Wed, 23 Dec 1992 16:57:19 GMT

In article <1992Dec21.080952.15309@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>
>The example below clearly shows that this is an entirely viable way to
>achieve nested functions with C++ (as now defined).  

>goes to great lengths to demonstrate that references to named entities
>declared locally within the function containing the "nested" function
>are possible (and legal) with a few minor exceptions, as long as the
>references in question obey the normal name scoping rules.

	The principal purpose of nested functions is to
access local (auto) data in the containing scope, and thats one of the
exceptions you list.

	Futhermore, I want to nest functions inside MEMBERS,
so these functions get access to the 'this' pointer and the
objects other members (with the same privileges as the containing
member), which implies the function cant be static.

>The problems with this technique are basically as follows:
>
>	o	We have to "invent" an otherwise useless and unnecessary
>		containing struct, union, or class type in order to be
>		able to nest functions.

	I'd live with that.
>
>	o	Due to the (silly?) prohibition against defining a function
>		member of a block-local struct, union, or class type outside
>		of (and after) its "parent" type, and due to the (silly?)
>		rule that says that all functions defined *within* a class
>		are implicitly `inline', our nested functions are always
>		necessarily `inline' (when using this technique for nesting)
>		even if we do not want them to be.

	Irrelevant, dont care, as long as I can still take its address.

>
>	o	Last but not least, although nested functions can legally
>		reference *most* names of *most* kinds of things declared
>		in a containing scope (including one local to a containing
>		function) there is one small and mildly annoying exception
>		to this general rule... i.e. we cannot access `auto' and
>		`register' *objects* declared within a containing local
>		scope.  

	This the whole purpose of nested functions. It is not a minor
and mildly annoying exception.

>
>I believe that it is this last item that concerns people the most.  In
>fact, I get the general impression that some people view these minor
>exceptions (to the general scoping rules) as being horrendous problems
>which are so utterly insurmountable that dramatic language changes are
>required in order to eliminate these exceptions.

	Indeed this is the problem that concerns me most with your
technique. No dramatic language change is required, its basically
the removal of a restriction resulting in a *simplification*
of the language syntactically.

	Its been done by GNU. 
>
>It would not concern me if the kinds of changes being suggested were
>(in general) trivial for implementors to implement, but when I hear about
>all of these complicated schemes for supporting dynamic "up-level addressing"
>and also such things as "special" kinds of function pointers for holding
>pointers to nested function (and a special new syntax for declaring such
>things) I shrink back in horror.  

	Why are you scared of one of the few things in computer
science that is totally and comletely understood, and that is
routinely taught to second year CS students? It is so established
that both the 386 and 68000 have hardware to support this
mechanism.

>Haven't the implementors already got
>enough to do??  Can't people figure out how to simply pass any needed
>`auto' variables which are local to the containing function as additional
>actual argument to the nested (called) function on those very rare occasions
>when this is actually necessary??  I mean what the devil is the problem here?

	If you keep adding new variables, and have several
pretend nested functions with parameters,  you have in effect
to duplicate the entire set for each function. Apart from
the horrid maintenance problem, its also extremely
inefficient.
>
>So why do people insist on attacking (and defeating) the third minor
>problem listed above (regardless of costs)?

	Because accessing auto variables is exactly the reason
why we want nested functions. I hadn't even *thought* of 
accessing anything else, never occured to me that I could
already access a local class name, because I dont care about
that if I cant access the local variables.

>
>Well, it appears that some people have this mental model of "nested
>functions" left over from the days when they programmed in Pascal, where
>*anything* in a containing scope could be accessed directly.  

	In my case, yes. I liked that ability very much.
Every block structured language should support it. It can
be overused, like anything else.

>Sadly, these
>folks don't seem to "get" the fundamental idea which made C into the big
>success that it is today... i.e. that it is *good* when potentially
>expensive run-time actions (e.g. indirection through some number of
>"static link" pointers) are made *explicit* to the programmer so that he
>or she will be more aware of the potential effects these things may have
>upon run-time performance.

	I dont agree that the language should force the user to
type letters in proportion to the execution time of the program
to remind them how slow its going to be.

	And you are completely wrong about the expense of accessing
variables, on the 386 for example the outer scopes at ANY level
can be accessed with exactly one extra indirection.
The technique is called a 'display'. The algorithm for maintaining
the display is trivial and implemented on the 386 and by
hardware. It can be done almost as easily with software.
What is horribly inefficient is passing lots of parameters
needlessly.

>
>Obviously, I have a strong disagreement with the folks who would (for the
>sake of eliminating a very minor restriction which only makes a difference
>in rare cases anyway) "hack" the language mercilessly (and thereby cause
>yet another headache for implementors).

	Why is eliminating the restriction against nested functions
a hack? You can nest everything else, why not functions?
>
>I mean c'mon folks... This endless "featurism" has got to stop somewhere!

	Agreed. Lets get rid of the feature that specifically
prohibits nested functions. We already have nested blocks,
and a nested function is just a named nested block
with parameters.

	A language that supports stuff as complicated as pointers
to members, multiple inheriance with virtual and nonvirtual bases,
virtual functions, nested classes etc etc should have no 
problems supporting something as simple as nested functions.
Compared to the problems of the type system, nested functions
just aren't that hard.

It has been done by GNU,
it can be done easily, 
it can be highly efficient,
it requires almost no new syntax, 
it is quite useful,
it simplifies the language by removing a restriction,
it is within the spirit of C to provide facilities that
  match the underlying hardware, 
  and most CISC machines have this hardware,
it can be implemented without hardware support on other machines,
it breaks no existing code,
it doesnt cost you anything if you dont use it.

If this were a MAJOR extension to the language (like exceptions)
I would agree it wouldn't be useful enough to add, but that
isnt the case.

Small conveniences are just the things programmers are usually
most grateful for. (Anyone for switch .. case 'a','d'..'f':  :=)
Remember the language is for programmers to use, the vendors
and committee's convenience is not so important as the standard
for the world most popular language, which we're going to get stuck
with for the next 20 years :-).

-- 
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
	Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
Newsgroups: comp.std.c++