7c0h

Articles tagged with "ramblings"

Write-only code

The compiler as we know it is generally attributed to Grace Hopper, who also popularized the notion of machine-independent programming languages and served as technical consultant in 1959 in the project that would become the COBOL programming language. The second part is not important for today's post, but not enough people know how awesome Grace Hopper was and that's unfair.

It's been at least 60 years since we moved from assembly-only code into what we now call "good software engineering practices". Sure, punching assembly code into perforated cards was a lot of fun, and you could always add comments with a pen, right there on the cardboard like well-educated cavemen and cavewomen (cavepeople?). Or, and hear me out, we could use a well-designed programming language instead with fancy features like comments, functions, modules, and even a type system if you're feeling fancy.

None of these things will make our code run faster. But I'm going to let you into a tiny secret: the time programmers spend actually coding pales in comparison to the time programmers spend thinking about what their code should do. And that time is dwarfed by the time programmers spend cursing other people who couldn't add a comment to save their life, using variables named var and cramming lines of code as tightly as possible because they think it's good for the environment.

The type of code that keeps other people from strangling you is what we call "good code". And we can't talk about "good code" without it's antithesis: "write-only" code. The term is used to describe languages whose syntax is, according to Wikipedia, "sufficiently dense and bizarre that any routine of significant size is too difficult to understand by other programmers and cannot be safely edited". Perl was heralded for a long time as the most popular "write-only" language, and it's hard to argue against it:

open my $fh, '<', $filename or die "error opening $filename: $!";
my $data = do { local $/; <$fh> };

This is not by far the worse when it comes to Perl, but it highlights the type of code you get when readability is put aside in favor of shorter, tighter code.

Some languages are more propense to this problem than others. The International Obfuscated C Code Contest is a prime example of the type of code that can be written when you really, really want to write something badly. And yet, I am willing to give C a pass (and even to Perl, sometimes) for a couple reasons:

  • C was always supposed to be a thin layer on top of assembly, and was designed to run in computers with limited capabilities. It is a language for people who really, really need to save a couple CPU cycles, readability be damned.
  • We do have good practices for writing C code. It is possible to write okay code in C, and it will run reasonably fast.
  • All modern C compilers have to remain backwards compatible. While some edge cases tend to go away with newer releases, C wouldn't be C without its wildest, foot-meet-gun features, and old code still needs to work.

Modern programming languages, on the other hand, don't get such an easy pass: if they are allowed to have as many abstraction layers and RAM as they want, have no backwards compatibility to worry about, and are free to follow 60+ years of research in good practices, then it's unforgivable to introduce the type of features that lead to write-only code.

Which takes us to our first stop: Rust. Take a look at the following code:

let f = File::open("hello.txt");
let mut f = match f {
    Ok(file) => file,
    Err(e) => return Err(e),
};

This code is relatively simple to understand: the variable f contains a file descriptor to the hello.txt file. The operation can either succeed or fail. If it succeeded, you can read the file's contents by extracting the file descriptor from Ok(file), and if it failed you can either do something with the error e or further propagate Err(e). If you have seen functional programming before, this concept may sound familiar to you. But more important: this code makes sense even if you have never programmed with Rust before.

But once we introduce the ? operator, all that clarity is thrown off the window:

let mut f = File::open("hello.txt")?;

All the explicit error handling that we saw before is now hidden from you. In order to save 3 lines of code, we have now put our error handling logic behind an easy-to-overlook, hard-to-google ? symbol. It's literally there to make the code easier to write, even if it makes it harder to read.

And let's not forget that the operator also facilitates the "hot potato" style of catching exceptions1, in which you simply... don't:

File::open("hello.txt")?.read_to_string(&mut s)?;

Python is perhaps the poster child of "readability over conciseness". The Zen of Python explicitly states, among others, that "readability counts" and that "sparser is better than dense". The Zen of Python is not only a great programming language design document, it is a great design document, period.

Which is why I'm still completely puzzled that both f-strings and the infamous walrus operator have made it into Python 3.6 and 3.8 respectively.

I can probably be convinced of adopting f-strings. At its core, they are designed to bring variables closer to where they are used, which makes sense:

"Hello, {}. You are {}.".format(name, age)
f"Hello, {name}. You are {age}."

This seems to me like a perfectly sane idea, although not one without drawbacks. For instance, the fact that the f is both important and easy to overlook. Or that there's no way to know what the = here does:

some_string = "Test"
print(f"{some_string=}")

(for the record: it will print some_string='Test'). I also hate that you can now mix variables, functions, and formatting in a way that's almost designed to introduce subtle bugs:

print(f"Diameter {2 * r:.2f}")

But this all pales in comparison to the walrus operator, an operator designed to save one line of code2:

# Before
myvar = some_value
if my_var > 3:
    print("my_var is larger than 3")

# After
if (myvar := some_value) > 3:
    print("my_var is larger than 3)

And what an expensive line of code it was! In order to save one or two variables, you need a new operator that behaves unexpectedly if you forget parenthesis, has enough edge cases that even the official documentation brings them up, and led to an infamous dispute that ended up with Python's creator taking a "permanent vacation" from his role. As a bonus, it also opens the door to questions like this one, which is answered with (paraphrasing) "those two cases behave differently, but in ways you wouldn't notice".

I think software development is hard enough as it is. I cannot convince the Rust community that explicit error handling is a good thing, but I hope I can at least persuade you to really, really use these type of constructions only when they are the only alternative that makes sense.

Source code is not for machines - they are machines, and therefore they couldn't care less whether we use tabs, spaces, one operator, or ten. So let your code breath. Make the purpose of your code obvious. Life is too short to figure out whatever it is that the K programming language is trying to do.

Footnotes

  • 1: Or rather "exceptions", as mentioned in the RFC
  • 2: If you're not familiar with the walrus operator, this link gives a comprehensive list of reasons both for and against.

A new and improved homeopathy

You might have heard of this new, alternative take on medicine called Homeopathy. If you haven't, the basic idea is that you take a (possibly active) substance, dilute it with alcohol or distilled water, and repeat the process until only the "vital energy" of the original substance remains. According to Hahnemann, the creator of Homeopathy (or, to be precise, according to the Wikipedia article), each dilution increases the potency of the preparation while ensuring that all traces of the original substance are effectively gone.

The efficacy of this practice has been called into question several times, which to me sounds less like a problem and more like an opportunity: how do we bring Homeopathy into the 21st century?

Enter the Nocebo effect. Unlike it's big brother the Placebo effect, the nocebo effect is at play when a treatment has a negative effect simply because the patient believes it to be so - the common example being patients that suffer from "side effects" when receiving an inert substance. While precise numbers are impossible to obtain, around 5% of all patients are considered susceptible to this nocebo effect.

If a nocebo "weakens" a patient's positive response to a medication, and Homeopathy is based on diluting substances, we can combine them both! In what I have decided to call "Martinopathy" in honor of its creator (me), I suggest the following clinical procedure: when a patient is prescribed a Martinopathic treatment for (say) common cold, they are first directed to a standard pharmacy, where they buy a common, over the counter, non-homeopathic common cold drug. They are then sent to their physician. The Doctor will take a look at the medicine, repeat to the patient "this medicine will not work" around 20 times, after which the patient is free to continue their treatment with their now-martinopathic medication. In this way the effect of the regular medicine has been "diluted" down to homeopathic standards, but this time in a scientifically sound way.

There is still some room for improvements. If costs are an issue, they could be kept low by martinopathing the medicine at the source - instead of yelling at a patient, a medical professional could yell at the boxes directly in the factory floor. It is not entirely clear whether the medical professional would have to be certified in this new treatment or not. But those are small details that we can sort after I get my Nobel prize.

Blog update!

It is tradition to start every new year with a blog post lamenting why I haven't posted more. Instead, I have decided to kickstart 2020 with a list of the changes I've made to the blog to ensure I write more, why I've made them, and what interesting tools I've found along the way.

A big problem in my blog has always been how difficult it is to actually get something published. As I've mentioned in the past, my blog is powered by a bunch of command-line tools and Bash. This works fine when I want to work from home, but makes it very difficult when I want to blog something spontaneously: writing a post involves SSHing into my server, and there's exactly one computer from which I can do that. Converting an entry to the final HTML is not hard, either, but is friction enough that I need to be really motivated to get into it.

Enter 2020. I am more and more concerned about the state of the modern web, where "the internet" has become a synonym for Facebook, Google, and not much more. At the same time, I realize that I'm part of the problem: I may not be putting content in Facebook, but I'm not really putting content anywhere. The little content I'm putting out is not particularly useful, either. Clearly, something had to change.

And thus, a plan for 2020 was born. In order to simplify blogging, I have now thrown away my custom blog engine and moved to Pelican. I've also embraced Markdown as document format, meaning I no longer have to worry about things looking ugly after I've written them down. All my previous content has been migrated from .html to .md using Pandoc.

On the content generation side, I've also decided to try something new. Rather than wait until inspiration strikes, I'll try to blog weekly about small problems and how I solved them. This will often involve talking about Bash and Python, so I'll have to pay special attention to other topics that could be interesting.

In the meantime, here are some changes you'll notice from the migration:

  • Some entries will look a bit different. My custom footnote CSS no longer works with Markdown, so I'll probably substitute them with regular, boring footnotes.
  • A couple entries with custom html will look weird for a while. It will take a bit to get them looking like before, and I'd rather avoid delaying the update until then.
  • The RSS feed will probably break a little bit. Seeing as the RSS will now be generated by Pelican, I imagine your RSS reader will panic a little bit.

Next in the pipeline: a showcase of my now-almost-defunct blog engine.

So, what did you say you do?

Tell me if the following sounds familiar:

Oh, hi! It's been such a long time! They told me that you are a researcher now, right? What are you working on?
Me? Oh, well, ...

  • ... I am developing a new carbulator theory that can hiperstat a maximum-entrophy logarithmic equation.
  • ... it's something complicated. Have you ever heard of carbulators? No? Don't worry, no one ever does.
  • ... you don't really want to hear that. It's super boring.

I am guilty of giving all of those answers at some point in my life. And while I am used to people not caring about my work, I'm not happy about it. Of course, I'm a nerd, so "doing boring things that no one cares about" is what I do. And I'm not saying everyone should be pasionate about Dungeons and Dragons^1. But I do think that, when I give a completely useless answer like the ones above, I'm contributing more to the problem than to the solution.

It is a fact that a lot of what we programmers and researchers do is considered boring by lots of people. But think about it, do you think it's boring? If the answer is "no", then I bet you could explain to me what's exciting about your job, why does it matter and/or what are you expecting to achieve. So all we need to do now is to better transmit this excitement to those around us. And yes, by "around us" I mean people who doesn't know what a carbulator is, have never heard the term in their life, and are probably none the worse for it.

I think a good start is my research section, in which I've listed some articles where I give a simple explanation of what I do. Not because I'm expecting my relatives to check my personal homepage, but because writing the articles has made me think really hard about what might be hard to grasp to non-technical readers, and next time I'll have a good script to begin with.

I can't tell you why I feel so strongly about this. Perhaps it's because the last time I was asked this question all I had were links to published papers, and that's unacceptable. Or because the time before that I straight up lied about it. Or maybe because I'm thousands of kilometers away from my family, and yet they don't have a clue about why I think it's worth it. And I have yet to find any downside to making knowledge more accessible.

So, what did you say that you do?

Footnotes

^1 I still can't find a Dungeon Master near me, though. And if you don't know what that is, no, it's not a sex thing. It's an old game...

I'm not that angry

One of the most enjoyable aspects of gaming for me is to try and pretend I'm the protagonist. That includes making choices the way I'd do them in real life. Of course, I understand that games are escapism, and I'm not blaming those that use games as an opportunity to murder pretty much anything that can be murdered. It's just not my style. I'm more the kind of gamer that's constantly being chased around by the guards I didn't kill because they didn't do anything.

Having said that, I'm having trouble with Angry Birds. I know, I shouldn't expect moral lessons from what is essentially a group of suicide birds bombing an enemy. But am I the only one who has trouble with a game that asks you to bomb a playground, including the kids playing there?

Level showing tiny pigs in a playground

Did you enjoy committing a crime against humanity? Do you need more genocide? Then good news! You can bomb the skate park, somebody's house, and even a cemetery. Not only you get to kill your enemies again, but this time you can get their friends and family too!

Level showing a cemetery with pigs around

Maybe it's because I'm having a bad day. Maybe it's because I'm putting too much thought into it. Maybe it's because I'm sick and tired of the phrase "collateral damage", or maybe I'm just missing some black humor. But in any case, I found out I can't bring myself to finish the game.

I hope that says something nice about me.

Page 1 / 2 »