Dmitri Shuralyov (dmitshur) was one of the first users of Sourcegraph whom we didn't personally know. We've enjoyed meeting up with him over meals and seeing him at all of the Go meetups in San Francisco. He is the quintessential early adopter—and creator—of new kinds of development tools, such as Conception-go (a platform for dev tools experimentation) and gostatus (which lets you track changes to a whole
GOPATH as if it's a single repository). He's bringing the Go philosophy to other languages, starting with markdownfmt (gofmt for Markdown).
We talked with Dmitri to learn about his sources of programming inspiration, and to hear about his current Go projects.
How and why did you start getting involved in open source programming?
I'm no stranger to using closed source software over the years. Some of it is really nice, and I enjoy using it. But as someone who writes code, I inevitably want to make it even better, fix bugs or contribute in other ways. But I can't do that unless the project is open source.
For all my personal projects, I always default to making them open source. Just because if someone out there likes it and wants to help out and make it better, I want to welcome that instead of denying them that opportunity.
In addition to that, I strongly believe in the benefits of code reuse, and open source libraries allow for that. When you have a specific task and there's one great library for it, you can use it. If you or someone else makes an improvement, everyone using that library benefits, and the improvement only needs to be done once.
What are the libraries and authors you have learned the most from (or who have most influenced your work)?
Without a doubt, the biggest influence and inspiration for my personal work has been Bret Victor. His talks and articles, especially Inventing on Principle and Learnable Programming, have helped me understand and convey what really drives me. I have a set of guiding principles that I believe would help make software development better, and my personal work is about finding out if that's the case.
On the programming side, one of the first non-trivial Go projects I wanted to make was to extend the Go-syntax printing of vars ala
fmt.Printf("%#v", foo) but have it work recursively on nested structs, producing gofmt-ed output. Dave Collins (@davecgh) had created go-spew, which did the deep printing part, but it wasn't quite gofmt-ed Go-syntax. With his permission, I forked go-spew to create go-goon, and proceeded to make the necessary output formatting changes. At that time, I was just learning about Go's reflection, so having a high quality working solution was a tremendous help.
I've made a few PRs to gddo, the source of godoc.org. Every time I thought I had a decent solution, Gary Burd (garyburd) would provide some really helpful feedback and suggestions. The end result would be much better code and seem obvious in retrospect. I've definitely learned a lot from that experience.
Gustavo Niemeyer (@gniemeyer) comes to mind as having some of the highest quality, nicely documented Go packages I've seen. He really sets a high bar in that regard. If you want to see how nice a Go package can be, definitely take a look at some of his work.
And of course the core members of the Go team that are largely responsible for most of the standard library. It's very often I end up peeking into the source of common funcs from std lib in order to confirm some detail or learn more about how they work. The Go standard library is an excellent learning material source in every sense.
What are you currently working on?
I've recently come to realize that the project I'm currently working is essentially my
GOPATH workspace. It includes my own open source repos, but also various open source libraries that I rely on.
My main personal project continues to be Conception, now written completely in Go. Being a very ambitious undertaking, it still requires a lot of work both on the frontend and backend. Luckily, the backend code is shared between many of my other repos. For example, I use my github_flavored_markdown package to render GFM inside Conception. My gostatus tool, which recently gained support for displaying git stash info, uses the same internal code to figure out the status of Go package repos, and Go-Package-Store reuses that yet again to present a list of Go packages in your
GOPATH that have updates, complete with the commit messages of what has changed.
markdownfmt: gofmt for Markdown
Lately, I've been working on improving the diff highlighting within github_flavored_markdown as well as inside Conception. Ideally, I want the same code to be doing the highlighting in both places, but the highlighting interfaces inside Conception need to be rewritten before that's possible. I've also just recently improved my
GoPackageWorkingDiff() func to include new/untracked files.
I'm also working on adding support for displaying notifications to trayhost, which is needed for the InstantShare client. InstantShare sits in your menu bar and allows you to instantly upload images and get a URL. The reason there's no delay, even for large images, is because both the upload and download are streamed. The backend server part was written by my friend Pavel Bennett (@pavelbennett/pavben) in Go.
Now that we're out of go1.3 feature freeze, I really want to fix issue 5551 in go/format of the Go standard library. It has existed since go1.1, and it has caused me a lot of grief and blocked many things I wanted to build that would require it. I still have to continue to shell out to the gofmt binary, which performs poorly for large inputs and isn't available in all contexts.
What do you use Sourcegraph for?
I use Sourcegraph on various occasions to get answers to ad-hoc programming questions. There was a time where I was looking for Go code that implements a certain public interface. Another time I wanted to find example usages of the
Just recently, I was looking at
Close bool in
net/http.Request. I really wanted to find examples of how it was being used in the real world, and I was easily able to do that with the help of Sourcegraph. That's just not something I would've been able to do in any other way.
But I feel that the things Sourcegraph offers now is just the tip of the iceberg, a preview of things to come. If you look at what it's doing, it's essentially going through all the open source code out there and performing code analysis on it. Then it's making this connected graph of all the identifiers and types and so on, currently presented as a nice web interface with links that let you navigate code easily. As its doing that, it's gaining the ability to answer more and more questions about code that you may run into during your day. The kind of questions and answers that may help you learn how to do something new, or figure out what code will be affected if you change some public API, and help you get your task done just a little faster. That's pretty exciting if you ask me!
What do you hope will improve about the field of programming in the next 5 years?
I like that you've grounded the question by specifying 5 years. But that also makes it harder to answer, because it has to be more realistic, and I can't just say "flying cars and code that writes itself" yet. 😃
But you've also mentioned "hope", so I will be a little over-optimistic.
I hope new formats that are released follow suit of Go and come with standard formatter tools (like gofmt) from day one. Having a tool that formats your and everyone else's code on save to look the same and pretty is incredibly helpful, and retrofitting such tools later on is much harder (if not impossible) than doing it right away.
I hope we will have more widespread code refactoring and high level manipulation tools at our disposal. I do love my text editor for writing code and it's great, but sometimes I want to be able to easily rename identifiers, not perform find and replace with a manually crafted query. Or move packages seamlessly without having to manually move folders and update import paths. Tools like @bradfitz's goimports that automatically add/remove my Go imports are so transformative, it's hard to imagine going back to having to do that manually. I'd love to see more of similar innovation and improvement in this field.
But most importantly, I really hope we have some kind of breakthrough that would allow public APIs to change more often and more easily, without breaking packages that depend on the old version of the API. It's really a shame to see API improvements being purposefully held back due to concerns about backwards compatibility. There are some attempts to help with this, for example applying semver to APIs. But that still requires people to manually update to new library APIs. gofix is an inspiration here, and perhaps it can be used as a starting point in turning this into reality. Can we do better than the status quo? I'm looking forward to finding out!
Thanks to Dmitri for his contributions to the dev tools and Go communities and for sharing his inspirations and projects with us!
This interview was conducted by Quinn Slack (@sqs).