Pushing value to a stream is a very common pattern, used for conditional returns and aggregation.
Currently, the only way to push a value to a stream is via a function call. But functions have strict types, so to keep the type checker happy we need to make a new function with proper types every time. It makes the code very cumbersome.
In the future, we should use (co)functors and (call profunctor optics to fix that better way: with no function execution, keeping the tetraplets untouched. Yet to do that, this pattern should be well identified in the code.
The proposition is to add custom syntax for pushing a value into a stream:
-- It must be a stream, defined in the scope
stream: *u32
-- Push a value into the stream: value may be a literal, a variable, constant, whatever
stream <<- value
Now it can be compiled with Op.identity. Later we will optimize with (apply or some other advanced AIR syntax.
Pushing value to a stream is a very common pattern, used for conditional returns and aggregation.
Currently, the only way to push a value to a stream is via a function call. But functions have strict types, so to keep the type checker happy we need to make a new function with proper types every time. It makes the code very cumbersome.
In the future, we should use (co)functors and
(call
profunctor optics to fix that better way: with no function execution, keeping the tetraplets untouched. Yet to do that, this pattern should be well identified in the code.The proposition is to add custom syntax for pushing a value into a stream:
Now it can be compiled with
Op.identity
. Later we will optimize with(apply
or some other advanced AIR syntax.Related to #200, #187