{"id":1156,"date":"2013-07-21T01:00:00","date_gmt":"2013-07-20T23:00:00","guid":{"rendered":"https:\/\/www.fussylogic.co.uk\/blog\/?p=1156"},"modified":"2013-08-05T14:13:26","modified_gmt":"2013-08-05T13:13:26","slug":"la-lambda","status":"publish","type":"post","link":"https:\/\/www.fussylogic.co.uk\/blog\/?p=1156","title":{"rendered":"La Lambda"},"content":{"rendered":"<p>Let\u00e2\u20ac\u2122s say we\u00e2\u20ac\u2122ve loaded a database table into memory and now we want to do some work with it. I\u00e2\u20ac\u2122m imagining a case where we\u00e2\u20ac\u2122ve selected a small subset of records from an enormous table (i.e.\u00c2\u00a0it wasn\u00e2\u20ac\u2122t cheap to fetch) and we want to pull records that meet particular conditions from our subset. Let\u00e2\u20ac\u2122s say it\u00e2\u20ac\u2122s customer transaction records, tens from millions, now we want to display them in various ways in a UI. We\u00e2\u20ac\u2122d rather not increase load on the database for these UI manipulations, so we\u00e2\u20ac\u2122re doing them locally in our client. (I appreciate that I\u00e2\u20ac\u2122m contriving a situation to hang the following examples around)<\/p>\n<p>The subset of records we\u00e2\u20ac\u2122re working with will be represented by a <code>list&lt;TTransactionRecord&gt;<\/code> object, <code>CustomerTransactions<\/code>. Let\u00e2\u20ac\u2122s say that we want this filtered into two lists \u00e2\u20ac\u201c all the debits and all the credits. Here\u00e2\u20ac\u2122s a first pass:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #1<\/span>\n<span class=\"dt\">void<\/span> filterTransactions() {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    <span class=\"co\">\/\/ Expensive database read -- do this once<\/span>\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionDebits;\n    list&lt;TTransactionRecord&gt; TransactionCredits;\n\n    <span class=\"co\">\/\/ Filter for our needs locally<\/span>\n    <span class=\"kw\">for<\/span>( <span class=\"dt\">const<\/span> <span class=\"dt\">auto<\/span> &amp;transaction : CustomerTransactions ) {\n        <span class=\"co\">\/\/ Predicate #1<\/span>\n        <span class=\"kw\">if<\/span>( transaction.isDebit() ) {\n            TransactionDebits.push_back(transaction);\n        }\n    }\n    <span class=\"kw\">for<\/span>( <span class=\"dt\">const<\/span> <span class=\"dt\">auto<\/span> &amp;transaction : CustomerTransactions ) {\n        <span class=\"co\">\/\/ Predicate #2<\/span>\n        <span class=\"kw\">if<\/span>( transaction.isCredit() ) {\n            TransactionCredits.push_back(transaction);\n        }\n    }\n}<\/code><\/pre>\n<p>Fairly typical. I\u00e2\u20ac\u2122ve purposely split the search into two loops, one for each predicate (a predicate just being a fancy word for any object\/function that can be tested for boolean response on a given input).<\/p>\n<p>Whenever you find yourself looping through a container, your first thought should be to reach for one of the C++ algorithms to replace your loop. We\u00e2\u20ac\u2122ll be looking at one in particular here, <code>copy_if()<\/code>. It\u00e2\u20ac\u2122s used like this:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">    <span class=\"ot\">#include &lt;algorithm&gt;<\/span>\n    <span class=\"co\">\/\/ ...<\/span>\n    copy_if( input.cbegin(), input.cend(), output.begin(), PREDICATE );<\/code><\/pre>\n<p>The proviso is that the output iterator must be able to cope with allocating new memory when it is assigned to and incremented. <code>vector&lt;&gt;<\/code> in particular does not support that and will SEGFAULT if you use it as above. The STL has got you covered though. We replace the simple output iterator with a smart iterator:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">    <span class=\"ot\">#include &lt;algorithm&gt;<\/span>\n    <span class=\"ot\">#include &lt;iterator&gt;<\/span>\n    <span class=\"co\">\/\/ ...<\/span>\n    copy_if( input.cbegin(), input.cend(), back_inserter(output), PREDICATE );<\/code><\/pre>\n<p>Magic; <code>back_inserter()<\/code> creates an iterator that converts assignments to, effectively, <code>push_back()<\/code>, which <code>vector&lt;&gt;<\/code> will handle regardless of the memory it already has allocated.<\/p>\n<p><code>PREDICATE<\/code> is the special part here. Before the output is assigned to, the element in question is passed to the function referenced by PREDICATE, which gives a boolean response. Essentially it provides the \u00e2\u20ac\u0153if\u00e2\u20ac\u009d part of our loop.<\/p>\n<p>Let\u00e2\u20ac\u2122s rewrite using <code>copy_if()<\/code>.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #2<\/span>\nbool customerDebitPredicate( <span class=\"dt\">const<\/span> TTransactionRecord &amp;O ) {\n    <span class=\"kw\">return<\/span> O.isDebit();\n}\nbool customerDebitPredicate( <span class=\"dt\">const<\/span> TTransactionRecord &amp;O ) {\n    <span class=\"kw\">return<\/span> O.isCredit();\n}\n\n<span class=\"dt\">void<\/span> filterTransactions() {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionDebits;\n    list&lt;TTransactionRecord&gt; TransactionCredits;\n\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionDebits), customerDebitPredicate);\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionCredits), customerCreditPredicate);\n}<\/code><\/pre>\n<p>It\u00e2\u20ac\u2122s arguable whether this is actually an improvement. It\u00e2\u20ac\u2122s certainly not reduced the number of lines of code enough to be considered simpler; and worse it\u00e2\u20ac\u2122s separated the predicate definitions from their usage. If we\u00e2\u20ac\u2122re reading this code we have now to stop when we reach the <code>copy_if()<\/code> to go and see what the <code>customerDebitPredicate()<\/code> actually does; and it\u00e2\u20ac\u2122s not immediately obvious at that point that <code>customerDebitPredicate<\/code> is a function. However, we\u00e2\u20ac\u2122re not done yet, this is only a step along the way, so let\u00e2\u20ac\u2122s hold our objections for now.<\/p>\n<p>Let\u00e2\u20ac\u2122s take an aside. What <em>is<\/em> a function? Disregarding how it\u00e2\u20ac\u2122s implemented, from our point of view as a user of the language, a function is a reference of a type that supports using the unary operator <code>()<\/code> on it. Compare that with say, the unary postincrement operator <code>++<\/code>. What, fundamentally, is the difference between these two constructs?<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">    x();\n    y++;<\/code><\/pre>\n<p>The answer is: none. The default implementation of <code>operator()()<\/code> (for that is the C++ way of naming the operator we\u00e2\u20ac\u2122re talking about) is to call the reference (for those types that are callable \u00e2\u20ac\u201c function references). C++ grants us the ability to add support for <code>operator()()<\/code> to our own types though, so where this is illegal:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">    <span class=\"dt\">int<\/span> x;\n    x();<\/code><\/pre>\n<p>This might not be:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">    TCustomType x;\n    x();<\/code><\/pre>\n<p>The times it isn\u00e2\u20ac\u2122t illegal is when we have done this:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">class TCustomType {\n  public:\n    <span class=\"dt\">void<\/span> operator()() {\n        <span class=\"co\">\/\/ ... whatever ...<\/span>\n    }\n}<\/code><\/pre>\n<p>Objects of this form are often called <em>function objects<\/em> or <em>functors<\/em>. They\u00e2\u20ac\u2122re objects that \u00e2\u20ac\u0153look like\u00e2\u20ac\u009d functions. With this in mind, let\u00e2\u20ac\u2122s make another change to our filter function:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #3<\/span>\nclass TTransactionDebitPredicate {\n  public:\n    bool operator()( <span class=\"dt\">const<\/span> TTransactionRecord &amp;O ) { <span class=\"kw\">return<\/span> O.isDebit(); }\n}\nclass TTransactionCreditPredicate {\n  public:\n    bool operator()( <span class=\"dt\">const<\/span> TTransactionRecord &amp;O ) { <span class=\"kw\">return<\/span> O.isCredit(); }\n}\n\n<span class=\"dt\">void<\/span> filterTransactions() {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionDebits;\n    list&lt;TTransactionRecord&gt; TransactionCredits;\n\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionDebits), TTransactionDebitPredicate() );\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionCredits), TTransactionCreditPredicate() );\n}<\/code><\/pre>\n<p>Note that the <code>copy_if()<\/code> calls have changed, we have to pass instantiations (albeit temporary ones) of the predicate objects, as the <code>operator()()<\/code> implementations are <em>not<\/em> static, they must be called on an instance.<\/p>\n<p>You might now be thinking, \u00e2\u20ac\u0153this is even worse, it\u00e2\u20ac\u2122s even more complicated than it was\u00e2\u20ac\u009d. Yes, it is; and in C++98 and in this particular case, what I\u00e2\u20ac\u2122ve done here wouldn\u00e2\u20ac\u2122t be justified. I\u00e2\u20ac\u2122ll return to this later, let it slide temporarily. For now, I\u00e2\u20ac\u2122d like to take a detour to show why this particular construction can be made to be useful.<\/p>\n<p>What if we were searching with a predicate more complicated than a simple boolean? Let\u00e2\u20ac\u2122s say we want to filter the transactions so that we get all those above five pounds and all those below zero (i.e.\u00c2\u00a0refunds).<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #4<\/span>\nclass TTransactionBigPredicate {\n  public:\n    bool operator()( <span class=\"dt\">const<\/span> TTransactionRecord &amp;O ) {\n        <span class=\"kw\">return<\/span> O.value() &gt; <span class=\"dv\">5<\/span>;\n    }\n}\nclass TTransactionSmallPredicate {\n  public:\n    bool operator()( <span class=\"dt\">const<\/span> TTransactionRecord &amp;O ) {\n        <span class=\"kw\">return<\/span> O.value() &lt; <span class=\"dv\">0<\/span>;\n    }\n}\n\n<span class=\"dt\">void<\/span> filterTransactions() {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionBigs;\n    list&lt;TTransactionRecord&gt; TransactionSmalls;\n\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionBigs), TTransactionBigPredicate() );\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionSmalls), TTransactionSmallPredicate() );\n}<\/code><\/pre>\n<p>We\u00e2\u20ac\u2122ve gone to all the effort of writing a class to test for greater-than-5. It\u00e2\u20ac\u2122s so specific in purpose that it\u00e2\u20ac\u2122s unlikely it\u00e2\u20ac\u2122ll be needed anywhere else. The compiler will almost certainly optimise the class and call away, so it\u00e2\u20ac\u2122s unlikely to have a runtime cost, but it has a think-time cost. Why bother? The answer is that we wouldn\u00e2\u20ac\u2122t; but with one small change we can suddenly make it worth the bother, and reveal the key power of functors. The key change is to add a constructor. For clarity, I\u00e2\u20ac\u2122ll just do the greater-than-5 version\u00e2\u20ac\u00a6<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #5<\/span>\nclass TTransactionGreaterThanPredicate {\n  public:\n    TTransactionGreaterThanPredicate(<span class=\"dt\">int<\/span> t) : mThreshold(t) {}\n    bool operator()( <span class=\"dt\">const<\/span> TTransactionRecord &amp;O ) {\n        <span class=\"kw\">return<\/span> O.value() &gt; mThreshold;\n    }\n  protected:\n    <span class=\"dt\">int<\/span> mThreshold;\n}\n\n<span class=\"dt\">void<\/span> filterTransactions() {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionBigs;\n\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionBigs), TTransactionGreaterThanPredicate(<span class=\"dv\">5<\/span>) );\n}<\/code><\/pre>\n<p>Look carefully at the magic contained here. <code>copy_if()<\/code> requires a function with a very particular function signature: <code>bool()(const TTransactionRecord &amp;O)<\/code>. We cannot change that signature, so we cannot parameterise that call to suit us. However, by passing a functor that can supply a function of that signature, we are able to parameterise the functor however we like via its constructor. Here we\u00e2\u20ac\u2122ve used a simple literal, but it could be anything \u00e2\u20ac\u201c a reference to another transaction say; an object that reads from a UI settings box; one that fetches a threshold from a file. We can add an arbitrary level of complexity to the predicate without having to change the search function one bit, <code>copy_if()<\/code> remains the same. This can be incredibly powerful. Even more so once you realise that you can even template the functor.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #6<\/span>\ntemplate&lt;typename T&gt;\nclass TGreaterThanPredicate {\n  public:\n    TGreaterThanPredicate(<span class=\"dt\">int<\/span> t) : mThreshold(t) {}\n    bool operator()( <span class=\"dt\">const<\/span> T &amp;O ) {\n        <span class=\"kw\">return<\/span> O.value() &gt; mThreshold;\n    }\n  protected:\n    <span class=\"dt\">int<\/span> mThreshold;\n}\n\n<span class=\"dt\">void<\/span> filterTransactions() {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionBigs;\n\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionBigs),\n        TGreaterThanPredicate&lt;TTransactionRecord&gt;(<span class=\"dv\">5<\/span>) );\n}<\/code><\/pre>\n<p>This is not a practical example, I can\u00e2\u20ac\u2122t think of a time you would use this exact form, but it demonstrates the principle. <code>TGreaterThanPredicate&lt;&gt;<\/code> will supply \u00e2\u20ac\u02dcgreater than\u00e2\u20ac\u2122 functionality for any class that supplies a <code>.value()<\/code> member.<\/p>\n<p>While we\u00e2\u20ac\u2122ve, hopefully, now shown how the extra complexity can be useful and worth having it would be nice if we could get it to be a little less verbose. With C++98 we were stuck. With C++11, we have a new syntax that allows just that: lambdas.<\/p>\n<p>In most respects we\u00e2\u20ac\u2122ve already seen lambdas. They are, in operation, exactly like one of the functors we\u00e2\u20ac\u2122ve already seen. Lambdas are simply syntactic sugar to make it possible to define an anonymous functor inline.<\/p>\n<p>Remember our first objection to splitting the predicates into their own functions? That we made it necessary to break off our reading of the <code>copy_if()<\/code> to read the predicate definition? Lambdas remove that necessity. The syntax for defining a (simple) lambda inline is this:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"dt\">auto<\/span> refToLamba = [](bool param){ <span class=\"kw\">return<\/span> param; };<\/code><\/pre>\n<p>The trigger is the \u00e2\u20ac\u0153<code>[]<\/code>\u00e2\u20ac\u009d, and you then write as you would a function definition, with whatever parameters you wish (those parameters will usually be determined by the caller you\u00e2\u20ac\u2122re passing the lambda to). Let\u00e2\u20ac\u2122s rewrite <em>example #4<\/em> with lambdas to show that happening:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #7<\/span>\n<span class=\"dt\">void<\/span> filterTransactions() {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionBigs;\n    list&lt;TTransactionRecord&gt; TransactionSmalls;\n\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionBigs),\n        [](<span class=\"dt\">const<\/span> TTransactionRecord &amp;O){ <span class=\"kw\">return<\/span> O.isDebit();} );\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionSmalls),\n        [](<span class=\"dt\">const<\/span> TTransactionRecord &amp;O){ <span class=\"kw\">return<\/span> O.isDebit();} );\n}<\/code><\/pre>\n<p>The body of the lambda is the body of the <code>operator()(const TTransactionRecord &amp;O)<\/code> that we wrote in <em>example #4<\/em>. The compiler effectively generates that functor as a temporary when we use the lambda syntax; and we\u00e2\u20ac\u2122re now back to being able to see the predicate inline, but also not having had to do any of the looping work ourselves.<\/p>\n<p>One final piece in the puzzle: just as we were able to add parameters to our functors, we can add parameters to our lambda. There would be little point in using a literal, as we did in <em>example #5<\/em>, we can just write that literal in the lambda body. However, it can be useful to do what\u00e2\u20ac\u2122s called <em>variable capture<\/em>. Let\u00e2\u20ac\u2122s consider a slightly different filter function, that itself takes a parameter.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #8<\/span>\n<span class=\"dt\">void<\/span> filterTransactions(<span class=\"dt\">int<\/span> threshold) {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionBigs;\n\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionBigs),\n        [](<span class=\"dt\">const<\/span> TTransactionRecord &amp;O){ <span class=\"kw\">return<\/span> O.value() &gt; threshold;} );\n}<\/code><\/pre>\n<p>This will fail. The lambda body is not considered part of the scope of <code>filterTransactions()<\/code> and so has no access to the <code>threshold<\/code> variable. What we need is the parameter to be passed as a constructor argument exactly as we did in <em>example #5<\/em>. Lambdas fortunately have a syntax for that.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #9<\/span>\n<span class=\"dt\">void<\/span> filterTransactions(<span class=\"dt\">int<\/span> threshold) {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionBigs;\n\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionBigs),\n        [=threshold](<span class=\"dt\">const<\/span> TTransactionRecord &amp;O){ <span class=\"kw\">return<\/span> O.value() &gt; threshold;} );\n}<\/code><\/pre>\n<p>The <code>[=threshold]<\/code> is the equivalent of adding an <code>int threshold<\/code> data member to the functor, and passing it by value to the functor constructor (just like <em>example #5<\/em>). Lambdas offer additional syntax that let us pass variables in the enclosing scope by <em>reference<\/em> instead of by value. That means we can modify them. That gives us quite a powerful facility. For example:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ Example #10<\/span>\n<span class=\"dt\">void<\/span> filterTransactions(<span class=\"dt\">int<\/span> threshold) {\n    list&lt;TTransactionRecord&gt; CustomerTransactions;\n    CustomerTransactions = dbFetchCustomerTransactions(CUSTOMER_ID);\n\n    list&lt;TTransactionRecord&gt; TransactionBigs;\n\n    <span class=\"dt\">int<\/span> rejectCount = <span class=\"dv\">0<\/span>;\n    copy_if(CustomerTransactions.cbegin(), CustomerTransactions.end(),\n        back_inserter(TransactionBigs),\n        [=threshold, &amp;rejectCount](<span class=\"dt\">const<\/span> TTransactionRecord &amp;O) {\n            <span class=\"kw\">if<\/span>( O.value() &gt; threshold ) {\n                <span class=\"kw\">return<\/span> true;\n            }\n            rejectCount++;\n            <span class=\"kw\">return<\/span> false;\n        });\n    <span class=\"co\">\/\/ rejectCount now tells us how many records _didn&#39;t_ match the<\/span>\n    <span class=\"co\">\/\/ predicate<\/span>\n}<\/code><\/pre>\n<p>There are some additional syntax features of lambdas, but you can simply <a href=\"http:\/\/www.stroustrup.com\/C++11FAQ.html#lambda\">look them up<\/a>. One that\u00e2\u20ac\u2122s particularly worth bearing in mind is the ability to pass <code>this<\/code> as a lambda parameter. That means you can get access to more than just the enclosing scope variables, you can get access to the enclosing object.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let\u00e2\u20ac\u2122s say we\u00e2\u20ac\u2122ve loaded a database table into memory and now we want to do some work with it. I\u00e2\u20ac\u2122m imagining a case where we\u00e2\u20ac\u2122ve selected a small subset of records from an enormous table (i.e.\u00c2\u00a0it wasn\u00e2\u20ac\u2122t cheap to fetch) and we want to pull records that meet particular conditions from our subset. Let\u00e2\u20ac\u2122s say\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.fussylogic.co.uk\/blog\/?p=1156\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[66,82,95,6],"_links":{"self":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1156"}],"collection":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1156"}],"version-history":[{"count":6,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1156\/revisions"}],"predecessor-version":[{"id":1179,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1156\/revisions\/1179"}],"wp:attachment":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1156"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1156"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1156"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}