-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: extend language or stdlib with future-like sync primitive #22293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Some previous discussion: #17466 |
@daskol You don't need features. With future/promise you will increase complexity, without real profit. |
@index0h Sure, it is not necessary to add new language expression. Here I implement future using standard lib. You presisely described my implementation. But what do you mean? In any case anyone will wait for result of execution a line of his or her code.
No, this is completely wrong. Look at definition of channels and futures. Future is read reduction of channel. Both channel and future are high level sync primitives. Channels are usefull in general case, however if it is needed only to get value people use futures(or channels avaliable for reading) to get result. |
Channels provide a capability that is otherwise unavailable in the language. The version of futures that you are presenting is already available in the language. So I don't agree that they are both sync primitives; channels are a primitive and futures can be built on top of channels. It seems to me that you are suggesting some syntactic sugar for a particular channel operation. That then leads to the question: why this sugar? Is this an operation so common that it merits extra support in the language? My guess is that it is not. For example, this syntactic sugar offers no way to cancel the operation if you decide later on that you don't need it. |
@ianlancetaylor I think academia guys do not think so[1]. Moreover, notion of eventual consistency actually is defined with happened-before relation which is promise or future or channel. So, future and channel are located on the same level. Future and channel hardware implementation is based on CAS, TAS or LL/SC operations that are real primitives. In this sence you are right that future is not primitive. In my point of view, such syntactic sugar is usefull at least in web application development. See issue #17466 where @funny-falcon gave examples in context requests to KV storage. Well, the current golang version cancels only with There is another one argument in order to "overload" |
@daskol I agree that futures and channels are on approximately the same level of power, but my point is simply that when you already have channels, you don't also need futures. The paper you cite is describing a system that doesn't have channels, so that the fact they find futures to be useful doesn't tell us much one way or another. Your other comments do not seem to me to be clearly related to this proposal. Perhaps they should be discussed on golang-nuts or some other forum. |
It sounds like a contradiction.
My comment was abount language change.
If you want to use futures, it's ok. But channel is a "generic" type, where you can set type, which it'll process. In futures you can use only interface{} so you must always cast types, or use code generation.
Your example is not working(( Use channels func main() {
result, ok := future.Go(func() future.RType {
time.Sleep(time.Second * 2)
return "test"
}).Get()
println(result.(string), ok)
}
// panic: interface conversion: future.RType is nil, not string Look, I'm writing this because your proposal not solve any problems, but it creates new instrument to resolve same tasks as channels. In golang it'll be just the same. |
Imho, my proposal (#17466) were much more in Go's way. This one is more "lets use technique I learned from other language" than "lets implement useful primitive in a way useful in this language". I could be mistaken. |
The question to ask now is: what can futures do that Go cannot already do with channels and/or package |
@ianlancetaylor Next time I will refer to more sensible papers. However, the paper intoduces notion of future. Everyone should know definition of channel but not future. So now everyone can just compare definition and understand that future and channels for reading are the same. Okay, except one point. You can think that I propose generalization of @index0h You improperly understand the appearance futures in JS. The fact is the simplest way to implement asynchronous behavior like coroutine, generators, channels, etc is to wrap some piece of code in future-promise pairs.
You use my example in wrong way. This is not the right place to explain. (Hint: read from closed channel of type I don't understand rest of your comments. They are quite messy. @funny-falcon Futures, promises and channels is about 40 years old. Well, they are older than almost all modern language. I pull this idea from academia. I suppose that closed form of @andlabs That is not right question. I can you ask similar questions too. What can channels do that Go cannot already do with package |
Try repeate again. In general I propose the following code to be correct in some sence future := go func() int {
return 42
}() The important thing is needed to discuss what properties does |
Yes, I know. And I also proposed future/ivar. I just made it closer to Go's way, I think. And your way is more like C++. I could be mistaken. |
Three things define completely programming language. They are type system, memory model and standard library. In Golang type system is not outstanding for now, quite good standard library and pretty modern memory model which is strong side of language especially in concurrent environment. Bellow I propose how to make strong side of lang stronger.
Motivation
Additional synchonization primitives on the level of standard library or language itself can improve readability and simplify source code. First of all, one should think about future.
The main advantage of future object is that panic can be handled nearby the place where a value of a delayed call is needed. Thus, if panic occures in some go-routine, it is handled in another go-routine. This behavious is relevant for wrapping of external library code.
On the other hand, there is a need to get the result of an asynchronous procedure execution. Certainly, channels could handle such communication issue. They allow a transmision of a value from one go-routine to another where it is required. First, the channel could be represented as a pair of promise object and future object in such communication scheme. However, such representaion is excessive. Second, there is no simple way to get the state of the go-routine execution (only the state of the result).
Examples and proposals
In my opinion, the best way to start is to check out an idiomatic modern C++ implementation.
The C++ example is not exactly portable due to the absence of generic types for now, so it forces us to use dynamic types (interfaces).
Moreover, it seems that it would be better to specify behavior of the
go
keyword in Golang to allow go-routine to return a value and forward panic situation.Probably, more drastic change in the language is an addition of the keyword
await
. It will increase readability and clarity, however, to my mind, this change is too dramatic since it suppresses flexibility and complicates implementation.The text was updated successfully, but these errors were encountered: