<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Undefined]]></title><description><![CDATA[Undefined]]></description><link>https://anirudhv.xyz</link><generator>RSS for Node</generator><lastBuildDate>Wed, 22 Apr 2026 21:24:18 GMT</lastBuildDate><atom:link href="https://anirudhv.xyz/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Beyond Scale: What Growth Means in B2B]]></title><description><![CDATA[The conventional playbook for engineering growth comes from companies like Google and Facebook; places optimizing for massive scale. But many of us work in B2B, where the challenges are fundamentally different.
Through many conversations with junior ...]]></description><link>https://anirudhv.xyz/beyond-scale-what-growth-means-in-b2b</link><guid isPermaLink="true">https://anirudhv.xyz/beyond-scale-what-growth-means-in-b2b</guid><category><![CDATA[Career]]></category><category><![CDATA[career advice]]></category><category><![CDATA[b2b]]></category><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Wed, 17 Dec 2025 16:30:19 GMT</pubDate><content:encoded><![CDATA[<p>The conventional playbook for engineering growth comes from companies like Google and Facebook; places optimizing for massive scale. But many of us work in B2B, where the challenges are fundamentally different.</p>
<p>Through many conversations with junior engineers over the years, I've seen the confusion this mismatch creates. Here's what growth actually means when complexity, not scale, is your primary challenge.</p>
<h2 id="heading-about-me">About me</h2>
<p>I have been writing software professionally for 13 years now, and worked across the stack with different languages and in different domains (Private Equity, Legal Tech, Finance) and while the language, market and domain kept changing, one thing remained constant: it was always B2B.</p>
<p>I’ve built software and software teams and this article is a combination of my experience as an IC and conversations I had as a manager.</p>
<h2 id="heading-the-scale-assumption">The Scale Assumption</h2>
<p>"Scale" carries outsized weight in software engineering. It's the word that gets thrown around in architecture reviews, used to justify technical decisions, and cited as the benchmark for engineering excellence.</p>
<p>When junior engineers ask me about growth, they often reference the same sources: blog posts from Google engineers optimizing for billions of requests, Meta's approach to managing 129K-GPU clusters, or Shopify handling 284 million requests per minute on Black Friday. The advice is solid; if you're working at that scale.</p>
<p>The problem is, most of us aren't. In B2B software, you're rarely optimizing for billions of users. Your database isn't collapsing under petabytes of data. When performance issues do arise, the solution is usually straightforward: fix an N+1 query, add a queue and worker, or provision more resources.</p>
<p>The conventional wisdom around engineering growth assumes scale is your primary constraint. But in B2B, complexity is what slows you down.</p>
<h2 id="heading-managing-scale-vs-business-complexity">Managing Scale vs (Business) Complexity</h2>
<p>If you've worked in B2B long enough, you've seen this pattern: You build a logical solution to a well-defined problem. Then you take it to customers. They love it, but they need a pre-approval workflow. And a different calculation method for European clients. And an integration with their legacy system. And custom notifications. And exceptions for certain user roles.</p>
<p>Each request makes sense in isolation. But requirements accumulate. What started as a clean, understandable system becomes a maze of conditionals, feature flags, and special cases. Your elegant solution disappears under layers of "if this client, then that behavior."</p>
<p>This is the primary challenge in B2B: <strong>building something that is malleable and extensible, all while it remains simple to reason with.</strong> You need software that can absorb customer-specific needs without collapsing, code that can handle variation without becoming incomprehensible to the next person who touches it. How do you get better at this?</p>
<p>First, <strong>the fundamentals still matter</strong>. Clean code, solid abstractions, good tests - these don’t change, whether you're managing scale of complexity. If anything, complexity makes poor engineering fundamentals more painful. You can’t hide bad design behind throwing more hardware at the problem. But beyond the fundamentals, here are some actionables specific to the B2B environment.</p>
<h2 id="heading-using-retros">Using retros</h2>
<p>Most retros ask what went well and what went badly. That's fine for high level feedback, but it doesn't give you much to act on. A more useful question: what slowed us down this sprint? What took longer than you expected? What felt like a grind?</p>
<p>Not just surprise requirements, or missed planning elements – focus on the engineering papercuts, things you can live with, but they slow you down anyways.</p>
<p>This shifts the conversation from general feedback to specific friction points. You start noticing patterns, the same integration keeps breaking, everyone struggles with the same part of the codebase, estimates are always off for a particular type of work.</p>
<p>From these, you can derive engineering projects and your opportunity to rethink, improve the codebase, maybe try a newer pattern or a library.</p>
<p>As an IC, you might not be able to act on everything immediately, but coming to these meetings prepared to answer these questions forces you to think differently about problems. You develop ideas about what could be better and start learning from the patterns you see.</p>
<p>I learned this late, the subtle shift from <em>what went wrong</em> to <em>what was more complicated than it should</em> lead to a different set of answers, but it was useful.</p>
<h2 id="heading-learn-from-on-call-dont-just-firefight">Learn from on-call, don't just firefight</h2>
<p>Being on-call gives you a unique view of your product that you don't get anywhere else. You see bugs across different subsystems, notice patterns in what breaks, and understand how customers actually use the software in ways that surprise you.</p>
<p>On-call often reveals where complexity manifests as fragility, edge cases you didn't account for, integrations that break under specific conditions, workflows you didn't know existed.</p>
<p>After you've put out the immediate fire, take time to learn from it. This might seem obvious, but in real life, this gets lost under time pressures.</p>
<p>This is your opportunity to identify which subsystems are fragile, where observability is lacking, and what patterns keep causing issues.</p>
<p>It's a chance to build the internal tooling that would have made debugging faster, or to advocate for hardening parts of the system that break too often.</p>
<p>On-call isn't just about fixing things; it's an opportunity to make the next incident easier to handle.</p>
<h2 id="heading-question-why-things-are-the-way-they-are">Question why things are the way they are</h2>
<p>My belief is that people grow when they try to make improvements every day instead of waiting for a large refactoring project to come around. This is something engineers can incorporate in their day-to-day work by questioning the friction they encounter.</p>
<p>Your build pipeline takes 8 minutes and everyone's learned to context-switch during builds. There's a pattern in the codebase that feels overly complex for what it does, but it's been there forever. Your tests are flaky, so the team just reruns them. You're copying the same boilerplate across files because that's how things are structured. These things become background noise.</p>
<p>Good engineers don't accept this. They ask: why am I writing code that doesn't make sense? Why does this need to be structured this way? Why are the builds this slow? These questions feel obvious, but they rarely get asked under delivery pressure.</p>
<p>The answers point to real improvements and learnings, profiling builds to find bottlenecks, refactoring confusing code, fixing flaky tests. You don't need permission to ask these questions or to chip away at the problems you find.</p>
<p>Share what you've noticed with your manager and team. If you've done some research or a small proof of concept, bring that too. Often, you'll find others have noticed the same friction. These conversations surface problems that affect everyone and create opportunities for team-wide improvements.</p>
<h2 id="heading-road-to-staff-engineer">Road to Staff Engineer</h2>
<p>As one goes up the ladder as an IC, the nature of work in terms of projects you do go from work assigned to you to work that you find for yourself. The impact of your work shifts from task local to project local to work that impacts your team too.</p>
<p>The underlying theme of the previous three suggestions is to develop higher-order thinking. Retros teach you to identify systemic problems, not just surface-level issues. On-call teaches you to see patterns across the product, not just individual bugs. Questioning friction teaches you to spot improvement opportunities others have normalized. This is how you move from executing tasks to identifying what needs to be done.</p>
<p>At senior and staff levels, a significant part of your value comes from knowing where to focus effort. You recognize which complexity is essential to the business and which is accidental. You know when to refactor and when to ship. You can look at a system and see not just what's broken, but what could be better.</p>
<p>These aren't skills you develop through large projects alone, they come from paying attention every day to what slows you down and why.</p>
<h2 id="heading-measuring-growth">Measuring Growth</h2>
<p>You'll know you're getting better at managing complexity when the gap between your expectations and reality starts to shrink. You estimate two days, it takes two days. You think a feature will be straightforward, and it mostly is. You anticipate where edge cases will appear, and you're right.</p>
<p>You're developing accurate intuition about where complexity hides in B2B systems. That intuition comes from paying attention to what slows you down, to what breaks in production, to what feels harder than it should be. The practices above are how you build it.</p>
<h1 id="heading-audio">🎤Audio</h1>
<p>I got Notebook LM to generate a conversation with this article at its core, you can listen to the ideas here - <a target="_blank" href="https://drive.google.com/file/d/1HanvXh2z_VfvDbJB6DNdPPfAkvzBilF8/view?usp=sharing">https://drive.google.com/file/d/1HanvXh2z_VfvDbJB6DNdPPfAkvzBilF8/view?usp=sharing</a></p>
<p><strong><em>Note: This article was initially published on LinkedIn -</em></strong> <a target="_blank" href="https://www.linkedin.com/pulse/beyond-scale-what-growth-means-b2b-anirudh-varma-xs2rc/?trackingId=HDE1JFUmeEhAOQ13IqJrlg%3D%3D">https://www.linkedin.com/pulse/beyond-scale-what-growth-means-b2b-anirudh-varma-xs2rc/?trackingId=HDE1JFUmeEhAOQ13IqJrlg%3D%3D</a></p>
]]></content:encoded></item><item><title><![CDATA[Why I support Manchester United]]></title><description><![CDATA[This article is a slightly different one from the usual ramblings I write about, and honestly its born out of discussions with people, online threads the latest one being this tweet where a Manchester United fan from India is being targeted because t...]]></description><link>https://anirudhv.xyz/why-i-support-manchester-united</link><guid isPermaLink="true">https://anirudhv.xyz/why-i-support-manchester-united</guid><category><![CDATA[sports]]></category><category><![CDATA[Manchester United]]></category><category><![CDATA[football]]></category><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Wed, 29 Oct 2025 22:26:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/OvZuM1_WOcQ/upload/f2f10f137d3e8df0b40186007629296f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This article is a slightly different one from the usual ramblings I write about, and honestly its born out of discussions with people, online threads the latest one being this tweet where a Manchester United fan from India is being targeted because they are going to watch a game at Old Trafford.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/ShanmukhSripada/status/1983472380711493694">https://twitter.com/ShanmukhSripada/status/1983472380711493694</a></div>
<p> </p>
<p>Before I get into it, a bit of context about who I am - I am from India, never been to Manchester, used to follow cricket very religiously for a while till the IPL and too much cricket happened and I lost track and interest. I started watching football and “supporting” United somewhere around 2007 or roughly since I was 13/14 years old.</p>
<p>Over the years, I have had quite a few conversations about why we end up supporting teams with different people -</p>
<ol>
<li><p>Those that don’t follow any sports or support any sports teams,</p>
</li>
<li><p>Those that are able to follow their local teams or their national teams and;</p>
</li>
<li><p>Lastly those (largely European football and lately F1) who end up following teams halfway across the globe.</p>
</li>
</ol>
<p>Conversations with the first group are mostly centered around them not being able to comprehend, what leads people to attach so much of their sanity and happiness to random people running around a ball and trying to put it into a net, especially those who don’t play the said sport.</p>
<p>The second group has overcome that challenge, and loves their local team and/or their national team, this would be a kid from Manchester that cries over Manchester United and England or someone from Bangalore that supports RCB and India. But if they don’t also belong to the third group, they often struggle to understand how can someone feel for some random team if they don’t have a local connection to them.</p>
<h2 id="heading-the-short-answer">The Short Answer</h2>
<p>As someone that belongs to the last group (and second), if I had to condense my understanding it would be this -</p>
<blockquote>
<p><strong>Its irrational</strong>, every fan, regardless of how they start supporting a team, has their own story, lore and justifications for why they support the team they do. It might start with a particular player, or silverware or fame, overtime every true fan crosses a threshold where they start feeling for that team and they can no longer answer why they actually support them.</p>
<p>For me it was a sense of community, belonging, the starting point of friendships, hope and of course entertainment.</p>
<p>Supporting a team and watching games - especially with other supporters creates a bond that is difficult to explain, but in that moment you feel like you’ve known those people all your life - and that high is addictive.</p>
</blockquote>
<p>This is my journey to how I became an ardent Manchester United fan, my thoughts on the differences b/w me and a local fan and how Manchester United became a part of who I am.</p>
<h2 id="heading-remember-the-name">Remember the name!</h2>
<p>That’s how it started, I distinctly remember Wayne Rooney being the reason behind me becoming a Manchester United fan. My memory is a little hazy on whether it was a game first or the cover for FIFA 06 that made me curios, but something about Rooney really got me hooked to football (as a spectator) and eventually to Manchester United.</p>
<p>It was all for Wazza initially, watching videos on YouTube and trying to catch some games/highlights on Star Sports and Ten Sports (this was a lot more challenging as a school going kid in India),</p>
<p>Fortunately for me, 2006-09 was a great time to be a Manchester United fan, the team was dominating PL and Europe, was stacked from Goalkeeper to Striker, the squad was a combination of skilled players and strong characters - VDS, Evra, Ferdinand, Vidic, Scholes, Giggs, Wes Brown, Neville and of course the attack of Rooney, Ronaldo and Tevez.</p>
<p><strong>If you already had a reason to follow them, it was very difficult to not fall in love with Manchester United at this time.</strong></p>
<h2 id="heading-understanding-the-game">Understanding the game</h2>
<p>To say that I am not very athletic - would not be wrong, this was even more true when I was 13/14. But whenever I start following a game closely, I do end up putting in time to understand how its played, the tactics and the stories. At that time, more than YouTube, I used to try and catch the random fillers that sports channels used to air which would have some interviews with coaches, managers and players as well as analysis (pre/post game).</p>
<p>And again, if you want to introduce someone to good football in 2006-09 era the few teams you would ask them to watch were Manchester United, Barcelona and maybe Chelsea and since no other team had a player called Wayne Rooney, I ended up with United.</p>
<h2 id="heading-truly-united">Truly United</h2>
<p>After a few years of primarily relying on highlights and somehow catching a few important games, I was finally grown up enough to be able to stay up for games and actually watch them live. This was the time I also discovered the Manchester United community on Reddit - /r/reddevils.</p>
<p>At that time, this was something I did not have IRL - a community of passionate, ardent United followers. It was a mix of local folks from Manchester and fans like me from around the globe, all coming together to celebrate wins, speculate on transfers and rant about losses.</p>
<p>This was the time I started reading a lot more about the history of the club - the founding, being saved from <a target="_blank" href="https://www.manutd.com/en/news/detail/how-a-missing-st-bernard-dog-helped-to-save-manchester-united-from-bankruptcy">bankruptcy because of a dog</a>, the bombing of Old Trafford during the world war, the arrival of Matt Busby, the Busby Babes, the Munich Disaster, the rebuild after and the European glory that followed, the Holy Trinity of Best, Law and Charlton, to how United was relegated, to the Early Fergie Years, the Class of 92, the PL dominance, the 99 treble with the iconic win in Camp Nou, to another rebuild, culminating in the CL win in Moscow in 2008 and beyond with inspirational stories of Matt Busby, Jimmy Muphy, the legend of Duncan Edwards fast forward to the modern era of Alex Ferguson and players like Roy Keane, Paul Scholes, Rooney, Ronaldo, Van Nistelrooy, Jaap Stam and even stories off the field from Carrington.</p>
<p>All of the above - the glory, the hardship but most importantly, the resilience, the mentality is what made me feel for United. Made me cross a point where watching United games and discussing them on online forums (&amp; later friends) became a ritual and often an escape, something to look forward to all week.</p>
<h2 id="heading-on-local-supporter-vs-outsiders">On Local Supporter vs Outsiders</h2>
<p>Ever since I’ve become a fan, I’ve seen and sometimes participated in the discussions around outsiders being true fans, and here is my take on it -</p>
<p><strong>Are we true fans? 100%, definitely yes!</strong> We plan our weekends and sometimes weekdays around United games, we might not purchase season tickets, but still might buy the jersey every now and then, we wake up and stay up at odd hours to watch games - we go crazy when we score, crazier when we win, we sing chants at screenings and can be pretty miserable when we lose (we can be really bad company after a loss).</p>
<p>But, can we compare this to a local? Maybe not. They have a little more skin in the game than we do. Consider a kid who’s a 3rd generation United fan, goes to a school where some kids are 3rd generation City supporters, the amount of banter this kid can get or dish out for that matter is insane, now do this for 38 games in a season, in the classroom, on the play ground, during recess etc and you can see why a local fan might feel a little more entitled than we do.</p>
<p>I do believe that while Manchester United is part of the identity for both sets of fans, the locals just have it a little more than us.</p>
<h2 id="heading-so-why-do-i-support-manchester-united">So, why do I support Manchester United?</h2>
<p>As I said before, I feel every fan ends up creating their own story around this.</p>
<p>In 2006/07, my story was that I like Wayne Rooney, hence I like Manchester United.<br />From 07-09, it might have been that Manchester United is the best team in the world, playing great, attractive, fluid football.</p>
<p>But if it was just these, then today these are not true - Rooney has retired from football, and if you follow football even a little, you would know that Manchester United, since 2014 has not been an easy team to follow.</p>
<p>Today, my answer to that question is - I just do, I love United and what it represents. A storied club without parallel, in persistence, character and history.</p>
<p>The legends that have played on the field and the ones that were on the sidelines, everyone has something to teach or was someone to learn from.</p>
<p>And as I said earlier, it also provides a sense of belonging now, whether it was the online community, a passionate group of friends or just faces you see when you go to a match or screening, you might not know their names, but you recognise them as your people for that match.</p>
]]></content:encoded></item><item><title><![CDATA[Jetbrains AI Assistant Review]]></title><description><![CDATA[I’ve always been a fan of JetBrains products. When I first switched from Eclipse to IntelliJ years ago, I was blown away by how smooth and powerful it was. A true IDE experience offers significantly more power than lightweight editors like VS Code—an...]]></description><link>https://anirudhv.xyz/jetbrains-ai-assistant-review</link><guid isPermaLink="true">https://anirudhv.xyz/jetbrains-ai-assistant-review</guid><category><![CDATA[cursor IDE]]></category><category><![CDATA[#ai-tools]]></category><category><![CDATA[Jetbrains]]></category><category><![CDATA[WebStorm]]></category><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Wed, 12 Mar 2025 07:25:28 GMT</pubDate><content:encoded><![CDATA[<p>I’ve always been a fan of JetBrains products. When I first switched from Eclipse to IntelliJ years ago, I was blown away by how smooth and powerful it was. A true IDE experience offers significantly more power than lightweight editors like VS Code—and this comes from someone who used VS Code daily for almost six years before returning to WebStorm.</p>
<p>Naturally, I wanted to explore what JetBrains had to offer in AI-assisted programming, especially compared to more popular options like Cursor and Windsurf.</p>
<h2 id="heading-the-experience">The Experience</h2>
<p>Having used Cursor previously, I was eager to see how a JetBrains-native AI solution would stack up.</p>
<p><strong>Spoiler alert:</strong> There’s a lot of catching up to do. JetBrains AI Assistant feels about a year behind Cursor in terms of capabilities. To be fair, this may explain why it’s the least expensive of the three options.</p>
<p>The workflow is straightforward—you provide a prompt, and it suggests changes. However, I frequently had to nudge it to account for the right files, particularly my <strong>Prisma Schema</strong> or dependencies in <strong>package.json</strong>. Cursor, in comparison, handled these tasks much more efficiently, requiring fewer manual corrections.</p>
<h2 id="heading-future-developments">Future Developments</h2>
<p>JetBrains is developing an agentic AI plugin called <strong>Junie</strong>, which could significantly improve their AI offerings. However, it’s still in early access and won’t be available for WebStorm initially, making it a non-factor for now.</p>
<h2 id="heading-unexpected-consequences">Unexpected Consequences</h2>
<p>One of the biggest reasons I’m dropping the AI Assistant (for now) isn’t just its lackluster performance—it’s how it degrades WebStorm’s core functionality.</p>
<p>I’ve had the TypeScript service silently fail multiple times, with no resolution from restarting it. This forced me to rely on CLI/build commands to catch errors or switch back to Cursor/VS Code just to see basic file errors.</p>
<p>The AI Assistant also introduced noticeable slowdowns. On several occasions, the editor became sluggish, leaving a full restart as the only fix. Disabling the AI Assistant improved performance slightly, but not enough to justify keeping it enabled.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I still love WebStorm and would prefer to use it as my daily driver. However, paying for both the <strong>IDE license</strong> and <strong>AI Assistant</strong> only makes sense if the AI features enhance, not degrade the core experience.</p>
]]></content:encoded></item><item><title><![CDATA[2024 - Year in Books]]></title><description><![CDATA[Harry Potter Series
I have been a Harry Potter fan since childhood, and to some degree, I credit the series for getting me into reading. 17 years after the release of Harry Potter and the Deathly Hallows, the final installment in the series, I decide...]]></description><link>https://anirudhv.xyz/2024-year-in-books</link><guid isPermaLink="true">https://anirudhv.xyz/2024-year-in-books</guid><category><![CDATA[books]]></category><category><![CDATA[yearinreview]]></category><category><![CDATA[Year End Summary]]></category><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Mon, 30 Dec 2024 22:11:44 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-harry-potter-series">Harry Potter Series</h2>
<p>I have been a Harry Potter fan since childhood, and to some degree, I credit the series for getting me into reading. 17 years after the release of Harry Potter and the Deathly Hallows, the final installment in the series, I decided to reread all of it after a friend gifted me the collection.</p>
<p>I don't usually reread books, but this one was definitely worth it. All nostalgia aside, I think I was able to better appreciate the writing, world-building, and complexity of characters this time compared to when I first read the books.</p>
<p>Another great aspect of rereading a series like this is that you can spot connections that were missed previously. For example, Albus Dumbledore uses the Deluminator in the first scene of the first book, which only reappears in the seventh book when he leaves it for Ron Weasley. The first book came out in 1997, and the seventh one in 2007—this minor detail is just one of many threads that connect the two books.</p>
<p>Reading the series also helped me build some momentum around reading early in the year.</p>
<h3 id="heading-three-body-problem-part-1">Three Body Problem - Part 1</h3>
<p>Continuing with the rereading trend, I picked up the first book (of 3) in the Three-Body series as a refresher before it began streaming on Netflix this year. This turned out to be a great decision again, as I observed details and connections that I had missed previously when reading part 2 (The Dark Forest) and part 3 (Death's End).</p>
<p>The Three-Body Problem books are among the most exhaustive, detailed, and imaginative books I have read, and I don't doubt that if I were to read all of them again, they would be as engaging as they were the first time.</p>
<h3 id="heading-the-last-mughal">The Last Mughal</h3>
<p><a target="_blank" href="https://www.goodreads.com/book/show/124429.The_Last_Mughal">https://www.goodreads.com/book/show/124429.The_Last_Mughal</a></p>
<p>This book by William Dalrymple is a history of the last days of the Mughal Empire in India, but more than that, it's the history of Delhi and its people in the 19th century.</p>
<p>There's a different feeling you experience when you read the history of places you've been to many times, of culture you have experienced firsthand. The Last Mughal does a great job of transporting you to the narrow lanes of 19th-century Delhi. It paints a vivid picture of the different people that lived there, the music they listened to, the food they ate (and that we still get in Delhi), their fights, annoyances, and luxuries.</p>
<p>For me, one of the most fascinating part of the book was reading about different areas (which were not considered part of Delhi then) and mapping them to the mega city and urban center that it has become now.</p>
<p>If you are in Delhi, or have ever lived there, I would definitely recommend reading this.</p>
<h3 id="heading-tuesdays-with-morrie">Tuesday’s with Morrie</h3>
<p><a target="_blank" href="https://www.goodreads.com/book/show/6900.Tuesdays_with_Morrie?ref=nav_sb_noss_l_14">https://www.goodreads.com/book/show/6900.Tuesdays_with_Morrie?ref=nav_sb_noss_l_14</a></p>
<p>As I have called out <a target="_blank" href="https://anirudhv.xyz/tuesdays-with-morrie">here</a>, Tuesday’s with Morrie was not a book I would typically pick up but it was a gift and a quick read, this was probably one of the best books I have read.</p>
<p>It’s a memoir written by Mitch Albom, documenting his many conversations with his terminally ill professor, Morrie Schwartz. The book has conversations on all topics that we think about at some point in our lives — money, love, relationships, meaning, death and emotions etc.</p>
<p>Another book I can see myself revisiting in the coming years.</p>
<h3 id="heading-the-psychopath-test">The Psychopath Test</h3>
<p><a target="_blank" href="https://www.goodreads.com/book/show/12391521-the-psychopath-test?ref=nav_sb_noss_l_8">https://www.goodreads.com/book/show/12391521-the-psychopath-test?ref=nav_sb_noss_l_8</a></p>
<p>Another experimental read, The Psychopath Test follows the authors journey into understanding different kinds of madness.</p>
<p>The book has many interesting stories — like one of a man who scammed his way into the Mental Hospital hoping for nicer amenities and found himself unable to convince the doctors of his sanity for another 20 years.</p>
<p>He talks of the <a target="_blank" href="https://en.wikipedia.org/wiki/Psychopathy_Checklist">Hare Checklist</a> to identify psychopaths, and its shortcomings and through that, advocates for a more balanced approach in diagnosing/labeling mental illness.</p>
<p>Despite the vague (to me) topic of the book, it was an interesting read and very well written.</p>
<h3 id="heading-the-hard-things-about-hard-things">The Hard Things about Hard Things</h3>
<p><a target="_blank" href="https://www.goodreads.com/book/show/18176747-the-hard-thing-about-hard-things?from_search=true&amp;from_srp=true&amp;qid=lWr9972SAX&amp;rank=2">https://www.goodreads.com/book/show/18176747-the-hard-thing-about-hard-things</a></p>
<p>Written by Ben Horowitz, this is one of the most raw accounts of what it takes to build and run companies. I have been an early employee at 2 early stage startups, and I was able to relate to many problems/circumstances described in the book, founders will probably relate even more.</p>
<p>There are plenty of great reviews and discussions about this book out there, but I would definitely recommend this book to anyone who is planning to startup and build their own company.</p>
<h3 id="heading-are-your-lights-on">Are your lights on?</h3>
<p><a target="_blank" href="https://www.goodreads.com/book/show/1044831.Are_Your_Lights_On_?ref=nav_sb_ss_1_19">https://www.goodreads.com/book/show/1044831.Are_Your_Lights_On_?ref=nav_sb_ss_1_19</a></p>
<p>A book recommendation from Reddit, this is a fun read that tries to help you get better at understanding and identifying real problems.</p>
<p>The author describes a problem as — a difference between things as desired and things as percieved;<br />Which can be solved by either by reducing desires or increasing perception.</p>
<p>The book talks about challenges faced in identifying problems, things to be aware of when designing solutions, and other questions you can ask to make sure that we solve the right problems for the right people.</p>
<h3 id="heading-the-golden-road">The Golden Road</h3>
<p><a target="_blank" href="https://www.goodreads.com/book/show/201608148-the-golden-road">https://www.goodreads.com/book/show/201608148-the-golden-road</a></p>
<p>The Golden Road is the latest book by William Dalrymple, it talks about ancient India (the sub-continent) and its role as an economic and cultural powerhouse.</p>
<p>It talks about the eastward spread of Buddhism and Hinduism from India to China and South East Asia, the trade of spices and metals between India and the west (Roman Empire and Egypt) and the rise and fall of different kingdoms and cultures in India and its neighbours.</p>
<p>My only complaint with this one was it felt too wordy at times, but a good read none the less.</p>
<h3 id="heading-essentialism-the-disciplined-pursuit-of-less">Essentialism: The Disciplined Pursuit of Less</h3>
<p><a target="_blank" href="https://www.goodreads.com/book/show/18077875-essentialism">https://www.goodreads.com/book/show/18077875-essentialism</a></p>
<p>Essentialism is a book that promotes the lifestyle of an Essentialist—designing your life by actively making choices (sometimes hard ones) rather than living in default mode. It advocates actively cutting out things that don't truly align with your goals and the way you want to live your life.</p>
<p>The one idea that drives everything in this book is that if you don't actively make choices for yourself, the world or someone else will make them for you. This is true in both your work and personal life.</p>
<p>The book provides a framework and many tools to design an essentialist life.</p>
<p>This is one of the better books I have read in the self-help/productivity genre.</p>
]]></content:encoded></item><item><title><![CDATA[Tuesdays with Morrie]]></title><description><![CDATA[Whenever someone asks me about my hobbies, reading books is probably the first or second thing I talk about, and like most people that read, I have my preferences - Biographies, History, Management/Productivity/Self Help, Sci-Fi and maybe some fictio...]]></description><link>https://anirudhv.xyz/tuesdays-with-morrie</link><guid isPermaLink="true">https://anirudhv.xyz/tuesdays-with-morrie</guid><category><![CDATA[books]]></category><category><![CDATA[book summary]]></category><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Wed, 18 Sep 2024 04:29:37 GMT</pubDate><content:encoded><![CDATA[<p>Whenever someone asks me about my hobbies, reading books is probably the first or second thing I talk about, and like most people that read, I have my preferences - Biographies, History, Management/Productivity/Self Help, Sci-Fi and maybe some fiction here and there.</p>
<p><strong>Tuesdays with Morrie</strong>, a memoir of a sociology professor, was not the kind of book that would typically be on my radar. Gifted by friend, it sat on my book shelf for a few months before I picked it up because I wanted a quick read, and I think I owe them a thanks for sharing this book with me.</p>
<p>Below are some of the highlights from the book —</p>
<blockquote>
<p><em>Over the years, I had taken labour as my companion and pushed everything else to the side.</em></p>
<p>— Mitch</p>
</blockquote>
<h2 id="heading-on-meaning">On Meaning</h2>
<blockquote>
<p><em>The way you get meaning into your life is to devote yourself to loving others, devote yourself to your community around you, and devote your- self to creating something that gives you purpose and meaning. — Morrie</em></p>
</blockquote>
<h2 id="heading-on-death">On Death</h2>
<blockquote>
<p><em>How can you ever be prepared to die?</em><br /><em>"Do what the Buddhists do. Every day, have a little bird on your shoulder that asks, 'Is today the day? Am I ready? Am I doing all I need to do? Am I being the person I want to be?' " — Morrie</em></p>
</blockquote>
<h2 id="heading-on-emotions">On Emotions</h2>
<blockquote>
<p><em>In order to detach from an emotion, one needs to experience it fully. Whether it's sadness, fear or loneliness, in many cases, our first instinct is to try and suppress it.</em></p>
<p><em>But in order to get out of it, you need to let go, experience it fully, then you can say that you know what that emotion exactly is and move away from it. — Morrie</em></p>
</blockquote>
<h2 id="heading-on-ageing">On Ageing</h2>
<blockquote>
<p><em>As you grow, you learn more. If you stayed at twenty-two, you'd always be as ignorant as you were at twenty-two. Aging is not just decay, you know. It's growth. It's more than the negative that you're going to die, it's also the positive that you understand you're going to die, and that you live a better life because of it. — Morrie</em></p>
</blockquote>
<h3 id="heading-on-the-old-envying-the-young">On The old envying the young</h3>
<blockquote>
<p><em>How can I be envious of where you are, when I've been there myself.</em></p>
</blockquote>
<h2 id="heading-on-money">On Money</h2>
<blockquote>
<p><em>Remember what I said about finding a meaningful yourself to loving others, devote yourself to your community around you, and devote yourself to creating some- thing that gives you purpose and meaning.</em></p>
<p>"Do the kinds of things that come from the heart. When you do, you won't be dissatisfied, you won't be envious, you won't be longing for somebody else's things.”</p>
</blockquote>
<h2 id="heading-on-marriage">On Marriage</h2>
<blockquote>
<p>Is there some kind of rule to know if a marriage is going to work? - Mitch</p>
<p>"there are a few rules I know to be true about love and marriage: If you don't respect the don't know how to compromise, you're gonna have a lot of trouble. If you can't talk openly about what goes on between you, you're gonna have a lot of trouble. And if you don't have a common set of values in life, you're gonna have a lot of trouble. Your values must be alike. "And the biggest one of those values, Mitch?" …. "Your belief in the importance of your marriage."</p>
</blockquote>
<h2 id="heading-on-culture">On Culture</h2>
<blockquote>
<p>Here's what I mean by building your own little sub- culture," Morrie said. "I don't mean you disregard every rule of your community. I don't go around naked, for example. I don't run through red lights.</p>
<p><strong>The little things, I can obey. But the big things-how we think, what we value those you must choose yourself. You can't let anyone or any society-determine those for you.</strong></p>
<p>"In the beginning of life, when we are infants, we need others to survive, right? And at the end of life, when you get like me, you need others to survive, right?"</p>
<p>His voice dropped to a whisper. "But here's the secret: in between, we need others as well."</p>
</blockquote>
<h2 id="heading-on-death-and-accepting-it">On Death — and accepting it</h2>
<blockquote>
<p>As long as we can love each other, and remember the feeling of love we had, we can die without ever really going away. All the love you created is still there. All the memories are still there. You live on in the hearts of everyone you have touched and nurtured while you were here....Death ends a life, not a relationship."</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Time Management tips for Senior Engineers]]></title><description><![CDATA[For Senior Engineers and leads in higher positions, time is a very precious resource. Amidst the constant demands for code reviews, brainstorming sessions, planning, meetings, and general assistance, your time to sit down and code often suffers. The ...]]></description><link>https://anirudhv.xyz/time-management-tips-for-senior-engineers</link><guid isPermaLink="true">https://anirudhv.xyz/time-management-tips-for-senior-engineers</guid><category><![CDATA[General Programming]]></category><category><![CDATA[Time management]]></category><category><![CDATA[senior-software-engineer]]></category><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Thu, 11 Jul 2024 14:11:47 GMT</pubDate><content:encoded><![CDATA[<p>For Senior Engineers and leads in higher positions, time is a very precious resource. Amidst the constant demands for code reviews, brainstorming sessions, planning, meetings, and general assistance, your time to sit down and code often suffers. The result? We're left feeling drained and unsatisfied with our productivity by day's end.</p>
<p>This is something that I have personally struggled with and have had multiple conversations about with many people in my team.</p>
<p>One approach that has worked for me, is to structure my work around focused 30 minute blocks - similar to the <a target="_blank" href="https://en.wikipedia.org/wiki/Pomodoro_Technique">Pomodoro technique</a>.</p>
<h2 id="heading-the-30-minute-work-block-why-it-works">The 30-Minute Work Block: Why It Works</h2>
<p>The 30-minute block is not arbitrary. It balances deep focus for you and accessibility for your team. During these blocks, <strong>mute all notifications</strong>. If you're in an open office, a simple "Do Not Disturb" note on your desk or laptop signals to others that you're in deep work mode.</p>
<blockquote>
<p>Worried about emergencies? Trust that if something truly requires your urgent attention, your team will find a way to get through.</p>
</blockquote>
<h2 id="heading-implementing-the-30-minute-strategy">Implementing the 30-Minute Strategy</h2>
<ol>
<li><p><strong>Schedule Your Blocks</strong>: Aim for periods of the day when you’re least likely to be interrupted. In my experience, early mornings or late afternoons often work best.</p>
</li>
<li><p><strong>Communicate Your Availability</strong>: Let your team know about this strategy. A shared calendar or a simple notification can help manage expectations.</p>
</li>
<li><p><strong>Prepare for Transition</strong>: If you're nearing the end of a block and aren't done, leave detailed comments or a <code>//TODO</code> in your code. This ensures you can pick up exactly where you left off without missing a beat.</p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>For senior engineers, the challenge isn’t just about managing time; it's about managing attention. The 30-minute work block is designed to respect your need for deep work while acknowledging your role as a leader and a resource for your team.</p>
]]></content:encoded></item><item><title><![CDATA[The Lucknow Food Trip of 2022]]></title><description><![CDATA[Earlier this week, I, along with a couple of friends visited Lucknow. While Lucknow has several tourist destinations, its a great place for foodies, specially if you are a non-vegetarian.

(Almost) All foods (Clockwise) - Makhan Malai/Daulat Ki Chaat...]]></description><link>https://anirudhv.xyz/lucknow-food-walk-2022</link><guid isPermaLink="true">https://anirudhv.xyz/lucknow-food-walk-2022</guid><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Wed, 23 Nov 2022 00:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1711692635066/74984140-ac96-4d65-bd84-59c2e1c49dbc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Earlier this week, I, along with a couple of friends visited <a target="_blank" href="https://www.tripadvisor.in/Tourism-g297684-Lucknow_Lucknow_District_Uttar_Pradesh-Vacations.html">Lucknow</a>. While Lucknow has several tourist destinations, its a great place for foodies, specially if you are a non-vegetarian.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693504732/c305ff70-7862-43d9-9b28-05e65dbd7b78.jpeg" alt class="image--center mx-auto" /></p>
<p><em>(Almost) All foods (Clockwise) - Makhan Malai/Daulat Ki Chaat, Nihari Kulcha, Idris Biryani, Tunday Kebab &amp; Shukla Chat</em></p>
<h2 id="heading-the-itinerary">The Itinerary</h2>
<p>Between the 3 of us, we wanted to eat the famous Tunday Kebab, Avadhi Biryani, Makhan Malai and Chaat(for the vegetarian among us). Luckily, all these are available in the Chowk, and so we settled on the following itinerary -</p>
<ol>
<li><p>Biryani at Idris Biryani.</p>
</li>
<li><p>Tunday Kebab at Tunday Kebabi.</p>
</li>
<li><p>Nihari at Raheems</p>
</li>
<li><p>Malai Makhan</p>
</li>
<li><p>Chaat at Shukla Chaat, Hazratganj, this was a recommendation from our cab driver.</p>
</li>
<li><p>Bajpayee Kachodi Bhandar, Hazratganj.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693599731/7e1918e1-03d0-4056-8a09-a3e6bfb8357c.jpeg" alt class="image--center mx-auto" /></p>
<p><em>The Streets of the Chowk</em></p>
<h2 id="heading-idris-biryani">Idris Biryani</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693664934/511aa6d0-8e87-45c6-9266-d395a2f3beea.jpeg" alt class="image--center mx-auto" /></p>
<p><em>Outside Idris, not pictured here - the actual biryani</em></p>
<p>My friend is a huge, huge Biryani fan, the kind that can start their day with the rice based delicacy, so naturally he wanted to have some Avadhi Biryani.</p>
<p>Idris was the most interesting experience for me. As soon as you reach, you are greeted with massive vessels slow cooking rice and meat, the smell of the biryani overpowering that of the crowd waiting to get it.</p>
<p>Idris has a small area for sitting, as luck would have it, it was so full, that they ran out of seats &amp; the cutlery. Our biryani was given to us in a box usually seen in traditional sweet shops.</p>
<p>The biryani itself was amazing, the spices were mild, but rich in flavour and the mutton was cooked perfectly. We would have liked one more piece, but at Rs. 150 for a half plate, that’s probably just me being greedy!</p>
<h2 id="heading-tunday-kebab">Tunday Kebab</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693676683/b7649812-a046-41e1-b4b2-926c60a60de7.jpeg" alt class="image--center mx-auto" /></p>
<p><em>Tunday Kebab and Mughlai Paratha</em></p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Tunde_ke_kabab">Tunday Kebab</a> is probably the most famous dish in Lucknow. You get it in both mutton and buffalo meat variants.</p>
<p>Not much to say here, this dish was every bit worth the hype. The kebab’s were soft, melting in your mouth and full of taste. The Mughlai Paratha was buttery, fresh and a perfect foil to the kebabs.</p>
<h2 id="heading-raheems-nihari">Raheem’s Nihari</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693687068/156a4cfd-1ee0-4bda-9f56-3c87df69cd32.jpeg" alt class="image--center mx-auto" /></p>
<p><em>Nihari and Kulcha</em></p>
<p>Right opposite Tunday, is a small, but busy outlet called Raheem’s. Raheem’s Nihari was another local recommendation I am glad I followed.</p>
<p>The slow-cooked stew of buffalo meat, accompanied by fresh kulcha, was tasty, tender and covered in a layer of Ghee.</p>
<p>The Kulcha itself was tasty and fresh and complemented the Nihari perfectly.</p>
<h2 id="heading-makhan-malai">Makhan Malai</h2>
<p>Growing up in the neighbouring city of Kanpur, winters were about foggy mornings, the struggle to get out of your comforter and Makhan Malai. 10 years ago, I moved to Delhi-NCR and then to Bangalore, and Makhan Malai is a dish that you don’t find easily anywhere (except Old Delhi on Winter mornings), naturally, I was so looking forward to reliving those memories.</p>
<p>Makhan Malai takes roughly 8 hours to prepare and is made with milk, cream, sugar, cardamom and dry fruits. Its fluffy, light and subtle in flavor.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693714057/bd233df8-72cb-42b4-a9f6-27ac98d9375f.jpeg" alt class="image--center mx-auto" /></p>
<p><em>Makhan Malai</em></p>
<p>My search for makhan came to an end on the other end of chowk, 10 minutes of walk from Raheem’s and Tunday and it was everything I expected it to be. It was fluffy, not very sweet, and delectable.</p>
<h2 id="heading-shukla-chaat">Shukla Chaat</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693730728/a537c97c-b488-4fb2-9480-3e43e9b113f1.jpeg" alt class="image--center mx-auto" /></p>
<p><em>Aloo Tikki and Pani Puri</em></p>
<p>After waiting patiently all day, it was time for the only vegetarian in the group to have some fun (&amp; food)!</p>
<p>On the recommendation of our cab driver, we made our way to Shukla Chaat in Hazratganj.</p>
<p>We started with Pani Poori (or Golgappe!) and they tasted amazing. The water was just the right amount of spice and the shop keeper offered us extra water for the complete experience.</p>
<p>Following the Pani Poori, was the Aloo Tikki, I don’t know how to describe these flavours, so I’ll just say it was full of flavours, fresh and damn tasty!</p>
<h2 id="heading-bajpayee-kachodi-bhandar">Bajpayee Kachodi Bhandar</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693741503/d22bf341-4d19-40be-beba-5cb9617a5fe6.jpeg" alt class="image--center mx-auto" /></p>
<p><em>The queue outside Bajpayee</em></p>
<p>A short walk from Shukla’s is the Bajpayee Kachodi Bhandar. When we arrived, we had to get in a long-(ish) queue. It was late afternoon, and the Kachodi place had run out of the Kachodi’s. So we opted for a plate of Chole Poori.</p>
<p>The Poori was crispy, deep-fried and the Chole were homely. It was a very familiar and flavour-ful combination.</p>
<hr />
<p>By the time we reached our hotel, all of us were happy, full and satisfied. Lucknow had fulfilled all the promises it made and left us with memories that we will cherish for times to come!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693751283/ccc8149d-5994-497f-a992-335f11170dd3.jpeg" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Repost - Migrating our 4 year old Angular project to a Monorepo]]></title><description><![CDATA[We migrated our conventional Angular workspace to an Nx Monorepo environment. Here’s all you need to know about this migration.
The Article is published on the SpotDraft blog - Read it here
Update: I ended up talking about this at TIL Conf, 2024, you...]]></description><link>https://anirudhv.xyz/spotdraft-monorepo-migration</link><guid isPermaLink="true">https://anirudhv.xyz/spotdraft-monorepo-migration</guid><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Fri, 07 Oct 2022 00:00:00 GMT</pubDate><content:encoded><![CDATA[<p>We migrated our conventional Angular workspace to an Nx Monorepo environment. Here’s all you need to know about this migration.</p>
<p>The Article is published on the SpotDraft blog - Read it <a target="_blank" href="https://web.archive.org/web/20221106072720/https://www.spotdraft.com/blog/frontend-migration-to-monorepo">here</a></p>
<h3 id="heading-update-i-ended-up-talking-about-this-at-til-conf-2024-you-can-find-it-here-httpswwwyoutubecomembedineypmwclvusiwb6g6ycrvkdekmrkampstart1652httpswwwyoutubecomembedineypmwclvusiwb6g6ycrvkdekmrkampstart1652">Update: I ended up talking about this at TIL Conf, 2024, you can find it here - <a target="_blank" href="https://www.youtube.com/embed/IneYPMWCLvU?si=Wb6G6yCrVkDekmRK&amp;start=1652">https://www.youtube.com/embed/IneYPMWCLvU?si=Wb6G6yCrVkDekmRK&amp;start=1652</a></h3>
]]></content:encoded></item><item><title><![CDATA[Book Notes: Psychology of Money]]></title><description><![CDATA[A genius is a man who can do the average thing when everyone else around him is losing his mind - Napolean

Table of Contents

Ronald James Read
Luck & Risk

Bill Gates: A study in Hidden Luck
Not worth the risk


Compounding
Getting Wealthy vs Stayi...]]></description><link>https://anirudhv.xyz/book-notes-psychology-of-money</link><guid isPermaLink="true">https://anirudhv.xyz/book-notes-psychology-of-money</guid><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Sat, 05 Mar 2022 00:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1711692640247/053329f2-c48a-4423-a519-513ad79328f8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="/static/c6c944c44188fa4eea3a6d20163beb54/3a5b9/cover.jpg"><img src="/static/c6c944c44188fa4eea3a6d20163beb54/3a5b9/cover.jpg" alt="Cover" /></a></p>
<blockquote>
<p>A genius is a man who can do the average thing when everyone else around him is losing his mind - Napolean</p>
</blockquote>
<h1 id="heading-table-of-contentstable-of-contents"><a class="post-section-overview" href="#table-of-contents"></a>Table of Contents</h1>
<ul>
<li><a class="post-section-overview" href="#ronald-james-read">Ronald James Read</a></li>
<li><p><a class="post-section-overview" href="#luck--risk">Luck &amp; Risk</a></p>
<ul>
<li><a class="post-section-overview" href="#bill-gates-a-study-in-hidden-luck">Bill Gates: A study in Hidden Luck</a></li>
<li><a class="post-section-overview" href="#not-worth-the-risk">Not worth the risk</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#compounding">Compounding</a></li>
<li><p><a class="post-section-overview" href="#getting-wealthy-vs-staying-wealthy">Getting Wealthy vs Staying Wealthy</a></p>
<ul>
<li><a class="post-section-overview" href="#survival-mentality--money">Survival Mentality &amp; Money</a></li>
<li><a class="post-section-overview" href="#applying-the-survival-mindset">Applying the Survival Mindset</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#tails-you-win">Tails, you win!</a></p>
<ul>
<li><a class="post-section-overview" href="#venture-capital-vs-index-funds">Venture Capital vs Index Funds</a></li>
<li><a class="post-section-overview" href="#tails-drive-everything">Tails drive everything</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#freedom">Freedom</a></li>
<li><p><a class="post-section-overview" href="#wealth-is-what-you-dont-see">Wealth is what you don’t see</a></p>
<ul>
<li><a class="post-section-overview" href="#rich-vs-wealthy">Rich vs Wealthy</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#save-money">Save Money</a></li>
<li><a class="post-section-overview" href="#surprise">Surprise</a></li>
<li><a class="post-section-overview" href="#room-for-error">Room for error</a></li>
<li><a class="post-section-overview" href="#youll-change">You’ll Change</a></li>
<li><a class="post-section-overview" href="#nothings-free">Nothing’s Free</a></li>
<li><p><a class="post-section-overview" href="#you--me">You &amp; Me</a></p>
<ul>
<li><a class="post-section-overview" href="#on-bubbles">On Bubbles</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#the-seduction-of-pessimism">The Seduction of Pessimism</a></li>
<li><p><a class="post-section-overview" href="#when-youll-believe-anything">When You’ll Believe Anything</a></p>
<ul>
<li><a class="post-section-overview" href="#appealing-fiction">Appealing Fiction</a></li>
<li><a class="post-section-overview" href="#incomplete-world-views-and-our-narratives">Incomplete World views and our narratives</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#all-together-now">All together now</a></li>
<li><a class="post-section-overview" href="#confessions">Confessions</a></li>
</ul>
<hr />
<ul>
<li>Doing well with money has little todo with how smart you are and a lot to do with you behave, and long term behaviour change can be difficult to achieve, even for the smartest people.</li>
<li>“Ordinary” people with no financial education can be wealthy if they have a handful of behavioral skills that have nothing to do with formal measure of intelligence.</li>
</ul>
<h1 id="heading-ronald-james-readronald-james-read"><a class="post-section-overview" href="#ronald-james-read"></a>Ronald James Read</h1>
<p>Ronald James Read was an example of using long-term behaviour and discipline to achieve success with money.</p>
<blockquote>
<p>Ronald James Read (October 23, 1921 – June 2, 2014) was an American philanthropist, investor, <strong>janitor, and gas station attendant.</strong></p>
<p>Read amassed a <strong>fortune of almost $8 million</strong> by investing in dividend-producing stocks, avoiding the stocks of companies he did not understand such as technology companies, living frugally, and being a buy and hold investor in a diversified portfolio of stocks with a heavy concentration in blue chip companies.</p>
</blockquote>
<p>Source: <a target="_blank" href="https://en.wikipedia.org/wiki/Ronald_Read_(philanthropist)">Wikipedia</a></p>
<hr />
<h1 id="heading-luck-riskluck-amp-risk"><a class="post-section-overview" href="#luck--risk"></a>Luck &amp; Risk</h1>
<blockquote>
<p>“Our findings suggest that individual investors’ willingness to bear risk depends on personal history.” Not intelligence, or education, or sophistication. Just the dumb luck of when and where you were born.</p>
</blockquote>
<p>Luck and Risk are the reality that every outcome in life is guided by forces other than individual effort.</p>
<p>In theory, people should make investment decisions based on their goals and characteristics of investment options available to them at the time.</p>
<p>However, whatever our goals maybe, our risk taking capacity is tethered to our life experiences, specially in the formative years of one’s life.</p>
<p>If you grow up at a time, when the economy is booming and healthy, and the markets are in a bull run, chances are that you would be investing more of your own money in the stock market, and be open to some riskier bets.</p>
<p>If one grows up in an economy going through a recession, they might prefer <em>Slow and Steady</em> instruments like Bonds and Deposits.</p>
<h2 id="heading-bill-gates-a-study-in-hidden-luckbill-gates-a-study-in-hidden-luck"><a class="post-section-overview" href="#bill-gates-a-study-in-hidden-luck"></a>Bill Gates: A study in Hidden Luck</h2>
<p>Bill Gates attended to one the only high schools in the world that had a computer.</p>
<p>Lakeside School had a computer, linked to a GE Mainframe for time-sharing, this meant that in 8th Grade, Gates had access to a computer more advanced than what most university graduates could access.</p>
<p>At 13, he met classmate Paul Allen who was also obsessed with the computer, the two hit it off, and the rest is history.</p>
<blockquote>
<p>In 1968 there were roughly 303 million high-school-age people in the world, according to the UN.</p>
<p>About 18 million of them lived in the United States. About 270,000 of them lived in Washington state.</p>
<p>A little over 100,000 of them lived in the Seattle area. And only about 300 of them attended Lakeside School.</p>
<p>Start with 303 million, end with 300. One in a million high-school-age students attended the high school that had the combination of cash and foresight to buy a computer.</p>
</blockquote>
<p>Bill Gates happened to be one of them.</p>
<p>Disclaimer: This is not meant to imply that Gates’ success is dumb luck, it still took incredible hard work, persistence and intelligence to achieve.</p>
<blockquote>
<p>If you give luck and risk their proper respect, you realize that when judging people’s financial success—both your own and others’—it’s never as good or as bad as it seems.</p>
</blockquote>
<h3 id="heading-understanding-luckunderstanding-luck"><a class="post-section-overview" href="#understanding-luck"></a>Understanding Luck</h3>
<p>It is important to understand the concept of <em>Hidden Luck</em>, specially when you are trying to learn from lives of others.</p>
<p>It is difficult to identify what is luck and what is skill, and we should not attribute 100% of outcomes to effort and decisions. When learning from others, focus less on specific individuals and case studies, and more on broad patterns.</p>
<blockquote>
<p>Success is a lousy teacher, it seduces smart people into thinking they cannot lose - Bill Gates</p>
</blockquote>
<p>However, the same goes in the other direction, failure can lead smart people into thinking their decisions were terrible when sometimes they just reflect the unforgiving realities of risk.</p>
<h2 id="heading-not-worth-the-risknot-worth-the-risk"><a class="post-section-overview" href="#not-worth-the-risk"></a>Not worth the risk</h2>
<p>There many things never worth risking, no matter the potential gain.</p>
<ol>
<li>Reputation</li>
<li>Freedom and independence</li>
<li>Family and friends</li>
<li>Happiness</li>
</ol>
<p>Your best shot at keeping these thing is knowing when its time to stop taking risks that might harm them. Knowing when you have is <em>enough</em></p>
<blockquote>
<p>“Enough” is realizing that the opposite - an insatiable appetite for more - will push you to the point of regret.</p>
</blockquote>
<hr />
<h1 id="heading-compoundingcompounding"><a class="post-section-overview" href="#compounding"></a>Compounding</h1>
<blockquote>
<p>$81.5B of Warren Buffet’s $84.5B net worth came after his 65th birthday</p>
</blockquote>
<p>If something compounds - if a little growth serves as the fuel for future growth, a small starting base can lead to results so extraordinary they seem to defy logic.</p>
<p>Warren Buffet is a phenomenal investor, but you are missing out if you attach all of his success to investing acumen. The real key to his success, is time.</p>
<p>Buffet started investing when he was 10 years old, had he started investing in his 30s and retired at 60, few people would have ever heard of him.</p>
<p>His skill is investment, but his secret is time - and that is how compounding works.</p>
<ul>
<li>Good investment isn’t necessarily about earning the highest returns, because the highest returns tend to be one-off.</li>
<li>Instead, its about earning pretty good returns that you can stick with and can be repeated for the longest period of time.</li>
</ul>
<hr />
<h1 id="heading-getting-wealthy-vs-staying-wealthygetting-wealthy-vs-staying-wealthy"><a class="post-section-overview" href="#getting-wealthy-vs-staying-wealthy"></a>Getting Wealthy vs Staying Wealthy</h1>
<blockquote>
<p>There are million ways to get wealthy…</p>
<p>But there is only one way of staying wealthy: some combination of frugality and paranoia.</p>
</blockquote>
<ul>
<li>Getting money requires taking risks, being optimistic and putting yourself out there.</li>
<li>Keeping money requires humility, and some fear. It requires acceptance that your current success has some element of luck and therefore is not infinitely repeatable.</li>
<li>The ability to stick around for a long time, without wiping out or being forced to give up, is what makes the biggest difference.</li>
</ul>
<h2 id="heading-survival-mentality-moneysurvival-mentality-amp-money"><a class="post-section-overview" href="#survival-mentality--money"></a>Survival Mentality &amp; Money</h2>
<p>There are 2 reasons why survival mentality is key with money -</p>
<ol>
<li>Few gains are so great that they’re worth wiping yourself out over.</li>
<li>The counterintuitive nature of Compounding.</li>
</ol>
<p>Compounding only works if you can give an asset years and years to grow. But getting and keeping that growth requires surviving all unpredictable ups and downs over time.</p>
<p>A lot of time can be spent to understand Buffet’s success, but that’s hard. Less hard but equally important is pointing out what he did not do -</p>
<ol>
<li>He did not get carried away with debt.</li>
<li>He did not panic sell during recessions, and he lived through 14.</li>
<li>He did not gamble on his reputation.</li>
<li>He did not attach himself to one world view or trend.</li>
<li>He did not rely on others’ money</li>
<li>He did not burn himself out, quit or retire</li>
</ol>
<blockquote>
<p>Having and ‘edge’ and surviving are two different things: the first requires the second. You need to avoid ruin. At all costs. - Nassim Taleb</p>
</blockquote>
<h2 id="heading-applying-the-survival-mindsetapplying-the-survival-mindset"><a class="post-section-overview" href="#applying-the-survival-mindset"></a>Applying the Survival Mindset</h2>
<h3 id="heading-financially-unbreakablefinancially-unbreakable"><a class="post-section-overview" href="#financially-unbreakable"></a>Financially Unbreakable.</h3>
<p><strong>More than I want big returns, I want to be financially unbreakable</strong>. And if I’m unbreakable, I actually think I’ll be able to get biggest returns, because I’ll be able to stick around long enough for compounding to work wonders.</p>
<p>Compounding does not rely on earning big returns, fast. <em>Good enough</em> returns sustained uninterrupted for the longest period will always win.</p>
<h3 id="heading-plan-for-the-plan-not-going-wellplan-for-the-plan-not-going-well"><a class="post-section-overview" href="#plan-for-the-plan-not-going-well"></a>Plan for the plan not going well</h3>
<ul>
<li>A plan is only useful if it can survive reality. And a future filled with unknowns is everyone’s reality.</li>
<li>A good plan embraces and emphasizes room for error.</li>
<li>The more you need specific elements of a plan to be true, the more fragile your plan becomes.</li>
</ul>
<p>You should be able to say -</p>
<blockquote>
<p>It will be great if the market returns 10% over the next 30 years, but if it only does 5%, I’ll still be OK.</p>
</blockquote>
<p>Margin of safety, is one of the most underappreciated forces in finance. It comes in many forms, frugal budget, flexible thinking and loose timelines.</p>
<p>This is different from being conservative, conservative is avoiding certain level of risk, while margin of safety is raising the odds of success at a given level of risk by increasing the chances of survival.</p>
<h3 id="heading-sensible-optimismsensible-optimism"><a class="post-section-overview" href="#sensible-optimism"></a>Sensible Optimism</h3>
<p>Optimism is the belief that things will go well, but that is incomplete. Sensible Optimism is a belief that the odds are in your favour and overtime things will balance out to a good outcome, even if there are some bumps along the road.</p>
<hr />
<h1 id="heading-tails-you-wintails-you-win"><a class="post-section-overview" href="#tails-you-win"></a>Tails, you win!</h1>
<p>Long tails, the farthest ends of a distribution of outcomes, have tremendous influence in finance, where a small number of events can account for majority of outcomes.</p>
<blockquote>
<p>Its not easy to understand that an investor can be wrong half the time and still make a fortune. It means that we underestimate how normal it is for a lot of things to fail.</p>
</blockquote>
<h2 id="heading-venture-capital-vs-index-fundsventure-capital-vs-index-funds"><a class="post-section-overview" href="#venture-capital-vs-index-funds"></a>Venture Capital vs Index Funds</h2>
<ul>
<li>Venture Capital is a tail-driven industry, if a VC makes 50 investments, they likely expect half of them to fail.</li>
<li>10 are expected to do pretty well;</li>
<li>and 1 or 2 are expected to drive 100% of the fund’s returns.</li>
</ul>
<p>While most people (rightly) view venture capital as a risky business, the distribution of success among large public stocks over time is not much different than venture capital.</p>
<p>Most financial advice is about <em>today</em>, but today is not that important. Over the course of your lifetime as an investor, the decisions you make today or tomorrow will not matter as much as what you do during those rare days, when everyone else around you is going crazy.</p>
<blockquote>
<p>Your success as an investor is determined by how you react to punctuated moments of terror, not the years spent on cruise control.</p>
</blockquote>
<h2 id="heading-tails-drive-everythingtails-drive-everything"><a class="post-section-overview" href="#tails-drive-everything"></a>Tails drive everything</h2>
<p>When you accept that tails drive everything in business, investing and finance, you realize that its normal for lots of things to go wrong, break, fail and fall.</p>
<blockquote>
<p>If you’re terrific in this business, you’re right six times out of ten - <a target="_blank" href="https://en.wikipedia.org/wiki/Peter_Lynch">Peter Lynch</a></p>
</blockquote>
<p>No investor or entrepreneur makes the right decision all the time. Most successful people are packed with horrendous ideas that are often acted upon.</p>
<blockquote>
<p>Investing is not about how often you are right vs wrong, its about how much money you made when you were right, and how much did you loose when you were wrong.</p>
</blockquote>
<p>You can be wrong half the time, and still make a fortune.</p>
<h1 id="heading-freedomfreedom"><a class="post-section-overview" href="#freedom"></a>Freedom</h1>
<ul>
<li>THE HIGHEST FORM of wealth is the ability to wake up every morning and say, “I can do whatever I want today.”</li>
<li>The ability to do what you want, when you want, with who you want, for as long as you want is priceless. Its the highest dividend money pays.</li>
<li>Money’s greatest intrinsic value, is its ability to give you control over your time.</li>
<li>Using your money to buy time and options has a lifestyle benefit few luxury goods can compete with.</li>
</ul>
<h1 id="heading-wealth-is-what-you-dont-seewealth-is-what-you-dont-see"><a class="post-section-overview" href="#wealth-is-what-you-dont-see"></a>Wealth is what you don’t see</h1>
<blockquote>
<p>Spending money to show people how much money you have is the fastest way to have less money</p>
</blockquote>
<ul>
<li>We judge wealth by what we see, because that is the information in front of us, hence we rely on appearances to gauge financial success - Cars, Homes &amp; Social Media photos.</li>
<li>Modern capitalism is making it easy to fake it.</li>
<li>True wealth is what what you don’t see.</li>
<li>Wealth is the car not purchased, the diamond not bought, the first class upgrade declined.</li>
<li>Wealth are the financial assets not converted into things you can see.</li>
<li>When most people think about being a millionaire, they mean they want to spend a million dollars, which is the opposite of being a millionaire.</li>
</ul>
<blockquote>
<p>if you spend money on things, you will end up with things, not money.</p>
</blockquote>
<h2 id="heading-rich-vs-wealthyrich-vs-wealthy"><a class="post-section-overview" href="#rich-vs-wealthy"></a>Rich vs Wealthy</h2>
<p><strong>Rich</strong> is the current income. Someone driving a BMW is almost certainly rich, because even if they purchased it with debt, you need a certain level of monthly income to afford that debt.</p>
<p><strong>Wealth</strong> is hidden, its the income not spent. Its values lies in offering you options, flexibility and growth to one day purchase more stuff than you could right now.</p>
<p>Diet and exercise offer a useful analogy, exercise is like being rich. You think, “I did the work and now deserve a treat”, wealth is turning down the treat meal and actually burning net calories.</p>
<blockquote>
<p>The problem is that it is very easy to find rich role models, its harder to find wealthy ones because by definition their success is more hidden.</p>
</blockquote>
<p>This is not to say that wealthy people are not spending crazy money on stuff. The difference is that we see the home they bought, not the one they could have bought had they stretched themselves thin.</p>
<h1 id="heading-save-moneysave-money"><a class="post-section-overview" href="#save-money"></a>Save Money</h1>
<ul>
<li>Past a certain level of income people fall into three groups: Those who save, those who don’t think they can save, and those who don’t think they need to save.</li>
<li>Building wealth has little to do with your investments or income and lots to do with your savings rate.</li>
<li>When compared to investing, personal savings and frugality, are parts of the money equation that are more in your control and have a 100% chance of being as effective in the future as they are today.</li>
<li>Learning to be happy with less money creates a gap b/w what you have and what you want - similar to the gap you get from growing your paycheck, but easier and more in you control.</li>
<li><strong>Past a certain level of income, what you need is just what sits below your ego.</strong></li>
<li>The most powerful way of increasing you savings is not to raise your income, but to increase your humility.</li>
<li>When you define savings as the gap b/w your ego and your income, you realize why so many people with decent incomes save so little.</li>
<li><strong>People with enduring personal finance success, tend to have a propensity to not give a damn what others think about them.</strong></li>
<li>You don’t need a specific reason to save.</li>
<li>Saving is a hedge against life’s inevitable ability to surprise the hell out of you at the worst possible moment.</li>
<li>Intelligence is not a reliable advantage in a connected world, flexibility is.</li>
</ul>
<h1 id="heading-surprisesurprise"><a class="post-section-overview" href="#surprise"></a>Surprise</h1>
<blockquote>
<p>History is the study of change, ironically used as a map of the future.</p>
</blockquote>
<ul>
<li>Things that have never happened before happen all the time.</li>
<li>A trap many investors fall into is what I call “historians as prophets” fallacy: An over-reliance on past data as a signal to future conditions in a field where innovation and change are the lifeblood of progress.</li>
<li>Investing is not a hard science, its a massive group of making imperfect decisions with limited information about things that will have a massive impact on their wellbeing, which can make even smart people nervous, greedy and paranoid.</li>
<li>The most important driver of anything tied to money is the stories people tell themselves and the preferences they have for goods and services.</li>
</ul>
<p>Two dangerous things happen when you rely too heavily on investment history as a guide to what’s going to happen next.</p>
<ol>
<li><p>You’ll likely miss the outlier events that move the needle the most</p>
<ol>
<li>A very, very small number of people were responsible for majority of the world’s direction in the last century.</li>
<li>The majority of what’s happening at any given moment in the global economy can be tied back to a handful of past events that were nearly impossible to predict.</li>
<li>The most important economic events of the future—things that will move the needle the most—are things that history gives us little to no guide about. They will be unprecedented events.</li>
</ol>
</li>
<li><p>History can be a misleading guide to the future of the economy and stock market because it doesn’t account for structural changes that are relevant to today’s world.</p>
<ol>
<li>Venture capital as an industry is barely 30 years old, before that people heavily relied on generosity of bankers. This means, that all historical data, before that is already out of date.</li>
<li>The S&amp;P 500 did not include financial stocks until 1976; today, financial make up 16% of the index. Technology stocks were virtually nonexistent 50 years ago. Today, they’re more than a fifth of the index. Accounting rules have changed over time.</li>
</ol>
</li>
</ol>
<p>The further back in history you look, the more general your takeaways should be. General things like people’s relationship to greed and fear, how they behave under stress, and how they respond to incentives tend to be stable in time. The history of money is useful for that kind of stuff.</p>
<p>But specific trends, specific trades, specific sectors, specific causal relationships about markets, and what people should do with their money are always an example of evolution in progress. Historians are not prophets.</p>
<h1 id="heading-room-for-errorroom-for-error"><a class="post-section-overview" href="#room-for-error"></a>Room for error</h1>
<blockquote>
<p>The most important part of every plan is planning on your plan not going according to plan.</p>
</blockquote>
<ul>
<li>There is never a moment when you’re so right that you can bet every chip in front of you.</li>
<li>History is littered with good ideas taken too far, which are indistinguishable from bad ideas.</li>
<li>Margin of Safety, or room for error is the only way to safely navigate a world governed by odds not certainties.</li>
<li>People underestimate the room for error; the person who speaks in absolutes will have more followers than the one who speaks in probabilities.</li>
<li>The person with enough room for error in part of their strategy (cash) to let them endure hardship in another (stocks) has an edge over the person who gets wiped out, game over, insert more tokens, when they’re wrong.</li>
<li>You can plan for every risk except the things that are too crazy to cross your mind. And those crazy things can do the most harm, because they happen more often than you think and you have no plan for how to deal with them.</li>
<li>A good rule of thumb for a lot of things in life is that everything that can break will eventually break.</li>
</ul>
<blockquote>
<p>The biggest single point of failure with money is a sole reliance on a paycheck to fund short-term spending needs, with no savings to create a gap between what you think your expenses are and what they might be in the future.</p>
</blockquote>
<hr />
<h1 id="heading-youll-changeyoull-change"><a class="post-section-overview" href="#youll-change"></a>You’ll Change</h1>
<blockquote>
<p>Long-term planning is harder than it seems because people’s goals and desires evolve over time.</p>
</blockquote>
<ul>
<li>Imagining a goal is easy and fun. Imagining a goal in the context of realistic life stresses that grow with competitive pursuits is something entirely different.</li>
<li>The first rule of compounding is to never interrupt it unnecessarily.</li>
<li>We should avoid extreme ends of financial planning. Assuming you will be happy with a low income, or choosing to work endless hours in pursuit of a higher income increases the odds that you will, one day find yourself at a point of regret.</li>
<li>Aiming, at every point in your working life, to have moderate annual savings, moderate free time, no more than a moderate commute, and at least moderate time with your family, increases the odds of being able to stick with a plan and avoid regret than if any one of those things fall to the extreme sides of the spectrum.</li>
<li>Sunk costs are a devil in a world where people change over time. They make our future selves, prisoners to our past, different selves.</li>
<li>Embrace the idea that financial goals made when you were a different person should be abandoned without mercy can be a good strategy to minimize future regret.</li>
</ul>
<hr />
<h1 id="heading-nothings-freenothings-free"><a class="post-section-overview" href="#nothings-free"></a>Nothing’s Free</h1>
<ul>
<li>Most things are harder in practice than they are in theory. Sometimes, this is because we are overconfident. Mostly, its because we are not good at identifying the cost of success, which prevents us from being able to pay it.</li>
<li>Successful investing demands a price. Its currency however is volatility, fear, doubt, uncertainty and regret.</li>
<li>The volatility/uncertainty fee—the price of returns—is the cost of admission to get returns greater than low-fee parks like cash and bonds.</li>
</ul>
<hr />
<h1 id="heading-you-meyou-amp-me"><a class="post-section-overview" href="#you--me"></a>You &amp; Me</h1>
<ul>
<li>Blaming bubbles on greed and stopping there misses important lessons about how and why people rationalize what in hindsight look like greedy decisions.</li>
<li><strong>Investors often take cues from other investors who are playing a different game than they are.</strong></li>
<li>When investors have different goals and time horizons, and they do in every asset class, prices that look ridiculous to one person can make sense to another.</li>
<li>A day trader can pick up an extremely risky stock, because they will hold it for a few hours, that does not make it a good fit for someone looking at a 2,5 or 10 year horizon.</li>
<li>It’s hard to grasp that other investors have different goals than we do, because an anchor of psychology is not realizing that rational people can see the world through a different lens than your own.</li>
</ul>
<h2 id="heading-on-bubbleson-bubbles"><a class="post-section-overview" href="#on-bubbles"></a>On Bubbles</h2>
<ul>
<li>Bubbles form when the momentum of short-term returns attracts enough money that the makeup of investors shifts from mostly long term to mostly short term.</li>
<li>The mere idea of a bubble is controversial, because no one wants to think they own an overvalued asset.</li>
<li>Bubbles aren’t so much about valuations rising, its a symptom of time horizons shrinking as more short term traders enter the playing field.</li>
<li>The formation of bubbles isn’t so much about people irrationally participating in long-term investing. They’re about people somewhat rationally moving toward short-term trading to capture momentum that had been feeding on itself.</li>
</ul>
<h1 id="heading-the-seduction-of-pessimismthe-seduction-of-pessimism"><a class="post-section-overview" href="#the-seduction-of-pessimism"></a>The Seduction of Pessimism</h1>
<blockquote>
<p>For reasons I have never understood, people like to hear that the world is going to hell - Historian Deirdre McCloskey</p>
</blockquote>
<ul>
<li>Pessimism sounds smarter than optimism.</li>
<li>Real optimists don’t believe that everything will be great. That’s complacency.</li>
<li>Optimism is a belief that the odds of a good outcome are in your favour over time, even when there will be setbacks along the way.</li>
<li>Pessimism just sounds smarter and more plausible than optimism.</li>
<li>Few question or try to explain why the market went up—isn’t it supposed to go up?—there is almost always an attempt to explain why it went down.</li>
<li>There are two topics that will affect your life whether you are interested in them or not: money and health. While health issues tend to be individual, money issues are more systemic.</li>
<li>There is an iron law in economics: extremely good and extremely bad circumstances rarely stay that way for long because supply and demand adapt in hard-to-predict ways.</li>
<li>There are lots of overnight tragedies. There are rarely overnight miracles.</li>
<li>Growth is driven by compounding, which always takes time. Destruction is driven by single points of failure, which can happen in seconds, and loss of confidence, which can happen in an instant.</li>
<li>In investing you must identify the price of success— volatility and loss amid the long backdrop of growth—and be willing to pay it.</li>
</ul>
<h1 id="heading-when-youll-believe-anythingwhen-youll-believe-anything"><a class="post-section-overview" href="#when-youll-believe-anything"></a>When You’ll Believe Anything</h1>
<blockquote>
<p>Appealing fictions, and why stories are more powerful than statistics</p>
</blockquote>
<ul>
<li>In 2007, we told a story about the stability of housing prices, the prudence of bankers, and the ability of financial markets to accurately price risk. In 2009 we stopped believing that story.</li>
<li>Once the narrative that home prices will keep rising broke, mortgage defaults rose, then banks lost money, then they reduced lending to other businesses, which led to layoffs, which led to less spending, which led to more layoffs, and on and on.</li>
</ul>
<p>At the personal level, there are two things to keep in mind about a story-driven world when managing your money.</p>
<h2 id="heading-appealing-fictionappealing-fiction"><a class="post-section-overview" href="#appealing-fiction"></a>Appealing Fiction</h2>
<blockquote>
<p>The more you want something to be true, the more likely you are to believe a story that overestimates the odds of it being true.</p>
</blockquote>
<p>There are many things in life that we think are true, because we desperately want them to be true, these are “Appealing Fictions”.</p>
<p>An appealing fiction happens when you are smart, you want to find solutions, but face a combination of limited control and high stakes.</p>
<h2 id="heading-incomplete-world-views-and-our-narrativesincomplete-world-views-and-our-narratives"><a class="post-section-overview" href="#incomplete-world-views-and-our-narratives"></a>Incomplete World views and our narratives</h2>
<blockquote>
<p>Everyone has an incomplete view of the world. But we form a complete narrative to fill in the gaps.</p>
</blockquote>
<ul>
<li>Part of the reason forecasting the stock market and the economy is so hard is because you are the only person in the world who thinks the world operates the way you do. When you make decisions for reasons that I can’t even comprehend, I might follow you blindly into a decision that’s right for you and disastrous to me.</li>
<li>Coming to terms with how much you don’t know means coming to terms with how much of what happens in the world is out of your control. And that can be hard to accept.</li>
<li>Psychologist Philip Tetlock once wrote: “We need to believe we live in a predictable, controllable world, so we turn to authoritative-sounding people who promise to satisfy that need.”</li>
<li>Business, economics and investing are fields of uncertainty, overwhelmingly driven by decisions that can’t easily be explained with clean formulas, but we desperately want it to, because the idea of being in control is beautiful and comforting.</li>
<li>We focus on what we know and neglect what we do not know, which makes us overly confident in our beliefs.</li>
</ul>
<hr />
<h1 id="heading-all-together-nowall-together-now"><a class="post-section-overview" href="#all-together-now"></a>All together now</h1>
<ul>
<li>Wealth is created by suppressing what you could buy today in order to have stuff or options in the future.</li>
<li>The question - “does this help me sleep at night?” is the best guidepost for all financial decisions.</li>
<li>Time is the most powerful force in investing, it makes little things grow big and big mistakes fade away.</li>
<li>Judging how you’ve done by focusing on individual investments makes winners look more brilliant than they were and losers appear more regrettable than they should.</li>
<li>Use money to gain control over your time, because not having control of your time is such a powerful and universal drag on happiness.</li>
<li>No one is impressed with your possessions as much as you are.</li>
<li>If you want respect and admiration, you are likely to gain those things through kindness and humility than horsepower and chrome.</li>
<li>Savings that are not earmarked for anything are hedge against life’s surprises.</li>
<li>You should like risk, because if pays-off over time, but you should be paranoid of ruinous risk because it prevents you from taking future risks that will pay off overtime.</li>
</ul>
<hr />
<h1 id="heading-confessionsconfessions"><a class="post-section-overview" href="#confessions"></a>Confessions</h1>
<ul>
<li>Like many things, even in finance, their is no universal truth. Its only about what works for you &amp; your family in a way that leaves you comfortable and sleeping well at night.</li>
<li>Our goal isn’t to be coldly rational; just psychologically reasonable.</li>
<li>Consumption became an explicit economic strategy in the years after World War II. An era of encouraging thrift and saving to fund the war quickly turned into an era of actively promoting spending</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Learning Rust - The Interesting Parts]]></title><description><![CDATA[I have been programming for some time now and have been fortunate enough to have worked on a bunch of different languages like Java, C#, Python, JavaScript (TypeScript).
I have been thinking of picking up a new language for sometime now and the choic...]]></description><link>https://anirudhv.xyz/learning-rust-the-interesting-parts</link><guid isPermaLink="true">https://anirudhv.xyz/learning-rust-the-interesting-parts</guid><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Fri, 10 Dec 2021 00:00:00 GMT</pubDate><content:encoded><![CDATA[<p>I have been programming for some time now and have been fortunate enough to have worked on a bunch of different languages like Java, C#, Python, JavaScript (TypeScript).</p>
<p>I have been thinking of picking up a new language for sometime now and the choice came down to Go &amp; Rust. As the title indicates, I went with Rust.</p>
<h2 id="heading-why-rustwhy-rust"><a class="post-section-overview" href="#why-rust"></a>Why Rust?</h2>
<ol>
<li><strong>The ecosystem</strong>: As a frontend/JavaScript developer, I am seeing more and more tools being re-written in Rust for performance benefits, and so hopefully, I would be able to contribute or at least learn from those code bases in the context of my day to day work.</li>
<li><strong>Its Different?!</strong>: All of my previous experiences have been in application-oriented, managed languages. Rust is similar, but has some interesting concepts like <a target="_blank" href="https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html">Immutability-by-default</a>, <a target="_blank" href="https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html">Ownership</a> etc.</li>
</ol>
<h2 id="heading-what-is-this-postwhat-is-this-post"><a class="post-section-overview" href="#what-is-this-post"></a>What is this post?</h2>
<p>This post is supposed to be just a journal of things that I might like, dislike or find interesting enough to document as I learn Rust enough to build a simple CLI app. I am following the <a target="_blank" href="https://doc.rust-lang.org/book">Rust Programming Language Book</a> and many snippets here are picked from there.</p>
<h2 id="heading-the-setup-rust-and-sublime-text-3-macosthe-setup-rust-and-sublime-text-3-macos"><a class="post-section-overview" href="#the-setup-rust-and-sublime-text-3-macos"></a>The Setup: Rust and Sublime Text 3 (MacOS)</h2>
<h3 id="heading-packages-requiredpackages-required"><a class="post-section-overview" href="#packages-required"></a>Packages Required</h3>
<ul>
<li><a target="_blank" href="https://rust-lang.github.io/rust-enhanced">Rust Enhanced</a>: The official Rust package for ST3.</li>
<li><a target="_blank" href="https://rust-analyzer.github.io/">rust-analyzer</a>: Language Server implementation for Rust.</li>
</ul>
<h3 id="heading-setup-the-language-serversetup-the-language-server"><a class="post-section-overview" href="#setup-the-language-server"></a>Setup the Language Server</h3>
<ul>
<li>Install the <a target="_blank" href="https://github.com/sublimelsp/LSP">LSP Package</a></li>
<li>Download the right package from releases.</li>
<li>Extract the package.</li>
<li>Rename to <code>rust-analyzer</code></li>
<li>Add to <code>$PATH</code></li>
<li>Make it executable <code>chmod +x rust-analyzer</code></li>
</ul>
<h3 id="heading-enable-the-language-server-in-sublimeenable-the-language-server-in-sublime"><a class="post-section-overview" href="#enable-the-language-server-in-sublime"></a>Enable the Language Server in Sublime</h3>
<ul>
<li>Open Command Pallete (Cmd + Shift + P)</li>
<li>Select <code>LSP: Enable Language Server Globally</code></li>
<li>Select <code>rust-analyzer</code></li>
</ul>
<h2 id="heading-the-interesting-partsthe-interesting-parts"><a class="post-section-overview" href="#the-interesting-parts"></a>The Interesting Parts</h2>
<h3 id="heading-matchmatch"><a class="post-section-overview" href="#match"></a>Match</h3>
<p>Rust has an expressive <code>match</code> syntax that can be used to compare values. A match expression is written like -</p>
<p>    use std::cmp::Ordering;</p>
<p>    fn main(){
        let guess = 4; // some sample value, can be input
        let secret = 5; // another value to compare against.</p>
<p>        match guess.cmp(&amp;secret) {
                Ordering::Less =&gt; println!("Under"),
                Ordering::Equal =&gt; println!("Match!!"),
                Ordering::Greater =&gt; println!("Over")
            }
    }</p>
<p>Each line in the <code>match</code> block is called an <code>arm</code>. In my opinion this makes the code very easy to read and understand at a glance.</p>
<h3 id="heading-built-in-error-handlingbuilt-in-error-handling"><a class="post-section-overview" href="#built-in-error-handling"></a>Built-In Error Handling</h3>
<p>Some operations, like I/O always require error handling. Rust’s <code>Result</code> type represents either a success (<code>OK</code>) or an error (<code>Err</code>).</p>
<p>The great thing here is that if a function returns a <code>Result</code>, then the caller must handle both success and failure cases.</p>
<p>Consider this code that converts a string to an int -</p>
<p>    let guess: u32 = match guess.trim().parse() {
                Ok(num) =&gt; num,
                Err(_) =&gt; {
                    eprintln!("{} is not a legit number, try again;", guess.trim());
                    return ()
                },
            };</p>
<h3 id="heading-immutable-variablesimmutable-variables"><a class="post-section-overview" href="#immutable-variables"></a>Immutable Variables</h3>
<p>One major difference in Rust vs the other langugages I mentioned above is that variables in Rust are immutable by default.</p>
<p>In cases where we need to re-assign a value to a variable, we need to explicitly mark that variable as mutable by using the <code>mut</code> keyword.</p>
<p>    let a = 5; //This is immutable, <code>a</code> cannot be re-assigned.
    let mut b = 10; // <code>b</code> can be reassigned.</p>
<h3 id="heading-shadowingshadowing"><a class="post-section-overview" href="#shadowing"></a>Shadowing</h3>
<p>Rust allows developers to re-declare a variable with the same name in a scope. This is called Shadowing.</p>
<p>Consider the following snippet -</p>
<p>    fn main() {
        let x = 5;</p>
<p>        let x = x + 1;</p>
<p>        {
            let x = x * 2;
            println!("The value of x in the inner scope is: {}", x); // This will print 12
        }</p>
<p>        println!("The value of x is: {}", x); // This is still 6.
    }</p>
<p>Honestly, the first time I saw this, I was pretty confused. Alot of other languages just refuse this kind of re-declaring of variables in scope.</p>
<p>Technically, this variable is still immutable, i.e. this snippet would fail -</p>
<p>    fn main() {
        let x = 5;</p>
<p>        x = x + 1; // will fail
    }</p>
<p>The usecase for shadowing defined in the <a target="_blank" href="https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing">Rust Book</a> is for running multiple transforms on the same variable without having to declare a bunch of variables names that we don’t care about.</p>
<p>It will interesting to see if this causes any issues on larger Rust codebases.</p>
<h3 id="heading-arraysarrays"><a class="post-section-overview" href="#arrays"></a>Arrays</h3>
<ul>
<li>Arrays in Rust are more like Java than JavaScript. While an array in JavaScript can grow in size after initialization, arrays in Rust are fixed size.</li>
<li>An array maybe initialized using the type of its elements and the the length like - <code>let x:[char, 5] = ['a','b','c','d','e']</code></li>
<li>Rust also provides a shorthand syntax when we want to create an array with the same elements like <code>let x = [3;'a']</code>. This creates an array like <code>['a','a','a']</code></li>
</ul>
<h3 id="heading-expressions-vs-statementsexpressions-vs-statements"><a class="post-section-overview" href="#expressions-vs-statements"></a>Expressions vs Statements</h3>
<p>Statements do not return a value. An assignemnt is a statement. Consider the following JavaScript snippet;</p>
<p>    const a = (b = 12)
    console.log(a) // prints 12
    console.log(b) // prints 12</p>
<p>Here the variable <code>a</code> gets a value 12, because <code>b=12</code> returns 12. However, assignments in Rust don’t return a value.</p>
<p>Expressions return a value, Rust is an <a target="_blank" href="https://en.wikipedia.org/wiki/Expression-oriented_programming_language">Expression oriented</a> language.</p>
<p>The block <code>{}</code> created for new scopes is an expression and thus can be assigned to variable like -</p>
<p>       let y = {
            let x = 3;
            x + 1
        };</p>
<p>Here the last line in the block does not end with a semi-colon (;), thats because expressions do not include ending semicolons, if we add a semicolon, then it becomes a statement and hence it does not return a value.</p>
<h3 id="heading-return-valuesreturn-values"><a class="post-section-overview" href="#return-values"></a>Return Values</h3>
<p>In Rust, the by default, the return value of the function is the value returned by the last expression in the function. Using <code>return</code> can be used to exit early, but otherwise its optional.</p>
<h3 id="heading-conditional-assignemntconditional-assignemnt"><a class="post-section-overview" href="#conditional-assignemnt"></a>Conditional Assignemnt</h3>
<p>Since <code>if</code> is an expression, conditional assignemnts don’t require additional syntax.</p>
<p>    let condition = true;
    let number = if condition { 5 } else { 6 };</p>
<h3 id="heading-infinite-loops-there-is-a-keyword-for-thatinfinite-loops-there-is-a-keyword-for-that"><a class="post-section-overview" href="#infinite-loops-there-is-a-keyword-for-that"></a>Infinite Loops? There is a keyword for that</h3>
<p>Rust has built-in support for infinite loops <a target="_blank" href="https://doc.rust-lang.org/book/ch03-05-control-flow.html#repeating-code-with-loop">using the <code>loop</code> keyword</a>. This is the first language where I am seeing this.</p>
<h4 id="heading-returning-with-break">Returning with break;</h4>
<p>Another first for me, was the ability to return values with the <code>break</code> keyword.</p>
<p>        let mut counter = 0;</p>
<p>        let result = loop {
            counter += 1;</p>
<p>            if counter == 10 {
                break counter * 2;
            }
        };</p>
<p>        println!("The result is {}", result);</p>
<ul>
<li>Note that since <code>loop</code> is treated as an expression that yields a value, we can put it on the right side of assignment.</li>
<li>The <code>break counter * 2</code> statement not only stops the loop, but assigns the value to the variable <code>result</code></li>
</ul>
<p><em>Source</em> <a target="_blank" href="https://doc.rust-lang.org/book/ch03-05-control-flow.html#returning-values-from-loops">https://doc.rust-lang.org/book/ch03-05-control-flow.html#returning-values-from-loops</a></p>
<h3 id="heading-ownershipownership"><a class="post-section-overview" href="#ownership"></a>Ownership</h3>
<p>Just refer - <a target="_blank" href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html">https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html</a></p>
<h4 id="heading-rules-of-ownership">Rules of ownership</h4>
<ul>
<li>Each value in Rust has a variable that’s called its owner.</li>
<li>There can only be one owner at a time.</li>
<li>When the owner goes out of scope, the value will be dropped.</li>
</ul>
<h4 id="heading-reassigning-objects">Reassigning ‘objects’</h4>
<p>Consider the following JS Code:</p>
<p>    const x = { foo: 1 }
    const y = x
    y.foo = 2 // this works and sets x.foo = 2</p>
<p>Here JavaScript assigns the reference to the variable x to y. So when some code alters <code>y.foo</code>, it’s actually changing <code>x.foo</code>.</p>
<p>Consider the following rust snippet</p>
<p>        let s1 = String::from("hello");
        let s2 = s1;
        println!(s1); // this errors.</p>
<p>In this case, Rust too copies the pointer to where “Hello” is stored, but does not copy the data itself. However, due to how ownership works, and to keep things simple, <code>let s2=s1</code> actually invalidates <code>s1</code> and transfers the ownership of <code>Hello</code> to <code>s2</code>. After the re-assignment <code>s1</code> can no longer be used. This is called <code>move</code>.</p>
<p>As explained <a target="_blank" href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#ways-variables-and-data-interact-move">here</a>, this is done so that <code>hello</code> only has one owner (s2) and when s2 goes out of scope, Rust can easily free up the memory.</p>
<p><strong>Note</strong>: Fixed length data like integers and floats, that is stored on the stack can be re-assiged without invalidating the old variable. <a target="_blank" href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#stack-only-data-copy">Read More Here</a></p>
<h4 id="heading-ownership-and-functions">Ownership and Functions</h4>
<p>Passing data to functions as arguments also transfers the ownership of that data. Assume a regular <code>say_hello</code> function like -</p>
<p>    fn say_hello(name: String)-&gt;String {
        String::from("Hello!, ") + &amp;name
    }</p>
<p>    fn main() {
        let s1 = String::from("foo");
        println!("{}", say_hello(s1));
        println!("{}". s1); // This would complain about <code>s1</code> having moved
    }</p>
<p>Passing variables to a function and then storing its return value back in a different variable will obviously be tedios and not always desirable. To get around this Rust has the concept of <a target="_blank" href="https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html">References</a></p>
<p>    fn say_hello(name: &amp;String)-&gt;String {
        String::from("Hello!, ") + &amp;name
    }</p>
<p>    fn main() {
        let s1 = String::from("foo");
        println!("{}", say_hello(&amp;s1));
        println!("{}". s1);
    }</p>
<p>The <code>&amp;</code> syntax creates a reference to the value of <code>s1</code>, but it does not own it. Creating references is called <strong>borrowing</strong>.</p>
<p><em>Notes</em></p>
<ul>
<li>References, just like variables are mutable by default. In order to change a reference, it needs to be marked with <code>&amp;mut</code>.</li>
<li>There can only be one mutable reference at a time.</li>
</ul>
<h3 id="heading-slicesslices"><a class="post-section-overview" href="#slices"></a>Slices</h3>
<p>Refer: <a target="_blank" href="https://doc.rust-lang.org/book/ch04-03-slices.html">https://doc.rust-lang.org/book/ch04-03-slices.html</a></p>
<hr />
<p><strong>Last Updated</strong>: 15 December 2021.</p>
]]></content:encoded></item><item><title><![CDATA[Tracking GitLab Todos with Hammerspoon]]></title><description><![CDATA[At SpotDraft we use self-hosted GitLab to host our source code and manage projects. One nice concept that GitLab uses is that of Todos. A Todo is created anytime an issue is assigned to you, a Merge Request requires your review or someone mentions yo...]]></description><link>https://anirudhv.xyz/gitlab-todos-hammerspoon</link><guid isPermaLink="true">https://anirudhv.xyz/gitlab-todos-hammerspoon</guid><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Sun, 23 Aug 2020 00:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1711692645154/b10f7252-ab1b-4b49-a878-c2ee876dacce.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>At <a target="_blank" href="https://spotdraft.com">SpotDraft</a> we use self-hosted <a target="_blank" href="https://gitlab.com">GitLab</a> to host our source code and manage projects. One nice concept that GitLab uses is that of <strong>Todos</strong>. A Todo is created anytime an issue is assigned to you, a Merge Request requires your review or someone mentions you in a comment, hence the Todos page serves as a hub for you to figure out what you can help with or what you can work on next.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711693839593/7f5651d4-a796-4a8c-808b-d8ef31d1030a.png" alt class="image--center mx-auto" /></p>
<p>So, to keep on top of my todos, without having to open GitLab all the time, I created a little <a target="_blank" href="https://www.hammerspoon.org/">Hammerspoon</a> script that simply keeps the count of todos in my MacOS menu bar. For those who are not familiar with Hammerspoon, it is a MacOS automation that makes it super easy to interact with the operating system using a Lua Scripting Engine.</p>
<h2 id="heading-the-code">The Code</h2>
<p>I have never written a single line of Lua in my life before, but even then thanks to great documentation by Hammerspoon and the set of extensions already available, it did not take long to make this functional <em>“app”</em></p>
<p>After installing Hammerspoon, open your <code>init.lua</code> file and add the following</p>
<pre><code class="lang-lisp">-- URL to open when the menu bar is clicked
local MENUBAR_CLICK_URL = <span class="hljs-string">"https://gitlab.com/dashboard/todos"</span><span class="hljs-comment">;</span>
-- GitLab access token to make the API call
local GITLAB_TOKEN = <span class="hljs-string">"&lt;Your Token&gt;"</span>
-- TODOs API URL
local GITLAB_TODO_API = <span class="hljs-string">"https://gitlab.com/api/v4/todos"</span>
local POLL_INTERVAL_MINUTES = <span class="hljs-number">15</span>

function onMenuClick()
    hs.urlevent.openURL(<span class="hljs-name">MENUBAR_CLICK_URL</span>)
end

gl_menu = hs.menubar.new()
gl_menu:setClickCallback(<span class="hljs-name">onMenuClick</span>)

function updateMenuBar(<span class="hljs-name">todos</span>)
    counter = <span class="hljs-number">0</span>
    for index in pairs(<span class="hljs-name">todos</span>) do
        counter = counter + <span class="hljs-number">1</span>
    end
    gl_menu:setTitle(<span class="hljs-string">"Gitlab Todos - "</span>..counter)
end

function callGitLab ()
    headers = {}
    headers[<span class="hljs-string">"PRIVATE-TOKEN"</span>]=GITLAB_TOKEN
    gl_menu:setTitle(<span class="hljs-string">"Fetching Todos..."</span>)
    hs.http.asyncGet(<span class="hljs-name">GITLAB_TODO_API</span>, headers, function(<span class="hljs-name">status</span>, data)
        todos = hs.json.decode(<span class="hljs-name">data</span>)
        updateMenuBar(<span class="hljs-name">todos</span>)
    end)
end

hs.hotkey.bind({<span class="hljs-string">"cmd"</span>, <span class="hljs-string">"alt"</span>, <span class="hljs-string">"ctrl"</span>}, <span class="hljs-string">"G"</span>, function()
    callGitLab()
end)

hs.timer.doEvery(<span class="hljs-name">POLL_INTERVAL_MINUTES*60</span>, callGitLab)

callGitLab()
</code></pre>
<p>The code (IMO) is quite straightforward -</p>
<ul>
<li><p>We have a function <code>callGitLab</code>, that calls an API call to fetch the Todos and update the menubar when it is loaded.</p>
</li>
<li><p>We set this function to refresh data every 15 minutes.</p>
</li>
<li><p>We create a hotkey combination to manually refresh.</p>
</li>
</ul>
<p>I have been looking at Hammerspoon to build something for sometime now, and this does not even scratch the surface of whats possible.</p>
<ul>
<li><p>Credits to <a target="_blank" href="https://shantanugoel.com/">Shantanu Goel</a> who built some cool things with Hammerspoon and his <a target="_blank" href="https://shantanugoel.com/2020/08/21/hammerspoon-multiscreen-window-layout-macos/">latest post</a> gave me the idea (&amp; motivation) to build this.</p>
</li>
<li><p>Also, <a target="_blank" href="https://zzamboni.org/post/just-enough-lua-to-be-productive-in-hammerspoon-part-1/">Just enough Lua to be productive in Hammerspoon</a> is a good series for someone who has no prior experience with Lua</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Solve the Cross-Origin Access error when working with iframes]]></title><description><![CDATA[As most of you would know, the iframe or inline frame element allows you to embed one HTML page into another.
Sites like YouTube and Google Maps use iframes to embed thier content in your website.
While embedding an iframe is pretty straightforward, ...]]></description><link>https://anirudhv.xyz/solve-cross-origin-iframe-error</link><guid isPermaLink="true">https://anirudhv.xyz/solve-cross-origin-iframe-error</guid><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Wed, 01 Jan 2020 00:00:00 GMT</pubDate><content:encoded><![CDATA[<p>As most of you would know, the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe">iframe</a> or inline frame element allows you to embed one HTML page into another.</p>
<p>Sites like YouTube and Google Maps use iframes to embed thier content in your website.</p>
<p>While embedding an <code>iframe</code> is pretty straightforward, customising the document inside the iframe is not that simple.</p>
<p>This post will breifly explain the Cross-Origin access problem that is faced when accesing an <code>iframe</code> document and how you can setup your development environment to overcome this problem.</p>
<h1 id="heading-iframe-security-101">iframe Security 101</h1>
<p>While <code>iframe</code> is a very powerful tool, it essentially means that you are running some arbitary code, loaded from a remote server (which you may or may not control) on your app and exposing your users to it. Naturally, this also means that one has to be very careful about security.</p>
<p>All Browsers implement a Cross-Origin Access Restriction to prevent the host document from accessing the <code>iframe</code> document, <strong>unless</strong> they have the same <em>origin</em>. This is done to prevent embedded documents access to your sites cookies, localStorage data etc.</p>
<h2 id="heading-what-is-origin">What is origin?</h2>
<p>Origin of a document is a combination of its protocol (http, https), domain &amp; port.</p>
<h1 id="heading-accessing-an-iframe-document">Accessing an iframe document.</h1>
<p>Now, lets say that your host app is at <code>https://your-awesome.app</code> and the iframe loads a document from <code>https://your-awesome.app/embed?id=123</code>.</p>
<p>When the user clicks a button, we want to inject some styles into the document of the iframe.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">iframe</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://your-awesome.app/embed/123"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-frame"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">iframe</span>&gt;</span>

// some functionality to inject CSS
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">injectStyles</span>(<span class="hljs-params">styleTag</span>)</span>{
     <span class="hljs-keyword">const</span> iframe = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"my-frame"</span>);
     <span class="hljs-keyword">const</span> embed = iframe.contentDocument;
     embed.head.appendChild(styleTag);
  }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Since both your app and the <code>iframe</code> have the same origin (<a target="_blank" href="https://your-awesome.app">https://your-awesome.app</a>), the browser will let you access the <code>contentDocument</code>.</p>
<h2 id="heading-local-development-challenges">Local development challenges</h2>
<p>When developing locally, your app URL mostly looks like <code>localhost:3000</code>, <code>localhost:5000</code> etc. Now, assuming that embed service will still be loaded from the remote server, the above code will show you an error while looks something like</p>
<blockquote>
<p>SecurityError: Blocked a frame with origin "http://www..com" from accessing a cross-origin frame.</p>
</blockquote>
<p>This error is very straightforward to understand, when developing locally, your origin is <code>http://localhost:3000</code> while the iframes origin is still <code>https://your-awesome.app</code>.</p>
<p>The solution to this problem is to somehow serve your local app and the iframe under the same origin, this will involve a couple of things -</p>
<ol>
<li><p>Serve our local app under <code>local-dev.your-awesome.app</code></p>
</li>
<li><p>Serve the iframe from <code>local-dev.your-awesome.app/embed</code></p>
</li>
</ol>
<h1 id="heading-setup-local-domain">Setup local domain</h1>
<p>What we want is that when we goto <code>local-dev.your-awesome.app</code> from our browser, it should load our app which is serving at <code>localhost:3000</code> , for this, we will update the <code>hosts</code> file.</p>
<pre><code class="lang-bash">nano /etc/hosts
<span class="hljs-comment"># add the following line to the end of the hosts file</span>
127.0.0.1 local-dev.your-awesome.app
<span class="hljs-comment"># Leave an empty line at the end of the file, it is required.</span>
</code></pre>
<p><em>Note:</em> On Windows, the hosts file can found at <code>c:\Windows\System32\Drivers\etc\hosts</code></p>
<p>Through this one line, we have told our machine that any request to <code>local-dev.your-awesome.app</code> should be sent to our localhost.</p>
<p>Now, when you go to the URL in your browser, it still won’t load our app. This is because our app is being served at port 3000, while the redirect is going to the default port(80). We need to setup a proxy to send requests from <code>/</code> to <code>localhost:3000</code>. To do this, you can use a nifty tool I found called <a target="_blank" href="https://github.com/bripkens/proxrox">proxrox</a>. Proxrox essentially spins up an Nginx instance with some custom configuration. This is what our proxrox configuration look like -</p>
<pre><code class="lang-yaml"><span class="hljs-comment">## .proxrox.yaml</span>
<span class="hljs-attr">proxy:</span>
  <span class="hljs-string">"/"</span><span class="hljs-string">:</span>  <span class="hljs-string">"http://localhost:3000"</span>
</code></pre>
<p>You can start proxrox with the config - <code>proxrox start .proxrox.yaml</code></p>
<p>When you go to <code>local-dev.your-awesome.app</code>, you should see your app being served.</p>
<p>This magic happens because proxrox configures a <code>proxy_pass</code> in nginx for us which takes all requests going to <code>/</code> and passes it to our app at <code>localhost:3000</code></p>
<h3 id="heading-setting-up-proxrox-on-linux">Setting up proxrox on Linux</h3>
<p>Setting up proxrox on linux takes some more effort due to permissions. Turns out only root processes are allowed to bind to port &lt; 1024. To get around this limitation, you can use <code>authbind</code>.</p>
<p>Authbind is a utility that allows processes to bind to 80/443 or other ports under 1024 without having to gain root access.</p>
<pre><code class="lang-bash">sudo apt-get install authbind
<span class="hljs-comment"># Bind 80 &amp; 443.</span>
sudo touch /etc/authbind/byport/80
sudo touch /etc/authbind/byport/443
sudo chmod 777 /etc/authbind/byport/80
sudo chmod 777 /etc/authbind/byport/443

authbind --deep proxrox start .proxrox.yaml
</code></pre>
<h1 id="heading-setup-proxy-for-iframe-document">Setup proxy for iframe document</h1>
<p>Now that our app is running at <code>local-dev.your-awesome.app</code>, we just need to get the embeds to serve at <code>/embed</code>. To do this, edit your <code>.proxrox.yaml</code> file again and add the following configuration -</p>
<pre><code class="lang-yaml"><span class="hljs-attr">proxy:</span>
  <span class="hljs-string">"/"</span><span class="hljs-string">:</span>  <span class="hljs-string">"http://localhost:3000"</span>
  <span class="hljs-string">"/embed"</span><span class="hljs-string">:</span> <span class="hljs-string">"https://your-awesome.app/embed/"</span>
</code></pre>
<p>Save the config and restart proxrox.</p>
<p>Update your frame <code>src</code> attribute -</p>
<p><code>&lt;iframe src="/embed/123"&gt;&lt;/iframe&gt;</code></p>
<p>Since the document and the embedded document both are being served from <code>local-dev.your-awesome.app</code>, you will no longer face the cross origin access error when trying to access the iframe.</p>
<p>This also gives you access to the iframe document, which means that you can insert scripts, styles and even listen to &amp; send messages to the document.</p>
]]></content:encoded></item><item><title><![CDATA[Flexbox - Align Items vs Align Content.]]></title><description><![CDATA[Flexbox is awesome. If you have worked with modern CSS, whether you are rolling your own or using a frameworks like Bootstrap & Foundation, chances are you are using Flexbox for layout and alignment.

To align or to justify..that is the question

For...]]></description><link>https://anirudhv.xyz/align-items-vs-content-flexbox</link><guid isPermaLink="true">https://anirudhv.xyz/align-items-vs-content-flexbox</guid><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Mon, 04 Feb 2019 00:00:00 GMT</pubDate><content:encoded><![CDATA[<p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a> is awesome. If you have worked with modern CSS, whether you are rolling your own or using a frameworks like Bootstrap &amp; Foundation, chances are you are using Flexbox for layout and alignment.</p>
<blockquote>
<p>To align or to justify..that is the question</p>
</blockquote>
<p>For a very long time, I have been trying to figure out what is the difference between <code>align-items</code>, <code>align-content</code> &amp; <code>justify-content</code> and how they work or more importantly <em>when</em> they work.</p>
<h3 id="heading-tldrtldr"><a class="post-section-overview" href="#tldr"></a>TL;DR</h3>
<ul>
<li>If you have set your <code>flex-direction</code> to <code>row</code>, then <code>justify-content</code> works on the horizontal axis and <code>align-*</code> properties work on the vertical axis.</li>
<li>If you have set your <code>flex-direction</code> to <code>column</code>, then <code>align-*</code> properties work on the horizontal axis and <code>justify-content</code> works on the vertical axis.</li>
</ul>
<iframe height="265" style="width:100%" src="//codepen.io/thebigfatpanda12/embed/preview/aXqjNq/?height=265&amp;theme-id=dark&amp;default-tab=html,result">See the Pen <a href="https://codepen.io/thebigfatpanda12/pen/aXqjNq/">Align items vs Justify Content</a> by Anirudh Varma (<a href="https://codepen.io/thebigfatpanda12">@thebigfatpanda12</a>) on <a href="https://codepen.io">CodePen</a>.</iframe>

<h3 id="heading-what-separates-align-items-and-align-contentwhat-separates-align-items-and-align-content"><a class="post-section-overview" href="#what-separates-align-items-and-align-content"></a>What separates align-items and align-content?</h3>
<ul>
<li><code>align-items</code> effect the alignment of items on the current line.</li>
<li><code>align-content</code> effects the alignment accross lines of a flex-container. This means that this property has no effect on single-line containers.</li>
</ul>
<p><em>The rest of the article is just a brain dump of everything I learned while trying to figure out the above.</em></p>
<h2 id="heading-nomenclaturenomenclature"><a class="post-section-overview" href="#nomenclature"></a>Nomenclature</h2>
<ul>
<li><strong>Flex Container</strong>: An element on which the <code>display</code> value is set to <code>flex</code>.</li>
<li><strong>Flex Items</strong>: <em>Direct</em> children of the flex containers are called flex items.</li>
<li><p><strong>Main Axis</strong>: The axis defined by the <code>flex-direction</code> property.</p>
<p>— <code>flex-direction:row</code> means that elements inside the flex container are aligned next to each other. Technically, these elements are aligned along the <a target="_blank" href="https://www.w3.org/TR/css-writing-modes-4/#inline-axis">inline-axis</a> (just like inline elements).</p>
<p>— <code>flex-direction:column</code> means that elements are aligned along the vertical axis i.e. below each other. Technically called the <a target="_blank" href="https://www.w3.org/TR/css-writing-modes-4/#block-axis">block-axis</a> (just like block elements)</p>
</li>
<li><p><strong>Cross Axis</strong>: The axis perpendicular to the main axis is called the cross axis.</p>
</li>
<li><strong>Single-line Container</strong>: Flex containers whose <code>flex-wrap</code> property is set to <code>nowrap</code>. By default every flex container is a single-line container.</li>
<li><strong>Multi-line Containers</strong>: Flex containers whose <code>flex-wrap</code> property is set to <code>wrap</code></li>
</ul>
<h2 id="heading-tldr-with-nomenclaturetldr-with-nomenclature"><a class="post-section-overview" href="#tldr-with-nomenclature"></a>TL;DR with Nomenclature</h2>
<p>Now that we know the jargon, we can rewrite the TL;DR as-</p>
<ul>
<li><code>justify-content</code> works on the Main Axis and <code>align-*</code> properties work on the Cross Axis.</li>
<li><code>justify-content</code> and <code>align-items</code> are similar in their behviour, the difference being that <code>justify-content</code> works on the the main axis while <code>align-items</code> works on the cross axis.</li>
<li><code>align-content</code> works only on multi-line containers and has no effect on single line containers.</li>
</ul>
<h2 id="heading-sourcessources"><a class="post-section-overview" href="#sources"></a>Sources</h2>
<ol>
<li><a target="_blank" href="https://www.w3.org/TR/css-flexbox-1/">w3.org</a> documentation on Flexbox is pretty comprehensive and a good read.</li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox">MDN</a> Flexbox documentation.</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Strucural vs Attribute Directives in Angular]]></title><description><![CDATA[Anyone who has worked with Angular would have used directives. According to the the official Angular documentation, there are 3 types of Directives:

Components

Structural Directives like ngIf and ngFor

Attribute Directives like ngStyle


This post...]]></description><link>https://anirudhv.xyz/angular-structural-vs-attribute-directives</link><guid isPermaLink="true">https://anirudhv.xyz/angular-structural-vs-attribute-directives</guid><category><![CDATA[Angular]]></category><category><![CDATA[Angular 2]]></category><category><![CDATA[Angular 4]]></category><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Thu, 03 Jan 2019 00:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Anyone who has worked with Angular would have used directives. According to the the official <a target="_blank" href="https://angular.io/guide/attribute-directives#directives-overview">Angular documentation</a>, there are 3 types of Directives:</p>
<ul>
<li><p>Components</p>
</li>
<li><p>Structural Directives like <code>ngIf</code> and <code>ngFor</code></p>
</li>
<li><p>Attribute Directives like <code>ngStyle</code></p>
</li>
</ul>
<p>This post primarily documents creating and using custom Structural Directives and how it differs with respect to the more commonly used attribute directive.</p>
<h2 id="heading-what-are-structural-directives">What are structural directives?</h2>
<p>As the name suggests, structural directives are responsible for manipulating the DOM structure by adding, removing or changing the elements they are attached to. Perhaps the most common structural directive most Angular developers use the <code>ngIf</code> directive, which is used to show/hide the elements based on a boolean condition.</p>
<blockquote>
<p>Beginner tip: The structural directives are prefixed with a <code>*</code> while attribute directives may be used just by adding their selector as an attribute to the element.</p>
</blockquote>
<h2 id="heading-creating-your-own-structural-directive">Creating your own structural directive.</h2>
<p>Lets assume that you have a payment configuration based on which you want to show or hide certain elements for certain users. We will create a directive, which will take an input for a feature flag and then show or hide the element based on the payment configuration.</p>
<p>Creating a structural directive is pretty similar to creating an attribute directive.</p>
<pre><code class="lang-typescript"><span class="hljs-meta">@Directive</span>({ selector: <span class="hljs-string">'[appRenderIfEnabled]'</span>})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> RenderFeatureDirective <span class="hljs-keyword">implements</span> OnInit{

    <span class="hljs-keyword">private</span> flag: <span class="hljs-built_in">string</span>;

    <span class="hljs-meta">@Input</span>()
    set appRenderIfEnabled(flag: <span class="hljs-built_in">string</span>){
        <span class="hljs-built_in">this</span>.flag = flag;
    }

    <span class="hljs-keyword">constructor</span>(<span class="hljs-params">
        <span class="hljs-keyword">private</span> templateRef: TemplateRef&lt;<span class="hljs-built_in">any</span>&gt;,
        <span class="hljs-keyword">private</span> viewContainer: ViewContainerRef,
        <span class="hljs-keyword">private</span> configService: ConfigService
    </span>) {}

    ngOnInit(){
        <span class="hljs-built_in">this</span>.configService.isEnabled(<span class="hljs-built_in">this</span>.flag).subscribe(<span class="hljs-function"><span class="hljs-params">enabled</span>=&gt;</span>{
            <span class="hljs-keyword">if</span>(enabled){
                <span class="hljs-built_in">this</span>.viewContainer.createEmbeddedView(<span class="hljs-built_in">this</span>.templateRef);
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-built_in">this</span>.viewContainer.clear();
            }
        });
    }
}
</code></pre>
<p>As you can see, the directive takes one input, the name of which must match with the selector that you choose (appRenderIfEnabled) in this case. The directive gets the reference to a <code>TemplateRef</code> and a <code>ViewContainer</code>, this is because a directive creates an embedded view inside the given <code>ViewContainer</code> and the <code>TemplateRef</code> is used to access the contents of the template/element the directive is attached to.</p>
<p>Now the custom directive is ready to be used, add it to any component like:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">my-pro-version-component</span> *<span class="hljs-attr">appRenderIfEnabled</span>=<span class="hljs-string">"'PRO_PACKAGE_ONLY'"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">my-pro-version-component</span>&gt;</span>
</code></pre>
<h2 id="heading-using-additional-input-with-your-directive">Using additional @Input with your directive.</h2>
<p>Till now, our directive is just taking the flag as an input, but what if you want to be able to provide a default value incase of missing configuration?</p>
<p>The key part of having additional inputs in structural directives is that the name of the input property must be prefixed with the selector. In our case, we want a <code>defaultConfig</code>, so the name of the input property would be <code>appRenderIfEnabledDefaultConfig</code>.</p>
<pre><code class="lang-typescript"><span class="hljs-meta">@Directive</span>({ selector: <span class="hljs-string">'[appRenderIfEnabled]'</span>})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> RenderFeatureDirective <span class="hljs-keyword">implements</span> OnInit{

    <span class="hljs-keyword">private</span> flag: <span class="hljs-built_in">string</span>;
    <span class="hljs-keyword">private</span> defaultConfig = <span class="hljs-literal">false</span>;

    <span class="hljs-meta">@Input</span>()
    set appRenderIfEnabled(flag: <span class="hljs-built_in">string</span>){
        <span class="hljs-built_in">this</span>.flag = flag;
    }

    <span class="hljs-comment">// must be prefixed with selector</span>
    <span class="hljs-meta">@Input</span>()
    set appRenderIfEnabledDefaultConfig(conf:<span class="hljs-built_in">boolean</span>){
        <span class="hljs-built_in">this</span>.defaultConfig = conf;
    }
</code></pre>
<p>The new input can be simply added using the following syntax:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">my-pro-version-component</span> 
    *<span class="hljs-attr">appRenderIfEnabled</span>=<span class="hljs-string">"'PRO_PACKAGE_ONLY';defaultConfig: true"</span>&gt;</span>
</code></pre>
<h3 id="heading-useful-links">Useful links -</h3>
<ul>
<li><p><a target="_blank" href="https://angular.io/guide/attribute-directives#directives-overview">Official Documentation for Directives</a></p>
</li>
<li><p><a target="_blank" href="https://angular.io/guide/structural-directives#write-a-structural-directive">Official Documentation for creating Structural Directives</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Bolt CMS: Using content types and relations]]></title><description><![CDATA[For a recent website project, I decided to use Bolt CMS, a free and open source content management system that is really powerful while being flexible and easy to use. One concept that I really liked was that of ContentTypes,
From the documentation —...]]></description><link>https://anirudhv.xyz/bolt-content-and-relations</link><guid isPermaLink="true">https://anirudhv.xyz/bolt-content-and-relations</guid><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Mon, 18 Dec 2017 00:00:00 GMT</pubDate><content:encoded><![CDATA[<p>For a recent website project, I decided to use <a target="_blank" href="https://bolt.cm/">Bolt CMS,</a> a free and open source content management system that is really powerful while being flexible and easy to use. One concept that I really liked was that of <a target="_blank" href="https://docs.bolt.cm/3.4/contenttypes/intro">ContentTypes,</a></p>
<p>From the documentation —</p>
<blockquote>
<p>Most websites will also have some form of news-like items, that are shown based on the date that they were published. Some other sites might have ‘book reviews’ or ‘event dates’ or even completely different content. All of these different types of content are called <strong>ContentTypes</strong> in Bolt, and you can add as many different ContentTypes as you need. Each ContentType is made up of <strong>Fields….</strong></p>
</blockquote>
<p>Our project was a dance company site, so we defined the following Content Types —</p>
<ol>
<li>Team Members.</li>
<li>Videos</li>
<li>Series (Collection of Videos)</li>
</ol>
<p>In Bolt, all contenttypes are defined in <em>contenttypes.yml</em>. Here is what a sample contenttype looks like —</p>
<p>This is pretty similar to creating a database table with the fields title, description, frameUrl &amp; type. The _record<em>template\</em> indicates the twig template to be used when the page for this content type is rendered.</p>
<h2 id="heading-relationsrelations"><a class="post-section-overview" href="#relations"></a>Relations</h2>
<p>Your database has relations, so it would be amazing if your contenttypes had relations, right? Bolt supports creating Relationships between your content types and it is pretty straight forward. Here is the <em>Series</em> contenttype —</p>
<p>Now, as I mentioned earlier. Series is a collection of Videos. The key here is <em>relations</em> configuration. The <em>works</em> field maps <em>series</em> to the <em>works</em> contenttype.<br />Multiple — true means that multiple *works *records can be associated to one <em>series</em> record.</p>
<h2 id="heading-retrieving-and-rendering-related-records-in-templatesretrieving-and-rendering-related-records-in-templates"><a class="post-section-overview" href="#retrieving-and-rendering-related-records-in-templates"></a>Retrieving and rendering related records in templates</h2>
<p>Here is how to list all related records in twig templates.</p>
<p>Here, the <em>record</em> refers to the current series.</p>
<p>You can read more about relationships here — <a target="_blank" href="https://docs.bolt.cm/3.4/contenttypes/relationships#">https://docs.bolt.cm/3.4/contenttypes/relationships#</a></p>
<p>About relations in templates — <a target="_blank" href="https://docs.bolt.cm/3.4/contenttypes/relationships#relations-in-templates">https://docs.bolt.cm/3.4/contenttypes/relationships#relations-in-templates</a></p>
<p>This is the first project that I have developed with Bolt CMS and really liked working with it so far, the extension ecosystem looks healthy and the future looks promising.</p>
]]></content:encoded></item><item><title><![CDATA[Dev Diary: My React, Redux & React Router Setup.]]></title><description><![CDATA[Note: This post is not meant to be about the inner workings of React, Redux or React-Router. This is a post detailing my experiences & understanding in creating an app using all 3 libraries, the problems I faced while doing it & how I got around them...]]></description><link>https://anirudhv.xyz/react-redux-setup</link><guid isPermaLink="true">https://anirudhv.xyz/react-redux-setup</guid><category><![CDATA[React]]></category><category><![CDATA[Redux]]></category><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Wed, 23 Aug 2017 00:00:00 GMT</pubDate><content:encoded><![CDATA[<p><em>Note: This post is not meant to be about the inner workings of React, Redux or React-Router. This is a post detailing my experiences &amp; understanding in creating an app using all 3 libraries, the problems I faced while doing it &amp; how I got around them.</em></p>
<p>Some background info on me, professionally I am a backend developer who primarily works with Java. I have worked with <a target="_blank" href="https://wicket.apache.org/">Apache Wicket</a> for a long time. For those who don’t know Wicket is a web framework for Java with components at its center. So when I wanted to learn a JavaScript frontend library/framework, I chose React as it was similar to Wicket in terms of creating components and composing them to create views while being lightweight enough that it was easy to learn in isolation.</p>
<h2 id="heading-v1-just-react">V1: Just React</h2>
<p>To start learning React, I made <a target="_blank" href="http://snooplay.surge.sh/">Snooplay</a>: A media player for Reddit. The first version of Snooplay was very simple, it just used React, no routing &amp; no state management. You can checkout the code for v1 <a target="_blank" href="https://github.com/anirudhvarma12/snooplay/tree/v1">here</a>.</p>
<h2 id="heading-v2-react-meets-router-amp-redux">V2: React meets Router &amp; Redux</h2>
<p>In order to extend my knowledge to Redux, Middlewares &amp; React Router, I decided to extend Snooplay with the following goals —</p>
<ul>
<li><p>The state for the entire app should be stored &amp; managed via <a target="_blank" href="http://redux.js.org/">Redux</a>.</p>
</li>
<li><p>The user should be able to change subreddits by altering the URL. eg: snooplay/r/movies. Routing to be handled by <a target="_blank" href="https://github.com/ReactTraining/react-router">React-Router.</a></p>
</li>
<li><p>Create the boiler plate using <a target="_blank" href="https://github.com/facebookincubator/create-react-app">create-react-app</a></p>
</li>
<li><p>All styling should be done via SASS/SCSS and compilation of the same has to be done via Webpack.</p>
</li>
</ul>
<p>Now that we know, what our goals are, lets get started. Here is some information on important packages —</p>
<ul>
<li><p>React: v15.6.1</p>
</li>
<li><p>Redux: v3.7.2</p>
</li>
<li><p>React-Redux: v5.0.6 (Package that helps connect react components with redux stores)</p>
</li>
<li><p>React-Router: v4.1.2</p>
</li>
<li><p>Redux-thunk: v2.2.0</p>
</li>
</ul>
<p>You can checkout the full <a target="_blank" href="https://github.com/anirudhvarma12/snooplay/blob/master/package.json">package.json file here</a>.</p>
<h3 id="heading-step-1-create-the-app-boiler-plate">Step 1: Create the app boiler plate.</h3>
<p>We will create the structure of the app by using Facebook’s create-react-app (CRA) tool. After your install CRA, go to your terminal and type the following command —</p>
<pre><code class="lang-bash">create-react-app &lt;app_name&gt;
</code></pre>
<p>create-react-app is a utility that creates a pre-configured project with Webpack &amp; Babel and other tools. This was made to get over the configuration issues that people usually face while wiring up different tools together.</p>
<p>This process can take some time, once it finishes you can <code>cd</code> into the directory and type <code>npm start</code> This would open your browser and you should be able to see the React App.</p>
<p>The entry point for the app is <code>index.js</code> which then renders the <code>&lt;App /&gt;</code> component from <code>app.js</code> .</p>
<h3 id="heading-step-2-installing-the-libraries">Step 2: Installing the libraries</h3>
<p>Now we need to install our essential libraries i.e. React-Router &amp; Redux.</p>
<pre><code class="lang-bash">npm install --save redux react-router
</code></pre>
<p>Both React-Router &amp; Redux are very modular libraries. For example, React-Router can also be used in React-Native projects, whereas Redux has no direct connection with React. To make it easy to use these libraries we will install 2 more libs.</p>
<ul>
<li><p>react-router-dom: Contains react components to be used in web projects.</p>
</li>
<li><p>react-redux: Helps connect our components with redux, thus making it easy to read &amp; change state from React components.</p>
<p>  npm install —save react-router-dom react-redux</p>
</li>
</ul>
<h3 id="heading-step-3-scss-integration">Step 3: SCSS Integration</h3>
<p>This step was very tricky, with many resources on the web. Some worked with Webpack 1 &amp; not with Webpack 2 while some refused to work at all.</p>
<pre><code class="lang-bash">npm install --save-dev css-loader extract-text-webpack-plugin node-sass sass-loader
</code></pre>
<p>Before we update our webpack configs, we need to *eject *our project. Eject basically means that we will now take care of the webpack &amp; other config instead of just working with what create-react-app gives us. To eject the project just run the following command —</p>
<pre><code class="lang-bash">npm run eject
</code></pre>
<p>After this process is completed, you will find a config folder which would contain 2 webpack files, one is _webpack.config.dev.js _&amp; other is *webpack.config.prod.js. *As you might have guessed, the dev file your devlopment profile (used when you do <code>npm start</code> ) and the prod file is your production profile that performs optimizations before creating a deployment bundle (run <code>npm run build</code> )</p>
<p>Now in our <code>webpack.config.dev.js</code> we will configure the <code>extract-text-webpack-plugin</code> to handle the scss files.</p>
<p><strong>3.1) Get the extract — text plugin in the file.</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> ExtractTextPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'extract-text-webpack-plugin'</span>);
</code></pre>
<p>Also declare the CSS file name -</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> cssFilename = <span class="hljs-string">'static/css/[name].[contenthash:8].css'</span>;
</code></pre>
<p><strong>3.2) Configure rules</strong></p>
<p>In the <code>module.exports</code> object, find the <code>module</code> property. In the <code>rules</code> array you need to find the following section —</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// "oneOf" will traverse all following loaders until one will                               // match the requirements. When no loader matches it will fall                               // back to the "file" loader at the end of the loader list.                               oneOf: [</span>
....
]
</code></pre>
<p>Here add the config to process <code>scss</code> files using appropriate loaders.</p>
<pre><code class="lang-javascript">{
<span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.scss$/</span>,
use: ExtractTextPlugin.extract([<span class="hljs-string">'css-loader'</span>, <span class="hljs-string">'sass-loader'</span>])                                 },
</code></pre>
<p><em>Note: Several examples on the internet use the loaders syntax, but that is deprecated.</em></p>
<p>Also, you should comment out the <code>css</code> loader that is pre-configured in the file.</p>
<h3 id="heading-step-4-redux-amp-redux-thunk">Step 4: Redux &amp; Redux-Thunk</h3>
<p>Before going forward here, I would like to mention 2 resources that helped me greatly in understanding Redux &amp; Thunks.</p>
<ol>
<li><p>Stephen Grider’s Modern React with Redux course on Udemy. Check it out here — <a target="_blank" href="https://www.udemy.com/react-redux/">https://www.udemy.com/react-redux/</a></p>
</li>
<li><p>Matt Stow’s Dummy’s Guide to Redux &amp; Thunk. Check it out here- <a target="_blank" href="https://medium.com/@stowball/a-dummys-guide-to-redux-and-thunk-in-react-d8904a7005d3">https://medium.com/@stowball/a-dummys-guide-to-redux-and-thunk-in-react-d8904a7005d3</a></p>
</li>
</ol>
<p>An introduction to the various terms you are going to see moving forward in reference to Redux.</p>
<ul>
<li><p>**State: **State refers to the data of the application that we store in Redux. Redux creates this one big JavaScript object to store all the state of the application. State can only be updated by Reducers.</p>
</li>
<li><p>**Reducers: **Reducers are plain JavaScript functions that are responsible for updating the state of the application. Each reducer is responsible for updating one part of the application state.</p>
</li>
<li><p><strong>Actions</strong>: An action is basically an object that describes an event that would result in a change in state. Each action has <code>type</code> property which helps reducers in deciding if they have to respond to this action or not. Function that return actions are called action creators.</p>
</li>
<li><p>**Redux-Thunk: **Action creators usually returns a plain JavaScript object. Redux-Thunk allows you to return functions instead of objects. These functions recieve <code>dispatch</code> &amp; <code>getState</code> store functions which allow you to further call actions from inside the function. Example of such action creator —</p>
</li>
</ul>
<p>Example of using Redux-Thunk</p>
<h3 id="heading-step-5-creating-our-store-and-using-redux">Step 5: Creating our store and using Redux.</h3>
<p>I would like to outline the process that I used to create my store.</p>
<ul>
<li><p>Design the app state on paper or as a JavaScript object in any text editor.</p>
</li>
<li><p>Create reducers for each property. At this step all reducers simply returned the state without any other process.</p>
</li>
<li><p>Bind reducer &amp; properties. This is how the state for Snooplay looks</p>
<p>  //As you can see, each property is assigned a reducer. const rootReducer = combineReducers({ currentPost: ReducerCurrentPost,<br />  posts: ReducerFetchPosts, subs: ReducerFetchSubreddits,<br />  currentSub: ReducerCurrentSubreddit, loaderVisible: ReducerLoadingState, notification: ReducerNotification, lastPostId: ReducerLastPost });</p>
</li>
<li><p>To provide the state to the entire application, you need to wrap your components with <code>Provider</code> component provided by <code>react-redux</code> package.</p>
</li>
<li><p>Now that we have linked our properties with our reducers, I would like to point out that in our reducer functions, <em>the _</em><code>state</code> property refers to the value of the property only and not the entire state_. For example, here is my ReducerCurrentPost-</p>
<p>  // here the state is the value of ‘currentPost’ property of the app // state and not the entire state. export default function currentPostReducer(state = null, action) {</p>
<p>  }</p>
</li>
<li><p>**Actions &amp; Action Creators. **As described earlier the action is simply a JS object with a type field. Any data that has to be sent to the reducer can be sent as the payload property of the action. Here is what the action creator to set the current post look like-</p>
<p>  //This is an action creator, returns an action with a type and //payload. export const setCurrentPost = (post) =&gt; { return { type: ACTION_CURRENT_POST, payload: post } }</p>
</li>
</ul>
<p>When this action is dispatched (called) like <code>setCurrentPost(post)</code> redux sends this action to all reducers. The the current post reducer can respond like-</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { ACTION_CURRENT_POST } <span class="hljs-keyword">from</span> <span class="hljs-string">'./../Constants'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">currentPostReducer</span>(<span class="hljs-params">state = null, action</span>) </span>{
    <span class="hljs-keyword">switch</span> (action.type) {
    <span class="hljs-comment">//This reducer checks the current action type</span>
    <span class="hljs-comment">//Returns the post (payload)</span>
    <span class="hljs-comment">//This post is updated in the state</span>
      <span class="hljs-keyword">case</span> ACTION_CURRENT_POST: {
        <span class="hljs-keyword">return</span> action.payload
      }
      <span class="hljs-attr">default</span>: {
        <span class="hljs-keyword">return</span> state;
      }
    }
}
</code></pre>
<p>Next, we want our components to update when the associated state is changed. So lets say we have a component which displays the current post. When the reducer updates the current post in the state, we want this component to re-render to show the new post. This is where the <code>connect</code> method from the <code>react-redux</code> library comes into play. It connects the react components with its associated state.</p>
<p><em>Note: In react world, components which work directly with the store are called Container Components and components which work only on the given props (irrespective of where the props are supplied from) are called Presentation Components.</em></p>
<p>This is what my PostContainer component looks like. It is directly connected to the store —</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { connect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-redux'</span>;
<span class="hljs-keyword">import</span> { bindActionCreators } <span class="hljs-keyword">from</span> <span class="hljs-string">'redux'</span>;
<span class="hljs-keyword">import</span> { setCurrentPost } <span class="hljs-keyword">from</span> <span class="hljs-string">'./../../actions/'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostContainer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{
    render(){
       <span class="hljs-keyword">return</span>(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{this.props.post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>)
   }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mapStateToProps</span>(<span class="hljs-params">state</span>)</span>{
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">post</span>: state.currentPost
    }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mapDispatchToProps</span>(<span class="hljs-params">dispatch</span>)</span>{
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">actions</span>:{
        <span class="hljs-attr">closePlayer</span>: bindActionCreators(setCurrentPost, dispatch)
      }
    }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> connect(mapStateToProps, mapDispatchToProps)PostContainer);
</code></pre>
<p>So whats happening here?</p>
<p>Here we create a Component that has to render some details about the current post of the application.</p>
<ul>
<li><p><code>mapStateToProps</code> is responsible for taking the entire application state and then getting out the relevant pieces needed to render the current component. These pieces are then provided to the components as <code>props</code><br />  In the above example the <code>currentPost</code> property of the application state is accessed using the standard props mechanism.</p>
</li>
<li><p><code>mapDispatchToProps</code> is used to call actions from inside the component. In the above example, I use the <code>setCurrentPost</code>action to close the player. you can call the <code>setCurrentPost</code> action by calling <code>this.props.actions.closePlayer(null)</code> .</p>
</li>
<li><p>In the end we use <code>connect</code>to wire all these together. Now whenever the <code>currentPost</code> property is updated in the state, <code>PostContainer</code> will be updated to reflect this change.</p>
</li>
</ul>
<p><em>Note: if you are wondering why to use mapDispatchToProps — Read</em><a target="_blank" href="https://stackoverflow.com/a/41782298/1563269">this StackOverflow answer</a></p>
<p>After this you can setup React-Router. There are many great examples/guides on how to do this. Just note that do not follow a react-router v3 guide if you are working with v4 as v4 is a complete re-write.</p>
<p>React Router setup was a breeze, one thing that bugged me was navigating to paths programmatically. To do this in v4, I have used the <code>withRouter</code> Component from <code>react-router-dom</code> package. This is what it looks like —</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { withRouter } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SubmitLink</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{

    handleClick = <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.props.onClick()) {
        <span class="hljs-built_in">this</span>.props.history.push(<span class="hljs-built_in">this</span>.props.navigateTo());
      }
    }

    render() {
      <span class="hljs-keyword">return</span> (
       <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"button"</span>&gt;</span>   {this.props.label}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></span>)
      }
    }
}

<span class="hljs-keyword">const</span> NavigableSubmitLink = withRouter(SubmitLink);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> NavigableSubmitLink;
</code></pre>
<p>This component first calls the <code>onClick</code> property, if that function returns true, then it calls the <code>navigateTo</code> function which returns the new path that it has to go to after computation. Using <code>withRouter</code> gives us access to updated <code>match</code>, <code>location</code>, and <code>history</code> props.</p>
<p>Ending Notes —</p>
<ul>
<li><p><strong>The real documentation is in the issues:</strong> In the Java world, we have Java Docs &amp; where they don’t help StackOverflow steps in. But in the JS world, most problems I ran into were solved somewhere in GitHub issues. <em>So if you run into problems, don’t skip the GitHub issues.</em></p>
</li>
<li><p>In the Udemy course linked above, they use <strong>react-promise</strong> middleware, but here I use <strong>react-thunk</strong> middleware even for Ajax calls. That’s just a personal preference because I prefer less magic in my code :)</p>
</li>
</ul>
<p>That’s the end of this article, I have tried to explain all the problems I faced and how I overcome them. If you want to more detailed explanations of React, Redux &amp; Redux-Thunk, look at the resources I have linked above.</p>
]]></content:encoded></item><item><title><![CDATA[In Search of a Code Buddy - Adventures of a lonely programmer]]></title><description><![CDATA[Programming has always been a collaborative task, one that has resulted in many success stories. Usually what a non-tech people hear are stories about the super — rich geeks, but we the programmers respect team work for what it has given us, the awes...]]></description><link>https://anirudhv.xyz/in-search-of-code-buddy</link><guid isPermaLink="true">https://anirudhv.xyz/in-search-of-code-buddy</guid><dc:creator><![CDATA[Anirudh Varma]]></dc:creator><pubDate>Fri, 15 Nov 2013 00:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Programming has always been a collaborative task, one that has resulted in many success stories. Usually what a non-tech people hear are stories about the super — rich geeks, but we the programmers respect team work for what it has given us, the awesome frameworks, libraries all originating from a single mind, contributed-to by many.</p>
<p>In our “code world” everything is about teams. But what happens when you are the team, the idea man, the programmer,the front-end designer &amp; even the graphics guy.</p>
<blockquote>
<p>TLDR; when you are the team, IT SUCKS!!</p>
</blockquote>
<p>Recently, working on my biggest project till date, I realized the pitfalls of working alone. There are many of them, I’ll just write up a few.</p>
<blockquote>
<p>Some times, while writing code our mind concentrates so much on the present problem that its easier to forget the bigger picture.</p>
</blockquote>
<p>When working on client’s project, we have a clearer view — the client’s view, but when you are the idea man, things are different, to-do lists are not that helpful, having someone who shares your idea he keeps you informed about the current state of affairs.</p>
<blockquote>
<p>Front-end, back-end, graphics do ‘em all and one of them is bound to suck.</p>
</blockquote>
<p>Gone are the days of master of all trades, now is the time for specialist at one…. or maybe two but not three. I started programming in Java, got my first job at 19 as a front-end developer doing HTML/CSS &amp; then got back to Java. While at my last project, I was responsible for the Front-End and the Back-End and believe me, some pieces of code sucks, and I know that.</p>
<p>The most important of them all</p>
<blockquote>
<p>Your code buddy keeps you upbeat</p>
</blockquote>
<p>When working for long hours, you are bound to burn out, and anyone who has written more than “Hello World”, understands the fact that one can come across very frustrating situations. Having a code buddy who understands this thing helps you to keep upbeat about the prospect of finishing what you important.</p>
]]></content:encoded></item></channel></rss>