`with` across function calls
Steven Schveighoffer
schveiguy at gmail.com
Fri Jan 18 14:51:35 UTC 2019
On 1/18/19 7:35 AM, 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.
All you seem to be looking for is a context with specified default
parameters. Why not make a struct?
auto context = With!g;
context.bar();
With opDispatch and introspection, this should be doable.
-Steve
More information about the Digitalmars-d
mailing list