Larry Price

And The Endless Cup Of Coffee

Going Remote: 4 Months in, Aka Remote Life 4-eva

| Comments

This is the third in a series of blog posts detailing my experience acclimating to a fully remote work experience. You may also enjoy my original posts detailing my first week and my first month.

Has it really been 4 months since I started riding the raging river of remote work? After my first month, I felt pretty good about my daily schedule and work/life balance. Since the last post, I’ve met many of my co-workers IRL, learned to find my own work, and figured out how to shake things up when I get in a rut.

But First, Did I Handle My Action Items?

During my first month, I struggled to figure out what to work on after finishing a task. At this point, it’s extremely rare that I don’t have a dozen things in the queue like a pile of papers in an In Box about to topple over. I am happily busy all the time, either pulling things off the top of the stack, plucking things from the middle, or coming up with some new feature that I need to add.

I feel a lot more comfortable on chat. Our IRC channels are a bit daunting at first, especially when there’s a lot of action going on. I’ve learned some good ways to interject or reach out to the people that I need to talk to.

Oh, and I still haven’t gotten a new floormat. Yes, this one’s still broken. For some reason, it just doesn’t annoy me as much as it used to. It’s almost endearing: like a three-legged puppy that I roll my chair across and stand on top of for 8 hours a day.

Meeting IRL

Why would you guys actually meet IRL? - Elliot, Mr Robot

I know a bunch of my coworkers by IRC nicks, and I see a few of their faces in a Google Hangout for our daily standup. This has been sufficient for me, but we did something truly magical in June. We met IRL.

The team I’m on (~10 people) and our sibling team (~10 people) met in Montréal, Québec, Canada, for about a week, and it was unlike any meeting-of-the-minds I’ve ever been to. The engineers were largely from the US and Europe. We all stayed in the hotel downtown and used a small conference room to hang out and work all day, every day. We woke up and ate breakfast together, met in the conference room at 9, had snacks and coffee, ate lunch together, stopped working precisely at 6, and met back in the lobby a few minutes later to go out on the town until 11 or midnight. It’s a truly intense social experience, especially for a group of people who spend most of their days only interacting with other humans through IRC, especially for a group of people who only meet twice a year or so.

This coming together allowed us to hash out a lot of our plans for the coming months, but I believe the true victory in this type of event is the camaraderie it creates. It’s nice to be able to put faces to nicks, think about the inflection in a person’s voice coming out in the way they type, and know exactly who I need to ping on IRC to accomplish certain tasks. It’s fun to hang out with people from all over the world, and it’s fun to go drinking with your coworkers, a thing I had temporarily forgotten.

I’ll note that we also happened to be in Montréal during the 23rd annual Mondial de la Biere, a huge international beer festival that lasted several days. I’ll also note that it was fun to try to speak little bits of French in Montréal, and I’m really looking forward to wherever the next sprint abroad may take us (most likely Europe in October).

Finding Work

With a decentralized company, the issue of finding things to work on for new employees can be tough. Do you give them something small and easy and possibly belittling? Do you give them something massive that will leave them scratching their heads for weeks and completely out of touch with the rest of the company? How can you find a good middle ground here?

I’d say I was “eased in” with smaller tasks into my current project. After the first few tasks were completed, it was often unclear to me where I should go next. There was always a list of bugs - was I the right person to work on them? Was there any other impending feature or unlisted bug that I should start looking into instead? These are hard questions for someone who hasn’t been around for very long.

Over time, I gained more and more responsibilities. I needed a bug fixed pronto in another project, so I did it myself and submitted an MP. Oh, you understand this codebase? You can be a maintainer now! Oh, I think I remember from your resume that you have some golang experience. We need this fixed ASAP, using SD cards is completely broken without it!

It’s all a slippery slope to having a bottomless bucket of super-interesting things to choose from to do work, perform code reviews, and answer community questions. Yet somehow it’s all happened in a way that is not overwhelming, but freeing. When I get stuck on a problem or need a short break from my current project, there’s plenty of other work to go around. Which leads me to…

Shaking Things Up

Routine can be helpful, but it can also be terrible. For the parts of May and June that I wasn’t traveling, I was largely waking up at the same time, making the same lunch, listening to the same music every day, petting the same cats, and picking up the same kinds of tasks from the backlog. None of this was bad per se, but I found myself getting a tad sluggish. It would be harder to work on menial tasks, and easier to come up with elaborate solutions to simple problems. So what did I do?

I started varying my sleep schedule. Some days I get out of bed at 7, other days I get out of bed at 8:45. Because I work from home, I don’t have to worry about fighting traffic or skipping breakfast.

I started varying my lunches. I was making some fun rissotto recipes, but since it’s summer I’ve been mixing up a bunch of different vegetables into a menagerie of salads: sauteed green tomatoes, onions, and zucchini; cukes and onions; pineapple, succotash, and eggs.

As I’ve gained more responsibilities for various projects, I’ve been able to branch into different kinds of tasks. After finishing up a big rework of one codebase, I can start jumping into bugs somewhere else. I can dig deep somewhere, and pivot when I’m ready to go back. There’s always something interesting to work on, and I can see the way different tasks help us towards our end goal. Not to mention I can always do bug hunts.

Remote Life 4-eva

It’s not just working remotely that makes this possible - it’s the people, the culture, and the fun and interesting products we’re creating. Maybe I’ll start blogging more about those things in the future. I don’t have much in this area that I’m looking to improve on, so this could be the last post in the series. Maybe I’ll do one at the 1-year mark to note any new tricks I’ve learned. Until then, keep looking our for other non-diary-entry blog posts.

Looking for advice on working remotely? Not sure if you’d like it? Do you have a strong disagreement with me as a person or my lifestyle choices? Hit me up and we can chat!

Writing Go/QML Convergent Ubuntu Apps

| Comments

Thinking about writing an Ubuntu application that will work in Unity 8? You’ll be writing a “convergent” app, which is an application that can respond to touch or mouse, and will adapt appropriately to a phone, tablet, or desktop screen. It will even be able to update its display on-the-fly if, say, you plug your phone into a monitor or bluetooth keyboard.

There are lots of ways to write a convergent application with the Ubuntu SDK. You can build apps in pure QML, C++ with QML, QtQuick, pure HTML5/Javascript, or even Golang with QML. We’ll be focusing on go apps for the rest of this post.

Go is a young language, and the recent release of go 1.6 has introduced some nasty changes particularly involving cgo. It has also introduced vendoring by default, which is a welcome change.

I’m using go 1.6.2. For me, the current project template provided by the Ubuntu SDK feels quite broken. I can’t get things to build locally, and furthermore I see no options for pushing an ARM build to my device.

Fortunately, I found this ubuntu-go-qml-template which is a template to enable running/building a go/qml application locally while also supporting building/installing onto an arm device. The kicker? This tool was designed to work for go 1.3.3. Sigh! Since I’m unwilling to compromise and use old technology, I forked the project and updated it to fit my more modern needs.

Because our go template will depend on QML, we depend on the go-qml project to create the necessary C bindings to allow us to use QML. However, with the update to go 1.6, the current version (revision 2ee7e5f) of go-qml will give a runtime error from cgo with the wonderfully helpful panic: runtime error: cgo argument has Go pointer to Go pointer. Another thorn in our side. Fortunately, this issue is in previously tread-upon ground and there is a fork of go-qml with enough of the cgo issues fixed to run our application with no problems. In the ubuntu-go-qml-template I forked above, I’ve gone ahead and vendored this fork of go-qml. It all works because of the default vendoring available in go 1.6.

With that background out of the way, let’s run through getting a project started:

1
2
3
4
5
6
7
8
9
10
11
$ sudo apt-get install golang g++ qtdeclarative5-dev qtbase5-private-dev \
                       qtdeclarative5-private-dev libqt5opengl5-dev \
                                           qtdeclarative5-qtquick2-plugin
# installing dependencies...
$ git clone https://github.com/larryprice/ubuntu-go-qml-template.git your-project-name
# cloning repo...
$ cd your-project-name
$ chroot-scripts/setup-chroot.sh
# building a chroot for ubuntu-sdk-15.04
# distro=vivid, arch=arm
# with go 1.6.2 with armhf compilation support

You may need to have other dependencies including click or phablet-tools. The above commands installed dependencies, cloned the repo, and built and/or updated a chroot for building our source for arm.

Next you’ll want to setup the project for your own needs. The original template creator included a nifty setup script to get this done:

1
2
$ ruby setup.rb -v -n your-project-name -a "Your Name" -e "your.email@example.com" \
                   -d "your-developer-namespace"

This will do some fancy gsub and file renaming to make the template your own.

If you check src/, you’ll find a main.go file ready for your use. You’ll also find a main.qml file in share/qml/. You can vendor all of your dependencies in vendor/, where you’ll already find the qml package.

As far as getting your application to work, there are more scripts available:

1
2
3
4
$ ./build.sh
# this will build your project locally
$ ./run.sh
# this will build your project locally and then run it on the desktop

The best part about this template is the ability to build for arm and load your applications onto a device:

1
2
3
4
5
$ ./build-in-chroot.sh
# builds the package using the vivid+armhf chroot we set up previously
$ ./install-on-device.sh
# builds for vivid+armhf and installs the click directly on
# the first USB-connected Ubuntu Touch device

Now you can run and install go/qml applications on desktop or on devices. Time to go build something cool!

Disclaimer: In the future, this template will likely need to be updated for new go versions or new default versions of the Ubuntu SDK. Don’t be afraid to make a comment below or submit a PR.

Effective Modern C++

| Comments

The Gist

How can one man give the world so much? Scott Meyers transformed my understanding of C++ with Effective C++, a book which not only teaches good C++ practices and principles, but also explains what’s going on behind the scenes to make those efforts so effectual. Effective Modern C++ is the same book aimed at a different audience. The audience of Effective C++ was the developer who could use C++ to build a humble home of straw or wood, but didn’t know that C++ was born to create homes of brick and mortar. Effective Modern C++ is for the seasoned developer who knows the brick home they built with C++98 can stand tall, but is bewildered by the plethora of modern amenities available in the top-floor penthouse that is C++11.

Takeaways

Even when first introduced to the language, it seemed the mentality around C++ was that it was simple, baremetal, and robust. It didn’t need garbage collection. It didn’t need decent threading (fork that). Lambdas? Type deduction? Go talk to a language specification who cares!

But here we are. C++11 can now act a little bit more like its cousins C# and Java, but run fast like its pappy C. I have been on a number of projects where C++11 is king for the last 3 months. The last time I had been on a C++ project, we seemed to be stuck in the ice age. As I first started reading this book, I would read one of the items and apply it directly to the code I was working on literally the following morning. This new C++ is downright luxurious compared to the old one.

C++11 gives us the auto pointer for type deduction, similar to var in C#. Some examples:

1
2
3
auto x = 1;                 // x is int
auto y = new Thing();       // y is Thing*
const auto z = "the thing"; // z is a const char*

C++11 also has new loop syntax for iterators:

1
2
3
4
5
6
7
8
std::vector<int> v{4, 6, 0, 3, 3};

for (const auto& value: v)
{
  std::cout << value;
}
std::cout << std::endl
// prints 46033

You may notice in the above code the use of curly braces to initalize the std::vector. Braced initialization allows us to use a std::initalizer_list to initalize STL objects, but it also allows basic construction.

There are now lambdas: function handles defined dynamically which can capture other variables (called a closure).

1
2
3
4
5
6
7
auto x = 5;
auto my_func = [&x](int y) {return x+y;};

my_func(5); // 10
my_func(3); // 8
x = 11;
my_func(5); // 16

In the above example, x is captured by reference. You could also copy-capture x by excluding the &.

You like garbage collection? We got you covered. There’s std::unique_ptr to represent one-shot memory that should be deleted when the pointer goes out of scope, and there’s std::shared_ptr which is reference counted and will be deleted when all references to the shared_ptr go out of scope. These language enhancements are essential, and anyone well-versed in the usage of boost::scoped_ptr and boost::shared_ptr will have no trouble getting the hang of these.

The concurrency API is pretty neat, though I haven’t had much chance to play with it. std::atomic allows you to create objects which are guaranteed to be read/write thread-safely. std::future allows you to fire off a command in another thread and continue after it’s completion.

Looking to override a method? You can indicate an intentional override with the override keyword to tell the reader and the compiler you’re intending to override a parent method. Comes in handy.

Another nice construct is nullptr. In C++, NULL is actually just 0. Because of this you might even see your fellow developers comparing pointers to 0 while you try to determine their intent. We can now compare and set our NULL pointers to nullptr: an improvement soft in functionality, but noticeable in readability.

Although I loved reading about C++ in bite-sized chunks throughout this book, there were a few things that went over my head (not just the first time). A major point of friction between myself and the author were universal references (&&) and the move operator. These concepts were new to me and difficult to grasp the first few times they were brought up in this book. It may have been the order they were presented, or it may have been my lack of contact with them in the real world, but I would recommend having some level of understanding for universal references before reading those parts of this book.

The move operation moves the contents of memory from one object into another, as opposed to a copy operation which will duplicate that memory. A universal reference is, in some sense, a way to allow either a copy or move to be called based on whether an lvalue or an rvalue is being passed in. There are lots of rules involved, and sometimes move is faster than copy but other times it isn’t. For me (and I assume many others), this confusion will lead me to largely ignore this feature for now.

There is also quite a bit of discussion early in the book about using type deduction in templates with auto and decltype, but this discussion made my head hurt and made me glad I don’t do much template metaprogramming.

On top of all this goodness (and more I didn’t mention), C++14 includes a lot of bonus features that make C++ even a little sweeter. Here’s a shortlist. (Looking for a list of C++11 features? Here you go.)

Action Items

Ranks, Streaks, and Karma - a Look at Competitive Contributions

| Comments

If you weren’t paying close attention, you may not have noticed that Github has recently removed Streaks from profile pages along with a few other changes.

For the uninitiated, Github tracked each user’s commit history every day and displayed this information prominently on the user’s profile for the past 365 days. When committing multiple days in succession, a “streak” is started. Your streak resets the next solar day you don’t commit to Github.

What was the purpose of the streak?

The streak encouraged developers to contribute public open-source code as frequently as possible. This is a very good thing! Maybe it even influenced some people to contribute to open-source projects that desperately needed help. Maybe it helped some developers explore new codebases and languages they never dreamt of exploring previously.

However, any good feelings that came from the streak are instantly dashed when you take a day off. All those good-feels you get after working hard to get a 10-day streak? Crushed in an instant. Now you need to start over, but you don’t bother because every time you feel a streak coming on it’s dashed away. This is a painful reminder that life is short, and you’ll only be rewarded in the short-term for any effort you put in.

So if the good-feels wasn’t the purpose, how about notoriety? Surely someone with a long streak is a good person and a noble developer!

Except for gists like this which will help you generate a 100-year streak. Or the fact that you could make empty commits to personal repos and manipulate the streak. Or you could be making minor documentation/newline changes every day. Not only that, but not all developers use Github as their primary source control platform. Developers could be making contributions to Bitbucket as well as Github and not have that reflected in their streak at all.

My theory is that streaks, though well-intended, served no purpose.

They were ripe for abuse and not a very good “reward” for contributing code on the side, nor a good indicator of how grey a developer’s beard is. Not all good developers make commits every day, and encouraging a commit-a-day is getting people trapped in the Silicon Valley bad-habit of never not working. For the time being, good riddance.

At Canonical, we use Launchpad to host most of our source code. Launchpad has this concept of “Karma” which tracks your commits, code reviews, bug reports, branch merges, etc on Launchpad. Karma decays over time but not immediately, which means that you can take days off and maintain Karma. From this number, you can usually tell if a user is new to the system, highly active recently, or has turned into a manager. For reference, mine is a little over 3000 as of this blog post. Although I mostly like the way Karma works, I don’t think it’s the epitome of source code gamification.

As far as I know, sites like Bitbucket and GitLab don’t have such a concept of rewarding heavy coders or giving some indication of recent activity outside of a news feed. Maybe a news feed style is enough?

The good people at Github want you to code socially, and I’m excited to see if they can come up with a fun and light way to gamify open-source software while avoiding some of the unfun aspects of streaks and the blaisé concept of news feeds.

What do you think? Do you miss streaks? Did streaks motivate you to contribute more frequently? Any ideas for a new system? Tell me in the comments!

Going Remote: 1 Month In

| Comments

This is the second in a series of blog posts detailing my experience migrating from a culture based on co-location to a fully remote environment. You may also enjoy my original post detailing my first week. Look out for another post in the fall.

I’ve spent an entire month working remotely. Whereas I spent much of my first week working remotely getting my home office in a working state, the rest of the month was largely spent acclimating to a culture of complete autonomy, getting comfortable with my peers, and finding my way around.

Attacking My Action Items

One of my action items from the week 1 post involved personalizing my workspace. I brought three posters from our second-floor study and planted them on the walls of my new office area downstairs. It makes my new office feel a lot more like my own space and a lot less like the formerly-unused living room. I have a 1994 Ren&Stimpy calendar hanging on the bookshelf as well as a few stickers and other various nerdy hangables. I’m fairly happy with the current state of my office.

I’ve made a point of exercising more during the work day. I work my biceps and triceps with my handheld weight, as many nose-to-the-ground push-ups as I can, and really hard bicycles until my abs tell me to stop. I’ve also been walking outside in the early afternoon to check on the state of my hop garden. Not to mention I’m still making significant use of my sit-stand desk.

As far as extracurricular activities go, I think I’m keeping steady. I’ve been going to my local Code&Coffee, and I just had a monthly meeting of Indy Golang. I’ve been reading a bunch of blogs and eating up modern C++ material. I’d like to make sure I get to IndySA every now and then, but I usually just whiff the date. I haven’t been doing much coding outside of work, but that hasn’t been high on my priority list recently. Since I currently work for an open-source company, I am embedded in the world of code all day, and I usually end the day very satisified.

I did not buy a better floormat. Still on the list.

Acclimation Station

Although my first week was a success, I’ll admit it was still a little awkward. However, I’ve found myself significantly more comfortable at the end of my first month.

In this position, there is a level of autonomy unlike any I have ever experienced. No one tells me what to work on next. I figure out what I’ll be doing almost entirely based on incoming bug reports, community rumblings, nebulous plans, or simply things that interest and/or annoy me about a project. Priorities are in the eye of the beholder, and it’s in my best interest to pick up work that is meaningful and relevant. I complete the task, get it into review, and make sure everybody’s happy. Since everyone has a shared goal, it’s unusual for developers to be especially nit-picky during reviews, and thus reviews become more focused on correctness, education, and mysterious edge cases.

Talking to people on IRC can be a little daunting because so many of my coworkers are just so good at it. At first, talking to the right people seemed impossible. Eventually, I’ve learned to become efficient with my IRC usage and I have certain channels relevant to my current tasks where I hang out. Although I describe our communications as “efficient”, that’s not to say we don’t joke around and have a good time. There are people I interact with every day who I consider work-friends even though we’ve never spoken face-to-face.

Over the past several weeks we’ve held two company-wide events. The first was a remote open forum with our CEO. During the remote forum, the CEO discussed how the company was doing and then she opened the floor for questions. Someone would ask a question in chat, people would vote for those questions, and then we would get an answer. It was done quite well and felt like a great introduction to the CEO and her vision for our company’s future. This week was a three-day conference spanning the entire organization. Presenters would share their faces and slides using Hangouts on Air, while attendees watched live and chatted together in a relevant channel. I learned a lot about the wider scope and relevance of my project, and I also got to hear about all the other interesting things going on around the company. I got to hear the founder do a Q&A, which gave rise to many great questions with humble, honest answers which gave me a good idea of what we are all about as an organization. Attendance was optional, so irrelevant presentations could be ignored as easily as closing a tab.

For the first couple weeks, I couldn’t figure out how some of my peers could be so busy all the time. Now I understand. I found myself working on projects several dependencies away from my own, adding features and fixing bugs such that our project could integrate with the dependency and we could get features shipped. Due to the nature of everything being open-source, I’m constantly working with my peers to figure out where a bug might be stemming from or the appropriate level to inject a feature or even just who to talk to about how things work. You fix a bug in one project and accidentally become a contributor while the project is in desperate need of many code reviews, which you then do and become an even more relevant member to the team.

Oftentimes, traditional office workers will say things to me like, “I don’t know how you work from home; I’d just be distracted all day and wouldn’t be able to get anything done.” I’ve found that to be completely untrue. There are many days where I have trouble not working in the evening. I’ll read up on some modern C++ techniques or read some misguided blog post about our projects, and I’ll think about jumping on the computer at 9pm just to take a peek. It takes a lot of self-restraint, but I’ve thus far been pretty good about not working after work. Hopefully I can keep that up.

In a few weeks, my team is meeting in Montreal to hang out and do code for a week. I’m excited for the opportunity to see everyone (not to mention to be in Montreal), and I’m certain that it will help me feel even more acclimated to this new environment.

Some New Action Items

  • Better floormat. Standing on my plastic mat right now, my feet do start to hurt. I need to run to an office supply store and find some rubber padding.
  • IRC Champion. Although I’m more comfortable on IRC, I know I could be better about reaching out at the right times to the right people.
  • Automaton. I still grope around for work when I’m not sure what to do next. I’d like to come up with a process to determine what should be next on the agenda without too much synchronous assistance.