www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is returning void functions inside void functions a feature or an

reply Rekel <paultjeadriaanse gmail.com> writes:
I recently found one can return function calls to void functions, 
though I don't remember any documentation mentioning this even 
though it doesn't seem trivial.

```d
void print(){
	writeln("0");
}

void doSomething(int a){
	if (a==0)
		return print();
	writeln("1");
}

void main(string[] args) {
	doSomething(0); // Prints 0 but not 1.
}
```

If this is intended, where could I find this in the docs? I 
haven't been able to find previous mentions on this, neither on 
the forum.
Aug 02 2021
next sibling parent reply jfondren <julian.fondren gmail.com> writes:
On Monday, 2 August 2021 at 14:31:45 UTC, Rekel wrote:
 I recently found one can return function calls to void 
 functions, though I don't remember any documentation mentioning 
 this even though it doesn't seem trivial.

 ```d
 void print(){
 	writeln("0");
 }

 void doSomething(int a){
 	if (a==0)
 		return print();
 	writeln("1");
 }

 void main(string[] args) {
 	doSomething(0); // Prints 0 but not 1.
 }
 ```

 If this is intended, where could I find this in the docs? I 
 haven't been able to find previous mentions on this, neither on 
 the forum.
I don't know where you can find this in the docs, but what doesn't seem trivial about it? The type of the expression `print()` is void. That's the type that `doSomething` returns. That's the type of the expression that `doSomething` does return and the type of the expression following a `return` keyword in `doSomething`. Rather than a rule expressly permitting this, I would expect to find to either nothing (it's permitted because it makes sense) or a rule against it (it's expressly forbidden because it has to be to not work, because it makes sense). C, C++, Rust, and Zig are all fine with this. Nim doesn't like it.
Aug 02 2021
next sibling parent Rekel <paultjeadriaanse gmail.com> writes:
On Monday, 2 August 2021 at 14:46:36 UTC, jfondren wrote:
 C, C++, Rust, and Zig are all fine with this. Nim doesn't like 
 it.
I had no clue, never seen it used in any case. I've always assumed one couldn't return void as it's not a value. I guess intuitions aren't always universal 😅. Good to know c is fine with this too! ^^
Aug 02 2021
prev sibling parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Monday, 2 August 2021 at 14:46:36 UTC, jfondren wrote:
 On Monday, 2 August 2021 at 14:31:45 UTC, Rekel wrote:
 [...]
I don't know where you can find this in the docs, but what doesn't seem trivial about it? The type of the expression `print()` is void. That's the type that `doSomething` returns. That's the type of the expression that `doSomething` does return and the type of the expression following a `return` keyword in `doSomething`. Rather than a rule expressly permitting this, I would expect to find to either nothing (it's permitted because it makes sense) or a rule against it (it's expressly forbidden because it has to be to not work, because it makes sense). C, C++, Rust, and Zig are all fine with this. Nim doesn't like it.
Wow. Just discovered that C accepts it. After 35 years of daily use of C, there are still things to discover.
Aug 03 2021
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Aug 02, 2021 at 02:31:45PM +0000, Rekel via Digitalmars-d-learn wrote:
 I recently found one can return function calls to void functions,
 though I don't remember any documentation mentioning this even though
 it doesn't seem trivial.
This is intentional, in order to make it easier to write generic code without always having to special-case functions that don't return anything. E.g.: auto myWrapper(alias func, Args...)(Args args) { // Don't have to special case void return. return func(args); } int hooray(int i) { return i+1; } void boo(int j) { return; } int z = myWrapper!hooray(1); myWrapper!boo(2); Otherwise you'd have to litter your code with redundant special cases: auto myWrapper(alias func, Args...)(Args args) { static if (is(ReturnType!func == void)) func(args); else return func(args); // same thing but different } Allowing `return func(args)` for void functions eliminates the need for such special cases. T -- "640K ought to be enough" -- Bill G. (allegedly), 1984. "The Internet is not a primary goal for PC usage" -- Bill G., 1995. "Linux has no impact on Microsoft's strategy" -- Bill G., 1999.
Aug 02 2021
parent reply Rekel <paultjeadriaanse gmail.com> writes:
On Monday, 2 August 2021 at 14:51:07 UTC, H. S. Teoh wrote:
 This is intentional, in order to make it easier to write 
 generic code without always having to special-case functions 
 that don't return anything.
Ooh that indeed seems useful. Thanks for the hint. Also slightly off topic, but when would one use an alias instead of a function/delegate? I haven't used aliases before.
Aug 02 2021
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 8/2/21 9:42 AM, Rekel wrote:

 when would one use an alias instead of a
 function/delegate? I haven't used aliases before.
alias will match both functions and delegates... and... any symbol at all. So, if you don't have a reason to constain the user, callable template parameters are most usefully aliases. Ali
Aug 02 2021
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Aug 02, 2021 at 04:42:14PM +0000, Rekel via Digitalmars-d-learn wrote:
[...]
 Also slightly off topic, but when would one use an alias instead of a
 function/delegate? I haven't used aliases before.
When you want a compile-time binding that could potentially elide the indirect function call to a delegate. // This generates a specialized template instance with // `callback` bound to the passed-in compile-time argument, for // each call to `myFunc`. auto myFunc(alias callback)(...) { ... } // This is a single common function that receives an opaque // runtime delegate and binds it at runtime. auto myFunc(int delegate(...) callback, ...) { ... } T -- An elephant: A mouse built to government specifications. -- Robert Heinlein
Aug 02 2021
prev sibling parent reply user1234 <user1234 12.de> writes:
On Monday, 2 August 2021 at 14:31:45 UTC, Rekel wrote:
 I recently found one can return function calls to void 
 functions, though I don't remember any documentation mentioning 
 this even though it doesn't seem trivial.

 [...]

 If this is intended, where could I find this in the docs? I 
 haven't been able to find previous mentions on this, neither on 
 the forum.
You got the answer in another reply but here is a bit of more fun: ```d void main() { return cast(void) 1; } ``` it's all about the type system and conversions
Aug 02 2021
parent reply Rekel <paultjeadriaanse gmail.com> writes:
On Tuesday, 3 August 2021 at 00:53:43 UTC, user1234 wrote:
 You got the answer in another reply but here is a bit of more 
 fun:

 ```d
 void main() {
     return cast(void) 1;
 }
 ```
What does casting to void do? Does it just ignore whatever follows it? On Tuesday, 3 August 2021 at 07:23:34 UTC, Patrick Schluter wrote:
 Wow. Just discovered that C accepts it. After 35 years of daily 
 use of C, there are still things to discover.
Hehe, glad to hear I'm not the only one. Feel like making a request to add this to the learning pages now "x3
Aug 03 2021
parent Paul Backus <snarwin gmail.com> writes:
On Tuesday, 3 August 2021 at 10:28:53 UTC, Rekel wrote:
 On Tuesday, 3 August 2021 at 00:53:43 UTC, user1234 wrote:
 You got the answer in another reply but here is a bit of more 
 fun:

 ```d
 void main() {
     return cast(void) 1;
 }
 ```
What does casting to void do? Does it just ignore whatever follows it?
Yes.
Aug 03 2021