Scoped values: API design

Ron Pressler ron.pressler at oracle.com
Tue Oct 1 20:55:00 UTC 2019


 
My initial, superficial impression is that the proposal has two prominent features:

1. Allow library code to set up multiple bindings.  
2. Support both a lambda-based and TWR-based scopes.

I think that the latter feature makes the API too rich, and if we can get a good TWR API,  
wrapping it with a lambda-based one is trivial, but not the other way around.

Moreover, AutoCloseables can be easily composed (to close multiple bindings) in a way  
that makes a public ScopedCollection class redundant.

Perhaps the right way is taking it one step at a time, and focus on a TWR approach first.  

Ron  


On 1 October 2019 at 16:21:07, Andrew Haley (aph at redhat.com(mailto:aph at redhat.com)) wrote:

> I've been experimenting with alternatives to try to design a
> reasonable API, with a view to making it as versatile as necessary and
> as small as possible. After a lot of failed attempts I've come up with
> this.
>  
>  
> A class ScopedBinder, which is a tuple of (Scoped name, T value).
>  
> A class ScopedCollection, which is an immutable collection of
> ScopedBinder. ScopedCollection implements run(Runnable) and
> call(Callable).
>  
> A static Scoped method is(T value), which produces an (immutable)
> instance of ScopedBinder.
>  
> A static scoped method collect(ScopedBinder ... values) which
> produces an (immutable) instance of ScopedCollection.
>  
>  
> Putting all this together, if you want to bind some scoped values
> and call some code, you'll:
>  
> Scoped.collect(myVar.is(999), myInt.is(-1)).run(
> () -> System.out.println(myVar.get() + ", " + myInt.get())
> );
>  
> A framework which needs some scoped values to be set can do something
> like this:
>  
> ScopedCollection getBindings() {
> return Scoped.collect(myVar.is(999), myInt.is(-1));
> }
>  
> and the caller would do:
>  
> myFramework.getBindings().run(
> () -> myFramework.start(someArgs)
> );
>  
> It makes sense also to have a shorthand for the single-argument form:
>  
> myVar.is(999).run(
> () -> System.out.println(myVar.get())
> );
>  
>  
> We could keep the bind() methods from my earlier proposal, but I'm not
> sure that they offer anything much.
>  
> With regard to the earlier AutoCloseable variants of the API we could
> also do something like
>  
> try (var x = Scoped.collect(myVar.is(999), myInt.is(-1)).bind()) {
> System.out.println(myVar.get() + ", " + myInt.get());
> }
>  
> but again I'm not sure it offers very much over the Runnable and
> Callable versions and it's far more open to abuse because programmers
> aren't forced to use it in a well-structured way.
>  
> Comments needed!
>  
> --
> Andrew Haley (he/him)
> Java Platform Lead Engineer
> Red Hat UK Ltd.  
> https://keybase.io/andrewhaley
> EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671



More information about the loom-dev mailing list