www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - braceless with statements

reply Stefan Koch <uplink.coder googlemail.com> writes:
Good Morning Everyone,

I recently found myself wanting to introduce a bunch of member 
variables into the scope of the function I was currently working 
on.
Of course D has a nice way to do that; The `with` statement.

so
```D
struct S { int x; }
int fn()
{
     S s;
     with(s)
     {
        x = 12;
        return x;
     }
}
```

this code works but it forces another level of indentation which 
makes it a little ugly.

So I did a small patch to my local version of dmd.
And now this works:
```D
struct S { int x; }
int fn()
{
     S s;
     with(s):
     x = 12;
     return x;
}
```

It is a really simple patch and I think it's worthwhile to have 
this in the main language.
Nov 12 2021
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 And now this works:
 ```D
 struct S { int x; }
 int fn()
 {
     S s;
     with(s):
     x = 12;
     return x;
 }
 ```
Note: this will actually create an invisible scope from `with(x):` towards the end of the parent scope. but it shouldn't affect anything you might do. I just wanted to point out that using `x` in the example above will not work it it's done before the `with` statement. only after and similarly the names introduced by `with` will go out of scope when the parent scope leaves. ```D { with(s): // only vaild for this scope } // s.x is not valid here anymore ```
Nov 12 2021
parent reply kdevel <kdevel vogtner.de> writes:
On Friday, 12 November 2021 at 10:59:39 UTC, Stefan Koch wrote:
[...]
 ```D
 {
 with(s):
  // only vaild for this scope
 }
 // s.x is not valid here anymore
 ```
That's good, but why stop half way? Drop the colon, drop the parentheses, allow a comma expression: A a; B b; ...; Z z; : with a, b, ..., z; which is "lowered" to with (a) { with (b) { : with (z) { : } : } : }
Nov 12 2021
parent reply user1234 <user1234 12.de> writes:
On Friday, 12 November 2021 at 12:52:28 UTC, kdevel wrote:
 That's good, but why stop half way? Drop the colon, drop the 
 parentheses,
parens can be removed that simply: ```d import std.stdio; struct L { struct R { static opUnary(string s : "-")() {writeln("oops");} } } void main() { with (L) - R; } ``` now remove the parens... oops the parser sees a binary minus ;)
Nov 12 2021
parent reply kdevel <kdevel vogtner.de> writes:
On Friday, 12 November 2021 at 21:44:25 UTC, user1234 wrote:
 void main()
 {
     with (L) - R;
 }
 
 now remove the parens... oops the parser sees a binary minus ;)
that would then translate into void main() { with (L - R) { } } for which the compiler complains about undefined identifier `R`. I must admit I have difficulty to get your point. Under the removed parantheses version you could (additionally) write the original code as void main() { with L; - R; }
Nov 12 2021
parent user1234 <user1234 12.de> writes:
On Friday, 12 November 2021 at 23:43:51 UTC, kdevel wrote:
 On Friday, 12 November 2021 at 21:44:25 UTC, user1234 wrote:
 void main()
 {
     with (L) - R;
 }
 
 now remove the parens... oops the parser sees a binary minus ;)
that would then translate into void main() { with (L - R) { } } for which the compiler complains about undefined identifier `R`. I must admit I have difficulty to get your point. Under the removed parantheses version you could (additionally) write the original code as void main() { with L; - R; }
you can craft code where both work
Nov 13 2021
prev sibling next sibling parent zjh <fqbqrr 163.com> writes:
On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 Good
Good.
Nov 12 2021
prev sibling next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 It is a really simple patch and I think it's worthwhile to have 
 this in the main language.
How about other statements, like `if`, `for`, `foreach`, `switch`? When extending `attribute:` syntax to statements, might as well include all of them for consistency. N.b. this is already allowed in global scope: ```D static if (true): ``` Not in function scope though.
Nov 12 2021
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 12 November 2021 at 11:05:54 UTC, Dennis wrote:
 On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 It is a really simple patch and I think it's worthwhile to 
 have this in the main language.
How about other statements, like `if`, `for`, `foreach`, `switch`? When extending `attribute:` syntax to statements, might as well include all of them for consistency. N.b. this is already allowed in global scope: ```D static if (true): ``` Not in function scope though.
I am not proposing anything grand like that. I don't think it has a very good fit for `if` or `for` Since their scope tends to end before their parent block scope.
Nov 12 2021
prev sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Friday, 12 November 2021 at 11:05:54 UTC, Dennis wrote:
 On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 It is a really simple patch and I think it's worthwhile to 
 have this in the main language.
How about other statements, like `if`, `for`, `foreach`, `switch`? When extending `attribute:` syntax to statements, might as well include all of them for consistency. N.b. this is already allowed in global scope: ```D static if (true): ``` Not in function scope though.
static if (true) should be banned from existence, use comments or delete if false.
Nov 12 2021
parent Dr Machine Code <jckj33 gmail.com> writes:
On Friday, 12 November 2021 at 11:26:41 UTC, Imperatorn wrote:
 On Friday, 12 November 2021 at 11:05:54 UTC, Dennis wrote:
 On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 It is a really simple patch and I think it's worthwhile to 
 have this in the main language.
How about other statements, like `if`, `for`, `foreach`, `switch`? When extending `attribute:` syntax to statements, might as well include all of them for consistency. N.b. this is already allowed in global scope: ```D static if (true): ``` Not in function scope though.
static if (true) should be banned from existence, use comments or delete if false.
why not use rather ```version(none)``` and ```version(all)``` ?
Nov 12 2021
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12.11.21 11:55, Stefan Koch wrote:
 
 It is a really simple patch and I think it's worthwhile to have this in 
 the main language.
Yes, please.
Nov 12 2021
parent Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 12 November 2021 at 13:01:15 UTC, Timon Gehr wrote:
 On 12.11.21 11:55, Stefan Koch wrote:
 
 It is a really simple patch and I think it's worthwhile to 
 have this in the main language.
Yes, please.
I'll leave it in this PR: https://github.com/dlang/dmd/pull/13305
Nov 15 2021
prev sibling next sibling parent reply user1234 <user1234 12.de> writes:
On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 Good Morning Everyone,

 [...]

 It is a really simple patch and I think it's worthwhile to have 
 this in the main language.
that's https://issues.dlang.org/show_bug.cgi?id=14332 BTW.
Nov 12 2021
parent russhy <russhy gmail.com> writes:
I approve!
Nov 12 2021
prev sibling next sibling parent reply Ogi <ogion.art gmail.com> writes:
On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 Good Morning Everyone,

 I recently found myself wanting to introduce a bunch of member 
 variables into the scope of the function I was currently 
 working on.
 Of course D has a nice way to do that; The `with` statement.

 so
 ```D
 struct S { int x; }
 int fn()
 {
     S s;
     with(s)
     {
        x = 12;
        return x;
     }
 }
 ```

 this code works but it forces another level of indentation 
 which makes it a little ugly.

 So I did a small patch to my local version of dmd.
 And now this works:
 ```D
 struct S { int x; }
 int fn()
 {
     S s;
     with(s):
     x = 12;
     return x;
 }
 ```

 It is a really simple patch and I think it's worthwhile to have 
 this in the main language.
I’m missing the point. Why using a struct to add some variables? At first I thought that you want to shadow already existing variables but this is prohibited in D and thank God for that.
Nov 12 2021
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/12/21 10:03 AM, Ogi wrote:
 On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 Good Morning Everyone,

 I recently found myself wanting to introduce a bunch of member 
 variables into the scope of the function I was currently working on.
 Of course D has a nice way to do that; The `with` statement.

 so
 ```D
 struct S { int x; }
 int fn()
 {
     S s;
     with(s)
     {
        x = 12;
        return x;
     }
 }
 ```

 this code works but it forces another level of indentation which makes 
 it a little ugly.

 So I did a small patch to my local version of dmd.
 And now this works:
 ```D
 struct S { int x; }
 int fn()
 {
     S s;
     with(s):
     x = 12;
     return x;
 }
 ```

 It is a really simple patch and I think it's worthwhile to have this 
 in the main language.
I’m missing the point. Why using a struct to add some variables? At first I thought that you want to shadow already existing variables but this is prohibited in D and thank God for that.
No, you are wanting to use the members of `s` many times, and don't want to have to repeat `s.` all the time. This isn't a great example because of the brevity. But imagine a long expression instead of the single-letter variable. `with` already works as noted in the first case, the second case would just be a way to write the same thing but without braces (and indentation). -Steve
Nov 12 2021
parent reply Ogi <ogion.art gmail.com> writes:
On Friday, 12 November 2021 at 15:33:38 UTC, Steven Schveighoffer 
wrote:
 No, you are wanting to use the members of `s` many times, and 
 don't want to have to repeat `s.` all the time. This isn't a 
 great example because of the brevity. But imagine a long 
 expression instead of the single-letter variable.

 `with` already works as noted in the first case, the second 
 case would just be a way to write the same thing but without 
 braces (and indentation).
I see, thanks. Can’t say I am a fan of this proposal. Are you in the same scope as a few hundred lines above? With braces and indentation, the answer is clear. Without them, you’ll have to look for `with` labels that don’t stand out visually at all.
Nov 13 2021
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Saturday, 13 November 2021 at 10:43:04 UTC, Ogi wrote:
 On Friday, 12 November 2021 at 15:33:38 UTC, Steven 
 Schveighoffer wrote:
 No, you are wanting to use the members of `s` many times, and 
 don't want to have to repeat `s.` all the time. This isn't a 
 great example because of the brevity. But imagine a long 
 expression instead of the single-letter variable.

 `with` already works as noted in the first case, the second 
 case would just be a way to write the same thing but without 
 braces (and indentation).
I see, thanks. Can’t say I am a fan of this proposal. Are you in the same scope as a few hundred lines above? With braces and indentation, the answer is clear. Without them, you’ll have to look for `with` labels that don’t stand out visually at all.
No you just look for the last open brace? The with statement doesn't behave like a stand alone scope.
Nov 13 2021
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/13/21 5:43 AM, Ogi wrote:
 On Friday, 12 November 2021 at 15:33:38 UTC, Steven Schveighoffer wrote:
 No, you are wanting to use the members of `s` many times, and don't 
 want to have to repeat `s.` all the time. This isn't a great example 
 because of the brevity. But imagine a long expression instead of the 
 single-letter variable.

 `with` already works as noted in the first case, the second case would 
 just be a way to write the same thing but without braces (and 
 indentation).
I see, thanks. Can’t say I am a fan of this proposal. Are you in the same scope as a few hundred lines above? With braces and indentation, the answer is clear. Without them, you’ll have to look for `with` labels that don’t stand out visually at all.
I don't really understand the question. What is the confusion you are having? Consider the `scope(exit)` rewrite: ```d { someCode; scope(exit) close(foo); someCode; } ``` This is equivalent to: ```d { someCode; try { // new scope! someCode; } finally { close(foo); } } ``` This introduces a new scope the same as a `with:` would introduce a new scope (and actually is simpler). Have you had confusion about that feature before? It makes perfect sense to me. -Steve
Nov 13 2021
next sibling parent Elronnd <elronnd elronnd.net> writes:
On Saturday, 13 November 2021 at 14:42:55 UTC, Steven 
Schveighoffer wrote:
 This introduces a new scope the same as a `with:` would 
 introduce a new scope (and actually is simpler). Have you had 
 confusion about that feature before? It makes perfect sense to 
 me.
FWIW I think with: is a good idea. However there is an important different between it and scope(exit/...): the latter binds no variables.
Nov 13 2021
prev sibling parent reply Ogi <ogion.art gmail.com> writes:
On Saturday, 13 November 2021 at 14:42:55 UTC, Steven 
Schveighoffer wrote:
 I don't really understand the question. What is the confusion 
 you are having?
Braces and indentations keep things sane: ```D struct S { int x; } S s; with (s) { /* lots of code here */ x = 42; //is this s.x? The answer is always yes. } ``` Now with `with:`: ```D struct S { int x; } S s; with (s): /* lots of code here */ x = 42; //is this s.x? Depends on the code above. ``` “Lots of code” can contain anything, including something like this: ```D struct X { void x(int i) {} } with (X()): ``` In this case `x` isn’t even a variable, it’s a function! But it would still compile.
Nov 14 2021
parent reply kdevel <kdevel vogtner.de> writes:
On Sunday, 14 November 2021 at 15:45:13 UTC, Ogi wrote:

[...]

 Braces and indentations keep things sane:

 ```D
 struct S { int x; }
 S s;
 with (s) {
 	/*
 	lots of code here
 	*/
 	x = 42; //is this s.x? The answer is always yes.
 }
 ```
Wrong: replace /* lots of code here */ with int x: ```D $ cat xxx.d struct S { int x; } void main () { S s; with (s) { int x; x = 42; //is this s.x? The answer is always yes. } import std.stdio; writeln (s); } $ dmd xxx $ ./xxx S(0) ```
Nov 14 2021
parent reply Ogi <ogion.art gmail.com> writes:
On Sunday, 14 November 2021 at 16:51:01 UTC, kdevel wrote:
Wrong: replace /* lots of code here */ with int x:
Hmm, it works indeed. Not sure if that’s intended, since the other way around is prohibited: ```D struct S { int x; } void main () { S s; int x; with (s) { x = 42; //Error: with symbol `onlineapp.S.x` is shadowing local symbol `onlineapp.main.x` } } ```
Nov 14 2021
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/14/21 12:39 PM, Ogi wrote:
 On Sunday, 14 November 2021 at 16:51:01 UTC, kdevel wrote:
 Wrong: replace /* lots of code here */ with int x:
Hmm, it works indeed. Not sure if that’s intended, since the other way around is prohibited: ```D struct S { int x; } void main () {    S s;    int x;    with (s) {       x = 42; //Error: with symbol `onlineapp.S.x` is shadowing local symbol `onlineapp.main.x`    } } ```
Yes, it's intended. I do get your point, but I don't think it's any more confusing than normal `with`. -Steve
Nov 14 2021
prev sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 12 November 2021 at 15:03:33 UTC, Ogi wrote:
 On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 [...]
I’m missing the point. Why using a struct to add some variables? At first I thought that you want to shadow already existing variables but this is prohibited in D and thank God for that.
The point is to inject member functions or variables from a struct or class. it saves some typing.
Nov 12 2021
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Friday, 12 November 2021 at 15:50:19 UTC, Stefan Koch wrote:
 On Friday, 12 November 2021 at 15:03:33 UTC, Ogi wrote:
 On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 [...]
I’m missing the point. Why using a struct to add some variables? At first I thought that you want to shadow already existing variables but this is prohibited in D and thank God for that.
The point is to inject member functions or variables from a struct or class. it saves some typing.
Or enums. Enums. ENUMS!!! :)
Nov 12 2021
next sibling parent reply Dr Machine Code <jckj33 gmail.com> writes:
On Friday, 12 November 2021 at 17:45:05 UTC, Stanislav Blinov 
wrote:
 On Friday, 12 November 2021 at 15:50:19 UTC, Stefan Koch wrote:
 On Friday, 12 November 2021 at 15:03:33 UTC, Ogi wrote:
 On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch 
 wrote:
 [...]
I’m missing the point. Why using a struct to add some variables? At first I thought that you want to shadow already existing variables but this is prohibited in D and thank God for that.
The point is to inject member functions or variables from a struct or class. it saves some typing.
Or enums. Enums. ENUMS!!! :)
what's wrong with them?
Nov 12 2021
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 11/12/21 11:47 AM, Dr Machine Code wrote:

 Or enums. Enums. ENUMS!!! :)
what's wrong with them?
They are great. :) 'with' helps especially with switch statements: enum LongEnumName { a, b, c } void main() { LongEnumName e; // 'LongEnumName.' is repeated for each case: final switch (e) { case LongEnumName.a: case LongEnumName.b: case LongEnumName.c: } // Same thing but shorter syntax: final switch (e) with (LongEnumName) { case a: case b: case c: } } Ali
Nov 12 2021
parent Dr Machine Code <jckj33 gmail.com> writes:
On Friday, 12 November 2021 at 20:52:22 UTC, Ali Çehreli wrote:
 On 11/12/21 11:47 AM, Dr Machine Code wrote:

 Or enums. Enums. ENUMS!!! :)
what's wrong with them?
They are great. :) 'with' helps especially with switch statements: enum LongEnumName { a, b, c } void main() { LongEnumName e; // 'LongEnumName.' is repeated for each case: final switch (e) { case LongEnumName.a: case LongEnumName.b: case LongEnumName.c: } // Same thing but shorter syntax: final switch (e) with (LongEnumName) { case a: case b: case c: } } Ali
oh I see, I do use that as well. Very helpful ;)
Nov 12 2021
prev sibling parent russhy <russhy gmail.com> writes:
On Friday, 12 November 2021 at 17:45:05 UTC, Stanislav Blinov 
wrote:
 On Friday, 12 November 2021 at 15:50:19 UTC, Stefan Koch wrote:
 On Friday, 12 November 2021 at 15:03:33 UTC, Ogi wrote:
 On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch 
 wrote:
 [...]
I’m missing the point. Why using a struct to add some variables? At first I thought that you want to shadow already existing variables but this is prohibited in D and thank God for that.
The point is to inject member functions or variables from a struct or class. it saves some typing.
Or enums. Enums. ENUMS!!! :)
i still believe enums shouldn't need one to use 'with(MyEnumType)' 'with' shouldn't be an argument for "we have it at home" kind of thing
Nov 12 2021
prev sibling parent Dr Machine Code <jckj33 gmail.com> writes:
On Friday, 12 November 2021 at 10:55:21 UTC, Stefan Koch wrote:
 Good Morning Everyone,

 I recently found myself wanting to introduce a bunch of member 
 variables into the scope of the function I was currently 
 working on.
 Of course D has a nice way to do that; The `with` statement.

 so
 ```D
 struct S { int x; }
 int fn()
 {
     S s;
     with(s)
     {
        x = 12;
        return x;
     }
 }
 ```

 this code works but it forces another level of indentation 
 which makes it a little ugly.

 So I did a small patch to my local version of dmd.
Do you use your own compiler version? do use it for anything but toy projects?
 And now this works:
 ```D
 struct S { int x; }
 int fn()
 {
     S s;
     with(s):
     x = 12;
     return x;
 }
 ```

 It is a really simple patch and I think it's worthwhile to have 
 this in the main language.
it's lowered to the very same code in your first example, right? tbh honest I like it, wouldn't mind that in the main language. I think this one of the syntax sugar examples that didn't make it hard and/or ugly to read
Nov 12 2021