-
Notifications
You must be signed in to change notification settings - Fork 55
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
Add stream basic type #406
Comments
According to the spec;
So, in a situation where the stream is defined with int j = 0;
var intStream = stream {
j += 1;
return j;
};
However, if we take a function or a lambda, the
int j = 0;
var intStream = stream<int> {
j += 1;
return j;
};
|
You made a little mistake in your example: the body of stream is supposed to return the same kind of value as an iterator. So it should be As currently designed: int j = 0;
var intStream = stream {
j += 1;
return { value: j };
}; would be a compile-time error. This is similar to how arrow functions require a contextually expected type, e.g.
is also a compile-time error. So you would have to write int j = 0;
stream<int> intStream = stream {
j += 1;
return { value: j };
}; or (if for some reason you cannot specify a variable type) int j = 0;
var intStream = <stream<int>>stream {
j += 1;
return { value: j };
}; I recognize that this is not great, but
But I would welcome other ideas.... |
We need to deal with the possibility that a stream will only be partially consumed, i.e. there is no call to the stream’s next method that returns nil or error. In this case, the stream does not have the opportunity to release resources (file handles, database connections) that it is using. We can provide a close operation on stream, but our stream constructor syntax does not provide a mechanism to specify code that runs on close. I think we may need to change our approach to stream constructor. Any thoughts @grainier? |
Another way to do the constructor would be for the spec to define an abstract basic type |
We should also allow stream<Customer,*> = dbClient->query("SELECT xxx"); The |
We have pushed the initial implementation of stream constructor and other stream related functions. In the current implementation, we desugar the stream constructor body to a lambda function and invoke that lambda function, every time the next function is called. So far this works fine, but as you mentioned, when the stream is partially consumed, we don't have a way to release the resources attached with the stream. For example, there is no API to close a stream returned from the new JDBC connector. With this new basic type, will the current stream constructor syntax be changed to |
The stream constructor syntax would become:
where the static type of expression would be required to belong to the built-in abstract object type I would expect, as you suggest, to have multiple implementations of a Java interface corresponding to StreamProvider. As well as |
I see If we introduce a new abstract object type called "Closable", we can use the term abstract object {
public close() returns error?;
} Since we have a plan to introduce a mechanism to release resources (#427), defining a separate abstract object type will be useful. |
It's a spec-internal name, so it doesn't affect the language what it is called. A Closeable abstract object type for #427 would need to have a |
Another approach would be to define type Foo object {
public function next() returns record {| xml value; |}|error? {
...
}
};
function main() {
Foo foo = new();
var x = new stream<xml,error>(foo);
// or
stream<xml,error> x = new(foo);
} lang.object would then include something along the lines of: # Like @typeParam but scope is object type definition rather than function definition
# default for scope is "function"
@typeParam { scope: "object" }
type ErrorType error;
@typeParam { scope: "object" }
type ItemType any|error;
// This is for map and is method-scoped
@typeParam
type Type1 any|error;
type EmptyIterator object {
public function next() returns () {
return ();
};
};
// This should probably not be public, i.e. users should stream<T,E>
// The binding from stream<T,E> to object:Stream is in the spec
type Stream object {
private abstract object {
public function next() returns record {| ItemType value; |}|ErrorType?;
} impl;
public function __init(abstract object { public function next() returns record {| ItemType value; |}|ErrorType?; } impl
= new EmptyIterator) {
self.impl = impl;
}
public function __iterator() returns abstract object { public function next() returns record {| ItemType value; |}|ErrorType?; } {
final var impl = self.impl;
return new (object {
public function next() returns record {| ItemType value; |}|ErrorType? {
return impl.next();
}
});
}
public function next() returns record {| ItemType value; |}|ErrorType? {
return self.impl.next();
}
public function 'map(function(ItemType val) returns Type1 func) returns stream<Type1,ErrorType> = external;
}; Phew! |
After talking to @hasithaa, we think making it an object type is doable, but requires compiler changes beyond what is realistic for 1.2. We accordingly suggest the following plan: For 1.2:
For 1.3:
The change from 1.2 and 1.3 should not make a difference to most user code. @sanjiva, @sameerajayasoma, @grainier What do you think? |
@jclark @sameerajayasoma Then, shall we proceed with the above plan? There are some dependent tasks pending on this change. |
Looks good .. +1. Lets go for it :). |
Cool. We'll proceed with this.. |
Fix grammar for stream. Add placeholder for explanation. Add reference to lang.stream. Rewrite stream.bal to match new stream design. Part of #406.
@mohanvive @gimantha Changes for stream basic type are in 487b382. Please review and add any problems to this issue. |
@jclark, if I understand correctly, according to the spec
So, this means both implicit & explicit declaration of streams should support type Foo object {
int i = 0;
public function next() returns record {| int value; |}? {
self.i += 1;
return { value: self.i };
}
};
stream streamA = new(foo); // [1] implicit
var streamB = new stream(foo); // [2] explicit Further, according to the spec;
Here, can you please clarify a bit on what you meant by basic type stream? And, If the |
Basic type is defined in the spec. Any stream value belongs to type |
stream<T,E>
is a new basic type representing a lazily constructed sequence of values of type T; it is iterable with error type E.Define
IteratorResult<T,E>
to berecord {| T value; |} | E?
.The
stream:next(stream<T,E>)
lang library function returnsIteratorResult<T,E>
. Other lang library functions as follows:Iterator<T,E>
The semantics of all the above are defined in terms of
next
. There is no length method.Stream constructor has syntax like an anonymous function.
The return type of the function body block for a
stream<T,E>
isIteratorResult<T,E>
.This is part of #340. It depends on #402.
The text was updated successfully, but these errors were encountered: