Monday, September 09, 2019

Technologies that inspired me

Cat's bored by SethBahl from flickr (CC-NC)

Nearly every day I run into another language, framework, or program. Most of them are just plain awful, and the ones which aren't are usually nothing special.

Every now and then I run into a true gem. Here's a list of such great technologies, in approximately the order I found them.

Perl

Perl was absolutely amazing compared with every language which came before it. Other languages were motivated by what worked for computers, or by some silly mathematical theory, or sometimes like with Java by outright hostility to programmers.

Perl tried to be as much like a natural language as possible. If what you wrote made some kind of sense, it was going to try to run it. And most of the time it worked.

Unfortunately Perl supported too much weird stuff, and it caused the language to collapse under its own weight, but the most influential languages of the 1990s like Ruby, Javascript, and PHP were very heavily inspired by Perl. And as next generation of languages was very heavily inspired by those, the legacy of Perl lives on.

Perl tried to double down on its philosophy with Perl 6, but without first dropping failed ideas it was never really going to work.

Regular Expressions

Text is nearly as common data type as numbers, but most pre-Perl languages didn't treat text data as first class. In many old languages text is literally an array of small numbers, or such other nonsense. Even today Erlang / Elixir do literally that - "Hello" is the same as [72, 101, 108, 108, 111].

Regular expressions are to text what arithmetic is to numbers, and let you extract or modify text with tiny amount of highly readable and highly performant code. They have weird reputation of unreadability, but one line of dense regular expression is infinitely easier to understand than 100 lines of text processing code it replaces.

It's key skill for every programmer, no matter what's the domain. If you don't know regular expressions, drop everything and do some regexp crosswords.

There used to be different variants of regular expressions, but these days basically every language uses some variant of "Perl-Compatible Regular Expressions". Except Unix grep command, which still uses stupid 1970s regexps for some crazy reason.

Wikis

Wiki was a revolutionary idea - just put a bunch of linked pages online, and let anyone who wants edit them. It sounds like a recipe for disaster, but it worked remarkably well. Wikipedia was the greatest success story of wikis, but there are all kinds of wikis for all kinds of content. And as a general rule, they're a lot more reliable than non-editable sites.

Ruby

Ruby took everything that made Perl great, everything that made Lisp great, everything that made Smalltalk great, then it threw away their bad parts. And then it added more magic on top.

It is the high point of programming langugae design, unmatched up to this day. Implementation issues aside, I'd rather use Ruby as it existed 20 years ago than any language that came out since. It's just baffling how far ahead of time it was.

Of course it could be even better, but that's true of anything.

I hope someday a language comes that's better than Ruby, but so far it doesn't look like anyone's even really trying. The best anyone's trying to do is to make their languages as close to Ruby as possible given various constraints.

Ruby on Rails

Ruby on Rails is another miracle technology. When it came out, it was completely unmatched as the best way to write web backends. Today, after the web changed beyond recognition, it's still completely unmatched as the best way to write web backends. It's rare for any technology to have such staying power.

To always stay on top, Rails evolved very aggressively, and Rails upgrades on large codebases are notoriously difficult, but then again, the choice is between upgrading Rails 4 to Rails 5, or writing your code in some shitty framework that's going to die, and fully rewriting it into another shitty framework that also won't last.

It's quite baffling that so far no real competitor to Rails emerged. The best everyone else can do is to copy as much as they can from Rails, and even that is usually really poor.

The main reason is that Ruby is completely unmatched at making DSLs than any other language, and Rails is very DSL-heavy. But other aspects of Rails success like everything working seamlessly out of the box (while being individually replaceable) without needing to duct tape a bunch of disparate components should be replicable, and yet nobody even tries.

Why so many frameworks come out without such basic things like comprehensive testing system, or database migration system, or sensible security defaults? I suspect their authors just don't get Rails, and people who get Rails use Rails.

TextMate

Once upon a time, there were thousands of editors and they were all 💩. It was a running joke that every programmer writes their own editor, and their own IRC client (and later their own Javascript framework).

And just as with infinite monkeys randomly typing on infinite number of keyboards, one of such attempt miraculously produced TextMate - the first editor which was not 💩.

Multiple cursors, command palette, file palette, extension system, nested file types, integration with modern UIs, sensible keybindings making use of what's on modern keyboards - TextMate was far ahead of everything else.

TextMate itself didn't last, but Sublime Text, Atom, VS Code, and some others are essentially TextMate clones, and they completely dominate the editor world.

The only non-TextMate editors still in use are people using IDEs like IntelliJ or Android Studio due to being forced to use programmer-hostile languages like Java. And people who use Vim because they still haven't figured out how to quit it.

jQuery

Javascript used to be awful beyond belief. Well, it's still not great, but back then doing even the most trivial dynamic interactions, like changing some class based on an user action was a page of code, and then another page of different code if you wanted to support more than one browser.

Then jQuery came, and with a few $("selector").action() you could write complex UI interactions with very little code. It was even bigger difference when it came to jQuery AJAX vs browser APIs for AJAX. The gap was as enormous as between regular expressions and manipulating text by shuffling arrays of characters around.

Gradually browser APIs became more compatible, more expressive, and less buggy, they added a lot of features to close the gap with jQuery, so now it's sort of viable to write short programs directly with browser APIs. And while jQuery is amazing at progressively enhancing website functionality, it's a stretch if you want to make Single Page Applications.

So is it the end of jQuery era? Not even close! jQuery is still vastly more popular than all frontend frameworks put together - 80% of top million websites use jQuery, while all the hipster frameworks put together are still just a rounding error. Currently most popular React at 1.6% is behind 20 different jQuery plugins.

And beyond jQuery itself, D3 is basically jQuery for data visualization. Most acceptance testing frameworks from Capybara to Cypress use jQuery-style for writing tests. Single Page Applications are useful, but most of the Web is better off not being an SPA, and good jQuery skills will never go to waste.

It might be unpopular opinion now, but I feel the best way people should learn frontend is still be HTML, CSS, jQuery, then ES6+ Javascript, and only then some SPA framework like React.

Amazon Web Services

I remember bad the old days when setting up any server required making a request to a grumpy sysadmin (or even worse - a grumpy DBA) and waiting potentially weeks for them to find some time for it. Even more fun if that required more physical hardware, and budget requests for those. Meanwhile, there was nothing you could do.

Then came Amazon and decided that making billions selling everything wasn't enough so it opened a small side business of getting rid of grumpy sysadmins. Want to start a new server? A few clicks and it's done by the time your coffee finished brewing. And they kept adding new services beyond the initial EC2 and S3, to simplify your life more and more.

I feels silly to even mention how great it is, as AWS and other Clouds won so utterly that most people barely remember the pre-Cloud days, and those who do would rather forget them.

pry

I didn't love debuggers, and I usually employed print-based debugging as my first choice, strace and friends as my second choice, and only used interactive debuggers if all else failed.

pry was something else. A hybrid of a debugger and REPL, with full power of Ruby metaprogramming and introspection, it was on a completely different level than anything I've used before.

Adding binding.pry became my first not the last resort. And then there's pry-rescue and other plugins to make things even more awesome.

I'm still annoyed that pry isn't just part of Ruby yet, and that bundler blocks pry unless you explicitly add it to every single Gemfile just in case.
Sure there's finally binding.irb, but irb is not even close to pry. Seriously, get your act together guys and get pry into Ruby standard library.

MongoDB document model

Relational databases are just a bunch of damn spreadsheets, and forcing your program's object oriented (or otherwise richly structured) data into spreadsheets for storage is invariably painful. Object-Relational Mapping tries to make it bearable, with limited degree of success.

There were many attempts to create alternative database models, but they were either specific to one programming language, or used something like XML which was just as awkward as spreadsheets.

Then came MongoDB, made everything JSON, and it was glorious. Oh and depending on your application it could easily be orders of magnitude faster than relational databases.

Unfortunately while MongoDB JSON-based document model was amazing, and its performance was generally outstanding, everything else about MongoDB was less so. Doing even relatively simple queries in MongoDB is stupidly painful compared with SQL, so you end up doing it all in application. Its performance-first defaults got a lot of people into trouble as well.

I'm surprised that even a decade later nobody managed to build anything that united JSON-based (as opposed to spreadsheet-based) document model with some rich query language that can at least match SQL.

Spreadsheet-based databases nowadays support JSON data a little bit, NoSQL databases nowadays have a bit richer query languages, but the gap between those two is still enormous.

Capybara

TDD lived in this weird state, where backend code was decently tested, but frontend testing was minimal and mostly manual.

Even today most tests for JS programs are fairly low value efforts, like "component renders without crashing" tests and snapshot tests.

Capybara was the first practical way to do end to end tests of web apps with dynamic frontend and dynamic backend as a single system.

Nothing better than Capybara was created so far. There's a bunch of fairly poor Capybara clones in other languages, which might be just about good enough. Cypress might be developing into the first real alternative, but it's very frontend-based and integration with dynamic backends is its secondary consideration.

Continuous Integration servers

I wasted too much time running tests manually, or not bothering to run them because the change I was doing was trivial, and the tests took too long.

There is an answer to that - CI servers. Most companies have them. But people coding for themselves, or coding Open Source software are still usually not using them.

Semaphore CI and many other sites let you easily setup CI for free for your Open Source project, and you should do that.

Chrome Developer Tools

The story started in the olden days with Firebug, which provided just console.log and a few other very simple functions. Or possibly even with the View Source button (which some people wanted to delete from browsers to "protect the source code", #truestory).

Nowadays every browser comes with amazing debugging and development tools, and they keep getting better every year.

It's one of few places where I feel Javascript has a big lead over other languages. pry might be as good as possible on terminal, but it's still limited to a terminal. Chrome Developer Tools have full power of the browser UI, and they fully use it.

Dropbox

I have multiple computers. Also multiple phones and tablets. Sharing content between them used to be such a mess - connecting and disconnecting external disks, or manually copying files by cables or rsync. Dropbox made it seem that the same file is magically present in every location. It just works, with very few issues.

Unfortunately Dropbox for phones is quite bad, so if anyone solves this better, I'm interested.

Weirdly many Dropbox alternatives like Google Drive are simply horrendous.

Slack

Just like everyone was writing their editor, everyone was writig their IRC client. Or some other chat system which was basically IRC clone.

They were all solving the wrong problem. The issue wasn't that IRC needed better UI, the issue was that IRC was based on fundamentally wrong assumptions (broadcast to whoever happens to be connected at time) that made it completely unsalvageable.

Slack fixed those assumptions, and it completely revolutionized workplace communication, not just in tech.

All post-Slack chat systems like Discord use basically Slack model.

Electron

Electron is the first time in history of computing where we have cross-platform desktop apps with decent UI. There's performance cost, as Electron apps bundle whole browser, and are infamous for their memory use, but there's no alternative, so let's just throw more hardware at the problem, and restart every now and then if it gets too bad.

There were a few earlier attempts like with Java, but the UX was just attrocious. I cringe whenever I have to use some Java-based GUI software.

Z3

Normal programming answers questions like x = 2+2 perfectly fine, but it is shockingly bad at dealing with questions like 2+x = 4. Z3 is an amazing system for answering just such questions.

Solving sudoku, hacking CTFs, proving hardware design? Z3 has you covered.

I liked it so much that I wrote a Ruby gem for it. It's much nicer than official APIs.

Docker

I initially dismissed Docker as just another VM. It turns out that such lightweight micro-VMs have a lot more uses, and just being able to install and run a lot of images neatly solves a lot of issues like CI, software with weird dependency, security isolation and so on.

Imba

Javascript used to have a million frameworks. They were generally called "MVC frameworks" back then, a name you don't hear much anymore, as it turns out MVC is a poor fit to what they were trying to do.

At certain point very-much-non-MVC React pretty much won, by being decent at solving smaller problem (views), not even trying to deal with the hard problem (model and network layers / state management), and so having a lot easier learning curve and fewer gotchas. Acceptable performance and being pushed hard by Facebook also helped.

I even liked React before I found Imba. Imba however, is on a completely different level. It's the least known technology on this list, so I'll need to write a separate post about it, but you'll get orders of magnitude higher performance at fraction of code size, all while being a lot simpler than React.

It's a tiny project with very few development resources, so it feels like it really needs someone to push it to some sort of Imba 2 fully embracing post-ES6 world. But even in its current state, it's years ahead of any alternative.