Streams are a convenient, platform-independent type for an enumerable/iterable collection. They are written by suffixing an asterisk (*) to the type of elements expected.
class Example def main is shared pass def bill(customers as Customer*) for c in customers c.billIfNeeded def foo(ints as int*) t = for i in ints where i > 0 print t def bar(ints as int*) t = List<of int>(t) t.sort t.reverse print t
- The general form of a stream type is "Foo*" where "Foo" is the element type.
- The "*" suffix can be thought of as "zero or more".
- The type "Foo*" can be read as "Foo stream" or "stream of Foo(s)".
- Streams can be applied to both primitive and complex types such as "int*" and "Shape*".
- Streams are portable between backends, whereas .NET's IEnumerable<of> and JVM's Iterable<of> are not.
- Streams are two-way compatible with IEnumerable/Iterable:
- Streams can be used whereever a compatible IEnumerable/Iterable is expected.
- An IEnumerable/Iterable can be used whereever a compatible stream type is expected.
- The term "compatible" means the same inner type: int* is compatible with IEnumerable<of int>/Iterable<of int>, but not IEnumerable<of String>/Iterable<of String>
- However, compatibility does not mean that you can use the methods of IEnumerable or Iterable, since these vary between platforms.
- Streams are an abstract type, so you cannot create them directly with a call on the type such as int*(). Instead, use a concrete class such as List<of> or yield results out of a method.
- Streams are defaulted to be empty rather than nil, so you don't have to guard their usage with an "if" statement. You can loop through them immediately.
- Portability and readability are the main motivations for having streams in the Cobra language.
- Also see "Streams" discussion