Jump to page: 1 2
Thread overview
Is returning void functions inside void functions a feature or an artifact?
Aug 02, 2021
Rekel
Aug 02, 2021
jfondren
Aug 02, 2021
Rekel
Aug 03, 2021
Patrick Schluter
Aug 02, 2021
H. S. Teoh
Aug 02, 2021
Rekel
Aug 02, 2021
Ali Çehreli
Aug 02, 2021
H. S. Teoh
Aug 03, 2021
user1234
Aug 03, 2021
Rekel
Aug 03, 2021
Paul Backus
August 02, 2021

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.

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.

August 02, 2021

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.

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.

August 02, 2021
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.
August 02, 2021

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! ^^

August 02, 2021
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.
August 02, 2021
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

August 02, 2021
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
August 03, 2021

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:

void main() {
    return cast(void) 1;
}

it's all about the type system and conversions

August 03, 2021

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.

August 03, 2021

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:

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

« First   ‹ Prev
1 2