4 ms·
`Executor.newVirtualThreadPerTaskExecutor` versus `go` really gets to the heart of why I think that Go developers aren't going to be switching. edit: Sorry, it
by insanitybit 3y ago
`Executor.newVirtualThreadPerTaskExecutor` versus `go` really gets to the heart of why I think that Go developers aren't going to be switching.
edit: Sorry, it's actually:
try (var executor =
Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(...)
)
instead of `go`
- kaba0 3y agoSo basically executor.submit(). And you still have a language that is significantly less verbose than go, objectively.
- insanitybit 3y agoYes, if you ignore more than half of the code it's quite concise.
- kaba0 3y agoHow many thread pools do you want to use? You only need that once.
- ivan_gammel 3y agoWrap it in class Go { static void go(…) } and it will look better with “import static”
- insanitybit 3y agoI assume `Go` would have to be Closeable and you'd still need the try-with-resources, right?
- kaba0 3y agoYou don't need a try-with-resources, you can manually call close if you want, or has to work in a non-lexical scope. But you often want the concurrently running threads to return some results, that try-with-resources is part of the structured concurrency that helps you with closing off a branching point, similarly to how we use while loops instead of gotos. `go` in itself corresponds to `goto` basically, with many of the same negatives.
- ivan_gammel 3y agoMaybe you re-read my comment, check the signature of Go::go() and think again?
- deleted 3y ago[deleted]
- erik_seaberg 3y agoYou’re likely to need a lot of boilerplate that “go” statement won’t generate: pass and wait for completed results, report errors, timeouts, cancellation, bounded parallelism, pushback, service monitoring.
- insanitybit 3y agoMy comment is perhaps too glib. I'm not trying to say that Go is better, I frankly like Java more. I only mean that if I'm in a Go mindset and I read the linked document on virtual threads, and I see that code example, I'm going to close the tab.
- deleted 3y ago[deleted]
- mattbee 3y agoStarting a virtual thread in Java isn't that clumsy: Thread.ofVirtual().start(() -> System.out.println("Hello"))
- zaphirplane 3y agoThe go example is missing the channels, select, wait group, context, cancellation Doesn’t sound like a fair comparison thou the Java version is missing things
- insanitybit 3y ago> The go example is missing the channels, select, wait group, context, cancellation The Java version would require all of those in the exact same way though.
- za3faran 3y agoJava has structured concurrency in the works, which will not be much more verbose, unlike golang.
- deleted 3y ago[deleted]
- foolfoolz 3y agogo will always lose vs java when it comes to code verbosity
- lenkite 3y agoExtend that to a full function and the Go code will be 2x more verbose than Java with all the `if err != nil` stuff.
- mike_hearn 3y agoIf you want to use that with more concise syntax, there is Kotlin for that. In which case abstracting that is one line of code tucked away in a utility file: fun <T> go(body: ExecutorService.() -> T): T = Executors .newVirtualThreadPerTaskExecutor() .use(body) Now you can write: val result = go { val result1 = submit { slowOp() } val result2 = submit { blockingOp() } result1.get() + result2.get() } or words to that effect. You can also reduce it a lot in Java too, as mentioned by another commenter. class Shortcuts { static <R> R go(Function<ExecutorService, R> task) throws RuntimeException { try (....) { return task.apply(service) } } } and then you can write: var result = go(service -> { var result1 = service.submit(() -> slowOp()); var result2 = service.submit(() -> blockingOp()); result1.get() + result2.get(); }); using static imports. Now if you're making a cultural point then sure, Java APIs tend to be named quite explicitly. It has advantages when searching or auto-completing, and it's easy to wrap with aliases if you want to abstract a boilerplate pattern away.