www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Nested function declarations

reply bearophile <bearophileHUGS lycos.com> writes:
This D2 code:

import std.math: sqrt;
void main() {
    double sqrt();
    double result = sqrt(9.0);
}

Generates the errors:
test.d(4): Error: function test.main.sqrt () is not callable using argument
types (double)
test.d(4): Error: expected 0 arguments, not 1 for non-variadic function type
double()

What is the purpose of nested function declarations in D? Is it a good idea to
just disallow them?

Bye and thank you,
bearophile
Jan 27 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
 What is the purpose of nested function declarations in D? Is it a good idea to
just disallow them?
In theory they may be used to define mutually recursive nested functions, like in this example, but in practice this is not allowed: import std.stdio: writeln; void main() { // Hofstadter Female and Male sequences int M(int); int F(int n) { return n ? n - M(F(n - 1)) : 1; } int M(int n) { // test.d(11): Error: declaration M is already defined return n ? n - F(M(n - 1)) : 0; } foreach (i; 0 .. 100) writeln(F(i)); } Bye, bearophile
Jan 27 2011
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Well, you might be linking to an external function /and/ don't want
the function to be visible at module scope:

void main() {
   extern(C) double func();  // linked from some C library..
   double result = func();
}

You don't have to worry too much about your first example, it might
compile but it won't link:

import std.math: sqrt;
void main() {
   double sqrt();
   double result = sqrt();
}

 Error 42: Symbol Undefined _D12externalTest4mainFZv4sqrtMFZd
--- errorlevel 1
Jan 27 2011
prev sibling next sibling parent reply "Akakima" <akakima33 gmail.com> writes:
"bearophile" <bearophileHUGS lycos.com> a écrit dans le message de news: 
iht0ha$2avd$1 digitalmars.com...
 This D2 code:

 import std.math: sqrt;
 void main() {
    double sqrt();
    double result = sqrt(9.0);
 }

 Generates the errors:
 test.d(4): Error: function test.main.sqrt () is not callable using 
 argument types (double)
 test.d(4): Error: expected 0 arguments, not 1 for non-variadic function 
 type double()
--- This one compiles, but does not link: import std.math: sqrt; void main() { double sqrt(double x); double result = sqrt(9.0); } --- And this one compiles and links ok. import std.math: sqrt; void main() { double sqrt(double x) { return 1.0; } double result = sqrt(9.0); } So, with the appropriate prototype it compiles, but there is a conflict with the sqrt() already defined in Phobos.
Jan 27 2011
parent wrzosk <dprogr gmail.com> writes:
On 28.01.2011 03:35, Akakima wrote:
 "bearophile"<bearophileHUGS lycos.com>  a �crit dans le message de news:
 iht0ha$2avd$1 digitalmars.com...
 This D2 code:

 import std.math: sqrt;
 void main() {
     double sqrt();
     double result = sqrt(9.0);
 }

 Generates the errors:
 test.d(4): Error: function test.main.sqrt () is not callable using
 argument types (double)
 test.d(4): Error: expected 0 arguments, not 1 for non-variadic function
 type double()
--- This one compiles, but does not link: import std.math: sqrt; void main() { double sqrt(double x); double result = sqrt(9.0); } --- And this one compiles and links ok. import std.math: sqrt; void main() { double sqrt(double x) { return 1.0; } double result = sqrt(9.0); } So, with the appropriate prototype it compiles, but there is a conflict with the sqrt() already defined in Phobos.
This works: import std.math: sqrt; import std.stdio; void main() { double sqrt(double x) { return 1.0; } double result = .sqrt(9.0); writeln(result); }
Jan 28 2011
prev sibling parent reply Tomek =?ISO-8859-2?Q?Sowi=F1ski?= <just ask.me> writes:
bearophile napisa=B3:

 What is the purpose of nested function declarations in D? Is it a good id=
ea to just disallow them? 1. Helper functions don't clutter the namespace. 2. Nested functions can access the outer function's stack frame. --=20 Tomek
Jan 29 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Tomek S.

 What is the purpose of nested function declarations in D? Is it a good idea to
just disallow them?
1. Helper functions don't clutter the namespace. 2. Nested functions can access the outer function's stack frame.
My question was not about "nested functions" but about "nested (empty) function declarations". Bye, bearophile
Jan 29 2011
prev sibling parent reply Tomek =?ISO-8859-2?Q?Sowi=F1ski?= <just ask.me> writes:
Tomek Sowi=F1ski napisa=B3:

 What is the purpose of nested function declarations in D? Is it a good =
idea to just disallow them? =20
=20
 1. Helper functions don't clutter the namespace.
 2. Nested functions can access the outer function's stack frame.
OK, I just noticed you asked about declarations, not nested functions in ge= neral. They're useful for testing: unittest { int foo(); static assert (is(ReturnType!foo =3D=3D int)); } --=20 Tomek
Jan 29 2011
parent reply dennis luehring <dl.soluz gmx.net> writes:
 They're useful for testing:

 unittest {
 	int foo();
 	static assert (is(ReturnType!foo == int));
 }
and else? is it worth?
Jan 29 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
dennis luehring:

 and else? is it worth?
Andrej has shown me another possible purpose: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=24196 Surely they aren't the most useful feature of D language :-) But my guess is that removing them increases the size of the compiler a bit. I don't know if they are worth, I don't like them much, I guess they don't hurt too much. Bye, bearophile
Jan 29 2011
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Well, I've never used this actually. If I have some external C
functions I either put them in a separate module and then import them
in when necessary, or wrap them in a struct/class. Whether or not
they're of any use in scoped declarations is beyond me. :)
Jan 29 2011
prev sibling parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
dennis luehring <dl.soluz gmx.net> writes:

 They're useful for testing:

 unittest {
 	int foo();
 	static assert (is(ReturnType!foo == int));
 }
and else? is it worth?
Don't class function declarations have the same issue? You can declare but all you'll get is a link error. Unless there some way like C++ to provide a definition elsewhere. class C { int foo(); } void main() { } superarray_error.obj(superarray_error) Error 42: Symbol Undefined _D16superarray_error1C3fooMFZi --- errorlevel 1
Jan 30 2011
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/30/11, Dan Olson <zans.is.for.cans yahoo.com> wrote:
 dennis luehring <dl.soluz gmx.net> writes:

 They're useful for testing:

 unittest {
 	int foo();
 	static assert (is(ReturnType!foo == int));
 }
and else? is it worth?
Don't class function declarations have the same issue? You can declare but all you'll get is a link error. Unless there some way like C++ to provide a definition elsewhere. class C { int foo(); } void main() { }
I think we've forgotten about D header files. (*.di). If a company doesn't want to share the source code but allows static linking to its libraries, providing .di header files is the way to go. The above code would be valid in a .di file AFAIK.
Jan 31 2011