News for hackers. Stuff that matters.
Re:Ruby 3.0 and the new FiberScheduler interface by chrisseaton on Wednesday December 30, 2020 @10:11AM (#25582295)
> It is inevitable that someFunction can only be called once someFuture has completed successfully. No language or technology can change that

This is just not a true statement - and that was the point of the original thread - the original paper on futures had them implemented transparently and able to be passed down into library code not expecting futures. It's also how Haskell's par works today. So it demonstrably can be implemented.

> I believe that the user (at the callsite) should both _know_

Ok but this is just a 'don't do that' argument. If a user tells us they have a good reason to do it, I'm interested in how we can enable them to do that.

> with a library function that just expects 3 values, this is not possible

But it is in Haskell using par, and other languages with more traditional futures.

> Here is how I would write it

Great... but you've rewritten the library code with 'two separate functions instead of one.' My original point was 'because it means existing code that expects a T cannot accept a Future<T>' and you're proving that back to me so hard that you've accepted you need to completely rewrite the code to do it!

Languages with traditional futures would let you just call the original, unmodified library code, with future values instead of actual values, and it would just work.

If you had library code like this, you could pass in future values of T for a, b, and c, and it would execute the expensive_operation on a and b as soon as it could, while c completes.

    def foo(T a, T b, T c)
        expensive_operation(a, b) + expensive_operation(b, c)
    end
> For instance, in your example: what happens if the library decides to always evaluate "c" eagerly even though "a" and "b" often fail and the whole calculation is aborted?

Yes this is a problem with transparent futures, as is the ordering issue you raised. But I wasn't arguing they didn't have their own issues. You're saying it's impossible and that is demonstrably false, because languages do do it.

(I did half of my PhD on these topics, and the other half on Ruby.)

Re:Ruby 3.0 and the new FiberScheduler interface by valenterry on Wednesday December 30, 2020 @10:58AM (#25582743)
> This is just not a true statement - and that was the point of the original thread - the original paper on futures had them implemented transparently and able to be passed down into library code not expecting futures. It's also how Haskell's par works today. So it demonstrably can be implemented.

Okay, technically you are right - however it changes the semantics of the program. I admit that I didn't mention this constraint though.

> Great... but you've rewritten the library code with 'two separate functions instead of one.' My original point was 'because it means existing code that expects a T cannot accept a Future<T>' and you're proving that back to me so hard that you've accepted you need to completely rewrite the code to do it!

> Yes this is a problem with transparent futures, as is the ordering issue you raised. But I wasn't arguing they didn't have their own issues.

I don't disagree with any of that. However, what you originally said:

> > Are you saying that generics on futures are bad?

> Yes - because it means existing code that expects a T cannot accept a Future<T>, which is the colouring problem being discussed.

And you imply that transparent futures are better than the ones with generics. So where we disagree is on what is worse. I am convinced that the problems (and there are certainly a lot of unknowns) you introduce with transparent futures is much worse than the performance you might gain in certain cases and the easier syntax in many cases.

Re:Ruby 3.0 and the new FiberScheduler interface by Rapzid on Wednesday December 30, 2020 @04:03PM (#25586080)
For what it's worth, I believe hiding the semantics of futures is not the way for most languages I use with concurrency primitives either.. And it would seem the language designers agree.

I believe it's important to expose the fact that an asynchronous(potentially parallel) task is doing something for you. The runtime semantics of an assignment would appear the same in code by be very different behind the scenes otherwise. Also, a lot of code is written to manage those tasks in use-case specific ways. How would you race or cancel transparent futures?