tag:whoshuu.com,2014:/feedif / else2018-07-10T11:53:51-07:00Huu Nguyenhttp://whoshuu.comSvbtle.comtag:whoshuu.com,2014:Post/using-tig-to-cherry-pick-across-branches2018-07-10T11:53:51-07:002018-07-10T11:53:51-07:00Using tig to cherry-pick across branches<p>If you know my dev style, you know that I love <a href="https://github.com/jonas/tig" rel="nofollow"><code class="prettyprint">tig</code></a>. For the past few years I’ve used it almost exclusively for one thing: staging/unstaging individual lines or chunks of code. For this task, <code class="prettyprint">tig</code> is without peer. It is so good at it that I neglected, for years, to explore the other features of <code class="prettyprint">tig</code> more fully.</p>
<p>Today I learned that it’s possible to <code class="prettyprint">git cherry-pick</code> commits across branches entirely in one session. To do this, first run <code class="prettyprint">tig</code> (I sometimes do this inside of <code class="prettyprint">nvim</code> using <code class="prettyprint"><Leader>g :Te<CR>:term tig<CR></code> - this opens <code class="prettyprint">tig</code> in a terminal nested inside of an <code class="prettyprint">nvim</code> session). This will open the main view, which shows the commits for the currently checked out branch, in all it’s DAG goodness. Pressing <code class="prettyprint">r</code> at this point will bring up the references view.</p>
<p>A git reference is a pointer to a git commit. Branches are references - human readable names that, while the name itself is static, point to different git commits over time as the branch evolves. The <code class="prettyprint">tig</code> references view shows all of the references you’ve interacted with.</p>
<p>Pick the branch you want to <code class="prettyprint">git cherry-pick</code> from and press <code class="prettyprint">Enter</code>. This will bring up a view similar to the main view, but for the branch you chose instead of the branch that is currently checked out. From here you can highlight the commit to pick, and press <code class="prettyprint">C</code> to bring up the <code class="prettyprint">git cherry-pick</code> prompt, which when confirmed will run the command as if you ran <code class="prettyprint">git cherry-pick <commit SHA1></code> yourself.</p>
<p>This is a huge improvement over my previous workflow for cherry-picking. Before I used to have to check out the branch I wanted to cherry-pick from first, run a <code class="prettyprint">git log</code> to see the SHA1 of the commit to cherry-pick, then copy that SHA1 to my clipboard using my mouse, or with <code class="prettyprint">tmux</code>. Now I can do all of this without switching branches, and while staying entirely within my keyboard. Any time you can use a workflow that’s confined to the keyboard (and even better, home row), you should take the time to learn and incorporate it.</p>
<p>So that’s all there is to it. I suspect it’s always been possible to do this with <code class="prettyprint">tig</code>, and it’s a testament to the power of the tool that I only bothered to learn to do it now after getting years of mileage out of just the most basic use-case.</p>
<p>For anyone building tools, take note. Find a workflow that takes just a hair too long and build something that makes the workflow faster and simpler.</p>
tag:whoshuu.com,2014:Post/breaking-the-glass2018-06-07T15:09:23-07:002018-06-07T15:09:23-07:00Breaking the glass<p>We all have an extra gear. Our day-to-day existence requires just a fraction of our full mental and physical focus. This makes evolutionary sense - most of our time is spent dealing with the same problems we dealt with the day before. If there’s no environmental change, then there’s no reason to spend finite willpower to change our behavior.</p>
<blockquote class="short">
<p>Put yourself in a situation where 120% of your focus is needed to survive.</p>
</blockquote>
<p>I remember two times in my life where, under both extraordinary external and internal stress, I had to break the glass.</p>
<p>The first time was when I first got to college. I coasted through high school on the belief that I was smart enough to not have to work hard. I failed algebra. Acing your exams isn’t enough when homework is worth half your grade.</p>
<p>I didn’t get into the university of my dreams. That hurt. I remember asking an orientation leader at the college I ended up going to what it would take to transfer out, and they told me I basically had to get straight A’s.</p>
<p>I got straight A+‘s the next two years and transferred out. For two years I studied every single problem in my classes until I could meticulously arrive from memory at the correct answers. I burned through more notebooks in those years than during any other time of my life. If you had asked me how to solve the time-dependent Schrödinger equation for a particle in an infinite potential well I could recite a solution as easily as I could recite the national anthem.</p>
<p>If I had gotten into my first choice university right out of high school, I doubt I would have ever pushed myself as hard as I did. In fact, when I did start taking classes there the next year, I went back to coasting. After all, the dream was achieved.</p>
<p>The second time I broke the glass was when I was trying to land my first internship. I’m not a naturally talented programmer. I wasn’t writing computer games at 12 years old, I was <em>playing them</em>, cause that’s what kids do. Recursion still gives me headaches.</p>
<p>After struggling for months to get an internship, I fell into a dark place. I felt my back against the wall, that familiar pressure of failing to live up to your own expectations. But now me and this wall have history. I knew what to do.</p>
<p>I spent the next month doing all of my studying by hand, pen and paper. I wrote solutions until I knew with certainty they would compile and produce the correct results. My professional career started right after my next interview, internship and all.</p>
<p>Put yourself in a situation where 120% of your focus is needed to survive. It doesn’t have to be all the time, but it can’t be never. True learning, the learning about yourself, who you are, and what kind of person you are, happens only through the crucible of struggle. There’s no other way. There’s no other learning that matters.</p>
tag:whoshuu.com,2014:Post/the-long-view2018-04-11T14:51:05-07:002018-04-11T14:51:05-07:00The Long View<p>Last year I made a list of <a href="http://whoshuu.com/goals" rel="nofollow">goals</a> I wanted to complete by the end of the year, which I got about a <a href="http://whoshuu.com/year-in-review-2017" rel="nofollow">50% success rate on</a>. This year I want to do things a bit differently. First because I’m late to making my resolutions, but mostly because I want to take a longer view on my growth.</p>
<p>One year is a very short amount of time in the grand scheme of learning new skills on a deeper level. I’m not a polymath, I can’t learn to be an expert on something in just a month, or even a year. I don’t have the dedication, the time, or the natural ability.</p>
<p>As in wealth management, there’s an entire industry dedicated to telling you that you can be X in Y time, where X grows ever larger in scale while Y shrinks to smaller and smaller timeframes. It takes real mental effort not to listen to that crap, especially when X is something you really want and Y is something you don’t have enough of.</p>
<p>In defiance of that ethos, I’m going to learn a few things, over a very long length of time, and hope to have the patience to delay my gratification during that time. In 3+ years time, I want to:</p>
<ul>
<li>Learn enough music to compose, record, and perform music in a live venue, however small</li>
<li>Play in a recreational basketball league and be in the top half of players</li>
<li>Have enough technical expertise to be a tech lead for a decently sized team</li>
</ul>
<p>These represent the three dimensions of my “ideal self” - I like to imagine who I am years from now and if I’m doing these things, I think I’d be happy. The good thing is that who I am and who I want to be at any point in time may change, and having a longer view allows me to roll with the punches while keeping an eye on my North Star.</p>
tag:whoshuu.com,2014:Post/year-in-review-20172018-01-02T14:50:38-08:002018-01-02T14:50:38-08:00Year in review: 2017<p>It’s in the books! A little bit over a year ago I started this blog with a post about <a href="http://whoshuu.com/goals" rel="nofollow">my goals for 2017</a>. Let’s see where I ended up on those:</p>
<ul>
<li>Read 6 books - I read 4 and am working, slowly, on the 5th, more on this in a later post</li>
<li>Complete 3 online courses - I completed 1, of all my goals I’m most disappointed in not having finished this one</li>
<li>Run 24 miles - I didn’t run 24 miles in open air, but did enough cardio to be well past this</li>
<li>Travel to a foreign country - I did this twice over by travelling to India and Canada, I’m proud of myself for finishing this</li>
<li>Publish a mobile app - I didn’t publish a mobile app but I did conceive and superficially start one</li>
</ul>
<p>Taken altogether, I’ve got about a 50% success rate on my goals for 2017. This is actually surprising since I haven’t looked at this list since I first wrote it, even though I told myself that I would be tracking my progress during the year. That’s something I should be better about.</p>
<p>Despite that, half is better than none and I can’t help but remember my 2017 with pride.</p>
tag:whoshuu.com,2014:Post/a-golang-proposal2017-11-26T12:00:36-08:002017-11-26T12:00:36-08:00A golang proposal<p>No language is perfect. Every language has warts that can’t be designed away. Recently I’ve been noticing this pattern show up a lot:</p>
<pre><code class="prettyprint lang-golang">thing, err := methodCouldErr()
if err != nil {
return err
}
useThing(thing)
</code></pre>
<p>Error propagation in golang is done by returning <code class="prettyprint">error</code> objects through the call stack until it’s ultimately consumed by some terminal caller. Done enough times – and I’ve seen entire functions comprised of successive uses of this idiom – this uses a lot of vertical real estate without adding much information. One way to avoid the vertical pollution is by combining the method call with the conditional:</p>
<pre><code class="prettyprint lang-golang">if _, err := methodCouldErr(); err != nil {
return err
}
</code></pre>
<p>This has an obvious drawback. A variable assigned inside the conditional can’t be used unless declared previously:</p>
<pre><code class="prettyprint lang-golang">var thing Thing
var err error
if thing, err = methodCouldErr(); err != nil {
return err
}
useThing(thing)
</code></pre>
<p>In the end, there are three different ways of propagating an error depending on what the situation needs, but it’s easy to mix these patterns up – I’ve seen all three in the same function on occasion.</p>
<p>At the risk of making it harder to decide, I propose a fourth pattern, a pattern to rule them all:</p>
<pre><code class="prettyprint lang-golang">return if thing, err := methodCouldErr(); err != nil; err
useThing(thing)
</code></pre>
<p>I call this the <code class="prettyprint">return-if</code> construct. It follows the syntax:</p>
<pre><code class="prettyprint">return if [statement; statement; ...]; conditional; return-value
</code></pre>
<p>Anything allowed in a normal <code class="prettyprint">if</code> conditional is allowed here. The only difference is that there is one additional clause at the very end, the <code class="prettyprint">return-value</code>. Variables declared in any of the <code class="prettyprint">statement</code>s would be in the calling scope, not the conditional scope, unlike an <code class="prettyprint">if</code> conditional. This isn’t for a particular reason other than quality of life.</p>
<p>Since this is a language change, it clearly would cause compatibility issues. Additionally, it’s hard to know if this could ultimately decrease readability in the long run. There is value in conciseness and expressiveness, but horizontal complexity could produce a cognitive burden if done excessively.</p>
<p>I’m not sure if there’s a right answer in this situation but it would be interesting to see if this might be a net positive for the language. No language is perfect, and we should constantly think about ways of improving our tools as an industry.</p>
tag:whoshuu.com,2014:Post/toward-better-git-hygiene2017-06-24T13:59:41-07:002017-06-24T13:59:41-07:00Toward better git hygiene<p>My first experience with git was when I was an intern at my first job. I knew very little about programming. I knew even less about git.</p>
<p>The extent of my knowledge on version control software was the time I had to use <a href="https://tortoisesvn.net/" rel="nofollow">TortoiseSVN</a> to download source code for a robotics project back in college. I never “committed” anything, whatever that meant. To me, version control software was just a fancier way to download stuff to my computer.</p>
<p>With that background on VCS, during my internship, I committed a week’s worth of code with the message “Update some stuff”. Someone who wasn’t even my manager rejected it and said, simply, “no omnibus commits”.</p>
<p>Since that point I made a concerted effort to practice good git hygiene. This involves knowing why git, or any kind of version control, is useful.</p>
<p><strong>Version control is critical for understanding how a project evolves over time</strong>.</p>
<p>Likewise, it enables the treatment of features and fixes as atomic units of change. It should be easy to revert a commit (or to find a set of related commits) and know exactly how that affects the project.</p>
<p>So how do you from “Update some stuff” to being a model of git cleanliness?</p>
<p>First, and this has been beaten to death numerous times, but use the <a href="https://en.wikipedia.org/wiki/Imperative_mood" rel="nofollow">imperative mood </a> for the first line. Imagine you’re in school and your instructor is telling you what to do for a project to grow it. This is that mood:</p>
<ul>
<li>Add pagination to the users endpoint</li>
<li>Fix the memory leak in the factory controller factory</li>
<li>Update the version to 2.3.4</li>
</ul>
<p>The imperative mood signals a command that is to be taken. One thing I’ve done for my commits is to use a simple set of starting words: <em>Add</em>, <em>Fix</em>, <em>Update</em>, <em>Remove</em>. It’s incredible how many changes map into these four words, and contrary to what you might initially think, it’s actually easier to write the rest of the commit message when you aren’t agonizing over how to start it.</p>
<p>Second, use tooling that enables line by line staging. Back in the day, any time I had changes in a file, I would always throw all of those changes into a single commit and be done with it. This often results in unwieldy and non-atomic changes in the git history.</p>
<p>I don’t blame my laziness for this, I blame my insufficient tooling. It was just too difficult stage changes interactively with the vanilla git command line. I’ve since upgraded to using <a href="https://github.com/jonas/tig" rel="nofollow"><em>tig</em></a>, an ncurses-based interface to git. The first few weeks using it felt awkward, but it was definitely worth it.</p>
<p>It doesn’t matter how many changes I make to a file, I can always hop right into <em>tig</em> and stage exactly which lines should go into which commit. This both lets me write code in whatever cadence feels right at the moment, and later preserve it in a natural way for the project as it grows.</p>
<p>Doing these two things helped me avoid making omnibus commits and improved my git hygiene immensely. In fact, even with just these changes, you could be a cleaner programmer than 90% (this is a totally made up but not entirely untrue number) of contributors on GitHub.</p>
<p>Don’t wait, git clean!</p>
tag:whoshuu.com,2014:Post/go-figure2017-03-04T15:25:12-08:002017-03-04T15:25:12-08:00Go figure<p>Learning a new programming language is painful sometimes. I remember when I was learning Python, and I would run into <a href="http://stackoverflow.com/q/1132941/2297365" rel="nofollow">language quirks</a> all the time. It was only after suffering through a few embarrassing pull requests that I finally grokked the dang thing.</p>
<p>The same thing is happening to me in Go. Let’s say you have two structs that have the same field:</p>
<pre><code class="prettyprint lang-golang">type A struct {
C string
}
type B struct {
C string
}
</code></pre>
<p>and then you have a list of interfaces that include two of these:</p>
<pre><code class="prettyprint lang-golang">interfaces := []interface{}{A{"hello"}, B{"world"}}
</code></pre>
<p>In this reduced example, all I wanted to do was access <code class="prettyprint">C</code> from both of these. It seemed natural to use a <a href="https://golang.org/doc/effective_go.html#type_switch" rel="nofollow">type switch</a>:</p>
<pre><code class="prettyprint lang-golang">for _, value := range interfaces {
switch c := value.(type) {
case A, B:
fmt.Println(c.C)
}
}
</code></pre>
<p><a href="https://play.golang.org/p/YEcSkJJ0Vu" rel="nofollow">Uh oh</a>. Go complains that <code class="prettyprint">c</code> is still an interface, and as a result has no field <code class="prettyprint">C</code>. That’s really strange, because this <a href="https://play.golang.org/p/T8XnGHbd7H" rel="nofollow">definitely works</a>:</p>
<pre><code class="prettyprint lang-golang">for _, value := range interfaces {
switch c := value.(type) {
case A:
fmt.Println(c.C)
case B:
fmt.Println(c.C)
}
}
</code></pre>
<p>So what doesn’t work with a compound case statement works just fine when you break the statement up into multiple cases. This baffled me.</p>
<p>It took some creative Googling to find this gem in the <a href="https://golang.org/ref/spec#Type_switches" rel="nofollow">spec</a>:</p>
<blockquote>
<p>The TypeSwitchGuard may include a short variable declaration. When that form is used, the variable is declared at the end of the TypeSwitchCase in the implicit block of each clause. In clauses with a case listing exactly one type, the variable has that type; otherwise, the variable has the type of the expression in the TypeSwitchGuard.</p>
</blockquote>
<p>In non-Golangese, this just means that a case has a single listing, the variable after <code class="prettyprint">switch</code> takes on the type of the case. If the case has more than one listing, it stays its original type, which is <code class="prettyprint">interface{}</code>.</p>
<p>I wish this type of thing would be more obvious. I expected the first pattern to be fully acceptable, or error out if compilation finds that one of the types doesn’t have a <code class="prettyprint">C</code> field. It’s more expressive and avoids duplication, both strong indicators of a proper language construct. Go figure, I guess.</p>
tag:whoshuu.com,2014:Post/factories-a-koan2017-02-17T21:03:32-08:002017-02-17T21:03:32-08:00Factories: a kōan<p>Young Pat walked up excitedly to Master Dsa.</p>
<p>“I’ve fashioned a factory to make shoes! Now I don’t need to make shoes by hand any more!”</p>
<p>Master Dsa was curious.</p>
<p>“How did you make that factory?”</p>
<p>“By hand.”</p>
<p>Master Dsa looked at Young Pat’s feet.</p>
<p>“How many feet do you have?”</p>
<p>Young Pat looked down, and was enlightened.</p>
tag:whoshuu.com,2014:Post/blink2017-01-15T22:39:11-08:002017-01-15T22:39:11-08:00Blink<p><a href="https://en.wikipedia.org/wiki/Blink_(book)" rel="nofollow">Blink</a> is an interesting and short read.</p>
<p>Structurally, the book is an example of its own thesis - reading any random subset of it is enough to discern the central insight. From the very beginning, Gladwell uses examples of “thin-slicing” to show that our intuitive machinery is powerful enough to make reasonably accurate judgments even with very little data. Some of the examples really are incredible, as in, if I didn’t trust that there’s data to back them up I probably wouldn’t believe them. </p>
<p>The most compelling example to me personally is the one of basketball players and “court vision”. I watch a lot of (read: too much) basketball. Some of the decisions professionals have to make cannot possibly be made in the rational mode of thought, the game moves too fast. Steph Curry practices with <a href="https://www.youtube.com/watch?v=O6CHAmdkVDM" rel="nofollow">sensory distraction tools</a>, and yet his body gives him enough information to make split second decisions and judgments.</p>
<p>It’s possible I could have gotten the gist of the book after just the first couple of chapters. Partially I kept going because the book is already so short, and partially because books are supposed to be enjoyable, and this is one I enjoyed a lot. Each story, even though it makes the same point as every other story, is told in a delightful and human way. If you’ve got the time, or incidentally, no time at all, it’s worth reading even just a bit of it.</p>
tag:whoshuu.com,2014:Post/beginner-tmux2017-01-07T13:50:29-08:002017-01-07T13:50:29-08:00Beginner tmux<p>I just finished my first week at my new job. I took the opportunity to learn a new technology that I’ll hopefully have fully integrated into my <a href="http://whoshuu.com/tools" rel="nofollow">toolbox</a> soon.</p>
<p>I’ve realized over the years that if I really want to learn and internalize something like a tool, I have to start at the very beginning. It takes a lot of discipline but I think the end result will be worth the effort.</p>
<p>That means not changing defaults, customizing shortcuts, or anything like that. I’m forcing myself to use vanilla tmux until I can open, detach, and reattach sessions with my eyes closed. To keep the scope of what I have to learn as small as possible, this is all I’ll be using tmux for, for at least the first few months.</p>
<p>As a reminder to myself, these are the commands I have to make second nature:</p>
<pre><code class="prettyprint">tmux new -s [name] # create a new session
tmux det # detach from session
tmux ls # show session list
tmux a -t [name] # attach to a session
tmux kill-session -t [name] # kill a session
</code></pre>
<p>There is also a set of keyboard shortcuts that are useful to know in case I’m not in a shell context:</p>
<pre><code class="prettyprint lang-bash">CTRL + b s # show session picker
CTRL + b d # detach from session
</code></pre>
<p>This is just the beginning. Features I’m looking forward to taking the time to learn after getting these basics down are:</p>
<blockquote class="short">
<p>Windows<br>
Panes<br>
Remote sessions</p>
</blockquote>
<p>That last one looks to be very useful, especially now that I’ve switched to a Linux development machine from an OS X one. It means I’ll be able to do most of my work in my preferred environment, and have the flexibility to attach to a session on a local VM for build work.</p>