www.digitalmars.com         C & C++   DMDScript  

D - function calling, nested function

reply K Sergey <K_member pathlink.com> writes:
I have the question. And I wand to ask it. The question is why?
Why for class members exist reserved word this, but no reserved word 
for function like result,return_address=caller,and
input_parameters=params=locals;

Sample of C++ code 
type classname::operator + (const type& lv,const type& rv)
{
type res;
for(int i=....) res[i]=lv[i]+rv[i];
return res;
}
Any C++ compiler create local variable for result and do some calculation. 
Then after it copy result to memory pointed by pointer obtain from caller 
(for example esi) Why we need extra operation per ordinary addition.
If where was a reserved word for result we will write:
type classname::operator + (const type& lv,const type& rv)
{
for(int i=....) result[i]=lv[i]+rv[i];
return result;
//or simply { return; }
}
and statment return should work like:
return;      => return result;
return expr; => { result=expr; return result; }
I think this could help increase overall performance for example of simple
vector,matrix... library.

----------------

C & C++ language has no nested function. This problem was solving using 
define and local structures. This breaks the main rule: THE SIMPLE THINGS
MUST BE SIMPLE. I think D language must have nested function. I assume that
there is no simple solution basing on C++ semantic. But I am sure should be
reserved word like locals and arguments should be declarated simular to 
structure definition
int L1(int a,b,c;flt q,w,e) 
int L1::L2(int z) // look's like sh..t
{
L1::result++;// access result of L1
result=z-a*b;
}
{
int s=L2(b+c); 

void L1::L3(int z) // crazy way
{
result=z-s;
}

return L3(s)*L2(b-c);
}

Another way is to declarate functions tag. Because function may have
same name, but different body. 
localsdef type func(params) { body(); } tag;
type tag::name(...) { ... }

or as a tag we may use local label name:
void a(flt f,complex& c,quaternion& q)
{
int t;  // visible for nested1 
place1:
long z; // invisible for nested1
dosomething1();
nested1();
dosomething2();
nested1();
dosomething3();
}
void local(place1)::nested1(...) { body(); }

Here another problem, passing local variables. We can introduce new
reserved word like 'temporary':
void a(...)
{
int t;temporary int t1,t2,t3,...;
place1:
long  z;
}

All I offer is easy implemented in i386 code.
Oct 16 2002
parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
"K Sergey" <K_member pathlink.com> wrote in message
news:aojocn$2ita$1 digitaldaemon.com...
 I have the question. And I wand to ask it. The question is why?
 Why for class members exist reserved word this, but no reserved word
 for function like result,return_address=caller,and
 input_parameters=params=locals;

 Sample of C++ code
 type classname::operator + (const type& lv,const type& rv)
 {
 type res;
 for(int i=....) res[i]=lv[i]+rv[i];
 return res;
 }
 Any C++ compiler create local variable for result and do some calculation.
 Then after it copy result to memory pointed by pointer obtain from caller
 (for example esi) Why we need extra operation per ordinary addition.
 If where was a reserved word for result we will write:
 type classname::operator + (const type& lv,const type& rv)
 {
 for(int i=....) result[i]=lv[i]+rv[i];
 return result;
 //or simply { return; }
 }
 and statment return should work like:
 return;      => return result;
 return expr; => { result=expr; return result; }
 I think this could help increase overall performance for example of simple
 vector,matrix... library.

That's not a bad idea, to have result be automatically declared so that it knows where to put it; as opposed to a temporary that you then return which the compiler has to know it's going to be returned in order to know where to allocate it more efficiently, but it could do that more easily if we just were explicit and formalized about our result, in order to be compliant the compiler would have to understand exactly which thing was the result and there'd never need to be an extra copy. In fact the result is just another word for an "out" parameter. Sometimes compilers would return out parameters by register. I like this idea. Personally I'd rather the functions took tuples as parameter lists and return values and was consistent about it. But that would still mesh with your idea, to give the result a formal name. I guess Walter's way is to have you to name all your parameters, whether they're results or out or inout. The result is just another out parameter. Dunno if an anonymous result even makes sense, maybe you should always be forced to name it even if you just choose the name result. The trick is that you don't want the caller to have to explicitly declare a variable to pass in as a parameter to receive the result, in some cases. I was thinking recently that a result could be assigned to a temporary variable by name only and it'd automatically receive the type of "anonymous struct containing all function results, or a single value" but you'd have to provide the name (couldn't use "result" keyword or could you? You could if you had result always refer to the result of the most recently executed function (prior to the current statement probably). If you used label syntax to refer to the result, would that work? int min,max minmax(int[] list) { max = -MAXINT - 1; min = MAXINT; for (i in list) { if (list[i] < min) min = list[i]; else if (list[i] > max) max = list[i]; } } { mm_result : minmax(list); printf("min=%d, max=%d", mm_result.min, mm_result.max); }
 C & C++ language has no nested function. This problem was solving using
 define and local structures. This breaks the main rule: THE SIMPLE THINGS
 MUST BE SIMPLE. I think D language must have nested function. I assume

 there is no simple solution basing on C++ semantic. But I am sure should

 reserved word like locals and arguments should be declarated simular to
 structure definition
 int L1(int a,b,c;flt q,w,e)
 int L1::L2(int z) // look's like sh..t
 {
 L1::result++;// access result of L1
 result=z-a*b;
 }
 {
 int s=L2(b+c);

 void L1::L3(int z) // crazy way
 {
 result=z-s;
 }

 return L3(s)*L2(b-c);
 }

PLEASE! Use some indenting! :) But I have often wished for local functions in C++.
 Another way is to declarate functions tag. Because function may have
 same name, but different body.
 localsdef type func(params) { body(); } tag;
 type tag::name(...) { ... }

 or as a tag we may use local label name:
 void a(flt f,complex& c,quaternion& q)
 {
 int t;  // visible for nested1
 place1:
 long z; // invisible for nested1
 dosomething1();
 nested1();
 dosomething2();
 nested1();
 dosomething3();
 }
 void local(place1)::nested1(...) { body(); }

That's kinda cool. But why not just put the function at the point of scope visibility? I don't really get it.
 Here another problem, passing local variables. We can introduce new
 reserved word like 'temporary':
 void a(...)
 {
 int t;temporary int t1,t2,t3,...;
 place1:
 long  z;
 }

 All I offer is easy implemented in i386 code.

Wouldn't temporary imply raii semantics? It would say maybe that nobody can keep this long term, and it could be incompatible with the "I take control over the parameter" keyword, "adopt". Calling a function with a "adopt" parameter allows one to store a reference to it, and thereafter the other storage object owns the parameter. In fact the routine must store the adopted parameter somewhere nonlocal or delete it. Explicit memory management. Explicit ownership control. In fact I think C++ already has this "temporary" keyword; it's called "auto". ;) But adopt sounds like a good keyword. Sean
Oct 17 2002
parent "Walter" <walter digitalmars.com> writes:
"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:aolo4k$1ld8$1 digitaldaemon.com...
 That's not a bad idea, to have result be automatically declared so that it
 knows where to put it; as opposed to a temporary that you then return

 the compiler has to know it's going to be returned in order to know where

 allocate it more efficiently, but it could do that more easily if we just
 were explicit and formalized about our result, in order to be compliant

 compiler would have to understand exactly which thing was the result and
 there'd never need to be an extra copy.  In fact the result is just

 word for an "out" parameter.  Sometimes compilers would return out
 parameters by register.

More advance compilers do this optimization automatically, it's called "named return value optimization". I think Zortech C++ was the first to do it <g>.
Oct 21 2002