Geoff Greer's site Geoff Greer 2024-01-27T16:17:27-08:00 Gasoline Car Review 2023-02-08T17:57:03-08:00 <p>I recently purchased a <a href="/miata/">Mazda Miata</a>. This car is interesting because instead of running on electricity, it is powered by a combustible liquid called gasoline. The vehicle has an engine that mixes the gasoline with oxygen from the air, ignites the mixture, and uses the resulting combustion to push the car forward. I don’t fully understand the details of how it works, but this difference in propulsion technology totally changes the experience of owning and operating a vehicle.</p> <p>After taking delivery of the car, my first hurdle was getting it to do anything. I opened the door (the handles are very prominent), sat in the driver’s seat, and… nothing happened. No screen showed any messages. The climate control didn’t turn on. The car seemed dead. I pressed the accelerator (Mazda calls this the “gas” pedal) but again, nothing. I called their support line and quickly figured out the issue: Unlike a normal car, a gas car needs to be “started”. Apparently it would be wasteful and expensive to keep the gasoline engine running all the time, so you’re only supposed to run the engine if you’re moving the vehicle. The starting process is pretty painless: You insert your key into a slot on the side of the steering column, push the clutch pedal (more on that later), then turn the key and hold it for a second or two. I succeeded on the first try, causing the car to jump to life and emit all kinds of crazy noises. Imagine if a steam locomotive had a baby with a machine gun. That’s the sort of noise that comes out of a gas car. It evokes both excitement and concern.</p> <p>My next bit of confusion was regarding the climate control. At first I thought it was broken, but it turned out that a gas car’s heating system is unique. Instead of using electricity to heat up coils or pump heat into the cabin, it uses the engine’s excess heat to warm the cabin. This means that the cabin won’t get warm until the engine has been running long enough to heat up. This only takes a few minutes, but on a cold morning it can feel like an eternity.</p> <p>With the engine running and the cabin warm, it was finally time for me to get moving. That’s when I ran into another quirk. Unlike normal electric motors, gasoline engines have a narrow range of RPMs that they can operate at. Too slow and the combustion reaction can’t self-sustain. Too fast and the engine explodes. To get around this limitation they use a transmission with multiple gears, sort of like a bicycle. The lower gears are for when you start moving. As you gain speed, you shift into higher gears to avoid hitting the engine’s RPM limit. This process of shifting gears involves careful coordination of the gas pedal, the clutch pedal (an extra pedal to the left of the brake pedal), and the shifter knob. I won’t get into the details, but shifting gears is definitely a skill that must be learned. Shifting gears can be fun in the right circumstance, but it can also be tedious and frustrating, especially in stop-and-go traffic.</p> <p>After lots of practice and profanity, I got back home and turned off the car. Again this step is unusual, but it’s necessary to save fuel. It was quite easy, as it was basically the reverse of starting the car: You turn the key in the opposite direction and remove it. The car became silent, so I got out and went inside to make dinner.</p> <p>The next morning I tried to start the car but nothing happened. Troubleshooting took a while, but I eventually figured it out: A gasoline car needs gasoline <em>and</em> electricity to run! Apparently the headlights didn’t automatically turn off after I left the car. This meant that the car’s tiny battery lost its charge and couldn’t turn the gasoline engine on. What a pain! To add insult to injury, the car lacks a standard charging port. I couldn’t just hook up an extension cord to charge it. I had to get someone else with a gas car to stop next to my stranded car, then pop both hoods and connect some giant alligator clips to both cars’ batteries, and <em>then</em> run the working car long enough to charge the dead battery. It gets worse. If you mess up this “jumper cable” configuration, <a href="">the battery can explode</a> and send acid everywhere. This is ridiculously unsafe, especially considering that the battery is so close to extremely flammable gasoline. I can only imagine how many of these vehicles would catch fire if they were common. Hopefully firefighters are trained in how to extinguish this unique type of fire.</p> <p>Oh and when you pop the hood you’ll notice another problem: there is no storage! The gasoline engine is <em>massive</em>. It occupies the entire front of the vehicle, leaving no room for luggage or groceries. You’ll have to fit all of your stuff in the trunk. It’s absurd that the owner’s manual neglected to mention this.</p> <p>Refueling was a mixed bag. Whenever I parked in my garage, I had to suppress the urge to plug the car in. Gasoline is only available at special stations, and it is prohibitively expensive to get a gasoline line installed in your home. So unlike a normal car, you don’t wake up every morning with full range. The only way to add range is to go to gas stations. These are similar to fast charging stations, but smelly and more dangerous. I certainly wouldn’t want to live near one. The stations require you to turn the engine off while fueling, meaning you can’t listen to music or otherwise entertain yourself. There is one upside: refueling is very quick. After I started the gas pump, I went to the bathroom and grabbed a snack. By the time I got back it was already done! A couple of other drivers were giving me dirty looks for bogarting the pump, so I quickly put the nozzle back and drove away. I was surprised that there was no interlock to prevent the car from moving while refueling. Maybe it’s intentional to allow for in-motion refueling in the future.</p> <p>The speed of refueling does help offset the lack of at-home gas pumps, but the dependence on gas stations gives me a lot of anxiety. What if I’m in the middle of nowhere and can’t reach a station before I run out of fuel? What if the station runs out of gas? With a normal car, I can plug in anywhere there is electricity. Even a standard appliance socket can add enough range to get to a fast charging station. But a gas car needs gasoline to move. If you’re too far from a fueling station, you have to have someone bring you gas. If that’s not an option, then you need to call a tow truck.</p> <p>After using a gas car for a while, I do find some aspects appealing. For one, it’s an engineering marvel. The machinery that harnesses combustion energy is ridiculously complicated. It’s amazing that the thing works at all. The word that comes to my mind after driving a gas car is “primal”. All of your senses are engaged: the sound and vibration of the engine; the smell of volatile chemicals and exhaust; the nagging reminder that you are speeding around with a tank full of napalm. Some may find it terrifying; others (such as myself) find it exhilarating.</p> <p>But no matter how enjoyable a gas car is at its best, it’s just not compelling for daily use. Compared to the status quo a gas car is inconvenient, slow, noisy, smelly, and dangerous. I think a few enthusiasts and hipsters will enjoy tooling around in these things, and rich people might have one for special occasions (along with their horses and sailboats), but the vast majority of people are better served with a normal car. I doubt these combustion vehicles will ever be popular.</p> Against the New York Times 2020-06-23T19:28:06-07:00 <p>I’ve been reading <a href="">Scott Alexander</a> since the days of his LiveJournal and <a href="">Lesswrong</a> posts (over a decade ago). Scott is an amazing writer. Over the years he has provided countless thoughtful and informative posts on a wide range of topics. He is also one of the nicest and most charitable people I have encountered.</p> <p>And the New York Times has endangered his safety and his livelihood for no good reason.</p> <p>Scott recently <a href="">decided to delete his entire blog</a> (<a href="/archive/NYT Is Threatening My Safety By Revealing My Real Name, So I Am Deleting The Blog _ Slate Star Codex (2020-06-23 11_30_17 AM).html">archive</a>) in response to an upcoming New York Times article that promises to reveal his real name. Scott is a psychiatrist. In his most recent (and only remaining) post, he explains why publishing his real name could be harmful:</p> <blockquote> <p>I think it’s plausible that if I became a national news figure under my real name, my patients – who run the gamut from far-left anarchists to far-right gun nuts – wouldn’t be able to engage with me in a normal therapeutic way. I also worry that my clinic would decide I am more of a liability than an asset and let me go, which would leave hundreds of patients in a dangerous situation as we tried to transition their care.<br /> …<br /> When I expressed these fears to the reporter, he said that it was New York Times policy to include real names, and he couldn’t change that.</p> </blockquote> <p>Apparently, the New York Times has a policy on using real names. From their <a href="">Guidelines on Integrity</a> (<a href="/archive/Ethical Journalism - The New York Times (2020-06-23 1_48_23 PM).html">archive</a>):</p> <blockquote> <p>No reader should find cause to suspect that the paper would knowingly alter facts. For that reason, The Times refrains outright from assigning fictional names, ages, places or dates, and it strictly limits the use of other concealment devices.</p> <p>If compassion or the unavoidable conditions of reporting require shielding an identity, the preferred solution is to omit the name and explain the omission. (That situation might arise, for example, in an interview conducted inside a hospital or a school governed by privacy rules.) If a complex narrative must distinguish among several shielded identities, it may be necessary to use given names with last initials or, less desirable, given names alone (Hilary K.; Ashley M.; Terry). Descriptions may serve instead (the lawyer; the Morristown psychotherapist). As a rare last resort, if genuine given names would be too revealing, real or coined single initials (Dr. D, Ms. L) may be used after consultation with senior editors. The article must gracefully indicate the device and the reason.</p> </blockquote> <p>Their stated policy seems rather strict in favoring the use of real names. In practice, it’s not so clear-cut. There are many examples of the Times avoiding any mention of subjects’ real names, typically with little or no justification. Here are a few cases:</p> <ul> <li><a href="">Banksy</a> (<a href="/archive/Banksy Is a Control Freak. But He Can’t Control His Legacy. - The New York Times (2020-06-23 12_40_49 PM).html">archive</a>)</li> <li><a href="">Virgil Texas</a>, co-host of the Chapo Trap House podcast (<a href="/archive/The Pied Pipers of the Dirtbag Left Want to Lead Everyone to Bernie Sanders - The New York Times (2020-06-23 11_30_02 AM).html">archive</a>)</li> <li>Performance artist and Libertarian candidate <a href="">Vermin Supreme</a> (<a href="/archive/Libertarians See Chance Amid Discontent Over Donald Trump and Hillary Clinton - The New York Times (2020-06-23 12_41_36 PM).html">archive</a>)</li> <li>Drag queens such as <a href="">Lil Miss Hot Mess, Sister Roma, and Heklina</a> (<a href="/archive/Drag Performers Fight Facebook’s ‘Real Name’ Policy - The New York Times (2020-06-23 12_38_25 PM).html">archive</a>)</li> <li><a href="">Women gamers and streamers</a> (<a href="/archive/Dozens of Women in Gaming Speak Out About Sexism and Harassment - The New York Times (2020-06-23 3_55_09 PM).html">archive</a>):</li> </ul> <blockquote> <p>The streamers did not provide their legal names to The New York Times. In years past, women gamers who have spoken out against the industry using their legal names have been subjected to further harassment, hacking and doxxing.</p> </blockquote> <ul> <li>Baseball statistician <a href="">Tom Tango</a> (<a href="/archive/Why Are Some New Statistics Embraced and Not Others_ - The New York Times (2020-06-23 12_42_49 PM).html">archive</a>)</li> <li>Gay niche erotica writer <a href="">Chuck Tingle</a> (<a href="/archive/Opinion _ Chuck Tingle’s Internet Magic - The New York Times (2020-06-23 12_39_10 PM).html">archive</a>)</li> <li><a href="">A Canadian who traveled to Syria to fight for ISIS</a> (<a href="/archive/Chapter 10_ One Year Later - The New York Times (2020-06-23 11_38_39 AM).html">archive</a>)</li> </ul> <blockquote> <p>Reporter: It’s still unclear what the true story is of the Canadian known as Abu Huzayfah al-Kanadi and the time he says he spent…</p> </blockquote> <ul> <li><a href="">A random person</a> (<a href="/archive/Commodes, if Not Commutes, Have Improved at Port Authority Bus Terminal - The New York Times (2020-06-23 12_44_51 PM).html">archive</a>):</li> </ul> <blockquote> <p>A second person who checked out the women’s restroom — and who asked not to be identified because she has always wanted to be an anonymous source — reported her findings by email…</p> </blockquote> <ul> <li><a href="">Jeremiah Moss</a> (<a href="/archive/A Cranky Blogger Crusades to Preserve the Ordinary in New York - The New York Times (2020-06-23 11_29_45 AM).html">archive</a>):</li> </ul> <blockquote> <p>Mr. Moss, which is not his real name — more on that to come — took part in a doomed attempt to save the Café Edison, a beloved Times Square coffee shop whose landlord was looking to replace it with a classier establishment.<br /> …<br /> A therapist and a writer, he says he is worried that clients might object to his activism.</p> </blockquote> <p>“A therapist and a writer”, hmmm… who else fits that description? Oh right, Scott Alexander!</p> <p>I hope these examples make it clear that in practice, the New York Times has no strict policy on using real names. If anything, they seem eager to protect the identities of people who would be harmed by having their real names published. This is why I am <em>extremely</em> suspicious of their motives for enforcing their real name policy against Scott. For some reason I cannot fathom, one of their reporters misled Scott about their name policy, then decided to publish Scott’s real name against his wishes. And because of this, we are all worse off. Scott is worse off. His patients are worse off. His readers are worse off.</p> <p>Slate Star Codex was an island of sanity in an ocean of madness. For now, it is gone.</p> <h2 id="what-you-can-do">What You Can Do</h2> <p>If you have a subscription to the New York Times, cancel it. If a reporter from the Times asks you for an interview or for information, refuse to talk to them and explain why.</p> <p>In fact <strong>do not talk to journalists</strong> in general. If you must, record everything. Journalists will quote you out of context, selectively edit your words, and even make up quotes and attribute them to you. All of these things have happened to me or to people I know. I’m sure there are some good journalists, but the bad ones are the majority of every major news organization.</p> <p>The old New York Times is dead. The New York Times of today is a wolf wearing the skin of a reputable newspaper. The sooner more people realize that, the sooner NYT’s influence wanes and the sooner that innocent, interesting people like Scott will feel free to spread their ideas.</p> In Defense of Richard Stallman 2019-09-30T01:16:45-07:00 <p>Richard Stallman has had a rough month. <a href="">This article</a> is a decent summary of the events. In short: Stallman made some technically-correct-but-utterly-tactless comments on a private mailing list, mostly in defense of his late friend and colleague <a href="">Marvin Minsky</a>. Someone leaked those comments to the public. He was then forced to resign from pretty much every position he held. He had to step down as president of the organization he founded— the <a href="">Free Software Foundation</a>. He was forced to resign from MIT’s <a href="">CSAIL</a>. He said that he is <a href="">stepping down as head of the GNU Project</a>. (Though this was later deleted, so it’s yet unclear.) <a href="">He is now likely homeless</a> and his friends (such as <a href="">Eric Raymond</a>) have <a href="">had trouble contacting him</a>.</p> <p>Frankly, none of this should have happened. In a sane world, people would have rolled their eyes at Stallman’s pedantry and he would continue furthering the cause of free software. Maybe a few people would chastise the person who leaked the emails, and that would be the end of it.</p> <p>But we don’t live in a sane world. We live in a bizarro world where someone can leak private communications, blatantly lie about what was said, and cause a selfless man’s life to be ruined. And in reaction to these events, people cheer. This is madness.</p> <p>Perhaps I should explain myself before I too am removed for having problematic opinions.</p> <h3 id="lies-damned-lies-and-journalism">Lies, Damned Lies, and Journalism</h3> <p>The original <a href="">Remove Richard Stallman post</a> contained leaked communications from a private mailing list. In it, the author quotes an email from Stallman where he explains that Marvin Minsky likely wouldn’t have known that the woman on Jeffrey Epstein’s island was coerced:</p> <blockquote> <p>…the most plausible scenario is that she presented herself to him as entirely willing. Assuming she was being coerced by Epstein, he would have had every reason to tell her to conceal that from most of his associates.</p> </blockquote> <p>A paragraph later, the author summarizes Stallman’s view as:</p> <blockquote> <p>…he says that an enslaved child could, somehow, be “entirely willing”.</p> </blockquote> <p>This is the <em>opposite</em> of what Stallman said, but this lie was repeated by the press. An <a href="">article in the Daily Beast</a> said:</p> <blockquote> <p>Stallman wrote that “the most plausible scenario” for Giuffre’s accusations was that she was, in actuality, “entirely willing.”</p> </blockquote> <p>An <a href="">article in Vice</a> spread the same lie:</p> <blockquote> <p>Early in the thread, Stallman insists that the “most plausible scenario” is that Epstein’s underage victims were “entirely willing” while being trafficked.</p> </blockquote> <p>There are two possibilities here. Either the author of the Medium post was not capable of correctly parsing the sentence, or she didn’t care about truth and was leveling as many accusations as possible in the hope that one would stick. In other words: she is either foolish or malicious. The same goes for the writers of the Vice and Daily Beast articles. To describe what they did as journalism would be an insult to journalists.</p> <h3 id="censorious-instincts">Censorious Instincts</h3> <p>What’s most disturbing about this is how many of my friends and peers support Stallman’s removal. At first it was because they took the false accusations at face value. When I pointed out that these accusations were lies, they supported Stallman’s removal for other reasons. They focused on his tone deaf communication style and awkward demeanor. They spoke of behavior from decades ago and pointed out the fact that he had a mattress in his office. (Apparently that’s where he often slept.) As far as I can tell, the worst allegations against Stallman involve him being a socially clueless aspie. He held his positions at MIT, GNU, and the FSF for over thirty years, and in that time nobody accused him of coercion, unwanted touching, or verbal harassment. If an occasional social gaffe or failed attempt at humor is all it takes to get thrown out on the street, nobody is safe.</p> <h3 id="the-big-picture">The Big Picture</h3> <p>I think everyone is overlooking a bigger issue: <strong>You don’t get the free software movement without a person like Richard Stallman.</strong> Its success depended on a stubborn pedantic ideologue. It required someone who couldn’t take a hint. It required someone who would tirelessly beat the drum and remind everyone of the arguments in favor of copyleft and user freedoms. If people in the 1980’s had the culture we have today, Stallman would have been sidelined long before his initiatives got off the ground. There would be no copyleft, no GNU General Public License, no Free Software Foundation, no GNU userspace (binutils, coreutils, etc), no GNU Compiler Collection, and (of course) no Emacs. Entire ecosystems of software would not exist today. People would be forced to use costly proprietary systems. Moreover, Stallman has devoted his life to ensuring equal access to software, not just for those who can afford dev kits and licenses. Without him students wouldn’t have nearly as many free tools to tinker with. It would be much harder to build new programming languages, web servers, frameworks, and companies. It is no exaggeration to say that Richard Stallman is responsible for creating trillions of dollars in wealth. And it’s not just wealth for the wealthy. It’s wealth for <em>all</em>.</p> <p>There are pedantic ideologues trying moonshots today. They’re not famous yet, because they haven’t succeeded. And due to their lack of fame, you won’t hear about them when they are inevitably canceled. And we will all be poorer for it.</p> <p>By satisfying the mob today, we are sacrificing our future. That’s the real risk.</p> <hr /> <p>Update: <a href="">According to his website, Stallman has found housing</a>. He also says he will continue to head GNU:</p> <blockquote> <p>I continue to be the Chief GNUisance of the GNU Project.<br /> I do not intend to stop any time soon.<br /> I found new interim housing — thanks to those who helped.</p> </blockquote> <p>Update (2019-10-01): I discussed Stallman’s removal with some others on <a href="">an episode of The Bailey Podcast</a>.</p> <p>Update (2021-04-04): Stallman is now back on the Free Software Foundation’s board.</p> Social Media 2019-06-30T00:20:27-07:00 <blockquote> <p>I just re-read the Unabomer’s manifesto. … It is a slightly crazy document… but the truth is that it is better reasoned and modulated than half of what I see on Twitter. And this is from people with blue check marks by their names and large followings.</p> </blockquote> <blockquote> <p>I don’t know what it means to be able to honestly say that half the people on Twitter seem less hinged than a man who was sending bombs in the mail, but it does seem that we’re performing an experiment on ourselves— the consequences of which are as yet undetermined. Anyway I’m very happy to have withdrawn to the degree I have. It feels far more sane.</p> </blockquote> <p>— <a href="">Sam Harris</a></p> <p>Social media definitely has potential, but I haven’t found it to be useful or interesting in a long time. I’ve drifted away from using Facebook, Twitter, and Reddit. When I occasionally revisit them, I am astounded by how insane many of the comments seem.</p> <p>On the bright side, I’m reading more books.</p> Thinkpad X210 2019-03-04T23:23:17-08:00 <p>A couple years ago, <a href="/2017/01/23/oldest-viable-laptop/">I used an old Thinkpad while my MacBook was being repaired</a>. I enjoyed the experience so much that <a href="/2017/07/16/thinkpad-x62/">I ended up getting a Thinkpad X62</a> (an X61 chassis with modern internals). Last September, the maker of the X62 announced that <a href="">a 3rd batch of X210s would be made</a>. I ordered one and received it in January. China has a bunch of laws that make it hard to move money across borders, so payment involved wiring $1200 to someone’s personal bank account in China, then e-mailing a address. It was a rather harrowing experience.</p> <p><img src="/images/x210.jpg" alt="My X210. Fonts are huge so that you can read screenfetch." /></p> <p>Like the X62, the X210 is made by <a href="">51NB</a>, a group of enthusiasts in Shenzhen. The X210 is an X201 chassis with:</p> <ul> <li>A <a href="">Core i7 8550u</a> (4 cores, turbo boost up to 4GHz)</li> <li>2× DDR4 SODIMM slots. I put 32 GB of RAM in.</li> <li>2× mini PCI Express slots. There’s an 802.11/Bluetooth card in one. The other is empty but could be used for LTE or a second wireless card.</li> <li>An M.2 NVMe slot. I put a 2TB SSD in it.</li> <li>A 2.5” SATA bay. I left it empty, but it’s possible to put a second SSD in.</li> <li>An upgraded screen (<a href="/archive/">12.6 inch, 2880×1920, 450 nits, wide gamut</a>). The bezel is cut to make room for the 3:2 aspect ratio. There is no webcam.</li> <li>Mini DisplayPort &amp; VGA out.</li> <li>3× USB 3.1 ports (no USB-C).</li> <li>SD card reader.</li> <li>Gigabit ethernet.</li> <li>Physical switch to toggle Wifi/Bluetooth.</li> <li>Headphone &amp; microphone jacks.</li> <li>Internal microphone &amp; speakers.</li> </ul> <p>The X210 is sold as either a motherboard that you install into your own chassis or as a barebones laptop where you bring your own RAM, SSD, and battery. I got the barebones kit.</p> <h2 id="my-impressions">My Impressions</h2> <p>I slightly prefer the X62’s more compact keyboard, but everything else is much better on the X210. The CPU is over twice as fast and runs cooler. The wifi is faster. The SSD is faster. The screen is <em>gorgeous</em>. It’s a 12.6” screen with a higher resolution than the 15” MacBook Pro. Overall, it’s just plain better.</p> <p>Linux worked out of the box. I had to install non-free drivers for the Broadcom wireless card, then tweak a few module options to get better power saving. Battery life is a little over 4 hours with the flush battery (55Wh) and 6-7 hours with the extended battery (80Wh). I haven’t finished tweaking all the power saving options, so the lowest idle state is PC3. Battery life would increase by 50% if I got PC6 or PC8 idle states. The fan only turns on if I’m doing something intensive like compiling go or scrolling in Slack.</p> <p>Update (2019-03-17): I managed to get PC7 idle by upgrading my kernel to 4.18 and replacing the r8168 module with r8169. Battery life has increased significantly. I now get 6 hours with the flush battery and 10 hours with the extended battery.</p> <p>Like most older Thinkpads, the X210 is easily repaired and upgraded. You can swap the battery in seconds without any tools. If the SSD fails, you can replace it. If the RAM fails, you can replace it. If the wifi card fails, you can replace it. If the screen fails, you can replace it. You can even replace the Trackpoint and the little rubber feet without much trouble. The laptop can be entirely disassembled with two Philips screwheads (#0 and #1). At no point do you encounter tape, glue, or pentalobe screws.</p> <h2 id="caveats">Caveats</h2> <p>The X210 isn’t perfect. It’s made by a group of enthusiasts, not a big company. With that comes some disadvantages:</p> <ul> <li>Like the X62, the mini DisplayPort cannot output in HDMI alternate mode. This means that miniDP→HDMI dongles won’t work.</li> <li>I sometimes notice <a href="">PWM</a> flicker on the screen. This only happens at the lowest brightness in a dark room when displaying mostly black content. I can see afterimages when my eyes <a href="">saccade</a>, similar to some brake lights at night. It’s about as noticeable as the PWM flicker on my iPhone X.</li> <li>If the motherboard breaks, you can’t walk into a store and get it replaced or repaired. Your only recourse is to e-mail the manufacturer and ship it back to China. I’ve only read about one case of this happening, and in that case the motherboard was DOA. The unfortunate user was shipped a new one within a few weeks.</li> </ul> <h2 id="conclusion">Conclusion</h2> <p>I love this laptop. It addresses almost all of the issues I had with the X62: better screen, better performance, and better microphone quality. More than anything, the X210 demonstrates just how much potential is being squandered by laptop manufacturers. If a small group in Shenzhen can make this laptop, Lenovo or Apple should be able to build something far better. Instead they make laptops with integrated batteries, fewer ports, soldered RAM, sub-par keyboards, and touchbars. Many professionals want something better.<sup id="fnref:hn" role="doc-noteref"><a href="#fn:hn" class="footnote" rel="footnote">1</a></sup></p> <p>I hope 51NB continues to build new internals for old chassis, because I doubt the major laptop manufacturers will get their heads out of their asses any time soon.</p> <p>Oh and if you’re wondering if I put stickers on my laptop, the answer is, “Yes.”</p> <p><img src="/images/IMG_1004.jpg" alt="I tend to go overboard with stickers." /></p> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:hn" role="doc-endnote"> <p>As evidenced by these Hacker News posts: <a href="">1</a>, <a href="">2</a>, <a href="">3</a> <a href="#fnref:hn" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div> Conserve Vertical Pixels 2018-04-02T00:07:15-07:00 <blockquote> <p>Every vertical pixel used for the UI bar signifies a theft from those who hunger and are not fed, those who are cold and are not clothed. <br /><br />— <a href="">Fakey Fakerson</a><sup id="fnref:fakey_tweet" role="doc-noteref"><a href="#fn:fakey_tweet" class="footnote" rel="footnote">1</a></sup></p> </blockquote> <p>Here’s a screenshot of Red Hat’s <a href="">OpenShift Console</a> viewed with Firefox on stock GNOME Shell:</p> <p><img src="/images/Screenshot from 2018-03-29 17-30-32.png" alt="Openshift console on" /></p> <p>You might notice a problem with this user interface: The top third of the screen is permanently occupied with stuff I don’t care about.<sup id="fnref:ui_issues" role="doc-noteref"><a href="#fn:ui_issues" class="footnote" rel="footnote">2</a></sup></p> <p>This screenshot is particularly egregious, but it exemplifies a common issue. Every layer in the UI stack eats vertical pixels. The OS has a menu bar. The application window has a title bar. The browser has tab and location bars. Finally, the website has two fixed bars: one containing a logo and user info; another for project info. Combine all of these with modern 16:9 screens, and you have a recipe for frustration.</p> <p>I’m sure if you asked each UI designer involved, they’d feel justified in their decision. The OS needs a menu bar. Application windows need title bars. Browsers need location and tab bars. No single pebble is responsible for the avalanche.</p> <p>But if you are a web designer, and you think that having a fixed bar on your site makes for happier users, you are almost certainly mistaken. If you <em>must</em> add a top bar, hide it as the user scrolls down, then show it on scroll up. This interaction pattern is common on mobile devices and it’s not much effort to add to PCs. You can use a library like <a href="">Headroom.js</a>.</p> <p>Hopefully, future designers will look back on this era of vertical annexation the same way we view excesses such as the <code>&lt;blink&gt;</code> tag.</p> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:fakey_tweet" role="doc-endnote"> <p>Hat tip to Gwern for bringing this tweet to my attention. <a href="#fnref:fakey_tweet" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:ui_issues" role="doc-endnote"> <p>Vertical space isn’t the only issue with that UI. The fonts are small and low contrast. The scrollbar takes up the entire height of the browser window, but the top two bars are fixed. Also, there’s a ton of wasted space on the right where that log viewer could expand to. <a href="#fnref:ui_issues" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div> Linux Laptop Locking 2018-01-02T03:49:05-08:00 <p>If you wrote your own systemd unit to lock your laptop on suspend, you might want to double-check its behavior. The top two Google results for <a href="">“systemd lock laptop on suspend”</a> both provide examples that lock on <em>resume</em>, not suspend.<sup id="fnref:google" role="doc-noteref"><a href="#fn:google" class="footnote" rel="footnote">1</a></sup> This is a security risk.</p> <p>How did I discover this? A few months ago, I switched to <a href="">Sway</a>, a <a href="">tiling window manager</a> similar to <a href="">i3</a>.<sup id="fnref:ubuntu" role="doc-noteref"><a href="#fn:ubuntu" class="footnote" rel="footnote">2</a></sup> Like i3, Sway requires a significant amount of configuration to get behaviors that Mac users take for granted.</p> <p>One feature I wanted was to lock the screen when I closed my laptop’s lid. Like any lazy programmer I googled some terms, consulted <a href="">the first Stack Exchange link</a>, and created the necessary systemd unit:</p> <figure class="highlight"><pre><code class="language-ini" data-lang="ini"><span class="nn">[Unit]</span> <span class="py">Description</span><span class="p">=</span><span class="s">Lock the screen</span> <span class="nn">[Service]</span> <span class="py">User</span><span class="p">=</span><span class="s">ggreer</span> <span class="py">Environment</span><span class="p">=</span><span class="s">DISPLAY=:0</span> <span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/local/bin/lock-screen</span> <span class="nn">[Install]</span> <span class="py">WantedBy</span><span class="p">=</span><span class="s"></span></code></pre></figure> <p>This is a pretty straightforward unit. On suspend, run <code class="language-plaintext highlighter-rouge">lock-screen</code>. Unfortunately, it’s wrong.</p> <p>A few weeks after adding the unit, I opened my laptop and stared at an unlocked screen. Immediately, I delved into logs to figure out how this happened. It wasn’t long before I found the answer: The system had failed to suspend <a href="">because of an sshfs mount</a>. This was a double surprise. I didn’t know that:</p> <ol> <li>A non-root process could prevent the kernel from suspending.</li> <li>My systemd unit was locking after suspend instead of before.</li> </ol> <p><a href="">The fix</a> didn’t require changing much:</p> <figure class="highlight"><pre><code class="language-diff" data-lang="diff"> [Unit] Description=Lock the screen <span class="gi"> </span> [Service] User=ggreer Environment=DISPLAY=:0 ExecStart=/usr/local/bin/lock-screen [Install] <span class="gd"> </span><span class="gi"></span></code></pre></figure> <p>Adding “<code class="language-plaintext highlighter-rouge">Before=...</code>” forces systemd to wait for <code class="language-plaintext highlighter-rouge">lock-screen</code> to start before suspending.<sup id="fnref:systemd_unit" role="doc-noteref"><a href="#fn:systemd_unit" class="footnote" rel="footnote">3</a></sup> Using <code class="language-plaintext highlighter-rouge"></code> is a little more robust, as <code class="language-plaintext highlighter-rouge"></code> only covers suspending to RAM. Sleep covers suspending to RAM, suspending to disk, and <a href="">hybrid sleep</a>.</p> <p>If you’re running a highly-customized Linux GUI, you’ll probably never be as secure as stock Fedora or Ubuntu. A single mistake (such as the one I made) can leave your system totally vulnerable. Less popular window managers often lack basic exploit mitigation techniques such as <a href="">clearing passwords from memory</a>.</p> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:google" role="doc-endnote"> <p>As of 2018-01-01, the top two results are <a href="">an Arch Linux forum post</a> and <a href="">a Stack Exchange answer</a>. Both use <code class="language-plaintext highlighter-rouge"></code> and omit <code class="language-plaintext highlighter-rouge">Before=...</code>. <a href="#fnref:google" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:ubuntu" role="doc-endnote"> <p>The release of Ubuntu 17.10 switched from Unity to Gnome Shell, making the user interface a nightmare. It’s like they tried their hardest to annoy users. For example, joining a wifi network went from two clicks to five. I’d rather deal with stupid config files and alpha-quality tiling window managers than continue to use Gnome Shell. <a href="#fnref:ubuntu" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:systemd_unit" role="doc-endnote"> <p>More information on the behavior of <code class="language-plaintext highlighter-rouge">Before=</code> and <code class="language-plaintext highlighter-rouge">After=</code> can be found in <a href="">systemd’s unit documentation</a>. <a href="#fnref:systemd_unit" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div> Freedom of Speech isn't About Speech 2017-10-05T22:26:24-07:00 <p>There’s been a lot of debate about free speech lately, and I’ve noticed that people on both sides often misunderstand why it’s a good idea. It’s commonly assumed that freedom of speech is about the right of the speaker to express their ideas, but if you read early formulations of the concept, you’ll find a totally different justification: Free speech is good because it benefits the audience, including those who disagree with the speaker. Freedom of speech isn’t about speech. It’s about hearing.</p> <h2 id="some-history">Some History</h2> <p>A concise version of this argument comes from Thomas Paine’s introduction to <a href=""><em>The Age of Reason</em></a>:</p> <blockquote> <p>You will do me the justice to remember, that I have always strenuously supported the Right of every Man to his own opinion, however different that opinion might be to mine. He who denies to another this right, makes a slave of himself to his present opinion, because he precludes himself the right of changing it.<sup id="fnref:reason_intro" role="doc-noteref"><a href="#fn:reason_intro" class="footnote" rel="footnote">1</a></sup></p> </blockquote> <p>Paine wrote this in 1794, while imprisoned in Paris. Paine avoided execution<sup id="fnref:paine_execution" role="doc-noteref"><a href="#fn:paine_execution" class="footnote" rel="footnote">2</a></sup> and eventually returned to the US.</p> <p>80 years later, John Stuart Mill made the same point in <a href=""><em>On Liberty</em></a>:</p> <blockquote> <p>But the peculiar evil of silencing the expression of an opinion is, that it is robbing the human race; posterity as well as the existing generation; those who dissent from the opinion, still more than those who hold it. If the opinion is right, they are deprived of the opportunity of exchanging error for truth: if wrong, they lose, what is almost as great a benefit, the clearer perception and livelier impression of truth, produced by its collision with error.<sup id="fnref:liberty" role="doc-noteref"><a href="#fn:liberty" class="footnote" rel="footnote">3</a></sup></p> </blockquote> <p>This is the most succinct and powerful argument for free speech that I have come across. It demonstrates why free speech must apply even to repulsive and wrong-headed ideas. We allow bad ideas because they help to strengthen good ideas. Hearing arguments for bad ideas allows us to find their flaws and discover better counterarguments. At the very least, debate forces us to re-examine why we believe what we believe. How do you know the planet is 4.5 billion years old and not 6,000? It’s useful to occasionally rebuild beliefs from the ground up. Doing so helps us be wrong less often.</p> <p>Alright. Let’s say you largely agree with Paine and Mill, but feel that certain things simply aren’t up for debate. Maybe some ideas are just too harmful or detestable to be tolerated in society. Even if that’s true, the cure is likely worse than the disease. Banning ideas creates practical problems.</p> <h2 id="who-decides">Who Decides?</h2> <p>The key question of censorship is: Who decides what to censor? Framing freedom of speech in terms of hearing reveals how insidious this question is. If you ask, “Who should decide which ideas one may speak or publish?”, many are willing to let a government body take the reins. If you ask, “Who should decide which ideas you may hear or read?”, people boggle. But as Paine and Mill pointed out, these are the same question. If you don’t trust others to decide what you can read or hear, then you don’t trust them to decide what can be written or uttered.</p> <h2 id="unintended-consequences">Unintended Consequences</h2> <p>Imagine our society passes laws to ban the publishing of abhorrent and bigoted ideas. No longer are people allowed to express racism, sexism, homophobia, or antisemitism. So we ban <em>Mein Kampf</em>. No great loss there. Can you think of some other influential texts that are full of racism, sexism, homophobia, and antisemitism? A couple come to my mind: The Bible and the Qur’an. Honestly, how can you <em>not</em> ban them? These texts contain passages endorsing <em>slavery</em>. For centuries the ideas in these books were used to justify pogroms. Even today they create needless suffering for much of humanity. If you find yourself struggling to find reasons why religious texts should be exempt, then you see the problem. If censorship laws are consistently applied, most religious texts will be banned. If they’re inconsistently applied, the people in charge will censor according to their own beliefs and biases. Would you trust the current administration with that kind of authority? Neither outcome seems desirable to me.</p> <h2 id="conclusion">Conclusion</h2> <p>The arguments above aren’t new<sup id="fnref:credit" role="doc-noteref"><a href="#fn:credit" class="footnote" rel="footnote">4</a></sup>, but they seem to have disappeared from discourse. That’s unfortunate, as freedom of speech is crucial to the well-being of our society. <em>That</em> is why it’s important, not because it’s good for the speaker, and certainly not because it’s some noble ideal to be worshipped for its own sake. The original basis for free speech was pragmatic, not dogmatic. If Paine and Mill had thought that censorship would make people better-off, they would have said so.</p> <p>I’m disappointed that so many people misunderstand this. Hopefully that changes.</p> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:reason_intro" role="doc-endnote"> <p>The full text of Paine’s <em>Age of Reason</em> is available <a href="">here</a>. <a href="#fnref:reason_intro" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:paine_execution" role="doc-endnote"> <p>From <a href="">Wikipedia</a>:</p> <blockquote> <p>Paine narrowly escaped execution. A chalk mark was supposed to be left by the gaoler on the door of a cell to denote that the prisoner inside was due to be removed for execution. In Paine’s case, the mark had accidentally been made on the inside of his door rather than the outside; this was due to the fact that the door of Paine’s cell had been left open whilst the gaoler was making his rounds that day, since Paine had been receiving official visitors. But for this quirk of fate, Paine would have been executed the following morning. He kept his head and survived the few vital days needed to be spared by the fall of Robespierre on 9 Thermidor (July 27, 1794).</p> </blockquote> <p><a href="#fnref:paine_execution" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:liberty" role="doc-endnote"> <p>From <a href="">chapter 2 of <em>On Liberty</em></a> <a href="#fnref:liberty" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:credit" role="doc-endnote"> <p>Credit where credit is due: In addition to Mill &amp; Paine, many of the ideas in this post come from <a href="">a speech by Christopher Hitchens</a>. <a href="#fnref:credit" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div> Grandfathered In 2017-09-19T02:36:14-07:00 <p>A useful way to recognize <a href="">status quo bias</a> is to ask, “What things wouldn’t be allowed if they were introduced today?” Here are some examples.</p> <h2 id="drugs">Drugs</h2> <p>The obvious ones: alcohol and tobacco. These are highly addictive and clearly harmful. Tobacco is responsible for ≈20% of premature deaths in the US.<sup id="fnref:tobacco" role="doc-noteref"><a href="#fn:tobacco" class="footnote" rel="footnote">1</a></sup> Alcohol is responsible for 10% of working-age deaths.<sup id="fnref:alcohol" role="doc-noteref"><a href="#fn:alcohol" class="footnote" rel="footnote">2</a></sup> Had these substances been discovered today, is there any doubt that authorities would crack down on them mercilessly? Is there any doubt that they would have the public’s full support? Our society has gone berserk over far less harmful substances. The reason these drugs are legal is <a href="">path dependence</a>.</p> <p>I’m not even sure if caffeine would be legal. <a href="">It’s addictive</a>, and people <a href="">regularly overdose on it</a>. If not for the centuries-old culture of cafés, it could easily have become a party drug.</p> <!-- prescription only: most over-the-counter medications (cough syrup, tylenol) --> <p>(Note: I am not saying it’s a good idea to ban these drugs, just that they would be banned if invented today.)</p> <h2 id="transportation">Transportation</h2> <p>Several forms of transportation would likely be restricted. Motorcycles are right out. They’re dangerous, noisy, and fueled by a carcinogenic, flammable liquid. It’s hard to convey just how hazardous motorcycles are. According to Wikipedia<sup id="fnref:motorcycle" role="doc-noteref"><a href="#fn:motorcycle" class="footnote" rel="footnote">3</a></sup>:</p> <blockquote> <p>Per vehicle mile traveled, motorcyclists’ risk of a fatal crash is 35 times greater than a passenger car.</p> </blockquote> <p>In the US, the fatality rate for motorcycles is 23 per 100 million miles traveled. Assuming a typical rider travels 4,000 miles per year and rides for 40 years, that amounts to a 4% chance of death. That’s only the risk of <em>death</em>. The chance of crippling injury or brain damage is likely higher.</p> <p><a href="">General aviation</a> (that is, private planes) would never be allowed today. Consider how society has reacted to drones. Now imagine drones were 50 times heavier and ran on leaded gasoline. Who would ever permit such machines to fly above their homes? Apparently we would, because they’re called Cessnas.</p> <h2 id="food">Food</h2> <p>Meat would certainly be banned, as it runs afoul of every animal cruelty law. Raising animals for slaughter would be as despised (and as illegal) as dog fighting. Even if meat caused no suffering, it would still be banned due to health concerns. Every year in the US, meat-borne diseases sicken millions and kill around 5,000 people.<sup id="fnref:meat" role="doc-noteref"><a href="#fn:meat" class="footnote" rel="footnote">4</a></sup> Had the same rate of illness and death come from Soylent, there would be class-action lawsuits and congressional hearings. People would ask, “How could the FDA let this happen?”</p> <p>Some plants might be stricken from the menu. Today’s produce is the result of selective breeding… or worse. Most grapefruits in your supermarket have radioactive ancestors, courtesy of <a href="">atomic gardening</a>. The changes made in GMOs are far more precise and limited in scope, yet most Americans are wary of ingesting such carefully-crafted organisms. We prefer to play it safe and deal with plants like lemons and celery, which can <a href="">cause chemical burns (warning: graphic images)</a>.</p> <p>Speaking of selective breeding: What about pets? Many dogs suffer from the traits bred into them. Examples include <a href="">Pugs</a>, <a href="">Bulldogs</a>, and <a href="">Shih Tzus</a>. Had these breeds been created today through genetic engineering, the public would be outraged.</p> <h2 id="fluoridation">Fluoridation</h2> <p>Could water fluoridation could happen today? I don’t think so. Too many people would express worry and doubt. Some would ask, “What if fluoride has long-term health consequences?” Others would claim that fluoride causes autism. There would be enough controversy and protest that I doubt any municipality would fluoridate their water. At best it would be like vaccination, with most parents giving fluoride supplements to their children.</p> <!-- Paper money. --> <!-- subwoofers? --> <h2 id="conclusion">Conclusion</h2> <p>These are just a few examples. I can go on, though I’ll spare myself the effort of going into detail. A lot of fun things are just plain dangerous: fireworks, mountaineering, football, boxing, surfing, auto racing. These all reliably kill and cripple people while serving no purpose other than entertainment. I doubt half of them would remain legal if introduced today.</p> <p>Again, I am not saying these things should be banned or restricted. I enjoy alcohol, caffeine, and fireworks (occasionally all at once). I wanted to show how society’s standards have changed so I could make another point: Had the past been as risk-averse as the present, would we be better off? I don’t think so. Does that mean we should we be more enthusiastic about allowing new inventions? Probably.</p> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:tobacco" role="doc-endnote"> <p><a href="">CDC: Smoking &amp; Tobacco Use</a> <a href="#fnref:tobacco" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:alcohol" role="doc-endnote"> <p><a href="">CDC: Alcohol Deaths</a> <a href="#fnref:alcohol" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:motorcycle" role="doc-endnote"> <p><a href="">Wikipedia: Motorcycle Safety</a> <a href="#fnref:motorcycle" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:meat" role="doc-endnote"> <p><a href="">CDC: Food-Related Illness and Death in the United States</a> <a href="#fnref:meat" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div> Thinkpad X62 2017-07-16T22:26:25-07:00 <p>Back in January, I <a href="/2017/01/23/oldest-viable-laptop/">used an old Thinkpad</a> while my <a href="/2015/04/19/2015-macbook-review/">12” Macbook</a> was being repaired. I found myself really enjoying some aspects of it. This nudged me down a path that ended with me modding a frankenpad built by some enthusiasts in Shenzhen.</p> <p>Using my old X61s left me frustrated with current laptops. Sure, the X61s was old and slow, but that was to be expected. What I didn’t expect was just how much laptops have regressed. Chiclet-style keyboards are abysmal compared to the keyboard on the X61s. I forgot how much I preferred 4:3 screens for work. Title bars and tabs tend to consume vertical space, which 4:3 screens have plenty of. The X61s screen was dim, but I fixed that with an <a href="">LED backlight conversion kit</a>.</p> <p style="text-align: center; font-size: 80%;"> <a href="/photos/x62/DSC_2305.JPG"><img alt="Dear Lenovo: Please bring back the classic keyboard" src="/photos/x62/DSC_2305.JPG" /></a> <br /> Dear Lenovo: Please bring back this classic keyboard </p> <p>Some features were nice to have, but not particularly compelling: I liked the form factor, though it was a bit thick. The removable battery came in handy a few times. And I enjoyed little details like the latching lid and thin bezel.</p> <p>Of course, some aspects of the X61s were embarassing by modern standards. The screen resolution was only 1024×768, and not <a href="">IPS</a>, meaning colors changed with viewing angle. The VGA-out restricted possibilities for external displays. Performance and battery life were… less than ideal. Even a maxxed-out machine (1.8GHz Core 2 Duo, 8GB of RAM, SATAII SSD) was a little sluggish for work.</p> <p>Despite its shortcomings, I ended up using the X61s more than my 12” MacBook. The X61s convinced me that a much better laptop could exist. The same chassis with modern components would be a very compelling product.</p> <h3 id="the-x62">The X62</h3> <p>In the quest for something better, I stumbled upon the X62. This “model” isn’t made by Lenovo. It’s the product of <a href="">51NB</a>, a group of enthusiasts in Shenzhen. The X62 is an X61 chassis but with:</p> <ul> <li>A 12” 1400×1050 IPS LCD (likely salvaged from an X60 tablet).</li> <li>An Intel <a href="">Core i7-5600U</a> (Broadwell. Dual core. Turbo boost up to 3.2GHz.)</li> <li>Up to 32GB of RAM.</li> <li>Mini DisplayPort &amp; mini-HDMI out.</li> <li>802.11ac, Bluetooth 4, USB 3, SD card reader, Gigabit Ethernet.</li> <li>SATA3 &amp; mSATA.</li> </ul> <p>I ordered one back in March and received it in June. As with the X61s, I replaced the backlight with an LED kit. This improved battery life and brought the screen brightness from 160 nits to over 600. The backlight mod took hours, as it involved disassembling most of the laptop.</p> <p><img src="/photos/x62/IMG_1163.jpg" alt="ThinkPad X62 disassembled. I'm so glad I only have to do this once." /></p> <p>You can see more pictures of the process <a href="/photos/x62">here</a>.</p> <h3 id="linux">Linux</h3> <p>Ubuntu 17.04 worked out of the box, but there was one annoyance: battery life. For some reason, the laptop was using 10 watts at idle. Thanks to <a href="">some forum posts</a>, I managed to tweak various kernel module options and got idle down to 4 watts. This drastically improved battery life. I then put together a script to enable power savings on startup. These tweaks should benefit most Linux users on modern Intel hardware:</p> <figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c">#!/bin/sh</span> <span class="c"># Disable the NMI watchdog</span> <span class="nb">echo</span> <span class="s1">'0'</span> <span class="o">&gt;</span> <span class="s1">'/proc/sys/kernel/nmi_watchdog'</span><span class="p">;</span> <span class="c"># Runtime power management for I2C devices</span> <span class="k">for </span>i <span class="k">in</span> /sys/bus/i2c/devices/<span class="k">*</span>/device/power/control <span class="p">;</span> <span class="k">do </span><span class="nb">echo </span>auto <span class="o">&gt;</span> <span class="k">${</span><span class="nv">i</span><span class="k">}</span> <span class="k">done</span> <span class="c"># Runtime power-management for PCI devices</span> <span class="k">for </span>i <span class="k">in</span> /sys/bus/pci/devices/<span class="k">*</span>/power/control <span class="p">;</span> <span class="k">do </span><span class="nb">echo </span>auto <span class="o">&gt;</span> <span class="k">${</span><span class="nv">i</span><span class="k">}</span> <span class="k">done</span> <span class="c"># Runtime power-management for USB devices</span> <span class="k">for </span>i <span class="k">in</span> /sys/bus/usb/devices/<span class="k">*</span>/power/control <span class="p">;</span> <span class="k">do </span><span class="nb">echo </span>auto <span class="o">&gt;</span> <span class="k">${</span><span class="nv">i</span><span class="k">}</span> <span class="k">done</span> <span class="c"># Low power SATA</span> <span class="k">for </span>i <span class="k">in</span> /sys/class/scsi_host/<span class="k">*</span>/link_power_management_policy <span class="p">;</span> <span class="k">do </span><span class="nb">echo </span>min_power <span class="o">&gt;</span> <span class="k">${</span><span class="nv">i</span><span class="k">}</span> <span class="k">done</span> <span class="c"># Disable Wake-on-LAN on ethernet port</span> ethtool <span class="nt">-s</span> wlan0 wol d<span class="p">;</span> ethtool <span class="nt">-s</span> eth0 wol d <span class="c">#Enable Audio codec power management</span> <span class="nb">echo</span> <span class="s1">'1'</span> <span class="o">&gt;</span> <span class="s1">'/sys/module/snd_hda_intel/parameters/power_save'</span><span class="p">;</span> <span class="c"># Low power wireless</span> iw dev wlan0 <span class="nb">set </span>power_save on</code></pre></figure> <p>I also had to use Realtek’s driver for the ethernet controller, as the default one wasted power. A <code class="language-plaintext highlighter-rouge">sudo apt install r8168-dkms</code> and a module blacklist later, I was in business. With these tweaks, my X62 idles in power state PC6. It’s possible to go lower, but I’m content with the current battery life.</p> <p>I wish Linux had better defaults, but this sort of thing is to be expected when it comes to open source software.</p> <h2 id="conclusion">Conclusion</h2> <p><a href="/photos/x62/DSC_2304.JPG"><img src="/photos/x62/DSC_2304.JPG" alt="ThinkPad X62" /></a></p> <p>The X62 is a niche product, but it really scratches an itch for me. There’s no other way to get a 4:3 matte screen, a great keyboard, and modern performance. My MacBook has become my secondary laptop. I’ve only taken it out of the house once since I got the X62, and that was for my Oregon bikepacking trip.</p> <p>Update: <a href="/2019/03/04/thinkpad-x210/">I’ve upgraded to an X210</a>, which is an X201s with better specs than the X62.</p> GNOME Terminal Antialiasing Saga 2017-06-14T19:49:46-07:00 <p><a href="/2016/08/26/gnome-terminal-cursor-blinking-saga/">Previously</a>.</p> <p>On lower-DPI displays, <a href="/2013/12/24/programming-fonts/">I like to use bitmap fonts</a> in my terminals and text editors. I was surprised to see that Gnome Terminal still <a href="">antialiased</a> and <a href="">hinted</a> my bitmap font:</p> <div style="text-align: center;"> <img alt="Gnome terminal making stuff blurry" src="/images/Screenshot from 2017-06-11 20-04-00.png" style="width: 471px; height: 239px;" /> </div> <p>Here’s a close-up:</p> <div style="text-align: center;"> <img alt="Enlargement of antialiasing" src="/images/Screenshot from 2017-06-11 20-04-00-crop.png" style="width: 450px; height: 135px; image-rendering: pixelated;" /> </div> <p>The red text is obvious, but you can also see tinges of blue and red on the white text. Not pretty.</p> <p>Other platforms make it easy to get the desired behavior. Both and PuTTY have checkboxes to disable antialiasing and subpixel hinting. But (as anyone familiar with Gnome would expect) Gnome Terminal has no GUI setting to change this.</p> <p>To solve the problem, I delved into <a href="">fontconfig</a>. My goal was to disable antialiasing for just one font. I created <code class="language-plaintext highlighter-rouge">~/.fonts.conf</code> and filled it with some guesses based on docs and related Stack Overflow answers:</p> <figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version='1.0'?&gt;</span> <span class="cp">&lt;!DOCTYPE fontconfig SYSTEM 'fonts.dtd'&gt;</span> <span class="nt">&lt;fontconfig&gt;</span> <span class="nt">&lt;match</span> <span class="na">target=</span><span class="s">"pattern"</span><span class="nt">&gt;</span> <span class="nt">&lt;test</span> <span class="na">name=</span><span class="s">"family"</span><span class="nt">&gt;</span> <span class="nt">&lt;string&gt;</span>ProggyTinyTTSZ<span class="nt">&lt;/string&gt;</span> <span class="nt">&lt;/test&gt;</span> <span class="nt">&lt;edit</span> <span class="na">mode=</span><span class="s">"assign"</span> <span class="na">name=</span><span class="s">"antialias"</span><span class="nt">&gt;</span> <span class="nt">&lt;bool&gt;</span>false<span class="nt">&lt;/bool&gt;</span> <span class="nt">&lt;/edit&gt;</span> <span class="nt">&lt;edit</span> <span class="na">mode=</span><span class="s">"assign"</span> <span class="na">name=</span><span class="s">"hinting"</span><span class="nt">&gt;</span> <span class="nt">&lt;bool&gt;</span>false<span class="nt">&lt;/bool&gt;</span> <span class="nt">&lt;/edit&gt;</span> <span class="nt">&lt;/match&gt;</span> <span class="nt">&lt;/fontconfig&gt;</span></code></pre></figure> <p>This had no effect. I re-read some fontconfig docs and noticed that <code class="language-plaintext highlighter-rouge">~/.fonts.conf</code> had been deprecated for a new config path: <code class="language-plaintext highlighter-rouge">~/.config/fontconfig/fonts.conf</code>. I moved the config file. Still no change.</p> <p>After reading <em>more</em> fontconfig docs, I found out about <code class="language-plaintext highlighter-rouge">FC_DEBUG</code>:</p> <blockquote> <p>To help diagnose font and applications problems, fontconfig is built with a large amount of internal debugging left enabled. It is controlled by means of the FC_DEBUG environment variable.</p> </blockquote> <p>Surely, debug logging would give me some clues. Naturally, this variable wasn’t just a boolean:</p> <blockquote> <p>The value of this variable is interpreted as a number, and each bit within that value controls different debugging messages.</p> </blockquote> <p>I tried setting <code class="language-plaintext highlighter-rouge">FC_DEBUG</code> to 35 (0b0100011), corresponding to verbose info for caching &amp; matching. It turns out that verbose logging lives up to its name:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ggreer@zinc:~% FC_DEBUG=35 fc-match -v ProggyTinyTTSZ family antialias hinting file | wc -l 29771 </code></pre></div></div> <p>That’s right: almost 30,000 lines of debug logs— almost as useless as no logs. I played with other values, eventually settling on <code class="language-plaintext highlighter-rouge">FC_DEBUG=4</code>. That generated “only” 5,000 lines and seemed to contain some useful clues.</p> <p>The first thing I noticed when scouring the debug logs was that many settings were being processed after my user config. I traced this down to the order of config files in <code class="language-plaintext highlighter-rouge">/etc/fonts/conf.d/</code>. The rule to load user configs was in the middle, not at the last thing done. To ensure no global config was overriding my directives, I ran <code class="language-plaintext highlighter-rouge">sudo mv 50-user.conf 99-user.conf</code>. Debug logs then confirmed that my rules were run last.</p> <p>Still, I saw blurry text.</p> <p>At this point, I’d been at it for almost two hours. I was getting pretty frustrated. With nothing better coming to mind, I stared at my XML. I tediously compared it against examples in the fontconfig docs. I saw one suspicious line: I was using <code class="language-plaintext highlighter-rouge">&lt;match target="pattern"&gt;</code>, while many examples used <code class="language-plaintext highlighter-rouge">&lt;match target="font"&gt;</code>. I changed the target attribute from “pattern” to “font”:</p> <figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version='1.0'?&gt;</span> <span class="cp">&lt;!DOCTYPE fontconfig SYSTEM 'fonts.dtd'&gt;</span> <span class="nt">&lt;fontconfig&gt;</span> <span class="nt">&lt;match</span> <span class="na">target=</span><span class="s">"font"</span><span class="nt">&gt;</span> <span class="nt">&lt;test</span> <span class="na">name=</span><span class="s">"family"</span> <span class="na">qual=</span><span class="s">"any"</span> <span class="na">compare=</span><span class="s">"eq"</span><span class="nt">&gt;</span> <span class="nt">&lt;string&gt;</span>ProggyTinyTTSZ<span class="nt">&lt;/string&gt;</span> <span class="nt">&lt;/test&gt;</span> <span class="nt">&lt;edit</span> <span class="na">mode=</span><span class="s">"assign"</span> <span class="na">name=</span><span class="s">"antialias"</span><span class="nt">&gt;</span> <span class="nt">&lt;bool&gt;</span>false<span class="nt">&lt;/bool&gt;</span> <span class="nt">&lt;/edit&gt;</span> <span class="nt">&lt;edit</span> <span class="na">mode=</span><span class="s">"assign"</span> <span class="na">name=</span><span class="s">"hinting"</span><span class="nt">&gt;</span> <span class="nt">&lt;bool&gt;</span>false<span class="nt">&lt;/bool&gt;</span> <span class="nt">&lt;/edit&gt;</span> <span class="nt">&lt;/match&gt;</span> <span class="nt">&lt;/fontconfig&gt;</span></code></pre></figure> <p>…and was at last rewarded with pixel-perfect text:</p> <div style="text-align: center;"> <img alt="Gnome terminal with correctly rendered fonts" src="/images/Screenshot from 2017-06-11 20-02-44.png" style="width: 471px; height: 239px;" /> </div> <p>A close-up:</p> <div style="text-align: center;"> <img alt="Enlargement of no antialiasing" src="/images/Screenshot from 2017-06-11 20-02-44-crop.png" style="width: 450px; height: 135px; image-rendering: pixelated;" /> </div> <p>Finally!</p> <p>This is yet more evidence of how ridiculously hostile Gnome is to users. I’m no novice, but it took me two hours to accomplish what takes two seconds on every other platform. What a waste.</p> Software Rot 2017-02-28T17:59:53-08:00 <p>In his book <a href="/2016/07/23/age-of-em/"><em>Age of Em: Work, Love and Life when Robots Rule the Earth</em></a>, Robin Hanson briefly discusses software rot:</p> <blockquote> <p>As software that was designed to match one set of tasks, tools, and situations is slowly changed to deal with a steady stream of new tasks, tools, and situations, such software becomes more complex, fragile, and more difficult to usefully change (Lehman and Belady 1985)<sup id="fnref:Lehman" role="doc-noteref"><a href="#fn:Lehman" class="footnote" rel="footnote">1</a></sup>. Eventually it is better to start over and write whole new subsystems, and sometimes whole new systems, from scratch.</p> </blockquote> <p>I’m pretty sure this is true. Adapting mature software to new circumstances tends to take more time and effort than writing new software from scratch. Software people don’t like to admit this, but the evidence is clear. Open source software has several high-profile examples.</p> <h2 id="multi-process-firefox">Multi-process Firefox</h2> <p>When it was first written, <a href="">Mozilla Firefox</a> ran everything in a single process. After the release of <a href="">Google Chrome</a>, it was clear that a multi-process model allowed for better security and performance. Mozilla developers soon started planning to make Firefox multi-process. That was in 2007.</p> <p>Almost a decade later, Mozilla finally <a href="">began rollout of multi-process Firefox</a>. This delay is not for want of trying. The teams at Mozilla are talented and driven. Still, Chrome was written from scratch in far less time than it has taken Firefox to change. There are two main reasons for this:</p> <ul> <li>Making a single process architecture multi-process means changing a <em>lot</em> of small things. Certain function calls have to be replaced with inter-process communication. Shared state must be wrapped in mutexes. Caches and local databases must handle concurrent access.</li> <li>Firefox needed to remain compatible with existing add-ons (or force devs to update their add-ons). Chrome got to create an extention API from scratch, avoiding such constraints.</li> </ul> <p>It gets worse. These constraints are at odds with each other: Overhaul the internal architecture, but alter public-facing APIs as little as possible. It’s no wonder Mozilla needed 10 years to accomplish this feat.</p> <h2 id="event-driven-apache">Event-driven Apache</h2> <p>When <a href="">Apache httpd</a> was first written, it used a process-per-connection model. One process would listen on port 80, then <code class="language-plaintext highlighter-rouge">accept()</code> and <code class="language-plaintext highlighter-rouge">fork()</code>. The child process would then <code class="language-plaintext highlighter-rouge">read()</code> and <code class="language-plaintext highlighter-rouge">write()</code> on the socket. When the request was finished, the child would <code class="language-plaintext highlighter-rouge">close()</code> the socket and <code class="language-plaintext highlighter-rouge">exit()</code>.</p> <p>This architecture had the advantage of being simple, easy to implement on many platforms, and… not much else. It was absolutely terrible for performance, especially when handling long-lived connections. To be fair: this <em>was</em> 1995. And Apache soon moved to a threaded model, which did help performance. Still, it couldn’t handle <a href="">10,000 simultaneous connections</a>. A connection-per-thread architecture takes 1,000 threads to service 1,000 concurrent connections. Each thread has its own stack and state, and must be scheduled by the operating system. It makes for a bad time.</p> <p>In contrast, <a href="">Nginx</a> used a <a href="">reactor pattern</a> from the start. This allowed it to handle more concurrent connections and rendered it immune to <a href="">slowloris attacks</a>.</p> <p>Nginx was first released in 2007, and its performance advantage was apparent. Years before the release of Nginx, the Apache devs had begun re-architecting httpd to perform better. The <a href="">event MPM</a> shipped with Apache 2.2 in 2005. Still, there were teething issues. Most importantly, the event MPM broke compatibility with popular modules like mod_php. It wasn’t until 2012 that Apache 2.4 shipped with it as the default.<sup id="fnref:httpd" role="doc-noteref"><a href="#fn:httpd" class="footnote" rel="footnote">2</a></sup> While far better than the previous <a href="">prefork</a> and <a href="">worker MPM</a>s, the worker MPM didn’t acheive parity with Nginx. Instead, it used separate thread pools for listening/accepting connections and processing requests. The architecture is roughly equivalent to running a load balancer or reverse proxy in front of a worker MPM httpd.<sup id="fnref:httpd2" role="doc-noteref"><a href="#fn:httpd2" class="footnote" rel="footnote">3</a></sup></p> <h2 id="cpython-gil">CPython GIL</h2> <p>Python is a nice programming language. It’s expressive, easy to learn (at least as programming languages go), and it’s supported on a wide variety of platforms. But for the past two decades, the most popular implementation of Python has had one major problem: it can’t easily take advantage of multiple CPU cores.</p> <p>The cause of Python’s lack of parallelism is its global interpreter lock, or GIL. From <a href="">the Python wiki</a>:</p> <blockquote> <p>In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)</p> </blockquote> <p>Originally, the GIL wasn’t a big deal. When Python was created, multi-core systems were rare. And a GIL is simple to write and easy to reason about. But today, even wristwatches have multi-core CPUs. The GIL is an obvious and glaring defect in what is otherwise a pleasant language. Despite CPython’s popularity, despite the project’s capable developers, despite sponsors such as Google, Microsoft, and Intel, <a href="">fixing the GIL isn’t even on the roadmap</a>.</p> <h2 id="conclusion">Conclusion</h2> <p>Even when given talented engineers, plenty of money, and clear vision, mature software can be extremely difficult to change. I tried to find cases that disproved software rot, but they don’t seem to exist. Robin Hanson <a href="">asked for counterexamples</a> and nobody came up with anything convincing. There are plenty of old software projects, but they haven’t had to adapt much. I’d love to find good counterexamples, as the current evidence paints a bleak picture for the long-term future of software.</p> <hr /> <h3 id="read-more">Read more</h3> <ul> <li><a href="">Overcoming Bias: Why Does Software Rot?</a></li> <li><a href="">Suprise: Software rots!</a></li> <li><a href="">Wikipedia: Software rot</a></li> </ul> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:Lehman" role="doc-endnote"> <p>The cite is for a text called <em>Program Evolution: Processes of Software Change</em>. The work is older than me, and I can’t find an online version. I bought a physical copy and have been slowly making my way through it. The terminology is odd, but the conclusions haven’t been particularly surprising. <a href="#fnref:Lehman" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:httpd" role="doc-endnote"> <p>The original version of this blog post contained some misapprehensions about the timeline. Thanks goes to <a href="">Paul Querna</a> for correcting them. <a href="#fnref:httpd" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:httpd2" role="doc-endnote"> <p>Anyone who knows about httpd’s internals will take issue with this sentence. The comparison sacrifices accuracy for brevity. I apologize. <a href="#fnref:httpd2" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div> Oldest Viable Laptop 2017-01-23T18:04:30-08:00 <p>What’s the oldest laptop you could reasonably do your job with? 3 years old? 5 years? 10? And if asked the same question 10 years ago, would your number be higher or lower? Thanks to a failing battery in <a href="/2015/04/19/2015-macbook-review/">my 12” MacBook</a>, I discovered my answer.</p> <p>For the 10 days it took to repair my MacBook, I had to use my backup laptop:</p> <p><img src="/photos/pics/thinkpad_x61s.jpg" alt="ThinkPad X61s" /></p> <p>This is a <a href="">ThinkPad X61s</a>. Despite being made in 2007, it’s been fine for work. Yes, everything about it is worse than my MacBook. It’s slower and heavier. It lacks a trackpad. The screen is a mere 1024×768, causing some websites to show their mobile layout.<sup id="fnref:font" role="doc-noteref"><a href="#fn:font" class="footnote" rel="footnote">1</a></sup> Still, the experience has been significantly better than I predicted. The only major hardware drawback is the lack of video camera. The main sources of frustration have been software. Ubuntu 16.04 doesn’t have a built-in dictionary or thesaurus. The default calendar app is a joke. <del>And Thunderbird doesn’t have a unified inbox view.</del> (Edit: <a href="">It does</a>. Thanks To Brendan Long for pointing this out.)</p> <p>Had a similar circumstance happened 10 years ago, my oldest viable laptop would not be so old. That is to say: There’s no way that in 2007, I’d be able to get by with a laptop from 1997. The performance issues would be insurmountable.</p> <p>Growing up, I never thought I’d be able to use decade-old hardware without issue. Either laptop improvements are well into diminishing returns, or progress in hardware has stagnated, or both.</p> <p>Update: It’s been two weeks since I got my MacBook back, and I still tend to use my ThinkPad more. I’m not sure if I’ll stick with it, but there’s something about this machine that causes me to favor it.</p> <p>Update (6 months later): I bought a <a href="/2017/07/16/thinkpad-x62/">Thinkpad X62</a>, which is an X61 with modern internals.</p> <p>Update (2 years later): <a href="/2019/03/04/thinkpad-x210/">I’ve upgraded to an X210</a>, which is an X201s with better specs than the X62.</p> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:font" role="doc-endnote"> <p>My terminal and editor windows had plenty of space thanks to <a href="/2013/12/24/programming-fonts/">pixel-perfect programming fonts</a>. <a href="#fnref:font" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div> Ag & Ripgrep: .ignore 2016-09-26T14:12:57-07:00 <p>A few days ago, <a href="">Andrew Gallant</a> (AKA BurntSushi) released <a href="">ripgrep</a>, a search tool similar to to <a href="/ag">ag</a>. To coincide with the initial release, Gallant wrote <a href="">a blog post comparing various search tools</a>. In it, he discusses both the advantages and shortcomings of a half-dozen tools, including ag. He finds bugs, pathological performance cases, and unexpected ways in which these tools can be sped-up. If the topic even remotely interests you, read Gallant’s blog post.</p> <p>When Gallant’s post <a href="">was discussed on Hacker News</a>, I <a href="">replied</a> with my thoughts. This spurred a pleasant and productive discussion. I noticed that both of our tools had ignore files (<code class="language-plaintext highlighter-rouge">.agignore</code> and <code class="language-plaintext highlighter-rouge">.rgignore</code>), so <a href="">I suggested we converge on a common name and format</a>. We quickly agreed on <code class="language-plaintext highlighter-rouge">.ignore</code> (surprisingly, it wasn’t taken). Within a couple of hours, both of us had added the feature into our respective projects.<sup id="fnref:ag" role="doc-noteref"><a href="#fn:ag" class="footnote" rel="footnote">1</a></sup><sup id="fnref:rg" role="doc-noteref"><a href="#fn:rg" class="footnote" rel="footnote">2</a></sup> The author of <a href="">sift</a> also <a href="">seems to be on board</a>.</p> <p>Support for <code class="language-plaintext highlighter-rouge">.ignore</code> files is in ag v0.33.0 and later. If you have <code class="language-plaintext highlighter-rouge">.agignore</code> files, don’t worry. You’ll have plenty of time to rename them. It will be at least six months before I deprecate them, and probably a year before they’re no longer read.</p> <p>The whole experience was positive for everyone involved. Andrew and I had an enjoyable exchange. Users of our tools were saved some trouble. And there’s a decent chance that more software will support the same <code class="language-plaintext highlighter-rouge">.ignore</code> standard. I’m happy to have played a part in creating this small gem of collaboration.</p> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:ag" role="doc-endnote"> <p><a href="">Ag pull request #974: Prefer .ignore to .agignore</a> <a href="#fnref:ag" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:rg" role="doc-endnote"> <p><a href="">Ripgrep pull request #41: Switch from .rgignore to .ignore</a> <a href="#fnref:rg" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div> GNOME Terminal Cursor Blinking Saga 2016-08-26T20:51:37-07:00 <p>When setting up a new computer, one of the first things I do is disable cursor blinking in the terminal. For the past decade, the Gnome team has worked diligently to make this as hard as possible.</p> <div style="text-align: center;"> <img alt="On. Off. On. Off. On. Off..." src="/images/gnome_terminal_cursor_blinking.gif" /> </div> <p>The story begins in 2006. Back then, Gnome Terminal had a checkbox in its settings. Here’s a screenshot from Ubuntu 6.06:</p> <p><img src="/images/gnome_terminal_ubuntu_6.png" alt="GNOME Terminal Settings in Ubuntu 6.06" /></p> <p>Unchecking “Cursor blinks” would stop the cursor from blinking. It was simple and accessible; exactly the kind of UI that has no place in a Gnome project. Some developers soon decided to “simplify” things by going, “…on a quest to remove all annoying tiny little bits in GNOME’s UI.” Instead of having a checkbox, they wanted the terminal to obey the global system setting (for cursors in text editors, browser URL bars, etc). Hence <a href="">Bug 342921 - Cursor blinking preference should follow system defaults</a>. The checkbox was removed in Gnome v2.22, meaning that the only way to disable blinking was to turn it off in the entire Gnome UI. This annoyed many people, as a giant blinking block is far more prominent than a thin blinking line. Users quickly responded. They created issues such as <a href="">Bug 533522 - Alllow override of system blink preference</a> and <a href="">Bug 534207 - Something to fix the cursor blinking problem soon</a>. Gnome was going through a UI freeze at the time, so the “fix” was to create a gconf setting. Now to disable terminal blinking, you had to run:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gconftool-2 --set "/apps/gnome-terminal/profiles/Default/cursor_blink" \ --type boolean "False" </code></pre></div></div> <p>Good luck figuring that out on your own. Fortunately, the magic invocation was quickly documented on sites such as Stack Overflow. It even made its way to <a href="">a page dedicated to stopping cursor blinks</a>. Things stayed that way for five years.</p> <p>Then Gnome 3 came out.</p> <p>The old magic invocation no longer appeased the Gnome gods. This issue was created: <a href="">Bug 702901 - Disabling blinking cursor not working</a>. The reason for the breakage was twofold. First: Gnome switched from gconf to dconf. Second: Gnome devs changed the config schema for terminal settings. In Gnome 2, each terminal profile was stored by name. This allowed for paths like <code class="language-plaintext highlighter-rouge">/profiles/Default/</code> to work across systems. Gnome 3 stored profiles by UUID. Since UUIDs tend to be rather <em>unique</em>, there isn’t a standard default key. One first has to get the UUID of the default profile, then set the appropriate key under it. Like so:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>% gsettings get org.gnome.Terminal.ProfilesList default 'b1dcc9dd-5262-4d8d-a863-c897e6d979b9' % gsettings set org.gnome.Terminal.Legacy.Profile:/org/gnome/terminal/legacy/profiles:/:b1dcc9dd-5262-4d8d-a863-c897e6d979b9/ cursor-blink-mode off % </code></pre></div></div> <p>To make it a one-liner, you have to use a subshell:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gsettings set org.gnome.Terminal.Legacy.Profile:/org/gnome/terminal/legacy/profiles:/:$(gsettings get org.gnome.Terminal.ProfilesList default | tr -d \')/ cursor-blink-mode off </code></pre></div></div> <p>Annoyingly, this information isn’t in Gnome’s answer to <a href=";redirect=Terminal%2FFAQ#How_can_I_stop_the_cursor_from_blinking.3F">How can I stop the cursor from blinking?</a>. Instead, they link to another answer, which contains this gem:</p> <blockquote> <p>Unfortunately, the gsettings tool can’t currently autocomplete the key names with relocatable schemas (that’s <a href="">this bug</a>), but you can just <a href="">read the schema itself</a>.</p> </blockquote> <p>I cannot recall encountering a more user-hostile experience. How many people are going to read a <em>700 line XML file</em> to tweak their terminal? It’s absurd. There are two possible explanations for such a terrible experience: Either the Gnome developers are indifferent to their users, or they are incompetent. Actually, it could be worse. It could be both.</p> <h3 id="conclusion">Conclusion</h3> <p>The issue to re-add the blink checkbox still exists: <a href="">Bug 559990 - Add UI for the cursor blink preference</a>. I doubt it will be fixed any time soon. In case you were curious: OS X has a non-blinking cursor by default. Changing it requires checking a box in the settings menu:</p> <p><img src="/images/Screen Shot 2016-08-29 at 18.35.49.png" alt="OS X settings" /></p> <p>…just like Gnome had 10 years ago.</p> <p>Desktop Linux is fraught with these sorts of issues. The only reason I use it is because I need to test software on the platform. If not for that, I doubt I’d ever touch a Linux GUI again.</p> <p>Update: <a href="/2017/06/14/gnome-terminal-antialiasing-saga/">the saga continues</a>.</p> <p>Update 2: As of v3.32.1, Gnome terminal has an option to disable cursor blinking.</p> <p><img src="/images/Screenshot from 2019-05-28 08-38-42.png" alt="GNOME Terminal now with option to disable blinking" /></p> Age of Em 2016-07-23T11:21:48-07:00 <p>Back in June, I read <a href="">Robin Hanson</a>’s book: <a href=""><em>Age of Em: Work, Love and Life when Robots Rule the Earth</em></a>. I found it fascinating. Two months later, the book’s ideas still pop into my mind daily. Nothing else I’ve read in the past year has done that. This post is a summary of the core ideas in <em>Age of Em</em>, followed by my observations and critiques.</p> <h2 id="the-author">The Author</h2> <blockquote> <p>I expect my analysis to be relevant for a large cloud of different but similar scenarios. In particular, conditional on my key assumptions, I expect at least 30% of future situations to be usefully informed by my analysis. Unconditionally, I expect at least 10%.<br /> – Robin Hanson, <em>Age of Em</em></p> </blockquote> <p>Let me make my bias known: I am a fan of Robin Hanson. He possesses a rare combination of intelligence, expertise, creativity, and civility. Moreover, he makes exceptional use of these gifts. Hanson looks at the big picture– the <em>really</em> big picture. For example: When examining <a href="">the growth of humanity over millions of years</a>, the invention of writing is a rounding error. At such a high-level view, all of human history can be described by three eras of growth<sup id="fnref:eras" role="doc-noteref"><a href="#fn:eras" class="footnote" rel="footnote">1</a></sup>:</p> <ol> <li>2,000,000 BC to 5,000 BC: Foraging, in which population doubled every 250,000 years.</li> <li>5,000 BC to 1600 AD: Farming, in which population doubled every 1,000 years.</li> <li>1600 AD to present: Industry, in which GDP doubled every 15 years.</li> </ol> <p>These numbers are approximate, of course. Hanson also notes that each transition to the next era took less than a doubling time of the previous era. E.g. industry replaced farming as the dominant growth mode in less than the doubling time of farming (1,000 years).</p> <p>If one extrapolates the numerological trend (admittedly, an absurdly weak argument), the next era after ours would have an economic doubling time on the order of months or weeks. This sounds crazy. How could a 200x speedup in economic growth <em>possibly</em> happen? What would such a world look like? <em>Age of Em</em> is Hanson’s attempt to answer these questions.</p> <h2 id="the-idea">The Idea</h2> <p>Today, economic growth is bottlenecked by people. Machines can be mass-produced, but people take decades to mature and learn skills. It’s possible to make more machines per worker, but one quickly runs into diminishing returns. Someone with 10 laptops or 10 bulldozers won’t be 10x as productive.<sup id="fnref:bottleneck" role="doc-noteref"><a href="#fn:bottleneck" class="footnote" rel="footnote">2</a></sup> To speed-up economic growth by 200x, the bottleneck must be removed. Something must substitute for human intelligence.</p> <p>When considering substitutes for human intelligence, most people’s thoughts turn to artificial intelligence. But Hanson is pessimistic about the arrival of de-novo AI. He thinks it is more likely that <a href="">brain emulations</a> will come first.<sup id="fnref:ai" role="doc-noteref"><a href="#fn:ai" class="footnote" rel="footnote">3</a></sup> (The “em” in <em>Age of Em</em> is short for “emulation”.) Creating such ems requires three key technologies, and none of them exist today:</p> <ol> <li>Fast, cheap computers.</li> <li>High-resolution scans of one or more human brains.</li> <li>Accurate models of all relevant cell types in the brain.</li> </ol> <p>Hanson doesn’t give any concrete timeline for when these technologies will exist. He only says “some time in the next century”. Fortunately, none of his analysis depends on when ems become feasible, just that they arrive before AI.</p> <p>Once ems are made, they’ll differ from us in several ways:</p> <ol> <li>Ems are immortal…-ish. So long as their hardware is maintained and powered, they can live indefinitely. This isn’t as great as it sounds. Today’s cars and houses are just as “immortal”.</li> <li>Ems can run at different speeds. Faster ems cost more to run, similar to how faster cloud servers cost more.</li> <li>Ems can “teleport” by transmitting their mind-state across a network. If latency is low enough, they need only to transmit their input and output signals.</li> <li><strong>Ems can be copied.</strong> Many consequences stem from this one difference.</li> </ol> <p>What makes <em>Age of Em</em> interesting is that it rigorously explores the consequences of ems, and that it does so by applying standard scientific models. There’s no hand-waving or contrarianism. The only unusual thing is the question being asked: “What would things be like in an em world?”</p> <h2 id="my-observations">My Observations</h2> <blockquote> <p>Seen up close and honestly, I expect the future usually to look like most places: mundane, uninspiring, and morally ambiguous, with grand hopes and justifications often masking lives of quiet desperation. Of course, lives of quiet desperation can still be worth living.<br /> – Robin Hanson, <em>Age of Em</em></p> </blockquote> <p>Reading <em>Age of Em</em> opened my eyes to how sloppy most futurism is. The field is filled with incomplete analyses and moralizing about the present day. In contrast, <em>Age of Em</em> treats the future like a real place. To use language from <a href="">construal level theory</a>: It kept me thinking in near-mode. I was pleased by the broad range of topics covered. These included: thermodynamics, software engineering, reversible computing, surveillance, city planning, language, and charity. No matter one’s interests, there’s something to engage with.</p> <p>Two specific parts of the book captivated me. They were software-related, of course. One section described the life of a software engineer:</p> <blockquote> <p>For software engineering tasks where parallel software and tools suffice, and where the software doesn’t need to interact with slower physical systems, em software engineers could be productive even when sped up to the top cheap speed. This often makes it feasible to avoid the costs of coordinating across many engineers, by having a single engineer spend an entire subjective career creating a large software system. For an example, an engineer that spent a subjective century at mega-em speeds would complete this period in less than 1 objective hour. Thus when such a delay is acceptable, parallel software may be written by a single engineer taking a subjective career length.</p> </blockquote> <p>This scenario may seem absurd, but it’s a decent prediction of what will happen in a world where minds can be copied and run at different speeds. While <em>you</em> may not want to live such a life, there are some people who will choose it. Those minds will dominate the em economy.</p> <p>Another section briefly discussed software rot. That is: Adapting mature software to new circumstances requires more time and effort than creating new software from scratch. Open source software has <a href="/2017/02/28/software-rot/">tons of examples of this</a>.</p> <p>Hanson claims to be applying standard models and theories to his em scenario, but I don’t know enough social science to tell if that’s true. When the text entered my areas of expertise (computer science, software engineering), I found nothing objectionable. Also, I haven’t heard any domain experts disputing his claim, so I’d bet money that Hanson correctly applied standard theories to this scenario.</p> <p>I’m not sure if the author intended it, but the text works well as an ebook. There are plenty of references and links to related chapters, so I had no problem jumping around. Many footnotes contained URLs, making it easy to track down more info on conclusions I was more skeptical about. I wish more ebooks took advantage of the medium in these ways.</p> <h2 id="my-criticisms">My Criticisms</h2> <blockquote> <p>In sum, even though many critics have reasonable points, I still think the analysis in this book was worth the effort.<br /> – Robin Hanson, <em>Age of Em</em></p> </blockquote> <p>While the ideas fascinated me, the writing itself was rather matter-of-fact. It wasn’t as dry as an academic paper, but neither was it particularly compelling. This could be taken in a positive light. It means the book succeeds on its ideas alone, not just due to fancy writing. And it’s not all dry. The penultimate chapter –on policy recommendations– uses more emotionally stirring language.</p> <p>When it comes to <em>Age of Em</em>’s core ideas, I can’t find any major flaws. To dispute the book requires either rejecting Hanson’s core assumptions or rejecting widely-accepted scientific models. The book contains so much detail that it would be easy to nitpick, but such pedantry is tiresome to read and to write.</p> <p>In my opinion, the weakest part of <em>Age of Em</em> is the assumption that em minds won’t be very tweakable. To be fair, I think it’s a valid simplifying assumption. The book is a straightforward, first-cut analysis. Complicating the base assumptions would have made for an intractable project. Still, one should not be very confident about how tweakable brain emulations can be. And even if most tweaks are hard, there may exist a few easy tweaks which could create a world we find utterly abhorrent. I’d really like to know what neuroscience has to say about this.</p> <h2 id="conclusion">Conclusion</h2> <blockquote> <p>…many of your ancestors would be tempted to disown you, if they were told many things about you. While they’d be pleased and impressed by many of your features, other things about you might horrify them.<br /> – Robin Hanson, <em>Age of Em</em></p> </blockquote> <p>When examined closely, the world described in <em>Age of Em</em> doesn’t sound so bad to me. Ems will be smarter, healthier, and harder working than almost everyone today. They’ll live long and fulfilling lives. Compared to our civilization, theirs will be larger, more capable, and more robust.</p> <p>I think many detractors neglect that last adjective: robust. Existential risk is a crucial consideration. Hanson notes that it would be very hard to eradicate ems. Also, sped-up ems could monitor nanotech or AI experiments and react far more quickly than humans. Even if one thinks an em world is less desirable than ours, the reduction in existential risk may be worth it.</p> <p>Lastly: As positive as my review is, I must admit that <em>Age of Em</em> will only interest a small subset of people. Fortunately, most people reading this will qualify.</p> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:eras" role="doc-endnote"> <p><a href="">Long-Term Growth As A Sequence of Exponential Modes</a> <a href="#fnref:eras" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:bottleneck" role="doc-endnote"> <p>You might ask, “If people are the bottleneck for economic growth, and population doesn’t double every 15 years, then how does our economy do that?” The answer is that much of today’s economic growth comes from making <em>better</em> machines. <a href="#fnref:bottleneck" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:ai" role="doc-endnote"> <p>Hanson backs this up with supporting evidence &amp; reasoning in the book. A shorter version is in a blog post titled <em><a href="">AI Progress Estimate</a></em>. <a href="#fnref:ai" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div> Bikepacking: The Idaho Hot Springs Loop 2016-07-22T16:48:55-07:00 <p>I recently rode the Idaho Hot Springs loop with my dad &amp; my uncle. In nine days, we traveled 510 miles and climbed 37,000 feet. It was rather enjoyable.</p> <p>Read <a href="">my dad’s write-up</a> for all the details. You can also view <a href="/photos/idaho_hot_springs_loop_2016/">my photo gallery of the trip</a>.</p> <p>For those who care to see where we went, I tracked the entire route on Strava:</p> <ul> <li>Day 1: <a href="">McCall to Warm Lake</a></li> <li>Day 2: <a href="">Warm Lake to Stanley</a></li> <li>Day 3: <a href="">Stanley to Ketchum attempt 1. My dad’s derailleur broke.</a></li> <li>Day 3: <a href="">Stanley to Ketchum attempt 2. Started at 4:30PM.</a></li> <li>Day 4: <a href="">Ketchum to Featherville</a></li> <li>Day 5: <a href="">Featherville to Cottonwood campground</a></li> <li>Day 6: <a href="">Cottonwood campground to Idaho City</a></li> <li>Day 7: <a href="">Idaho City to Trail Creek campground</a></li> <li>Day 8: <a href="">Trail Creek campground to Cascade</a></li> <li>Day 9: <a href="">Cascade to McCall</a></li> </ul> <p>Lastly, this trip caused me to break <a href="/2015/01/07/burnout-is-in-the-mind/">my GitHub streak</a>. I brought <a href="/2015/04/19/2015-macbook-review/">my laptop</a>, but most nights I was too tired to do anything. At the end, my streak had been going for 1280 days. That’s 3 years, 6 months, and 3 days. Or put another way: over 10% of my life. I don’t know if I’ll ever exceed that, but I’ve already gotten back in the groove.</p> Interesting Tech that is Just Around the Corner 2016-05-14T17:36:23-07:00 <p>When talking about near-future technologies, much of the discussion surrounds stuff like self-driving cars and <a href="">CRISPR</a>. Rarely do people notice the more modest things that are both closer to fruition and more likely to be brought to market. Allow me to provide some examples.</p> <h2 id="vr-with-eye-tracking">VR with Eye Tracking</h2> <p>VR is becoming commercially feasible, but few have paid attention to how it can be improved with <a href="">eye-tracking</a>. It may seem like a minor addition, but it’s not just a joystick-like input. Eye-tracking allows for far more interesting VR experiences.</p> <p>Imagine this technology being used in a VR <a href="">Silent Hill</a> or <a href="">Resident Evil</a>. You put the headset on and start playing. You see something move in your peripheral vision, but by the time your eyes have <a href="">saccaded</a>, it’s gone. No matter how hard you try, you can’t get a good look at it. With only hints and sounds to go on, your imagination fills in the rest.</p> <p>Such a game would be –without a doubt– the scariest game <em>ever</em>. I can’t wait to play it.</p> <h2 id="paralympics">Paralympics</h2> <p>It’s likely that some Paralympic records will soon exceed their Olympic counterparts. At top speed, the best below-the-knee prosthetics are more efficient than natural legs.<sup><a href="#ref_1">[1]</a></sup> So why haven’t the records already fallen? Several reasons:</p> <ul> <li>Compared to able-bodied athletes, the talent pool of below-the-knee amputee athletes is miniscule. Oscar Pistorius was in the top 0.1% of that group. Usain Bolt is in the top 0.000001% of able-bodied athletes.</li> <li>Runners on prosthetics take longer to accelerate to top speed, harming their performance in shorter distance events. Unfortunately, the longest Paralympic event for below-the-knee amputees is 400m.</li> </ul> <p>So the technology is here, but it’s hard to predict exactly when a Paralympic athlete will hold an overall record. It depends on a sufficiently elite athlete emerging from the talent pool (effectively a random event) and the whims of the International Paralympic Committee. I’d put even money on it happening before or at Tokyo (2020).</p> <h2 id="implantable-blood-glucose-monitors">Implantable Blood Glucose Monitors</h2> <p>1 in 12 adults worldwide have diabetes.<sup><a href="#ref_2">[2]</a></sup> Sufferers can lose limbs or even go blind. With proper blood glucose monitoring, many of these maladies can be avoided. Today, this requires pricking the skin to get a blood sample. It’s really hard to get people to cut themselves a half-dozen times a day, especially when the consequences of poor blood glucose management are years or decades away. Even then, 5-6 measurements per day doesn’t allow for very accurate management. Implantable glucose monitors solve these problems.</p> <p>Several companies have such devices in trials. It’s likely that they’ll be publicly available in a few years.</p> <h2 id="conclusion">Conclusion</h2> <p>There are so many inventions that will improve our lives. Most of them won’t make the news. Most of them –when held in isolation– won’t fundamentally change the human condition. But they gradually accumulate, and eventually we look back and think, “Wow, stuff sure was primitive back in the day.”</p> <p>Don’t forget that.</p> <hr /> <ol> <li> <p><span id="ref_1"></span> <a href="">Wikipedia: The Mechanics of Oscar Pistorius’ running blades</a></p> </li> <li> <p><span id="ref_2"></span> <a href="">Wikipedia: Epidemiology of diabetes mellitus</a></p> </li> </ol> Warrantless Fingerprinting 2016-03-18T23:24:34-07:00 <p>Imagine a world in which the police needed a warrant to dust for latent fingerprints. That is, after a crime is discovered or reported, the police have to go to a judge and demonstrate probable cause that person X is involved. If the judge agrees, a fingerprint warrant is issued. Only then can the police dust the crime scene for fingerprints, and the only information they’re allowed to use is whether X’s fingerprints are present.</p> <p>It would be a world much like this one, except criminals would be caught less often.</p> <p>Now imagine living in that world and trying to convince others that the country would be better-off if police <em>didn’t</em> need a warrant to dust for fingerprints. Yes, you admit, there’s a chance that some innocent peoples’ privacy could be infringed, but more criminals would be brought to justice. And with more fingerprints, prosecutors wouldn’t have to rely on flimsier evidence such as eyewitness testimony. In addition to convicting more criminals, this could spare innocent people from prison. In short: we could reduce crime, save lives, and make justice more just.</p> <p>Is there any doubt that despite your benevolent intentions, you would be branded a fascist? After all, you are a proponent of <em>warrantless fingerprinting</em>. Many of your friends and peers would think less of you for that. If you had any fame, you would likely be hounded by the <a href="">ACLU</a> and the <a href="">EFF</a>. Despite being sincere in your views and using straightforward reasoning, people would continually misrepresent you as an authoritarian who hates privacy.</p> <p>Hopefully, this is starting to sound familiar.</p> <p>Our current legal system is the product of many historical accidents. In some circumstances, it may give too much leeway to police and prosecutors. In others, it may give too little. Reasonable, intelligent people can come to different conclusions about this. Those in favor of warrantless X are not authoritarian or fascistic. Those against warrantless X are not paranoid anarchists. So please tone down the rhetoric and <a href="/2015/03/25/please-stop-getting-outraged/">stop getting outraged</a>.</p> On Learning C, Part 4: What Should I Read? Why Should I believe you? 2016-02-10T22:30:00-08:00 <h3 id="table-of-contents">Table of Contents</h3> <ul> <li><a href="/2016/01/04/on-learning-c-part-1-k-r/">Part 1: K&amp;R</a></li> <li><a href="/2016/01/18/on-learning-c-part-2-zed-shaws-learn-c-the-hard-way/">Part 2: Zed Shaw’s Learn C the Hard Way</a></li> <li><a href="/2016/02/04/on-learning-c-part-3-c-programming-substance-guidelines/">Part 3: C Programming Substance Guidelines</a></li> <li><a href="/2016/02/10/on-learning-c-part-4-so-what-should-i-read/">Part 4: What Should I Read? Why Should I believe you?</a> (You are here.)</li> </ul> <hr /> <h2 id="why-should-i-believe-you">Why should I believe you?</h2> <p>When it comes to C, I am quite proficient. I’ve been employed professionally to write C. I created <a href="/ag/">a somewhat popular open source project in C</a>. I have extensive experience profiling C programs<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup><sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup>, optimizing them<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">3</a></sup><sup id="fnref:4" role="doc-noteref"><a href="#fn:4" class="footnote" rel="footnote">4</a></sup>, and making them multithreaded<sup id="fnref:5" role="doc-noteref"><a href="#fn:5" class="footnote" rel="footnote">5</a></sup>. I’ve contributed to other open source C projects. In short, if I’m not worth taking seriously on this topic, then very few people are.</p> <h3 id="how-i-learned-c">How I Learned C</h3> <p>C was my first real programming language.<sup id="fnref:6" role="doc-noteref"><a href="#fn:6" class="footnote" rel="footnote">6</a></sup> I was introduced to it at the age of 13. Thanks to some luck and an advanced placement test, I was allowed to take up to two classes per semester at <a href="">Gonzaga University</a>. Wanting to learn more about programming, I enrolled in CS121.</p> <p><br /></p> <p><img alt="My student ID" src="/images/student_id.jpg" style="width: 512px; height: 330px;" /></p> <p>I stuck out a little on campus.</p> <p><br /></p> <p>I distinctly remember an early assignment where I was completely stumped by a bug. I’d almost finished the program, but there was one issue that I couldn’t fix. An <code class="language-plaintext highlighter-rouge">if</code> statement was always evaluating to <code class="language-plaintext highlighter-rouge">TRUE</code>, even when it shouldn’t. The <code class="language-plaintext highlighter-rouge">else</code> was never taken. The program compiled without warnings. It was incredibly frustrating.</p> <p>I spent <em>two days</em> staring at that code. I didn’t know about debuggers, so I peppered my code with <code class="language-plaintext highlighter-rouge">printf()</code>s. I commented and uncommented chunks of code. No matter what I tried, I simply couldn’t understand why the program was misbehaving. I was almost in tears when I asked my dad for help. He saw the problem in seconds:</p> <figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="k">if</span> <span class="p">(</span><span class="n">a</span> <span class="o">=</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span></code></pre></figure> <p>I had a single equals in a conditional. That meant I was assigning <code class="language-plaintext highlighter-rouge">a</code> to <code class="language-plaintext highlighter-rouge">b</code> instead of comparing them. As soon as I added another equals, my program worked flawlessly. All that effort and frustration was caused by a single missing character.<sup id="fnref:7" role="doc-noteref"><a href="#fn:7" class="footnote" rel="footnote">7</a></sup></p> <p>I’m still surprised that, afterwards, I remained interested in writing code. I’ve quoted him before, but <a href="">Douglas Crockford</a> <a href=";t=26m50s">said it best</a>:</p> <blockquote> <p>I think there has to be something seriously wrong with you in order to do this work. A normal person, once they’ve looked into the abyss, will say, “I’m done. This is stupid. I’m going to do something else.” But not us, ‘cause there’s something really wrong with us.</p> </blockquote> <p>This was undoubtedly the most difficult educational experience of my life. I really did learn C the hard way.</p> <h2 id="so-what-should-i-read">So what should I read?</h2> <p>Honestly? I’m not sure. For those who want to to learn C, I have yet to find a book that I can unconditionally recommend. The only text I can personally suggest is <a href="">the Kernighan and Ritchie book</a> from <a href="/2016/01/04/on-learning-c-part-1-k-r/">part 1</a>. As I said in that post, caveats apply.</p> <p>For those who know some C and are looking to improve their skills, there are better resources. I’ve heard good things about <a href="">Robert Love</a>’s <a href=""><em>Linux Kernel Development</em></a> (<a href="">PDF</a>). And though it covers <em>much</em> more than C, <a href=""><em>Computer Systems: A Programmer’s Perspective</em></a> will teach you all the gory details of how source code gets turned into machine code.</p> <!-- There are also a few resources I haven't reviewed, bu [Modern C]( by [Jens Gustedt]( C Programming: A Modern Approach --> <p>The dearth of good C books is a bit of a bummer, but there may be a silver lining. I think many learners rely too much on books. It’s often more educational to poke around on your own. Read other people’s code. Examine open source projects. Ask others for help. And if you’re not sure how something works, <a href="/2012/01/30/programming-we-can-do-science/">do science</a>!</p> <hr /> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:1" role="doc-endnote"> <p><a href="/2012/01/23/making-programs-faster-profiling/">Making Ag Faster: Profiling with Valgrind</a> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:2" role="doc-endnote"> <p><a href="/2012/02/08/profiling-with-gprof/">Profiling with Gprof</a> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:3" role="doc-endnote"> <p><a href="/2015/02/08/optimizing-ag-special-casing-file-extensions/">Optimizing Ag: Special-casing File Extensions</a> <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:4" role="doc-endnote"> <p><a href="/2012/09/03/profiling-ag-writing-my-own-scandir/">Profiling Ag. Writing My Own Scandir</a> <a href="#fnref:4" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:5" role="doc-endnote"> <p><a href="/2012/09/07/the-silver-searcher-adding-pthreads/">The Silver Searcher: Adding Pthreads</a> <a href="#fnref:5" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:6" role="doc-endnote"> <p>Before that, I’d only written a few toy programs in <a href="">Logo</a>, <a href="">QBasic</a>, and <a href="">TI-BASIC</a>. <a href="#fnref:6" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:7" role="doc-endnote"> <p>If you’re wondering why the compiler didn’t warn about this, it’s because this happened in 1998. Back then, gcc didn’t warn about assignments in conditionals. Nowadays, any sane compiler will complain. How fortunate one is to learn C today. 🙂 <a href="#fnref:7" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div>