Thread overview
Variable declaration primary expression
Jan 20
IchorDev
Jan 20
IchorDev
Jan 21
IchorDev
Jan 20
IchorDev
Jan 21
Andre
Jan 21
IchorDev
January 20

Someone brought up this clever idea here: https://github.com/dlang/dmd/pull/20653#issuecomment-2581474608
What does everyone think about being able to declare variables in expressions? Is there any pre-existing syntax that blocks us from being able to easily do this?

January 21
On 21/01/2025 9:41 AM, IchorDev wrote:
> Someone brought up this clever idea here: https://github.com/dlang/dmd/ pull/20653#issuecomment-2581474608
> What does everyone think about being able to declare variables in expressions? Is there any pre-existing syntax that blocks us from being able to easily do this?

I don't know about syntax, but rewrites do use VarDeclaration in an expression (including CommaExpression).

I'd call this long overdue if it works in syntax.

January 20

On Monday, 20 January 2025 at 20:41:42 UTC, IchorDev wrote:

>

Someone brought up this clever idea here: https://github.com/dlang/dmd/pull/20653#issuecomment-2581474608
What does everyone think about being able to declare variables in expressions? Is there any pre-existing syntax that blocks us from being able to easily do this?

This sounds like a great feature for writing absolutely horrendous code.

Imagine: variables declared in the middle of function calls. Variables declared inside the initialization of other variables.

struct Point
{
    double x = (double y = 0);
}

void main()
{
    import std.stdio;
    readf("%f, %f", (Point p).tupleof);
    writefln("p = (%f, %f)", p.x, p.y);
}

Is this really what we want? If someone submitted code like this to one of your projects, would you accept it?

January 20

On Monday, 20 January 2025 at 21:31:18 UTC, Paul Backus wrote:

>

On Monday, 20 January 2025 at 20:41:42 UTC, IchorDev wrote:

>

Someone brought up this clever idea here: https://github.com/dlang/dmd/pull/20653#issuecomment-2581474608
What does everyone think about being able to declare variables in expressions? Is there any pre-existing syntax that blocks us from being able to easily do this?

This sounds like a great feature for writing absolutely horrendous code.

Imagine: variables declared in the middle of function calls. Variables declared inside the initialization of other variables.

struct Point
{
    double x = (double y = 0);
}

void main()
{
    import std.stdio;
    readf("%f, %f", (Point p).tupleof);
    writefln("p = (%f, %f)", p.x, p.y);
}

Is this really what we want? If someone submitted code like this to one of your projects, would you accept it?

This is just stupid. Read the link I posted. You intentionally using the concept in the dumbest possible way is a completely worthless argument that could be used against almost every aspect of D. Here you go:

void
main
(
string
[]
args
)
{
}

Would you accept this into your projects? No? What if you got a PR with variable names in Hindi? No? What if you got a PR that dereferences uninitialised pointers? No? See it’s not the compiler’s job to force everyone write code in one specific ‘correct’ way. You can misuse every feature of the language. That’s your choice, but you can’t blame others saying ‘you can write stupid code, so the language is faulty’.

Currently, variable declarations in expressions are limited to a few special cases that make them feel really backhanded and arbitrarily strict to use.
Want to declare a variable and also run some code if it’s not null? Easy.

if(auto a = b in c){
    //code
}

This pattern is great for simplifying null pointer checks. I use it everywhere. But… what if we want to do it three times, nested? We can just use && right???
Haha, no. You were tricked and now this nice syntax has gone rotten. You have to use the pyramid of doom:

if(auto a = b in c){
    if(auto d = e in a){
        if(auto f = g in d){
            //code
        }
    }
}

And suddenly what was a really useful feature becomes a terrible drag because you can only use it once per if statement, requiring many layers of nested if statements instead of just utilising the usual && early-out rules.

January 20
On Monday, 20 January 2025 at 21:08:09 UTC, Richard (Rikki) Andrew Cattermole wrote:
> On 21/01/2025 9:41 AM, IchorDev wrote:
>> Someone brought up this clever idea here: https://github.com/dlang/dmd/ pull/20653#issuecomment-2581474608
>> What does everyone think about being able to declare variables in expressions? Is there any pre-existing syntax that blocks us from being able to easily do this?
>
> I don't know about syntax, but rewrites do use VarDeclaration in an expression (including CommaExpression).
>
> I'd call this long overdue if it works in syntax.

What do you mean by ‘works in syntax’?
January 21
On 21/01/2025 12:23 PM, IchorDev wrote:
> On Monday, 20 January 2025 at 21:08:09 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> On 21/01/2025 9:41 AM, IchorDev wrote:
>>> Someone brought up this clever idea here: https://github.com/dlang/ dmd/ pull/20653#issuecomment-2581474608
>>> What does everyone think about being able to declare variables in expressions? Is there any pre-existing syntax that blocks us from being able to easily do this?
>>
>> I don't know about syntax, but rewrites do use VarDeclaration in an expression (including CommaExpression).
>>
>> I'd call this long overdue if it works in syntax.
> 
> What do you mean by ‘works in syntax’?

I just mean that if there are no problems in the grammar then it would be a good addition.

January 21

On Tuesday, 21 January 2025 at 01:18:08 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

I just mean that if there are no problems in the grammar then it would be a good addition.

Absolutely agreed. I think the codegen would be the bigger issue, surely? I’m not sure if all the existing special cases reuse the same code but I have a feeling they don’t.
Do you think it should be necessary to explicitly initialise the variable (e.g. auto x = y) or should default initialisation be possible? I’m not sure why anyone would want to use default initialisation?
Also if this syntax were to work in declaration lists then it should only declare a variable for the duration of a single expression, hence:

module example;
bool x = int* y = ctfeFn() && *y == 2;
auto z = y; //Error: no variable `y` in scope

However this is probably too complex to implement since it adds a whole new variable scope, and you could just use a CTFE lambda:

module example;
bool x = { int* y = ctfeFn(); return *y == 2; }();
auto z = y; //Error: no variable `y` in scope

Ultimately the purpose of this syntax would be making declarations inside of flow control statements. I don’t think it would be a huge shame if it were forbidden elsewhere, but let me know if you think of any other cool use-cases.

January 21

On Monday, 20 January 2025 at 20:41:42 UTC, IchorDev wrote:

>

Someone brought up this clever idea here: https://github.com/dlang/dmd/pull/20653#issuecomment-2581474608
What does everyone think about being able to declare variables in expressions? Is there any pre-existing syntax that blocks us from being able to easily do this?

If I understand it correctly this would solve my issue https://github.com/dlang/dmd/issues/18890


with (auto p = new Panel())
{
	parent = this;
	text = "bla";
	with (new Button())
	{
		parent = p; // Here p is needed
		text = "bla2";
	}
}

The syntax with (auto p = new Panel()) is currently not allowed.

January 21

On Tuesday, 21 January 2025 at 16:59:12 UTC, Andre wrote:

>

On Monday, 20 January 2025 at 20:41:42 UTC, IchorDev wrote:

>

Someone brought up this clever idea here: https://github.com/dlang/dmd/pull/20653#issuecomment-2581474608
What does everyone think about being able to declare variables in expressions? Is there any pre-existing syntax that blocks us from being able to easily do this?

If I understand it correctly this would solve my issue https://github.com/dlang/dmd/issues/18890


with (auto p = new Panel())
{
	parent = this;
	text = "bla";
	with (new Button())
	{
		parent = p; // Here p is needed
		text = "bla2";
	}
}

The syntax with (auto p = new Panel()) is currently not allowed.

That’s a very clever use of the syntax. I don’t see why that shouldn’t work.