| Thread overview | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 13 Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
![]() | It's generally been agreed on in the past that {} without () in lambdas causes ambiguity with block statements.
These are the simpler cases where it could be a problem. But I recently thought of lazy, and how expression-statements are coerced to delegates under the hood, but what if you wanted to pass a block statement to a function that takes lazy? Anyway, I'd rather not have to juggle these questions in my mind, and a simple solution would be to deprecate function literals that omit the parentheses for the parameter list. Having to type an extra 2 characters is well worth not having to think about the edge cases. Thank you | |||
June 13 Re: Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
Nick Treleaven ![]() Posted in reply to ABrightLight | On Saturday, 13 June 2026 at 00:05:38 UTC, ABrightLight wrote: > It's generally been agreed on in the past that {} without () in lambdas causes ambiguity with block statements. Function literals have their attributes inferred unless one initializes a declaration and the type is specified. > See https://github.com/dlang/dmd/issues/18021. > These are the simpler cases where it could be a problem. But I recently thought of lazy, and how expression-statements are coerced to delegates under the hood, but what if you wanted to pass a block statement to a function that takes lazy? Do you mean an expression is coerced to a delegate? And passing a nullary function literal? That doesn't seem to work well due to likely inferred attribute mismatch, regardless of literal syntax:
> Anyway, I'd rather not have to juggle these questions in my mind, and a simple solution would be to deprecate function literals that omit the parentheses for the parameter list. Having to type an extra 2 characters is well worth not having to think about the edge cases. I agree in theory. I don't know how much code it would break (e.g. when upgrading edition). | |||
June 13 Re: Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
Nick Treleaven ![]() Posted in reply to Nick Treleaven | On Saturday, 13 June 2026 at 16:25:15 UTC, Nick Treleaven wrote: > On Saturday, 13 June 2026 at 00:05:38 UTC, ABrightLight wrote: >These are the simpler cases where it could be a problem. But I recently thought of lazy, and how expression-statements are coerced to delegates under the hood, but what if you wanted to pass a block statement to a function that takes lazy? Do you mean an expression is coerced to a delegate? And passing a nullary function literal? That doesn't seem to work well due to likely inferred attribute mismatch, regardless of literal syntax: Sorry, it does work actually:
| |||
June 14 Re: Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
ABrightLight ![]() Posted in reply to Nick Treleaven | On Saturday, 13 June 2026 at 16:28:13 UTC, Nick Treleaven wrote: > On Saturday, 13 June 2026 at 16:25:15 UTC, Nick Treleaven wrote: >On Saturday, 13 June 2026 at 00:05:38 UTC, ABrightLight wrote: >These are the simpler cases where it could be a problem. But I recently thought of lazy, and how expression-statements are coerced to delegates under the hood, but what if you wanted to pass a block statement to a function that takes lazy? Do you mean an expression is coerced to a delegate? And passing a nullary function literal? That doesn't seem to work well due to likely inferred attribute mismatch, regardless of literal syntax: Sorry, it does work actually: The issue with lazy in such examples is that normally expressions get coerced to a delegate that then returns the results of evaluating those expressions. But if you pass function pointers or delegates to lazy, there is ambiguity.
However I agree with you that inference is also a problem here. | |||
June 14 Re: Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
Nick Treleaven ![]() Posted in reply to ABrightLight | On Sunday, 14 June 2026 at 05:07:58 UTC, ABrightLight wrote: > On Saturday, 13 June 2026 at 16:28:13 UTC, Nick Treleaven wrote: >Sorry, it does work actually:
The issue with lazy in such examples is that normally expressions get coerced to a delegate that then returns the results of evaluating those expressions. But if you pass function pointers or delegates to lazy, there is ambiguity. The parameter type is void, whereas you are passing an argument of type Anyway I thought your original point was about a lazy parameter being passed a >
However I agree with you that inference is also a problem here. Another way to avoid that is by using | |||
June 14 Re: Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
Nick Treleaven ![]() Posted in reply to Nick Treleaven | On Sunday, 14 June 2026 at 15:28:30 UTC, Nick Treleaven wrote: > On Sunday, 14 June 2026 at 05:07:58 UTC, ABrightLight wrote: >The issue with lazy in such examples is that normally expressions get coerced to a delegate that then returns the results of evaluating those expressions. But if you pass function pointers or delegates to lazy, there is ambiguity. OK. It really would be clearer if lazy parameters always had to be explicitly called. Otherwise a lazy parameter can be evaluated more than once accidentally in the function. | |||
June 15 Re: Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
Dukc ![]() Posted in reply to ABrightLight | On Saturday, 13 June 2026 at 00:05:38 UTC, ABrightLight wrote: > It's generally been agreed on in the past that {} without () in lambdas causes ambiguity with block statements. Let's take an example
What is this? Either it's a function literal that is not used anyhow, or a block statement followed by an empty statement (the semicolon). The language disallows the first interpretation, as you'd have to use the value of the function literal somehow, meaning the second interpretation is right. If you meant a function literal, you should use it somehow - call it or assign it to something. While there's no technical ambiguity, the line between the meanings is thinner than I would like. Maybe we could disallow | |||
July 21 Re: Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
Anton Pastukhov ![]() Posted in reply to Dukc | On Monday, 15 June 2026 at 11:00:05 UTC, Dukc wrote: > On Saturday, 13 June 2026 at 00:05:38 UTC, ABrightLight wrote: >[...] Let's take an example
What is this? Either it's a function literal that is not used anyhow, or a block statement followed by an empty statement (the semicolon). The language disallows the first interpretation, as you'd have to use the value of the function literal somehow, meaning the second interpretation is right. If you meant a function literal, you should use it somehow - call it or assign it to something. While there's no technical ambiguity, the line between the meanings is thinner than I would like. Maybe we could disallow This is a good point. D is too lenient with brackets omission, in this particular case and others. I was bitten by this more than once. | |||
4 days ago Re: Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
Quirin Schroll ![]() Posted in reply to Nick Treleaven | On Saturday, 13 June 2026 at 16:25:15 UTC, Nick Treleaven wrote: > On Saturday, 13 June 2026 at 00:05:38 UTC, ABrightLight wrote: >It's generally been agreed on in the past that {} without () in lambdas causes ambiguity with block statements.
Function literals have their attributes inferred unless one initializes a declaration and the type is specified. The issue isn't attributes ( The issue with this code and D is that lambdas can become two similar yet incompatible things when neither One mitigation would be to allow in implicit conversion from a function pointer to a delegate. One can do that manually, but it requires repeating the function arguments. It's particularly bad because a lambda function argument behaves differently enough so that it often can't be extracted into a variable. (The variable gets typed as a function pointer, which I already said is incompatible.) Lambdas without captures are in some Schrödinger-style superposition where they can become function pointers or delegates, whatever is needed. If no choice is made, they become function pointers, probably because they use one less pointer and can be optimized more aggressively. This is similar to array literals which know their size when used immediately: A template can infer a The biggest difference is that array literal become the type with the lower amount of information. Now that | |||
2 days ago Re: Deprecate lambdas that omit parentheses in empty parameter lists | ||||
|---|---|---|---|---|
| ||||
Nick Treleaven ![]() Posted in reply to Quirin Schroll | On Wednesday, 23 September 2026 at 15:15:58 UTC, Quirin Schroll wrote: > On Saturday, 13 June 2026 at 16:25:15 UTC, Nick Treleaven wrote: >On Saturday, 13 June 2026 at 00:05:38 UTC, ABrightLight wrote: >It's generally been agreed on in the past that {} without () in lambdas causes ambiguity with block statements.
Function literals have their attributes inferred unless one initializes a declaration and the type is specified. The issue isn't attributes ( Yes, I clearly wasn't thinking when I wrote that, sorry. > A lambda is inferred to become a function pointer if it doesn't capture anything. You can force it to become a delegate type by spelling it out: The issue with this code and D is that lambdas can become two similar yet incompatible things when neither One mitigation would be to allow in implicit conversion from a function pointer to a delegate. This discussion says the calling convention is different: > Now that That's why I argued for syntax for a static array literal instead of complicating declaration syntax. | |||
Permalink
Reply



