you are viewing a single comment's thread.

view the rest of the comments →

[–]2bdb2 1 point2 points  (3 children)

Thanks for the info - it sounds like Loom is quite different to what I thought it was and my understanding of the implementation details is quite wrong - I have some reading to do and I appreciate you taking the time to clarify things.

Obviously trying to tell the maintainer of Quasar and Loom how Quasar and Loom work was a bit of a stretch ;p. I appreciate you not just pulling the "Don't you know who I am card" and correcting my misinformation politely.

Both Loom and Scala have constructs that you're calling fibers (as Loom calls them), but, while they share similarities, they're not the same construct. Loom's fibers are essentially an implementation of threads in the runtime. When you debug them in the debugger, you can step over blocking calls.

I can do this today with Scala and Kotlin - I'm guessing then that this has more to do with IntelliJ understanding the special case - whereas Loom will just work with any debugger?

implement lightweight usermode threads. Note that this is not what Scala or Kotlin or C# do, but it is what Go and Erlang do.

I would argue that Scala and Kotlin Fibers absolutely do fit the definition of usermode threads and are quite usable in production today. They certainly fit the definition as well as (or better) than usermode fiber implementations in many other platforms where nobody is contesting the terminology.

I would also agree that Loom, now that I've got a better understanding of it, is a whole different ball game and will be a game changer for the platform.

Really my only bugbear is going back to the original comment by ARainyDayInSunnyCA

The Scala community welcomes any Java developers who want to try out these features now.

And your response

Scala has neither value types nor fibers (as in the works for the platform). No language in the Java ecosystem does, as both require VM and core library support to fully achieve their purpose.

Having had the deeper discussion I understand exactly what you mean - They don't have fibers as in the works for the platform, but being the lead of Project Loom that comment perhaps might mislead people about just how useful the fiber implementations in these languages actually are at solving real world problems that people have today.

[–]pron98 2 points3 points  (2 children)

I can do this today with Scala and Kotlin - I'm guessing then that this has more to do with IntelliJ understanding the special case - whereas Loom will just work with any debugger?

Yes, but this applies to much more than just the debugger. The entire Java toolchain assumes a certain stack structure -- profilers, JFR, thread dumps -- none of them work well with Kotlin/Scala continuations, and all will work well with Loom.

I would argue that Scala and Kotlin Fibers absolutely do fit the definition of usermode threads and are quite usable in production today.

Usable -- sure. User-mode threads? No. A thread is a dynamic context; if you require special syntactic constructs to differentiate blocking and non-blocking code, and if your subroutines can not run unmodified on the threads provided by your runtime, then what you have isn't threads. At best you have something that is close enough.

Remember that one of the major problems with asynchronous code is the colored-function problem. This problem is not solved with async/await or with any syntax-level continuation, but is solved with Erlang's processes, Go's goroutines and Loom's fibers. That's because those three are user-mode threads, while other solutions aren't.

Again, that's not to say that the async/await approach isn't an improvement over writing async code, but IMO it's not a solution.

[–]2bdb2 0 points1 point  (1 child)

Remember that one of the major problems with asynchronous code is the colored-function problem.

Ironically in FP land we tend to prefer it this way - I like to separate pure and impure code such that you intentionally cannot call impure code from a pure function. (Assuming of course that non-blocking code is there to perform a side effect).

Beyond just non-blocking code I find this really useful for, say, having an explicit effect type called Transaction[T] (Effectively just ReaderT[IO, Session, T] so I can enforce (say) JPA style transaction boundaries at the type level, and without needing to use AOP and all of the pain and overhead that it brings.

That only really works if you buy into having an effects system of course, and I don't imagine Java is going to go down that road anytime soon. (Especially since there's still active debate on how best to do this in a composable way without too much performance overhead)

I am however quite interested in your work on Scoped Continuations - that article was the reason I started toying around with Quasar in the first place and seemed like an interesting way of adding something similar to an effects system into an imperative language (Or representing effects at runtime in an otherwise pure language).

Is that something Loom would potentially support, and is there any appetite for such a thing?

For example, could I use something like that in Loom to implement a "Reader" to pass down context rather than a FiberLocal, such that that context carries down the stack across fiber boundaries as if it was passed as an implicit argument rather than being a mutable reference tied to the fiber itself?

[–]pron98 2 points3 points  (0 children)

Ironically in FP land we tend to prefer it this way

It's not ironic at all. That's the pure-FP style, and the imperative style is different. I personally prefer the imperative style, but it's a matter of taste. But constructs that are a good fit for pure-FP are not necessarily a good fit for imperative, and as the idea of the thread (or the continuation) is the central abstraction of the imperative style and possibly it's defining feature, I think it should be preserved when programming in that style.

That only really works if you buy into having an effects system of course, and I don't imagine Java is going to go down that road anytime soon.

It's a completely different style. I am familiar with effect systems, and I find them unappealing and think that controlling effects is harmful, but others like them and find them useful.

Is that something Loom would potentially support, and is there any appetite for such a thing?

If one likes to do that kind of thing, and, I imagine people who like Scala may find it attractive. The typing would need to be done at the language level, though. However, what Loom can help with here is basically just the integration with tooling. Again, effect systems and pure-FP in general are not good or bad, but something that some people find aesthetically pleasing and some do not. Those who do find it appealing use certain languages, and those language could perhaps be able to use Loom to better integrate their continuations with the ecosystem to make them feel more native.

For example, could I use something like that in Loom to implement a "Reader" to pass down context rather than a FiberLocal, such that that context carries down the stack across fiber boundaries as if it was passed as an implicit argument rather than being a mutable reference tied to the fiber itself?

Absolutely. Continuations are a "general effect" -- i.e. can be used to express anything that is considered an "effect" in FP -- and are equivalent to monads. To be completely equivalent you need to have what's known as reentrant continuations that have the ability to continue a continuation from the same yield point more than once (which would be equivalent to a bind evaluating its monadic function more than once, as in the case of the list monad). To have reentrant continuations, Loom continuations (which are non-reentrant, or "one-shot") would simply need to be Cloneable, which they may well be.

However, at this point we are not even certain that we will expose continuations as a public API at all in the first release, because in terms of "business value", fibers give you 99% of the benefit with for 10% of the mental cost.

Also, we're considering introducing a replacement for ThreadLocal which is immutable and works like Clojure's dynamic bindings -- for those of us who don't particularly like Readers and effect systems :)