A little over a year ago, I wrote about some formative experiences I had with computers early in my life. That article focused on the Timex Sinclair 1000 , but sitting off in the wings are two other computers - the Commodore 64 and the Apple II . A few weeks ago, there was some dialog between John Gruber , Drew Saur , and Jason Snell that's brought those two machines back to mind. It's all very…
Lately, I've been reading "Beyond Mach 3" ), Col. Buddy Brown's memoir of his years piloting the U-2 and SR-71 spy planes. If you like that sort of thing, it's an interesting read on its own, but it also has parallels to the software industry, particularly in the way it describes pilot workload. The concept of pilot workload provides a nice way to think explicitly about the burdens our systems…
Over the last few months, I've started making an attempt (with the help of my patient coworkers) to more intentionally learn the programming language Haskell. I have professional reasons why this is directly important, but it's also been a good way to challenge some long held assumptions. Being purely functional and lazily evaluated, Haskell lacks traits like implicitly sequenced evaluation,…
If you've been around programming for a while you've no doubt come across the Lisp family of languages. One of the oldest language familess still in use, much of what we take for granted in modern programming has roots in Lisp. This includes everything from dynamic memory management to first class functions and a comprehensive library of standard data structures. However, despite the considerable…
As a child of the 80's, I had a front row seat to the beginning of what was then called personal computing. My elementary school got its first Apple around the time I entered kindergarten. That was also the time personal computers were starting to make inroads into offices (largely thanks to VisiCalc and Lotus 1-2-3 ). By modern standards these machines weren't very good. At the time they were…
Over most of the ten years I've been using git , I've been a strong proponent of merging over rebasing. It seemed more honest to avoid rewriting commits and more likely to produce a complete history. There are also problems that arise when you rewrite shared history, and you can avoid those entirely if you just never rewrite history at all. While all of this is true, the hidden costs of the…
This image has been circulating on LinkedIn as a tongue and cheek example of a miminum viable product. Of course, at least one of the responses was that it's not an MVP without some extras. It needs 24/7 monitoring or a video camera with a motion alarm. It needs to detect quakes that occur off hours or when you're otherwise away from the detector. The trouble with this statement is the same as…
Like a lot of engineers, I have a handful of personal projects I keep around for various reasons. Some are useful and some are just for fun, but none of them get the same sort of investment as a funded commercial effort. The consequence of this is that it's all the more important to keep things as simple as possible, to focus the investment where it counts. Part of the way I achieve that is that…
Amazingly enough, git is now 14 years old . What started out as Linus Torvald's 'three day' replacement for BitKeeper is now dominant enough in its domain that even the Windows Kernel is hosted on git. (If you really are amazed by the age of git, that last bit might be even more amazing.) In any event, I also use git and have done so for close to ten years. Along with a compiler and an editor, I'd…
Despite several good online resources, it's not necessarily obvious how friend 's wrap-authorize interacts with Compojure routing. This set of routes handles /4 incorrectly: ( defroutes app-routes ( GET "/1" [] ( site-page 1 )) ( GET "/2" [] ( site-page 2 )) ( friend/wrap-authorize ( GET "/3" [] ( site-page 3 )) #{ ::user }) ( GET "/4" [] ( site-page 4 ))) Any attempt to route to /4 for a user…
I've lately run across several interesting small computer history sites. If you have any interest in small computing's emergence from 1980 to 1990 or so, these are worth a look. In no particular order: OS/2 Museum - Covers OS/2, but also gets into detail around PC architecture. Among other interesting bits, this is just one of several articles on A20 gate handling , and here's something on the IBM…
It's been a long time coming, but I've finally replaced blosxom with a custom CMS I've been writing called Rhinowiki . More than a serious attempt at a CMS, this is mainly a fun little side project to write some Clojure , experiment a bit with JGit , and hopefully make it easier to implement a few of my longer term plans that might have been tricky to do in straight Perl. Full source in the link…
This is a bash function definition that takes you to the top level directory of a git project. function cdtop () { local git_root; git_root=`git rev-parse --show-toplevel`; if [ $? -eq 0 ] then cd ${git_root} else return 1 fi } Here's a git alias that does serves a similar purpose. What this does is define a new alias, exec , that executes a shell command in the current project's root. git config…
Since my last post, I dropped by an Apple Store to take a look at the 2015 MacBook. It is difficult to overstate how startlingly small the new machine is in person. I may be biased by the internal specifications, but the impression is much more 'big tablet' than 'small laptop'. The other standout feature was the touchpad. It continues Apple's tradition of high-quality touchpad implementations,…
One of the key attributes I look for when writing and reviewing code is that code should express the intent of the developer more than the mechanism used to achieve that intent. In other words, code should read as much as possible as if it were a description of the end goal to be achieved. The mechanism used to achieve that goal is secondary. Over the years, I’ve found this emphasis improves the…
In my last post , I started porting the RPN calculator example from Java to Clojure, moving a functional program into a functional language. In this post, I finish the work and show how the Clojure calculator models both state and calculator commands. Going back to the last post, the Clojure version of the Read-Eval-Print-Loop (REPL) has the following code. ( defn main [] ( loop [ state (…
So far in this series , I’ve taken a basic calculator written in Java and transformed it from a command-oriented procedural design into a more functional style. In some ways, this has made for simpler code: calculator state is better encapsulated in value objects, and explicit control flow structures have been replaced with domain-specific higher order functions. Unfortunately, Java wasn’t…
In the last installation of this series, we started using Java iterators to decompose the monolithic REPL (read-eval-print-loop) into modular compoments. This let us start decoupling the semantics of the REPL from the mechanisms that it uses to implement read, evaluate, and print. Unfortunately, the last version of rpncalc only modularized the command prompt itself: the ‘R’ in REPL. The evaluator…
Sometimes, it’s easy to focus so much on the architecture of a system that the details of its implementation get lost. While it’s true that inattention to architectural concerns can cause a system to fail, it’s also true that poor attention to the details can undermine even the best overall system design. This post covers a few minor details of code structure that I’ve found to be useful in my…
Update 2019-01-17 : KSM recently redesigned their website in a way that removes the original blog. Because of this, I've taken some of what I wrote then for KSM and re-hosted it here. Thanks are due both to KSM Technology Partners for allowing me to do this and to the Wayback Machine for retaining the content. All the links below are updated to reflect the articles' new locations. Sorry for the…