`with` across function calls

12345swordy alexanderheistermann at gmail.com
Fri Jan 18 13:51:53 UTC 2019


On Friday, 18 January 2019 at 12:35:33 UTC, Nicholas Wilson wrote:
> So now that I finished moving LDC from my LLVM backend to an 
> externally maintained "backend" I was thinking about how I 
> could improve the design of the API. I was not very happy with 
> the use of globals which basically follow the pattern:
>
> struct Global { void* handle; }
> Global g;
>
> void usercode()
> {
>      g = ...;
>      Foo foo; foo.foo();
>      bar();
>      Bar.baz();
> }
>
> Here foo bar and baz call functions that somewhere down the 
> call need to use `g` at some point. The value of `g.handle` is 
> not going to be change by the library code, but it can't be 
> immutable or const because handle is passes to other functions 
> and it needs to be assignable by the user when they need to 
> initialise it.
>
> I was hoping to be able to change that to something like
> // note no global
> void usercode()
> {
>      auto g = ...;
>      with (g)
>      {
>          Foo foo; foo.foo();
>          bar();
>          Baz.baz();
>      }
> }
>
> but then I realised that I can't pass that implicitly down the 
> call stack even if I change foo, bar and baz. I was reminded of 
> Martin Odersky's DConf Keynote and wondered if implicit 
> parameters could be used to do something like:
>
> void bar(with Global g)
> {
>
> }
>
> or
>
> struct Bar
> {
>     void baz(Global g = with)
>     {
>
>     }
> }
>
> such that
>
> void usercode()
> {
>      {
>          auto g = ...;
>          with (g) // or with g:
>          {
>              bar(); // calls: bar(g);
>          }
>      }
>      // or
>      {
>          with g = ...;
>          Baz.baz(); // calls: Baz.baz(g);
>      }
> }
>
> Obviously this requires a DIP, but what you do think of it?
>
> The example above is a bit simplified, the call that I'm trying 
> to not pass `g`directly to looks like
>
> q.enqueue!(f!(args))(arg_set1)(arg_set2);
>
> and the function within that needs `g` also needs `f`. The 
> expected usage is a whole lot of those calls all in one spot 
> with different `f`, `args`, `arg_set1`, `arg_set2` I really 
> don't want the user to have to repeat themselves anymore than 
> absolutely necessary.

The main issue I see with this is unintentional function calls.
with (g)
{
   bar(); //Meant to call bar() but end up calling bar(g)
}


More information about the Digitalmars-d mailing list