Generally speaking you would use the handler if the function that returns the value is asynchronous. In that case the handler is just a callback from the asynchronous process.

You might also pass a handler if the function returning the value might return many values over time. i.e. it runs in a loop and produces intermediate values that have to be handled by the external handler.

Still another scenario is the "Tell-Don't-Ask" discipine which says that no function should return a value, rather they should all forward their results to other functions in other objects. This is not a discipline that I adhere to very closely; but others swear by it.

From: (benc) at 05/24/23 08:27:50 on wss://relay.damus.io

CC: #[3]

>---------------

>#[4]​ I got an interesting question I’d like to hear your take on.

>

>Is there any wisdom when comparing the pros and cons of returning a value versus passing an interface?

>

>// two options for handling a value.

>class Foo {

> int returnValue();

> void passInterface(Handler);

>}

>

>interface Handler {

> void handle(int);

>}

Reply to this note

Please Login to reply.

Discussion

The real life scenario that inspired this quest dealt with life cycle. The value returned was supposed to be used to allow a caller to manage the result.

We found instances where consumers where simply ignoring the result leaving things in a bad state.

The handler forces the consume to provide _something_ to manage the result. I think this fits the Tell Don’t Ask idea.

If I encountered an API that forced me to pass a handler for no reason other than to force me handle a result, I'd be miffed. The handler is inconvenient to say the least. For example, handlers prevent the simple composition of functions.

I cannot say f(g(x)) if g returns its value through a handler.

Instead I have to do something horrible like this:

interface H {handle(x)};

class H_imp : H {x get(); handle(x) {this.x = x;}};

H h = new H_imp;

g(h, x);

f(h.get);

From: (benc) at 05/24/23 08:44:34 on wss://nos.lol

CC: #[4]

>---------------

>The real life scenario that inspired this quest dealt with life cycle. The value returned was supposed to be used to allow a caller to manage the result.

>

>We found instances where consumers where simply ignoring the result leaving things in a bad state.

>

>The handler forces the consume to provide _something_ to manage the result. I think this fits the Tell Don’t Ask idea.

That’s fair.

I think what is goofy in my situation is that I have an internal api that requires orchestration that a consumer shouldn’t have to do in the first place.

I should encapsulate that behavior and just keep it simple.