Jump to page: 1 2 3
Thread overview
A couple of extensions to `with` that would be worthwhile
Oct 13, 2021
MrSmith
Oct 13, 2021
Adam D Ruppe
Oct 13, 2021
Basile B.
Oct 13, 2021
Paul Backus
Oct 13, 2021
Basile B.
Oct 13, 2021
Adam D Ruppe
Oct 14, 2021
Mathias LANG
Oct 13, 2021
Paul Backus
Oct 13, 2021
deadalnix
Oct 13, 2021
Paul Backus
Oct 13, 2021
Salih Dincer
Oct 13, 2021
Andre Pany
Oct 13, 2021
max haughton
Oct 13, 2021
Timon Gehr
Oct 14, 2021
Tejas
Oct 14, 2021
jfondren
Oct 14, 2021
Tejas
Oct 14, 2021
Paul Backus
Oct 14, 2021
Tejas
Oct 14, 2021
Paul Backus
Oct 14, 2021
Antonio
Oct 14, 2021
Paul Backus
October 13, 2021
We have an awkward idiom in the dmd source code:

https://github.com/dlang/dmd/search?q=extendedPathThen
https://github.com/dlang/dmd/search?q=toWStringzThen

It's a tail wagging the proverbial dog. Clearly we could do with better ways. We can improve the `with` statement as follows:

1. Accept named `with`:

with (auto xpath = extendPath(name)) {
    // the only name injected here is xpath
}

All destructors for the expression involved in `with` are called AFTER the with is done.

2. Accept primitive types in named `with`:

with (auto xpath = extendPath(name).str) {
    // the only name injected here is xpath
    // assume str has type wstring, then xpath
    // also has type string
}

Again, the destructor of the temporary object created is called AFTER the with statement ends, even though the object is only used as a temporary.

3. Accept `with` with colon:

with (auto xpath = extendPath(name).str):

The meaning is like a scoped `with` that extends though the end of the scope.

4. Accept `with` at top level.

All `with` forms that take a type should be accepted at top level. This allows entire modules or fragments thereof to look names up in a flexible manner.

October 13, 2021

On Wednesday, 13 October 2021 at 11:13:32 UTC, Andrei Alexandrescu wrote:

>
  1. Accept with with colon:

with (auto xpath = extendPath(name).str):

The meaning is like a scoped with that extends though the end of the scope.

Isn't this equivalent to:

auto xpath = extendPath(name).str;
October 13, 2021
On Wednesday, 13 October 2021 at 11:13:32 UTC, Andrei Alexandrescu wrote:
> 1. Accept named `with`:
>
> with (auto xpath = extendPath(name)) {
>     // the only name injected here is xpath
> }

I've wanted this before, but not the "only name injected" thing, since that defeats the whole point of `with`.

I'd want it to be a standard with statement, just with a name given for the overall thing so you can refer to it as a whole in that scope too.

> with (auto xpath = extendPath(name).str) {
>     // the only name injected here is xpath
>     // assume str has type wstring, then xpath
>     // also has type string
> }

What's the difference between this and `if(auto xpath = ...)` ? It wouldn't be null anyway.

Or between it and

---
{
  auto xpath = ....;
  // stuff
}
---

?


That's why I think the with needs to keep its with behavior even if you give it a name.
October 13, 2021
On Wednesday, 13 October 2021 at 11:13:32 UTC, Andrei Alexandrescu wrote:
> We have an awkward idiom in the dmd source code:
>
> https://github.com/dlang/dmd/search?q=extendedPathThen
> https://github.com/dlang/dmd/search?q=toWStringzThen
>
> It's a tail wagging the proverbial dog. Clearly we could do with better ways. We can improve the `with` statement as follows:
>
> 1. Accept named `with`:
>
> with (auto xpath = extendPath(name)) {
>     // the only name injected here is xpath
> }
>
> All destructors for the expression involved in `with` are called AFTER the with is done.

Isn't this the same thing as a normal block scope?

    {
        auto xpath = extendPath(name);
        // the name xpath is available here
        // ...
    } // xpath is destroyed here

As far as I can tell the reason a block scope isn't used in DMD is that these methods don't use destructors for cleanup, they use manual memory management. So maybe that's the real source of the awkwardness.

> 3. Accept `with` with colon:
>
> with (auto xpath = extendPath(name).str):
>
> The meaning is like a scoped `with` that extends though the end of the scope.

This would also be useful for types like ddash's Expect [1], which define static factory methods for each case of a sum type. The example in the linked documentation could be rewritten as:

    Expect!int toInt(string str) {
        with(typeof(return)):
        import std.conv: to;
        try {
            return expected(str.to!int);
        } catch (Exception ex) {
            return unexpected(ex.msg);
        }
    }

...where the `with` statement is used to bring `expected` and `unexpected` into scope, and the colon avoids introducing an extra level of nesting.

[1] https://aliak00.github.io/ddash/ddash/utils/expect/Expect.html

> 4. Accept `with` at top level.
>
> All `with` forms that take a type should be accepted at top level. This allows entire modules or fragments thereof to look names up in a flexible manner.

Seems like a natural "turtles all the way down" extension of the above.
October 13, 2021

On Wednesday, 13 October 2021 at 13:05:06 UTC, Adam D Ruppe wrote:

>

On Wednesday, 13 October 2021 at 11:13:32 UTC, Andrei [...]

>

with (auto xpath = extendPath(name).str) {
// the only name injected here is xpath
// assume str has type wstring, then xpath
// also has type string
}

What's the difference between this and if(auto xpath = ...) ? It wouldn't be null anyway.

Or between it and

{
auto xpath = ....;
// stuff
}

?

I think that the point of proposal 1 is to have something like, after lowering to common AST constructs:

{
  {
    auto xpath = ....;
    scope (exit) destroy(xpath)
    // stuff
  }
  // destroy(xpath) really happens here
}
October 13, 2021

On Wednesday, 13 October 2021 at 13:16:36 UTC, Basile B. wrote:

>

I think that the point of proposal 1 is to have something like, after lowering to common AST constructs:

{
  {
    auto xpath = ....;
    scope (exit) destroy(xpath)
    // stuff
  }
  // destroy(xpath) really happens here
}

Destructors are already called automatically at the end of a block scope.

October 13, 2021

On Wednesday, 13 October 2021 at 13:20:02 UTC, Paul Backus wrote:

>

On Wednesday, 13 October 2021 at 13:16:36 UTC, Basile B. wrote:

>

I think that the point of proposal 1 is to have something like, after lowering to common AST constructs:

{
  {
    auto xpath = ....;
    scope (exit) destroy(xpath)
    // stuff
  }
  // destroy(xpath) really happens here
}

Destructors are already called automatically at the end of a block scope.

so proposal 1. is definitively not useful.

October 13, 2021

On Wednesday, 13 October 2021 at 11:13:32 UTC, Andrei Alexandrescu wrote:

>

It's a tail wagging the proverbial dog. Clearly we could do with better ways. We can improve the with statement as follows:

I prefer with() while using the arsd.simpledisplay because it's needed a scope.

However, when you use double with(), an issue to come up! Compiled as follows, my only solution is:

Painter window;
with(Color) window = new Painter("AxialPCB", black, gray, red);
with(window)
{
 //...
}
window.Handlers.eventLoop(0);

The new ideas are great about with() like the same inline import! If I used this way, it can't access it from the outside:

with(new Painter("AxialPCB", Color.black, Color.gray, Color.red) { //*/ }
October 13, 2021
On Wednesday, 13 October 2021 at 11:13:32 UTC, Andrei Alexandrescu wrote:
> We have an awkward idiom in the dmd source code:
>
> https://github.com/dlang/dmd/search?q=extendedPathThen
> https://github.com/dlang/dmd/search?q=toWStringzThen
>
> [...]

There is also an open issue for #1

https://issues.dlang.org/show_bug.cgi?id=13526

Kind regards
Andre
October 13, 2021
On Wednesday, 13 October 2021 at 11:13:32 UTC, Andrei Alexandrescu wrote:
> We have an awkward idiom in the dmd source code:
>
> https://github.com/dlang/dmd/search?q=extendedPathThen
> https://github.com/dlang/dmd/search?q=toWStringzThen
>
> [...]

We could also have a trailing with to allow  Haskell style blah where blah = xyz code.
« First   ‹ Prev
1 2 3