On Wed, Feb 21, 2018 at 11:31 AM, Steven Watanabe via Boost < boost@lists.boost.org> wrote:
AMDG
On 02/21/2018 10:11 AM, Zach Laine via Boost wrote:
On Wed, Feb 21, 2018 at 10:28 AM, Steven Watanabe via Boost < boost@lists.boost.org> wrote:
On 02/20/2018 11:16 PM, Zach Laine via Boost wrote:
On Tue, Feb 20, 2018 at 9:29 AM, Steven Watanabe via Boost < boost@lists.boost.org> wrote: <snip> That looks like a great candidate for an example, so I made one out of it:
https://github.com/tzlaine/yap/commit/4b383f9343a2a8affaf132c5be1eeb 99a56e58df
<snip> [snip]
evaluate(let(_a = 1_p << 3) [ _a << "1", _a << "2" ], std::cout); // prints 3132, but should print 312
Why should that print out 312? Isn't equivalent to:
std::cout << 3 << "1", std::cout << 3 << "2"
? If not, why not?
The expected behavior is that _a is a local variable, not macro-like substitution.
let(_a=<expr>) [ <body> ]
should be equivalent to
auto _a = <expr>; { <body>; }
rather than:
#define _a <expr> <body>;
Also, let(_a=_a+_a)[let(_a=_a+_a)[let(_a=_a+_a)[...]]] has exponential cost.
Sure. It's also not allowed, though. From the let docs:
Right. Assume the whole thing is wrapped in let(_a=1_p)[] and then it is legal. (each _a refers to the _a in the outer scope.)
I think I get it now. It seems evaluation *must* happen outer-to-inner, not inner-to-outer, and that you need substitutions for things like placeholders so you can do partial evaluations in order to figure out what type a let-placeholder will be. This is the first really compelling use case I have seen for why transform_evaluate() is necessary. Zach