www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Please improve the with statement by allowing initialisation

reply Dejan Lekic <dejan.lekic gmail.com> writes:
This is what we currently _have_ to do in D:
```d
auto app = new Application();
auto win = new Window();
with (win) {
   setTitle("Example");
   setDefaultSize(200, 200);
   setChild(mainBox);
}
app.addWindow(win);
```
In most cases you really do not want the `auto win = new Window;` 
line because you should be able to do it all inside the with 
block. Since with statement does not allow initialisation one 
would try:

```d
auto app = new Application();
with (new Window) {
   setTitle("Example");
   setDefaultSize(200, 200);
   setChild(mainBox);
   app.addWindow(???); // we CAN'T refer to the object created by 
the `new Window`
}
```

What I do is I make classes that I want to use the with statement 
on have a property called `self` that simply return this. This 
allows me to write something like:

```d
auto app = new Application();
with (new MyWindow) {
   setTitle("Example");
   setDefaultSize(200, 200);
   setChild(mainBox);
   app.addWindow(self); // MyWindow implements self
}
```

I would still prefer an initialisation because it matches what we 
have in the `for` statement, but I would not mind if D allows 
something like `this` in the with block, yet I would not call it 
`this`. `self` maybe. `that`? I do not know. This is precisely 
why I prefer the initialisation instead - because I do not know 
what would be the best name for this reference...

Please do not even start with the fluent APIs in this thread. 
Why? Because what I am asking above does not require people to 
refactor their libraries to make them "fluent", it will work out 
of box with anything.

For those who wonder what am I talking about - let's assume this 
particular library I am using has a fluent API. Then I could 
write the code above like this:
```d
auto win = new Window;
win.setTitle("Example")
    .setDefaultSize(200.200)
    .setChild(mainBox);
app.addWindow(win);
```
This would work because all Window methods return this. We do not 
always have luxury of being able to change the library we use, 
especially make such a drastic change so that all methods return 
this (which would be required for the fluent API to work).
Mar 12
next sibling parent reply Dejan Lekic <dejan.lekic gmail.com> writes:
On Wednesday, 12 March 2025 at 18:55:45 UTC, Dejan Lekic wrote:
 the with block. Since with statement does not allow 
 initialisation one would try:
As usual, I forgot to give an example of what I am actually asking for... ```d auto app = new Application(); with (auto win = new Window) { // currently not allowed setTitle("Example"); setDefaultSize(200, 200); setChild(mainBox); app.addWindow(win); } ```
Mar 12
next sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Wednesday, 12 March 2025 at 19:01:46 UTC, Dejan Lekic wrote:
 On Wednesday, 12 March 2025 at 18:55:45 UTC, Dejan Lekic wrote:
 the with block. Since with statement does not allow 
 initialisation one would try:
As usual, I forgot to give an example of what I am actually asking for... ```d auto app = new Application(); with (auto win = new Window) { // currently not allowed setTitle("Example"); setDefaultSize(200, 200); setChild(mainBox); app.addWindow(win); } ```
What you want has nothing to do with the WithStatement, what you want is "inline variables", i.e a VariableDeclaration as an Expression.
Mar 13
parent Dejan Lekic <dejan.lekic gmail.com> writes:
On Thursday, 13 March 2025 at 12:38:51 UTC, Basile B. wrote:
 What you want has nothing to do with the WithStatement, what 
 you want is "inline variables", i.e a VariableDeclaration as an 
 Expression.
Thanks for clearing that up! :) I am not a language expert so I do not know the terminology. Obviously I want something similar to what the [for statement](https://dlang.org/spec/statement.html#for-statement) gives us - ability to initialise the variable and use it in inside the block.
Mar 13
prev sibling next sibling parent matheus <matheus gmail.com> writes:
On Wednesday, 12 March 2025 at 19:01:46 UTC, Dejan Lekic wrote:
 On Wednesday, 12 March 2025 at 18:55:45 UTC, Dejan Lekic wrote:
 the with block. Since with statement does not allow 
 initialisation one would try:
As usual, I forgot to give an example of what I am actually asking for... ```d auto app = new Application(); with (auto win = new Window) { // currently not allowed setTitle("Example"); setDefaultSize(200, 200); setChild(mainBox); app.addWindow(win); } ```
This should be easy to fix/upgrade, since we can already instantiate a class: import std; class foo{ void hi(string who){ writeln("Hi ", who); } } void main(){ auto f = new foo(); f.hi("There!"); foo f2; with(f2 = new foo()){ hi("Again!"); } } Hi There! Hi Again! One thing missing is Declaration. (I wonder why this is not already implemented!?). Matheus.
Mar 13
prev sibling next sibling parent reply Sergey <kornburn yandex.ru> writes:
On Wednesday, 12 March 2025 at 19:01:46 UTC, Dejan Lekic wrote:
 On Wednesday, 12 March 2025 at 18:55:45 UTC, Dejan Lekic wrote:
 the with block. Since with statement does not allow 
 initialisation one would try:
As usual, I forgot to give an example of what I am actually asking for... ```d auto app = new Application(); with (auto win = new Window) { // currently not allowed setTitle("Example"); setDefaultSize(200, 200); setChild(mainBox); app.addWindow(win); } ```
You can use `if` ```d if (auto win = new Window) { ... } ```
Mar 13
parent Dejan Lekic <dejan.lekic gmail.com> writes:
On Thursday, 13 March 2025 at 13:40:28 UTC, Sergey wrote:
 You can use `if`
 ```d
 if (auto win = new Window) {
 ...
 }
 ```
Yes, we discussed this on IRC. I see no benefit as it is the same as ```d auto win = new Window(); with (win) { ... } , and using if there is really confusing.
Mar 13
prev sibling next sibling parent Paul Backus <snarwin gmail.com> writes:
On Wednesday, 12 March 2025 at 19:01:46 UTC, Dejan Lekic wrote:
 On Wednesday, 12 March 2025 at 18:55:45 UTC, Dejan Lekic wrote:
 the with block. Since with statement does not allow 
 initialisation one would try:
As usual, I forgot to give an example of what I am actually asking for... ```d auto app = new Application(); with (auto win = new Window) { // currently not allowed setTitle("Example"); setDefaultSize(200, 200); setChild(mainBox); app.addWindow(win); } ```
Seems like a totally uncontroversial change to me. We already allow using a declaration in `if`, `while`, and `switch` statements; there's no reason `with` shouldn't work the same way.
Mar 13
prev sibling parent Nick Treleaven <nick geany.org> writes:
On Wednesday, 12 March 2025 at 19:01:46 UTC, Dejan Lekic wrote:
 On Wednesday, 12 March 2025 at 18:55:45 UTC, Dejan Lekic wrote:
 the with block. Since with statement does not allow 
 initialisation one would try:
As usual, I forgot to give an example of what I am actually asking for... ```d auto app = new Application(); with (auto win = new Window) { // currently not allowed setTitle("Example"); setDefaultSize(200, 200); setChild(mainBox); app.addWindow(win); } ```
Just to mention that there's an issue filed for this (in 2014 and duplicate in 2015): https://github.com/dlang/dmd/issues/18890
Mar 14
prev sibling parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Wednesday, 12 March 2025 at 18:55:45 UTC, Dejan Lekic wrote:
 This is what we currently _have_ to do in D:

 This would work because all Window methods return this. We do 
 not always have luxury of being able to change the library we 
 use, especially make such a drastic change so that all methods 
 return this
```d struct window{ void settitle(string){} void setsize(int,int){} } auto fluantize(T)(){ struct flaunt{ T t; typeof(this) opDispatch(string __s,A...)(A args){ mixin("t."~__s)(args); return this; }} return flaunt(); } unittest{ auto win= fluantize!(window) .settitle("foo") .setsize(1,2); } ``` this is bad but you dont "have to" or "change the lib"
Mar 12
parent reply Dejan Lekic <dejan.lekic gmail.com> writes:
On Wednesday, 12 March 2025 at 19:25:23 UTC, monkyyy wrote:
 this is bad but you dont "have to" or "change the lib"
I expected people to start discussing fluent API that is why I wrote what I wrote. Let's stop it right here. I do not want to write code like that if I do not have to. I would rather prefer to use the with statement. Thanks.
Mar 12
parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Wednesday, 12 March 2025 at 19:35:53 UTC, Dejan Lekic wrote:
 On Wednesday, 12 March 2025 at 19:25:23 UTC, monkyyy wrote:
 this is bad but you dont "have to" or "change the lib"
I expected people to start discussing fluent API that is why I wrote what I wrote. Let's stop it right here. I do not want to write code like that if I do not have to. I would rather prefer to use the with statement. Thanks.
I have no idea what a fluent api is, you had code you want, heres a small bit of templates that does it. I know it as a "builder pattern" and assoate it with verbose impossible to read code
Mar 12
parent Derek Fawcus <dfawcus+dlang employees.org> writes:
On Wednesday, 12 March 2025 at 19:45:08 UTC, monkyyy wrote:
 I have no idea what a fluent api is, you had code you want, 
 heres a small bit of templates that does it. I know it as a 
 "builder pattern" and assoate it with verbose impossible to 
 read code
He gave two examples of code. The first he wanted, the second he didn't. You provided a way to templatize the form he didn't want to use :-( DF
Mar 13