Skip to content

Instantly share code, notes, and snippets.

@andrewsg
Last active August 26, 2016 19:55
Show Gist options
  • Save andrewsg/ae9803a625d13016bb96 to your computer and use it in GitHub Desktop.
Save andrewsg/ae9803a625d13016bb96 to your computer and use it in GitHub Desktop.
Add'l notes for Programming as Communication talk

--- For instance, you'd think addition is dead simple, right? a + b = c. But in machine code, there's no platonic idea of a number; it's all just ones and zeroes in fixed-length slots in memory. Let's say your CPU register is 16 bits, of which the largest unsigned integer you can store is 65535 (2^16-1, the "-1" because of zero). If "a" is 60000 and "b" is 10000, then what is "c"? Ruby is smart enough to recognize that c will be too large for the CPU to handle in one 16-bit word, so it will break the problem up behind the scenes. It will correctly answer 70000. The logic to do all of the work behind the scenes to handle the conversion from one-word to multiple-word numbers and display the result as a single number involves the execution of thousands of lines of machine code. ---

--- There are three big downsides to using compilers as vs. writing machine code yourself:

One, compilers themselves tend to be slow to run, because they're so complex. So every time you change anything in your program, you have to recompile, which takes anywhere from a second to several hours depending on the size of your program.

Two, the machine code that compilers generate is usually accurate, but isn't always as fast or concise as possible. Sometimes it's possible to make faster-running programs using hand-tuned machine code than it is to make them using compiled code. As computers get faster and as compilers get smarter, this is becoming less of a concern.

Three, every layer of complexity you put on top of machine code makes it harder to debug problems, because there is more code involved -- for instance, the compiler itself, which may have bugs of its own -- and because the computer has a hard time communicating what is wrong because it only speaks machine code. ---

--- Machine code software, and therefore software that's translated directly into machine code, needs to know in advance what types of data every function handles, in part so it knows how much memory to allocate for the input and output. You also have to put up with a lot of quirks of real hardware; for instance, if you tell the CPU to do something and it takes a long time, there may or may not be a way to stop it and say "wait, the user wants to cancel this operation" or "wait, the user pressed the power button" or "wait, the CPU is needed for a moment to process this incoming data from the internet". And if your program has a bug, then depending on the bug, the CPU itself can stop working, can put itself into an inconsistent state, or can silently change your data in an unpredictable way. It's also vulnerable to hackers who understand in great detail how the CPU works, and can use that understanding to break your program (with carefully crafted data, for instance) in a way that benefits them. ---

--- For some languages there is more than one compiler that supports the language. C in particular has a multitude of different compilers, all implementing the same language. Since the C language specification does not strictly spell out every detail of an implementation, not all of these compilers behave in the same way in many edge cases. Sometimes a program written for one compiler won't successfully compile on any other at all. ---

@andrewsg
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment