Day 23 — Why is it called a.out?

tl;dr

a.out is short for "assembler output", the filename of the output of Ken Thompson's PDP-7 assembler. It remains the default output filename for executables created by compilers like gcc, even though the created files actually are not in the original a.out format! [source]


Today I paired with Will to work on a Javascript library he's building to draw underlines (that look hand-drawn) on a web page. I'm a relative front end beginner, so I had a lot of questions like "How does one even do this?"! Would it require creating a new font in which characters have hand-drawn underlines? (I guess I went in the "new font" direction because I recently learned about the xkcd font.)

Will mentioned that there exists a CSS property called text-decoration-style that can be used to choose between various underlining styles! text-decoration-style: wavy; gives you a "wavy" underline. Yay waves! We weren't sure if it's possible to implement a new hand-drawn style for this property, so Will pointed out that Rough.js might give us a quick start.

I also learned about the existence of the canvas and svg tags, and found this really cool VS Code extension which does automatic page reloads every time you change your HTML code.

We came up with the following code which draws a line in an svg below a paragraph on the page so that the text appears to be underlined. It doesn't resize dynamically though, so implementing a new style for the CSS property mentioned above might be a better way to go.


  // paragraph to underline
  let p = document.getElementById('paragraph');

  // bounding rectangle for the paragraph
  // https://www.w3schools.com/JSREF/met_element_getboundingclientrect.asp
  let rect = p.getBoundingClientRect();

  // svg container below the paragraph
  let svg = document.getElementById('svg');
  const rc = rough.svg(svg);

  // draw underline 10 units below paragraph using roughjs
  let line = rc.line(rect.x, rect.y + 10, rect.right, rect.y + 10);

  // append line to the svg container
  svg.appendChild(line);

I also went to the NixOS User Group meeting and asked Michael a lot of beginner questions about NixOS. He showed me how he manages his Nix configs. And how NixOS installs every package in a /nix/store/<hash> directory, and automatically adds symlinks for executables to the relevant bin directory. I was also curious about how he manages Python virtual environments.

We created one with python -m venv .venv and were able to activate it, but when we tried to upgrade pip using python -m pip install --upgrade pip, it upgraded the pip associated with the Nix Python that came from /nix/store (IIRC). We thought that we could use the pip from the virtual environment by removing python -m, but we ran into a ModuleNotFoundError: No module named 'pip._internal' (related GH issue). I guess some paths need to be fixed before this can work.

I liked the NixOS package config in which you can list all packages you need (along with their versions), and use the config on another system to get the same setup. I wonder if there's a way to automatically pin packages when you install them (like poetry does) so you don't have to manually update the config every time. I also wonder if there's a tool that does this for Ubuntu, because at this point I have run so many apt installs that I've completely lost track of what all I've installed.

I also set up the emscripten toolchain to compile C/C++ code into WebAssembly. The shell script they give out doesn't run in the fish shell so I had to use zsh. After a emsdk install latest, I had to add the following to my .zshrc for everything to work.


  export PATH="/home/vinayak/dev/emsdk:$PATH"
  export PATH="/home/vinayak/dev/emsdk/node/12.18.1_64bit/bin:$PATH"
  export PATH="/home/vinayak/dev/emsdk/upstream/emscripten:$PATH"
  source "/home/vinayak/dev/emsdk/emsdk_env.sh"

I wrote some C after so long!


  #include <stdio.h>

  int main() {
      printf("hello, world!\n");
      return 0;
  }

And used gcc to compile it like the good old days! When I was learning C in college, I never wondered why the output of that compilation is called a.out, so today I looked into it. It's short for "assembler output", the filename of the output of Ken Thompson's PDP-7 assembler. a.out remains the default output filename for executables created by compilers like gcc, even though the created files actually are not in the original a.out format!


  $ gcc hello_world.c
  $ ./a.out
  Hello, world!

The emscripten toolchain gives you emcc which can compile C/C++ code into a WASM. It also creates a verbose Javascript file which imports the generated WASM binary.


  $ emcc hello_world.c
  $ node a.out.js
  Hello, world!

After that, I wrote a simple add function in C, but wasn't able to compile it into a WASM (that exports the function) so that I can call it from Javascript. I'll try to do that tomorrow!


I finally managed to do a very short run after 2 weeks! And I found out from a friend that I appeared in a Netflix documentary for two seconds! This very short video was shot at India Gate (I'm second from right) at around the 8km mark into the 21k 2016 New Delhi Marathon. In the background, you can also see the infamous Delhi smog which will engulf the city again in the coming winter months :(