Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Clone this wiki locally
Streamline guarantees correct sequencing of statements but does not guarantee that all the subexpressions of a given statement will be evaluated as you would expect them to be. For example:
f(g(1), h(_, 2));
In callback mode, streamline will generate code that evaluates the second argument (
h(_, 2)) before the first one (
g(1)). As a general rule, streamline will evaluate asynchronous subexpressions before the synchronous ones. So you should not write code that relies on the order in which subexpressions will be evaluated (this is dangerous practice anyway).
On the other hand, streamline does preserve sequencing and lazy evaluation of logical and ternary operators. For example:
x = g(1) && h(_, 2); y = g(1) ? h(_, 2) : k(_, 3)
In these statements,
g(1) will be evaluated first and
h(_, 2) will not be evaluated if
g(1) is false.
Note: the transformation engine could be modified to preserve evaluation order in all cases but then the generated code would grow significantly and would be harder to read and debug. I find it preferable to generate lean code and require the programmer to stick to sane programming practices. Also, the fibers and generators modes is different: they generate simpler code that always preserves evaluation order.
The arguments variable
arguments variable must be handled with care inside streamlined functions.
The problem is that this variable contains the magic callback (the
_ parameter) but it hides it from the streamline compiler. The streamline compiler knows about one particular use of this variable:
So, it will correctly transform this call. On the other hand, streamline may become very confused if you start to modify the
arguments variable. For example, you might
splice it, which could change the index of the
_ parameter, or you could extract the
_ callback and call it directly. NEVER DO THIS!