Reflecting on My Experience With Go, One Year After

In my little more than a year day-to-day developer experience with Go, I have so far learned three things:

  1. I can change my entire view of how programming works, even after 12+ years of doing it in one form or another.
  2. People are blaming Java for all the wrong reasons
  3. People are praising Go for all the wrong reasons

Let me explain. This post is not about saying that “language A is better than language B”, or vice versa. It is about asking ourselves the question why things work the way they do, and whether doing them differently is a bad, or potentially, good thing.

Before joining the Go camp, I had worked quite a few years as a Java developer, with all the stereotypes that this role could evoke in one’s head. I co-developed data-processing systems for various industries. Yet, much of the code I wrote was just boilerplate: passing data from one format to the other, or devising complex abstractions behind what should have really just been calling a function and obtaining its result. Yes, the code was difficult to comprehend, but I was proud of it for this exact reason. The more hoops I created, the more secure I felt that:

  1. I was doing what I thought was right
  2. If people didn’t understand the code, they’d have to come to me for an advice, further boosting my ego.

The language is not to blame for this

The fact that much of the existing Java code is full of bureaucracy has nothing to do with the language itself, or with its platform. Our developer community should bear the sole responsibility. I can assure anyone that perfectly functioning Java applications can be written without 90% of the ceremony. They will be smaller and run faster. Most probably, easier to comprehend, too. And yet, they won’t get you hired in any well-respected company. They just won’t pass the developer prejudice test. I know. I’ve seen many elegant solutions and rejected them for not being idiomatic enough.

Go isn’t a silver bullet either

For much of the same reasoning, jumping ship towards Go, just because “it is not Java”, won’t bring anyone far. Even before I started writing Go, I had heard and read many stories, about how simple and fast it made everything, how little ceremony it had, compared to Java, how it would eventually kill all other languages, etc. All blah, blah. Despite all of the above being true, you have to discover the truth in each for yourselves. If you approach the language out of desperation with your current way of working, you’re going to be set for a rough path.

See, if you all you wanted was to get a faster running (name language of choice), you could certainly do it. Yet, holding on to the mental baggage of your previous experience will be hard and messy. My first Go project started out as a rewrite of a Spring Boot app I’d started earlier, so I thought I’d just organize it the same way. To keep the story short, let’s just say it was a spectacular disaster. Only after I started from scratch, did it really start taking off.

Go is a language without (less) idioms

Let’s do a naive math experiment. Imagine that you could create valid programming expressions combining any 3 keywords, from a programming language’s vocabulary. Thus, if a language only has 10 keywords, the maximum number of possible expressions is 10 * 9 * 8 = 720. In contrast, a language, with, say, 20 keywords would end up having 20 * 19 * 18 = 6840 expressions. Twice as many keywords would result in almost 10 times as many expressions!

Languages tend to encourage the creation and use of idioms. With that many possible expressions, it’s a normal behaviour for an individual, or a group of people to start associating and using expressions for certain things. The problems usually occur when another group comes with its own way of expressing the same thing. Both are perfectly valid, but each group would have issues understanding the other.

This is not to say that Go having a very strict and concise nature, is totally devoid of idioms. That would be impossible. It is in our nature to try to associate and abstract certain concepts. Yet, when a language has a deliberately smaller vocabulary, the chances for different groups accidentally finding multiple ways of doing the same thing are smaller. This helps the communication between people a great deal, but comes with a very obvious downside. Code (or any written expression, for that matter) without idioms is very, very verbose.

So, whoever told you that Go is not a verbose language, probably either lied to you on purpose, or had’n really seen any other programming languages up until that point. But hey, we agreed that verbosity in the name of communication and common understanding is a actually a good thing, right?s

Go is a test for senior engineers

A lot has been said about the initial concept about Go, and how the idea was to design a language for juniors fresh out of college, and with little programming experience. I think that understanding the beauty of going back to the roots of programming, can be a cathartic experience for many seasoned programmers.

See, junior programmers start with little baggage and preconceptions, so in their view, anything that can be done with code is fair and justified. Including, burning a CPU, or erasing a disk due to an arithmetic error.

Somewhere along the middle of the career path, a bunch of principles start to pile up. All of them out of the desire to step on what’s already been learned, and to make sure that things are smoothly and safely without immediate supervision. Learning and applying the principles is great, because it ensures a gradual path forward. But for many, it becomes a dogma which they blindly stick to, without asking whether a simpler alternative could be better.

The problem with principles is that they only work well around 80% of the time. It is the remaining 20% that can be disastrous for a project, or for one’s career. It is the understanding where to apply a principle, and where to deliberately throw it away in the name of pragmatism, which turns a software engineer into a senior software engineer.

To really appreciate Go, one needs to learn how to discern what makes it and its community stand out from the rest. One needs to go through a phase of utter disgust with the language, for it “lacking” certain feature. Moving on despite the urge to go back to a familiar ground, would result in one of two things:

  1. Make one realise that indeed, the Go language is not what they need or want
  2. Learn to appreciate going back to the roots, as well as when to favour pragmatism over principles

In any case, it would be an interesting experience.

A Crystal in Go’s World

Imagine a programming language with the ergonomic syntax of Ruby, the speed of execution of C, the concurrency model of Go, and last but not least, a compiler that performs null checks at compile time. Sounds like a dream? Well, this language exists, but chances are, you haven’t heard of it so far.

Meet Crystal!

Crystal is all of the above, plus it has types, outstanding documentation, and a strong community, delivering a steady stream of new libraries (a.k.a “shards”). Don’t get fooled by the current version number (0.32.1). Crystal has been around for quite a few years (since 2012) and has a mature set of language features and an ecosystem of good libraries.

Where does the speed come from?

Crystal produces fast and lightweight native applications using the LLVM infrastructure. When I say fast, I mean, really fast. Take the fastest Go code you can find and chances are, the same code in Crystal will perform at least on par with it, and often quite a bit faster. Measuring Crystal’s performance against that of Ruby makes no sense.

There are no runtime frameworks or virtual machines necessary. One can just grab the compiled binary and deploy it. When compared with deploying and running a Ruby application, this feels like a whole different league.

Note that there are some caveats, which I am going to discuss in a future blog post. For now, let’s just say that building and distribution are equally as easy, as those in Rust. As of yet, nothing can beat the Go compiler speed-wise, but my experience with the Crystal tooling has been more than pleasant so far.

CSP-style concurrency

One of the things that make Go so interesting is its concurrency model. The idea about goroutines that communicate via channels is based on an approach dating back to the late 1970s, called Communicating Sequential Processes (CSP). Crystal uses an analogous approach. Programs run in what is known as “fibers”. The main fiber can spawn any number of concurrent fibers that send and receive data via blocking channels.

channel = Channel(Nil).new

spawn do   
    puts "Before send"   
    puts "After send" 

puts "Before receive" 
puts "After receive"

Why re-invent Ruby in 2020?

The creators of Crystal obviously didn’t intend on changing the world of programming by creating a new language. They just loved Ruby and felt it sad to leave it for a more performant and type-safe alternative. Due to a series of trade-offs at the implementation level, Ruby is still slower and more memory-hungry than its competitors. Despite perfectly serving the needs of a large segment of Web users through Rails, its performance puts it at the back of the pack, when it comes to other use cases.

The point is fair and valid. As a language, Ruby has a concise and elegant syntax for writing. Once beyond the basic idioms, writing Ruby evokes pure joy. Crystal brings that joy to an even higher level through type-safety, native speed, and extremely simple concurrency model.

Don’t get me wrong, I like Go too, precisely because of its verbosity and lack of idioms. When working with others on a big project, I’d prefer more ceremony and hoops, in the name of transparency and equal code comprehension. Different languages exist to serve different purposes and be used by different groups of people. The trick is knowing when to use and when the other.

So, is Crystal worth having a look?

Absolutely! If only to know that it exists and keep an eye on it, I’d go check it out and write a few applications with it. Whether Crystal will take off in the future is a bit more difficult to say, however. As mentioned, the 99% resemblance to Ruby is nice, and so is the blazing-fast performance. Yet, I am missing the Crystal community’s drive towards more prominence. There has been a long-awaited move towards a 1.0 release, which is a crucial milestone and would surely bring in many newcomers. To my understanding, the language and its tooling are stable enough for a 1.0 release.

I understand that Crystal does not have the backing of either Google or Mozilla. Neither does it have multi-billion-dollar use-cases to put on its home page. I understand that fighting for the same space with Go, C/C++, and Rust is an unfair battle. Yet, I also believe that we’re long past the days when choosing one technology over another was a zero-sum game. All it needs is a little push.

I am hoping for the best!

[Quote] Manual Work is a Bug

Here are a few lines from Manual Work is a Bug that I firmly stand by:

The successful engineer has a quick way to create documents for new procedures and to find existing procedures. People with this mindset avoid the cognitive load of deciding whether or not a task is worth documenting, because they document everything. On finding a potential improvement, they are not slowed by the speed bump of switching from a document viewer to a document editor because they work from the editor at the start. Heck, they have a dedicated second monitor just for their editing app!


The successful engineer realizes that the earlier he starts collaborating, the sooner others can contribute. Together they can create a culture of documentation that spreads throughout the team. Thus, every project is collaborative and has a “stone soup” feeling, as all are invited to bring their skills and insights. The more people who embody this culture, the more success it has.


By creating a culture of continuous improvement, constantly taking baby steps along the four phases, the work becomes less stressful and easier to manage. While the other reasons listed here are quite logical, what motivates me to maintain this discipline is more emotional: I want to reduce stress and have more time for creativity and joy.

Thomas A. Limoncelli

Using gohack for Temporary Modifications to Go Module Dependencies

I started programming Go right at the time when the topic of modularization heated up. Of course, we all know how it all played out with Go modules. They are here and they are (IMO) great. I have spent a significant amount programming Python before virtual environments were really a thing, and believe me, things got really messed up at times.

One big disadvantage of modules is that one can’t really edit them. For a good reason, of course. You want them to be clean and reproducible, but occasionally, one needs to just insert a log.Printf or a tiny inspection function somewhere. One option is to call mod vendor, but this would copy all the dependencies to the vendor folder. Clearly, a lot more overhead than what one would need.

This is where gohack comes in really handy. It uses a clever feature of the Go modules, called replace. It allows the user to manually override the path to a given dependency. Instead of doing all of this manually, however, gohack will do it all for you.

After installing go-installing gohack, go to your module-bound Go project and use it instead of go get for a given dependency:

gohack get

gohack will fetch the code and store it in a special place inside your $HOME directory. It will also do the go.mod replacements for you:

replace => /home/me/gohack/

All the edits you now do to the dependency that was added to your $HOME folder, will now affect the project that uses it.

Once you have done checking, and want to revert to using the original dependency, you can simply use the undo functionality:

gohack undo

or to revert all changes to all “hacked” dependencies:

gohack undo

Make temporary edits to your Go module dependencies – rogpeppe/gohack

Trip to Vienna

My wife and I spent the last two days in beautiful Vienna. This trip changed quite a few of the prejudices and assumptions I had previously had about the Austrian capital.

There is no doubt that Vienna is a world city, both historically, geographically, and culturally. For years in a row, the city has been named the world’s best place to live in, and as much as Munich is trying to steal the title, it’s not come close yet.

Yet, I’ve always put such statistics aside, after having read the stories of tens of expats who had chosen Austria as a place to start a new life. Especially in the 90s and 00s, people claimed, living as an expat in Austria was hard. Being judged by everyone, and having to fight prejudice everywhere, made the lives of many first and second generation expats quite a traumatic experience.

I know, being a tourist is something completely different. People would gladly take your money, no matter what country you come from. Yet, I’m just such a type of person. I like to imagine living in the places I visit.

Breaking the prejudice

For the two days in Vienna, I changed a few of my assumptions about the Austrian capital and the Austrian culture.

First, the obvious things. The city is extremely clean, and the central parts feel really, really safe. Coming from Munich, one develops a certain sense of noticing these things. At the same time, however, Vienna seems to open up to many more and diverse activities at all times. Munich is pretty boring and conservative in that regard. Despite its (on paper) population of 1.5 million people, Munich often feels dead on evenings, Sundays and holidays. Vienna looked like a normal big city, hustling and bustling at all times. If are coming from other parts of the world where big city culture is prevalent, don’t expect miracles. This is Europe after all.

What was even more surprising was people’s reception, which appeared to be totally friendly and positive. Everywhere we went, my wife and I were met warmly and openly. Now, I have to say again that being a tourist is quite different from actually living in a place. Plus, we have lived long enough in a German-speaking world to pass for locals. On that note, the other interesting fact was that everybody spoke Hochdeutsch (standard German taught in school) with a tiny hint of southern Bavarian-like accent. This was perfect, because I felt like home, as if I were in Munich. Sadly, this is not often the case if you go up the mountains. There you can frequently lost the track when you start speaking to locals. However, the same can be said about villages in Bavaria, so…

The verdict

For the two days we spent in Vienna, I liked it well enough to imagine living there at some point. The city is big enough, and opportunities for work, development, and recreation appear everywhere. Not to mention the housing situation, which from what I have hear is way more affordable than that in Munich. I am not yet sure, if I would like my future kids to grow up in Austria. I haven’t had enough exposure yet to decide on that, but I hope that a lot of the old walls have fallen and stereotypes have been erased.

P.S. Write me a comment describing your tourist or expat experience in Vienna, and Austria in general. Especially, if you are fellow software engineers working there. I would love to hear what you have struggled with.

Happy 20th Anniversary, Aqua! 🎉

Twenty years ago, Steve jobs showed the Aqua interface to the world for the first time:

Much of what we know and love (or hate) about the macOS today, is reminiscent of the original Aqua UI. The Dock, the Finder, the window management. A lot has changed visually, but the core principles are still there. It’s a sign of Apple’s persistence, but also a testament of how much of a good job the team did at the time. If something is working well, you’d rarely change it, right?

Here’s to another exiting decade! 🎉

Twenty Years Ago, Steve Jobs Showed Off the Aqua Interface for the First Time – 512 Pixels
At Macworld 2000, Steve Jobs unveiled the user interface for Mac OS X. It was called Aqua.

2019 Recap

It’s that time of the year again! Every year, it feels like a lot of time passes by without much happening. Then, you sit down to reflect on it, only to realize that you can write a book of everything you have lived through. This year was particularly groundbreaking, so grab a cup of coffee and get ready for a lengthy recollection. Happy reading!

Tying the knot

2019 was the year I got married to my fiance and long-time partner-in-crime, Vesela. This is by all means, the absolute highlight of this year. It is also one of the few moments in life which give you a reassurance that you are not alone on your mission. I am looking forward to many more happy moments together; as a small, but gradually increasing family. 💍🎉


2019 was also a year of career decisions and reflecting upon my professional future. I should start by saying that I am happy at my job. In the past year, I have learned a great deal about managing projects and people’s expectations. It was tough learning it firsthand, but aren’t those the most effective lessons anyway?

The year gave me an opportunity to question everything I had known to this point. I reached the ultimate conclusion that software engineering principles give way to well-argued, pragmatic decisions. I used to laugh at people who would blindly put principles before anything, until I ended up being the one refusing to let go of old baggage. I had the chance to correct my mistakes, and make a 180-turn on how I approach building software (or just about anything else). Welcome to the senior club.

Seeking independence

Sometimes, I envy those who are happy to work for someone else, OK with being a tiny part of the Big Establishment. For good or for bad, I am nothing like that. I am a person, very much driven by his own internal mission to change things (for the better, I hope), and this is as much of a curse, as it is a blessing.

Being able to work on things you personally care about, at your own pace, and under your autonomy is not easy. It sounds fancy on paper, but grown-up life does not give a damn about one’s cravings. There are “more important” things, like being able to sustain a style of living that corresponds to the environment you live in. In a place like Munich, there is a low-margin of error. You either keep crawling the career ladder => create a more and more lavish lifestyle, or you start slowly slipping away.

The biggest trap is when you think that you can keep satisfying grown-up life’s needs, but also find time to make your inner self happy. You are essentially trading life, your health, and time with your loved ones for money.

There were many sleepless nights 2019. More than in other years. At times, it got pretty dark, as I sought the direction forward. This was a clear call that I needed to cut the cord and re-align my priorities in life.

Starting from October this year, I traded a significant portion of my salary and future pension savings, for 20% of the week dedicated to things I really care about. Yes, I earn a bit less, but I have more life. Time, I can devote to people, causes, and ideas I had so far neglected. It was a tough decision, but I am grateful to my family, friends, and my employer for the support. For the short period of time I have so far been on this new contract, it started bearing fruits. I am finally working on making the world’s podcasts easier to discover. I read more, write more, and engage in ventures, I’d previously only set aside for the future.

The first step was made. Step by step, I will turn this into a profitable venture, without hampering my personal life, or the lives of those I care about.

Between Germany and Bulgaria

In 2020, my wife and I will have spent 10 years of our lives in Germany. This is a serious threshold which makes one reflect upon the past decade, and look forward to the future. A future, in which we bridge the gap between the country we live in (Germany), and the country we come from (Bulgaria).

Life in Germany wasn’t exactly like walking on a red carpet. There were a lot of hardships: cultural, linguistic, and financial challenges. Looking back however, I still think that sticking around was a great decision. I got my Master’s degree here, built up a career, and a life that allows me to fight for the things I care for.

When I came to Germany, it felt like a way out. I had never been a particular fan of my country. What drove me away was the apathy passed from one generation to another. The stifling of young people’s ambitions. Carrying your parents generation’s fears forward.

Shrugging and saying that nothing can be changed won’t do anything. Change requires action. Looking at my memories of Bulgaria when I left and Bulgaria now, I see a critical mass of young spirit bubbling up. This gives me hope, and I wish it does the same to many more Bulgarians abroad. It’s about time to roll up our sleeves and unite our brains.

Germany is where I built my life, but Bulgaria is where I was born and raised. Part of what makes me who I am is the mix of cultures I’ve lived through. It took me a decade to come to peace with my country of origin. I (and I can certainly say the same for my wife, too) will dedicate the next one bridging the gap and making our homeland a better place for our kids to be proud of.

See you in 2020!

What’s new in Mixtape: A New UI

Mixtape started out as a simple proof-of-concept. During the first few months, I focused on getting the backend and search index parts of the project done. This meant intentionally putting the user experience aside. For a long time, its UI has consisted of a page of results rendered on the server, with some limited interactivity provided by quickly scrapped up JavaScript. Long story short, it was functional, but not very usable.

Of course, I never really neglected the UI part. My decision was intentional, justified by the fact that I am the sole initiator and (still) only developer behind Mixtape. As soon as I reached a certain working stage with the backend, it was frontend’s turn to be hauled over.

The new Mixtape UI

Mixtape’s new UI in action

The new Mixtape UI is an early-stage in-progress work and still looks visually similar to the old one, but is actually a single-page JavaScript app (SPA).

I know what you might be thinking – search engines and SPAs don’t work well together, because of SEO, right? Well, this certainly used to be the case, but not anymore; at least, if Google is concerned. The Google crawler is “smart” enough to wait for the loading of (some) client JavaScript. This is more than enough to let the content of the search results appear on the page that is to be indexed. With some clever client-side routing, you can make your SPA look and feel like a classic Web site. It will have the share-able links and everything, but the added interactivity and groove of a modern Web app.

The frontend tech stack

I am not the biggest fan of how frontend development has evolved. I still remember the days when a bit of JQuery magic could do miracles to any Web page. Yes, it felt like an ugly hack, but one got up and running in no time. Well, things moved on, and although I am happy that modern frameworks brought in a bit of structure, a big portion of frontend development nowadays feel like putting a rocket engine on a bicycle. It works, and when set up correctly, it will no doubt be fast, but does anyone in all of their sanity need that?

What put me off, was when I started spending more of my front end development time, fiddling with the compiler and build tooling, than getting features out. As a backend programmer, I am no stranger to complex build setups, but getting to that level of complexity on the front end, felt kind of odd to me.

That is, until I discovered Svelte. It makes everything seem extremely simple, like in the good old jQuery days. There is no complex syntax to learn, or concepts to pay attention to. Write simple HTML, JavaScript, and CSS, wrap those up in a Svelte component and reuse the component across your app. What frontend development really should have evolved into.

Let’s be frank, Svelte does make a heavy use of a compiler, but this is where the level of complexity stops at. The compiler is fast and does its job in the background, without turning my laptop into a drone. Kind of like the Go compiler, the Svelte tooling does its job well, and you would rarely notice it. Perhaps, I am talking about tiny fractions-of-the-second improvements, but when you multiply those by the number of different files, and the hundreds of compilation runs a day, it does contribute to a significant portion of time saved.

The other big discovery on the front end stack was Tailwind CSS. At a first glance, Tailwind looks like a strange mix between Bootstrap, and using inline CSS directly. Yet, the biggest win over Bootstrap is the agnostic nature of Tailwind’s CSS class names. One won’t find names like card, panel, textbox, etc, because such don’t exist, and you might not need them. The argument is that since UI differs from project to a project, using a cookie-cutter component such as a card or a panel will always require extensive tweaking. One might be better off laying those out from scratch every time. Tailwind is a thin abstraction on top of using inline CSS directly, and the syntax is easy to remember, so building complex UI components is actually not hard at all.

I would rather stop geeking out here, because the point of this post was not to discuss the stack, as much as announce the progress going on with the project. As always, I would be more than happy to hear your feedback.

Merry Christmas! 🎄

Tip: Enable a Go Language Server in VS Code

For those writing Go using VS Code, you might be missing on way faster code completion and a ton of helpers, by not using a language server (e.g. gopls). As I figured out, the language server option is still considered “experimental” and won’t be turned on by default. Just open the “Settings” menu, scroll down to the Go plugin’s settings page, and check, if “Use Language Server” is turned off. If yes, you might want to turn it on and see the difference.

How to Request an App Refund on the Apple App Store

Buying the wrong product happens all the time, and apps make no exception to that. Although it does not apply to every country, if you live within the EU, you have the right to ask for a full refund of your purchases, no strings attached. You can do that with apps you have bought from the App Store too, without having to provide an explanation. It is actually very easy, though providers ty to put a few stones on the way. In the case of the App Store, I don’t think you can really do it from the app itself. You have to go to a special site instead:

After signing in, you will see all the apps you have downloaded for free or purchased. Find the one you want to refund (assuming, you are within 14 days of the purchase). Click on “Report a Problem” (I know, you are actually exercising your rights, but just keep playing the game). Be careful to select the right option from the menu:

The right option is down below

See how far below the right option is? Anyway, once you choose it, there are no further obstructions. Just hit “Cancel Purchase” and you are good to go!