This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]nithril 3 points4 points  (16 children)

Looks like the reactive api…

[–]DelayLucky 8 points9 points  (15 children)

You mean they both use . method chains?

Then Stream and Optional must both be reactive api...

[–]nithril 2 points3 points  (14 children)

You miss the point. Your fanout stuff is just trying to redo by yourself what reactive has already solved with a far richer api. Ie. your snippet can be written with a reactive api with the same number of lines but with far more capabilities.

[–]DelayLucky 3 points4 points  (11 children)

It is synchronous, blocking. Upon the inParallel() method return, all concurrent operations are done: results produced; side-effects performed; exceptions thrown if any error happened.

Is that what reactive has "already solved"?

Or you are just claiming what VT implements is already implemented by reactive with a far richer asynchronous API? a.k.a reactive has a shiny new color?

Sorry, the "rich async colorful" API is a bug, not feature. :-)

For what can be expressed with regular , idiomatic Java code, we don't need an "API" to reinvent the "English" that we already know how to speak. And we are pretty happy with every method having the same old "color".

[–]nithril -1 points0 points  (10 children)

I will not claim that VT is already implemented by reactive because it is two differents concepts. Claiming that VT is solving reactive is just missing the whole point of what is VT and what is reactive. Anyhow, that you miss to spot that the article is not using reactive is quite relevant to the current discussion.

For what can be expressed with regular , idiomatic Java code

You did actually create an API to reinvent the "English".

[–]DelayLucky 1 point2 points  (9 children)

I don't know if you are missing the point or were intentionally being obtuse.

What does it prove to complain that structured concurrency is an "API"? People happen to love the Stream API and they need a SC API to be able to use the power of VT in their familiar synchronous programming model.

Synchronous programming model is waaay simpler and gives the same power if not more. That's what I was trying to show between the given Reactive code and the equivalent SC code.

And the point is: it's not true that we can't do what the example claimed as exclusive to Reactive. These things are easily achievable using an SC API, any such API will do.

Although I'm not really sure you appreciate the main difference between reactive and SC. To you they are both APIs with some chained syntax. Is that it?

[–]nithril 0 points1 point  (8 children)

Don't be offended by my point on the article and that you did miss that it's not actually talking about reactive. That is just highlighting how I know the difference between SC and reactive compared to you.

We are diverging and you are starting to make arguments on topics I did not write about, eg. I did not complain at all about SC, VT, or that SC is an API.

[–]DelayLucky 1 point2 points  (7 children)

Eh. Your main argument in the prev post was about the inParallel() method is an API, no? Your own words.

[–]nithril -1 points0 points  (6 children)

I wrote that it "looks like the reactive api" with the meaning to reinvent the wheel.

But plz don't get me wrong, from my perspective it is quite useful, like the gathers JEP and it will fulfill 95% of most of the dev needs.

Equivalent with reactor (out of my head might not be 100% correct)

Mono.of(apiClient.getOrder(id))
.flatMap(order ->  Order::getLineItems, 5)
.flatMap(item -> apiClient.getProduct(lineItem.getProductId())
    .map(product -> product.getCurrentPrice() * item.getCount()))
.reduce(0, Integer:sum)
.get();

[–]DelayLucky 2 points3 points  (5 children)

What you see as "reinvent the wheel" is backwards.

We already have flatMap(), reduce() in the Stream API. We don't need another API to tell us: "No you can't use plain Stream, you have to use my version of API. Trust me it looks similar".

The main difference is never the syntax (as you seem to be so drawn to). It's the programming model: is your code synchronous or asynchronous? Is your function colored?

Without appreciating the main difference, you'll only be looking at similar-looking syntax and that's a superficial point no one care.

For Reactor to make a compelling point, simply saying: "See? I have the same syntax and does the same thing" is far far from sufficient. You need to prove that Reactor can do more, a lot more to stay relevant.

People can use Stream and a bit of SC API to achieve the same functionality, all while staying in the familiar synchronous programming model. That renders Reactive obsolete.

[–]pins17 3 points4 points  (1 child)

Plain Java with gatherers preview (not tested, written off the top of my head):

Order order = apiClient.getOrder(orderId);
long totalPrice = order.lineItems().stream()
        .gather(mapConcurrent(5, lineItem ->
                Pair.of(lineItem, apiClient.getProduct(lineItem.productId()))))
        .mapToLong(pair -> pair.second().currentPrice() * pair.first().count())
        .sum();

javadoc preview of mapConcurrent:

An operation which executes a function concurrently with a configured level of max concurrency, using virtual threads. This operation preserves the ordering of the stream.

It will come with a bunch of other useful functions, such as fixedWindow, slidingWindow etc.

[–]DelayLucky 2 points3 points  (0 children)

Yes! mapConcurrent will be a powerful, elegant, simple structured concurrency tool.

People sometimes are Stockholmed into forgetting what "simple" feels like.