{"id":4753,"date":"2008-11-18T14:14:00","date_gmt":"2008-11-18T14:14:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2008\/11\/18\/stupid-lambda-tricks\/"},"modified":"2019-02-18T18:53:58","modified_gmt":"2019-02-18T18:53:58","slug":"stupid-lambda-tricks","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/stupid-lambda-tricks\/","title":{"rendered":"Stupid Lambda Tricks"},"content":{"rendered":"<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Hi.<span>&nbsp; <\/span>I&rsquo;m Arjun Bijanki, the test lead for the compiler front-end and Intellisense engine.<span>&nbsp; <\/span>One afternoon a few months ago, I was sitting in my office in building 41 thinking about test passes, when an animated discussion between a couple of colleagues spilled into the hallway and grabbed my attention.<span>&nbsp; <\/span>My recollection is that Boris Jabes, whom some of you might have seen deliver the &ldquo;<\/font><a href=\"https:\/\/channel9.msdn.com\/pdc2008\/TL13\/\"><font face=\"Calibri\" color=\"#0000ff\" size=\"3\">10 is the new 6<\/font><\/a><font face=\"Calibri\" size=\"3\">&rdquo; talk at PDC last week, was trying to convince the other colleague that you could write an automatic <\/font><a href=\"http:\/\/en.wikipedia.org\/wiki\/Memoization\"><font face=\"Calibri\" color=\"#0000ff\" size=\"3\">memoization<\/font><\/a><font face=\"Calibri\" size=\"3\"> function for C++0x lambdas.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">I became intrigued.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">For those that haven&rsquo;t used C++0x lambdas before, the feature provides a way to define unnamed function objects.<span>&nbsp; <\/span>VCBlogger STL wrote up a <\/font><a href=\"http:\/\/blogs.msdn.com\/vcblog\/archive\/2008\/10\/28\/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx\"><font face=\"Calibri\" size=\"3\">great post<\/font><\/a><font face=\"Calibri\" size=\"3\"> that describes lambdas and their syntax in more detail.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Interestingly, lambdas can be recursive.<span>&nbsp; <\/span>For example, here&rsquo;s a lambda that implements the fibonacci series using recursion: <\/font><\/p>\n<p class=\"MsoNormal\"><span>#include<\/span><span>&lt;iostream&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>#include<\/span><span>&lt;functional&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>using<\/span><span> <span>namespace<\/span> std;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>using<\/span><span> <span>namespace<\/span> tr1;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>int<\/span><span> main()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>\/\/ implement fib using tr1::function<\/span><span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>function&lt;<span>int<\/span>(<span>int<\/span>)&gt; fib1 = [&amp;fib1](<span>int<\/span> n) -&gt; <span>int<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>if<\/span>(n &lt;= 2)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> 1;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>else<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> fib1(n-1) + fib1(n-2);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>cout&lt;&lt;fib1(6);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>}<\/span><font size=\"3\"><font face=\"Calibri\"> <span><\/p>\n<p><\/span><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Note that we had to actually <i>name<\/i> the lambda in order to implement the recursion.<span>&nbsp; <\/span>Without a name, how would you make the recursive call?<span>&nbsp; <\/span>This self-referencing places some restrictions on how a recursive lambda can be used; the lambda doesn&amp;rsquo\n;t refer to <i>itself<\/i>, it refers to <\/font><span>fib1<\/span><font face=\"Calibri\" size=\"3\">, which happens to be itself.<span>&nbsp; <\/span>The restriction is subtle, and shown by the following code: <\/font><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>function&lt;<span>int<\/span>(<span>int<\/span>)&gt; fib1_copy = fib1; <span>\/\/ copy fib1<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>fib1 = [](<span>int<\/span> n) { <span>return<\/span> -1; };<span>&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ fib1 now does something else<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><span>cout&lt;&lt;fib1_copy(6);<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ uh oh, doesn&#8217;t do what we expect<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Quiz: what would <\/font><span>fib1_copy(6)<\/span><font size=\"3\"><font face=\"Calibri\"> return? <span><\/p>\n<p><\/span><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Anyway, <\/font><span>fib1 <\/span><font face=\"Calibri\" size=\"3\">isn&rsquo;t a particularly efficient implementation of the algorithm, but, even though I don&rsquo;t come from a functional programming background, I find the recursive solution has a certain elegance.<span>&nbsp; <\/span>By changing this function to cache values it has already computed, we can make it faster:<\/font><\/p>\n<p class=\"MsoNormal\"><span>function&lt;<span>int<\/span>(<span>int<\/span>)&gt; fib2 = [&amp;fib2](<span>int<\/span> n) -&gt; <span>int<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>static<\/span> map&lt;<span>int<\/span>,<span>int<\/span>&gt; cache;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>if<\/span>(n &lt;= 2)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> 1;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>else<\/span> <span>if<\/span>(cache.find(n) == cache.end())<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>cache[n] = fib2(n-1) + fib2(n-2);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> cache[n];<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">(At this point, I should make the caveat that we&rsquo;re really getting into parlor trick territory.<span>&nbsp; <\/span>A functor class is a far better bet for production code, and can do everything here, and more.) <\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Now the function is really hard to read, and I may as well just implement it iteratively.<span>&nbsp; <\/span>This is where the automatic memoization function comes in.<span>&nbsp; <\/span>What we&rsquo;d really like to write is something nice and clean like <\/font><span>fib1<\/span><font face=\"Calibri\" size=\"3\">, but allowing us to memoize it for the faster computation of <\/font><span>fib2<\/span><font face=\"Calibri\" size=\"3\">:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ memoize the fib1 function and find fib(6)<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>memoize(fib1)(6);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">The three of us tried for an hour or so to write the <\/font><span>memoize()<\/span><font face=\"Calibri\" size=\"3\">function, but intercepting <\/font><span>fib1<\/span><font face=\"Calibri\" size=\"3\">&rsquo;s recursion to insert a cache proved difficult. <\/font><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>\/\/ what goes into the highlighted calls?<span>&nbsp; <\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>\/\/ we want to use a cache, not call fib directly.<\/span><span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> <span>fib1<\/span>(n-1) + <span>fib1<\/span>(n-2);<span> <\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\">\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">If we had a function to independently manage the cache, we make the recursive call this way:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> check_cache(fib1,n-1) + check_cache(fib1,n-2);<span> <\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">This is much cleaner than <\/font><span>fib2<\/span><font face=\"Calibri\" size=\"3\">, but even so, I had to intentionally write <\/font><span>fib1 <\/span><font face=\"Calibri\" size=\"3\">to make use of the cache.<span>&nbsp; <\/span>It would be a nicer if I didn&rsquo;t have to do that.<span>&nbsp; <\/span>Eventually, we figured out that we needed a way to hook the recursion and insert our own adapter that checks the cache before making the recursive call.<span>&nbsp; <\/span>That way, we can write <\/font><span>fib1<\/span><font face=\"Calibri\" size=\"3\"> normally, and under the covers check the cache. <\/font><span>tr1::function<\/span><font face=\"Calibri\" size=\"3\"> doesn&rsquo;t seem to support this, so after a couple of tries, I coded up <\/font><span>adaptable_function <\/span><font face=\"Calibri\" size=\"3\">and<\/font><span> memoize_adapter<\/span><font face=\"Calibri\" size=\"3\"> (Warning: Templates Ahead). <\/font><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>template<\/span><span>&lt;<span>class<\/span> Arg&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>struct<\/span><span> adaptable_function<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>tr1::function&lt;Arg(Arg)&gt; func;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>typedef<\/span> tr1::function&lt;Arg(tr1::function&lt;Arg(Arg)&gt;,Arg)&gt; adapter_type;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>adapter_type adapter;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ binds a function<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>adaptable_function(tr1::function&lt;Arg(Arg)&gt; <span>const<\/span>&amp; f) : func(f) <\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ invokes the bound function through an adapter, if one exists<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Arg <span>operator<\/span>()(Arg p) <span>const<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>if<\/span>(adapter)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> adapter(func, p);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>else<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> func(p);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>void<\/span> set_adapter(adapter_type <span>const<\/span>&amp; a)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>adapter = a;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>void<\/span> clear_adapter()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>adapter = adapter_type(); <span>\/\/ better way to clear a tr1::function?<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>private<\/span><span>:<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/relies on self-referential recursion, so the class is non-copyable<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>adaptable_function(adaptable_function <span>const<\/span>&amp;);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\">\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><span style=\"FONT-FAMIL\"><\/span><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi.&nbsp; I&rsquo;m Arjun Bijanki, the test lead for the compiler front-end and Intellisense engine.&nbsp; One afternoon a few months ago, I was sitting in my office in building 41 thinking about test passes, when an animated discussion between a couple of colleagues spilled into the hallway and grabbed my attention.&nbsp; My recollection is that Boris [&hellip;]<\/p>\n","protected":false},"author":289,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4753","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>Hi.&nbsp; I&rsquo;m Arjun Bijanki, the test lead for the compiler front-end and Intellisense engine.&nbsp; One afternoon a few months ago, I was sitting in my office in building 41 thinking about test passes, when an animated discussion between a couple of colleagues spilled into the hallway and grabbed my attention.&nbsp; My recollection is that Boris [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/4753","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/289"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=4753"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/4753\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=4753"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=4753"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=4753"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}