PragPub 2012-12: Issue #42

Table of Contents

Features

Web Programming in Haskell

by Paul Callaghan

Paul returns with another rich article on the Haskell language, this one focusing on Web programming.

Dealing with the Politics Of a Cloud Move

by Jesse Anderson

Last month Jesse showed you how to cost-justify the move to the cloud. But if you’re still getting resistance, here’s how to overcome it.

Agile in the Small

by Brian Tarbox

If you can’t change your company, change your company.

Threads

by Michael Swaine

A look back at a legendary figure in personal computer history: Jack Tramiel.

Departments

Up Front

by Michael Swaine

Haskell, Jack Tramiel, agile in the small, and the cloud.

Choice Bits

AI springs back. Also, a real warp drive?

The Quiz

by Michael Swaine

A monthly diversion at least peripherally related to programming.

Calendar

Want to meet one of our authors face-to-face? Here’s where they’ll be in the coming months.

Shady Illuminations

by John Shade

John looks at the dark side of 3D printing.

But Wait, There’s More...

Coming attractions and where to go from here.

Except where otherwise indicated, entire contents copyright © 2012 The Pragmatic Programmers.

Feel free to distribute this magazine (in whole, and for free) to anyone you want. However, you may not sell this magazine or its content, nor extract and use more than a paragraph of content in some other publication without our permission.

Published monthly in PDF, mobi, and epub formats by The Pragmatic Programmers, LLC, Dallas, TX, and Raleigh, NC. E-Mail support@pragprog.com, phone +1-800-699-7764. The editor is Michael Swaine (mailto:michael@pragprog.com). Visit us at http://pragprog.com

ISSN: 1948-3562

Up Front

Haskell for Web Programming

by Michael Swaine

On December 19, 1871, Mark Twain received the first of his three patents for suspenders.

And that’s not even the most exciting news we have for you this month!

Paul Callaghan is back this month with another meaty article on the Haskell language. The special twist this time around is that he’s showing examples of Web programming in Haskell, and along the way introduces Fay, which is Haskell’s answer to CoffeeScript.

Jesse Anderson has some advice for anyone shepherding their company onto the cloud. You can run into resistance from a lot of sources, and Jesse shows you the right approach for overcoming resistance to a cloud move for every likely source.

Brian Tarbox changed jobs recently, going from a really, really big company to a really small startup. He’s had to rethink everything he thought he knew about agile development, and he shares the insights he picked up in the process.

Commodore International and its founder, Jack Tramiel, were hugely important in the history of the personal computer. Remember the Commodore 64? Then you might want to follow me down memory lane in a little tribute article to Jack and what Jack built.

The other regular features are here, of course, and John Shade tells you that all he wants for Christmas is—no, not suspenders. Good guess, but that’s not it. What John wants but won’t get is a 3D printer. And then he tells you all the reasons you should be very, very worried about 3D printing.

Choice Bits

Hot Books and The Talk of the Tech

AI springs back.

What’s Hot

Top-Ten lists are passé—ours goes to 11. These are the top titles that folks are interested in currently, along with their rank from last month. This is based solely on direct sales from our online store.

1^ | NEW | iOS SDK Development
2v | 1 | Practical Vim
3^ | 5 | Agile Web Development with Rails
4v | 2 | Core Data
5^ | NEW | The Cloud and Amazon Web Services
6^ | 10 | Programming Ruby 1.9
7^ | NEW | Seven Databases in Seven Weeks
8^ | NEW | The Rails View
9^ | NEW | Rails Recipes
10^ | NEW | Deploying Rails
11v | 7 | The Pragmatic Programmer

The Talk of the Tech: AI Springs Back

Artificial intelligence is hot again. Anyway, it’s getting prime space in The New Yourk Times, where John Markoff discussed some of the recent successes of deep learning, the latest buzzword in neural nets. Siri and Google Street View are well-known examples of the technology, but a recent success in its use in drug design is getting some attention.

A history of hype. But Gary Markus, in the New Yorker, warns that deep learning, like every past hot topic in artificial intelligence, is just another brick in the wall. Still, deep learning, in some cases “performs far better than its predecessors.”

Several recent articles have suggested interesting applications for the latest advances in artificial intelligence. Here are some of the things AI might be good for:

Googling the ungoogleable. Some information is inherently hard to search for. Google hates that, and according to a report in Technology Review, they have some ideas on how to google the ungoogleable. But they’re no using artificial intelligence, it sounds like. They’re just trying to map the darkness. Let’s try again...

Learning why Kandinsky makes you cry. That’s more like it. This article from ExtremeTech describes a system that uses machine vision to analyze features of abstract art and correlate them with emotions in viewers of the art. The artist Wassily Kandinsky argued that abstract art must achieve its emotional effects through perfectly objective, analyzable means. This system seems to support Kandinsky.

Replacing analysts. Dell, according to an article in Logistics Viewpoints, is using machine learning to power forcasting software.

Determining intents from tweets. And if AI can replace analysts, surely it can replace marketing gurus, as this VentureBeat article suggests.

Emotion on demand. Then let’s replace animators. Video games are too expensive. Technology Review thinks emotions may become plug-ins. OK, maybe that’s not AI. But surely this is...

Controlling things by thinking. Controlling stuff with your mind, yeah, that’s more like it. This article in Technology Review describes work in this area that starts humbly, with moving a cockroach’s leg. But this surely implies...

Brain-controlled helicopters! All I want for Christmas is one of these. Technology Review again, with hope for those who want to fly choppers with their brains. But wait...

Forget all that other stuff. This is the coolest thing ever. NASA is working on a FTL warp drive. io9 has the details.

You can follow us at www.twitter.com/pragpub.

Web Programming in Haskell

Part One

by Paul Callaghan

Paul returns with another rich article on the Haskell language, this one focusing on Web programming.

The next few articles in this series on the Haskell language will look at web programming via Haskell. Web programming is supported in various ways, from low-level libraries for the basic operations like communicating over http and creation of html documents, up to sophisticated frameworks for building apps and performant web servers for running the apps. January’s article will look at the frameworks, primarily Yesod. This article will look at Fay, which is a Haskell alternative to CoffeeScript.

Replicating the libraries and frameworks of other languages is not too difficult. The interesting question—following a key theme of this series of articles—is how we can use Haskell’s facilities to improve the experience of web programming. For example, less coding and better maintainability via more powerful abstractions, more safety through using the language style and type system to avoid certain problems, or even improved performance by supporting certain kinds of optimization behind the scenes. Even more interesting is to understand the cases and phenomena where Haskell isn’t enough and where more powerful techniques, like dependent types, might provide additional leverage.

Fay—Another Javascript Alternative

Fay was started in early 2012 by Chris Done as a relatively straightforward way to support Haskell-style programming in browsers. It is one of several options in the Haskell-ish area (see this comparison for more details) but for now it seems the front-runner in terms of simplicity, usefulness, and active development.

One important point, though: Fay is very much a work in progress, and some examples may not work in all versions. It’s worthwhile installing a particular recent release and reviewing the test and example files for that version. I’m using version 0.10 in this article. Also remember that the examples are still in flux, too, and some could be rough early experiments rather than showing the current ideas and understanding of the developers.

There are several reasons for my wanting to cover Fay here. Firstly, there’s the pragmatic approach of deliberately piggy-backing on an existing language and its tools instead of inventing a new language and needing to develop tools to go with it—but without requiring the complexity of the full compiler. It also removes the need to learn a new language and its semantics. Secondly, I believe that Fay has many advantages over CoffeeScript that are worth considering, particularly if you need to do moderately complex programming and would benefit from Haskell features like more flexibility with new data structures and support from the type checker. For one thing, it’s easy to isolate the core business code from the the UI parts and check that the ghc-compiled version behaves as expected—and identically to the via-fay-and-node-etc. version.

Also, it’s an excuse to look through some fairly complex Haskell code (the Fay compiler itself) and discuss the techniques used. We also get to cover a few of the core implementation details behind Haskell, such as how laziness and pattern matching work. Finally, it gives me personally a great excuse to tinker and have fun—which in itself is a very important reason. May you find time to tinker as well this month!

Using and Installing Fay

The Fay web page contains several examples, showing both the Haskell code and the compiled result. There is also a web-based IDE for experimenting with Fay, which is itself written using Fay (see github.com/faylang/fay-server. The IDE allows creation and editing of user-supplied code, or modification of standard examples and libraries. Both of these pages rely on Javascript that was compiled from Haskell via Fay, and the IDE page uses Ajax calls to a server that does the compilation. Later on, we’ll look at how these pages use Fay.

To install on your own machine, start by installing the haskell platform to give you the GHC compilers, several standard 3rd-party libraries, and a few useful development tools. (The web page has instructions for the usual OS platforms.) Then, install the latest stable release of Fay via cabal (Haskell’s package manager, like Ruby’s gem or Node’s npm), with the following line. Assuming you’re running this in a non-root account, the line will download the latest release of Fay and any relevant dependencies, configure and compile them for your setup, and place the results in $HOME/.cabal. GHC will check these directories when compiling code.

cabal install fay

It’s probably useful to clone the Fay language repository and the IDE repository so you can look at the various tests and examples contained within—but ensure that you check out the branch relevant to the release you have installed. Further information, including how to run the tests, is on the main Fay web page.

A Simple Example: Laziness and Partial Application

This simple example shows the key ideas of the translation from Haskell to Javascript. Remember that laziness is technically an implementation technique provided by most Haskell compilers, rather than a fixed part of the language—but for now I’ll wave my hands on such details. Given this code,

| foo :: Double -> Double -> Double
| foo x y = x * x + y

We want it to behave in various ways. One, that foo 3 is meaningful etc., and can be applied to another number to get a result, i.e. when fix_3 = foo 3 then fix_3 1 gives 10. Two, that foo 3 (1/0) won’t evaluate its arguments before the call (so it will find the division-by-zero problem only when it tries to do the addition in the function body, not before) - i.e. that it is “lazy.”

This is what the current version of Fay will generate:

| var BasicTwo$foo = function($p1) {
| return function($p2) {
| return new $(function() {
| var y = $p2;
| var x = $p1;
| return _(Fay$$add)(_((Fay$$mult)(_(x))(_(x))))(_(y));
| });
| };
| };

Note: the example output in this article will typically be the result after the initial translation stage with some minor optimizations added, using constructs that keep the translation simple, rather than immediately generating optimal code. So there could be further simplifications to be made. Such improvements are not always best done inside the compiler, and usually there are specific tools that can do a much better job anyway! Fay users often run the generated code through tools like Google’s closure compiler to squeeze out extra performance.

Firstly, partial application is served by the outer two function constructs, thus taking its two arguments one at a time. This is straightforward and nicely supported by Javascript of course. The laziness is supported by three constructs that work together:

function () { ...BODY... }—which creates a “thunk” or suspended value.

new $( ...THUNK... )—which helps avoid repeat evaluation of a thunk.

_(val)—which forces evaluation of a thunk until it is a real value.

When the code has both arguments, the immediate result is a “thunk” that represents the suspended execution of the function body. This means that the computation isn’t done right away but is wrapped up in a new function that will only be called if the result is actually required. This use of a 0-arity function is a standard way to get lazy effects in a non-lazy context, well explored in Lisp and Scheme work (e.g. see SICP section 3.5.1), and works by freezing the relevant values in the closure but not performing the computation until the function is called. (However, Haskell VMs are lazy by design and so do not require this technique: the laziness is implemented much more efficiently.)

The evaluation is forced by applying the _(...) function, which ensures it returns a real value rather than a thunked value. This forcing also shares the results of evaluations, so for uses like foo (1 + 2) 3, the addition on the first argument will be done at most once. Finally, the new $( ... ) is part of a wrapping mechanism to indicate whether a value is ready for use or if evaluation is required.

Running the above code is simple. Here is the complete example.

| {-# LANGUAGE NoImplicitPrelude #-} -- 1
| module BasicTwo where -- 2
| import Language.Fay.Prelude -- 3
| foo :: Double -> Double -> Double -- 4
| foo x y = x * x + y -- 5
| main :: Fay () -- 6
| main = putStrLn (show (foo 1.2 3)) -- 7

The important line is (7). Following convention, the entry point for the code is called main, and it just prints the result of a simple call. Lines (1) and (3) disable the standard Haskell Prelude in favor of a cut-down version that matches Fay’s default library and the facilities available from Javascript (e.g. just one numeric type). Line (2) is used to namespace the generated code. Notice that in line (7), Fay provides putStrLn to print strings on stdout, and show to convert certain values to string form (though this show is a special function provided by Fay rather than the class version—see the documentation for details). The compiled code for BasicTwo$main looks like this.

| var BasicTwo$main = new $(function() {
| return _(Language$Fay$Stdlib$putStrLn)(
| _(Language$Fay$Stdlib$show)(
| _( _(BasicTwo$foo)(1.2) )(
| 3
| )
| )
| );
| });

Foreign Functions and the Fay Monad

How does putStrLn work in Fay?

The default implementation maps it to Javascript’s console.log(...) method. This section explores how this mapping works and how it fits into the rest of Fay.

When working with other Javascript libraries—JQuery is a prime example—we’ll need some flexibility in calling bits of Javascript. Fay achieves this through its FFI—Foreign Function Interface. The ideas are similar to how several Haskell implementations link into underlying C libraries, but adjusted for the Javascript setting.

| putStrLn :: String -> Fay ()
| putStrLn = ffi "(function(x) { if (console && console.log)
| console.log(x) })(%1)"

Behind the scenes, the Fay compiler arranges for the input value to be mapped from a Haskell string to its Javascript equivalent, then after the code has been executed, to collect any relevant return value and convert it back to Haskell. FFI calls can be used to execute any piece of Javascript, though some calls will need to be done in a particular order. One example is printing several strings using putStrLn, and as in conventional Haskell, this order can be controlled simply and unobtrusively via monads. Hence Fay provides the type constructor Fay (as in the result type of putStrLn above) with the standard monad interface (return and (>>=)). The monadic framework is also useful when interacting with many Javascript libraries. The following shows some simple operations via JQuery.

| data JQuery
| select :: String -> Fay JQuery
| select = ffi "window['jQuery'](%1)"
| getVal :: JQuery -> Fay String
| getVal = ffi "%1['val']()"
| setVal :: String -> JQuery -> Fay JQuery
| setVal = ffi "%2['val'](%1)"

So, select produces a result set, from which we can get a value (of the first item) with getVal or set the value (of the first item) with setVal. The type JQuery is used as a placeholder for a JQuery result set, partially ensuring that we use the API appropriately. It’s like an abstract type, in that we don’t have a direct way to build a value or take a value apart, but we can obtain one by calling select and use it in relevant operations. For example,

| foo = do name <- select "input#name_field"
| txt <- getVal name
| setVal (txt ++ " smith") name

And it is easy enough to write a new shorthand operation for this combination, so we can just write foo = chgVal (\s -> s ++ " smith") "input#name_field".

| chgVal :: (String -> String) -> String -> Fay ()
| chgVal change_fn selector
| = do elems <- select selector
| txt <- getVal elems
| setVal (change_fn txt) elems
| return ()

The return () at the end just ensures that the return result from setVal is discarded and so the operation has the expected type. I’m assuming that we don’t want to chain from this operation.

As an interesting side note, observe that the definition of ready below is the same as select, but the types are different. select can only be used to filter on a string expression to return a JQuery result set, whereas ready can only be used to bind some imperative block of Fay actions to the ready event and should not return any useful value. Details like this can help to prevent silly mistakes (if only petrol pumps had a similar type system—it would have saved me from an expensive and embarrassing trip to the car dealership recently...).

| ready :: Fay () -> Fay ()
| ready = ffi "window['jQuery'](%1)"

This being Haskell, we can also let our imagination loose and play with other ways to use jQuery idioms and to use the type system. For example, we might find that setVal mostly needs to work on complex JQuery expressions, so we might prefer setVal_v2 as below, to allow code like setVal_v2 field_one (select "input#other" >>= getVal).

| setVal_v2 :: JQuery -> Fay String -> Fay JQuery
| setVal_v2 result_set value_action
| = do value <- value_action
| setVal value result_set

Another possibility is to have a specialized version of the Fay monad reserved for JQuery that is used to protect against inadvertent mixing of JQuery code and other Fay IO code. Or perhaps to add more detail into the name of the JQuery type so that it reflects what is in the result set, say one thing or many, which might also help to weed out errors. For example, the result set after setVal will always contain just the modified item. We’re still experimenting to see what looks good!

An Example—the Fay Home Page

The Fay home page is generated from a Haskell script, and the interactive features are provided via a Fay script. The scripts are here and here, respectively. The Fay script currently does three jobs: passing the Javascript code samples through a beautifier (js-beautify) and a highlighter (highlight.js), setting up the show/hide toggle on the code samples and setting the initial state depending on the example’s size, and building the TOC.

While noting the comment at line 10 (and the point about “still experimenting” with good ways to interact with JQuery), here’s the TOC code. It’s a sequence of actions via the JQuery library, written in monadic style. The first few lines create a div for the TOC and fill it with a heading and an unordered list, then insert it in the document after a certain title element. Next, loop through the h2 elements in the document using each on the result set. For each h2, the anchor is set from the element’s position in the list, then a link to this anchor is added in the unordered list. The final return True ensures that the monadic result matches the expected type, rather than whatever was returned by the previous action in the loop’s block.

| setupTableOfContents :: Fay ()
| setupTableOfContents = do
| toc <- makeElement "<div class='table-of-contents'>
| <p>Table of Contents</p></div>"
| query ".subheadline" >>= after toc
| ul <- makeElement "<ul></ul>" >>= appendTo toc
| headings <- query "h2"
| each headings $ \i heading ->
| let anchor = ("section-" ++ show i)
| h = wrap heading
| in do -- Make sure the anchor exists at the heading point.
| attr h "id" anchor
| -- Make the entry.
| li <- makeElement "<li></li>" >>= appendTo ul
| a <- makeElement "<a></a>" >>= appendTo li
| getText h >>= setText a
| -- Link up to an anchor.
| attr a "href" ("#" ++ anchor)
| -- For the indentation.
| getTagName heading >>= addClass li
| return True

The type given to each elsewhere in the code is each :: JQuery -> (Double -> Element -> Fay Bool) -> Fay (), so it is a monadic action done only for its side effects (since it returns the boring value ()), and requires a result set (or so we hope—the typing doesn’t distinguish this yet) and a function that expects a number (Javascript numbers are all double precision) and a DOM element, and returns a monadic action that will eventually produce a boolean value. The DOM element is converted to a result set with wrap :: Element -> JQuery, exactly like $(element) or jQuery(element) in plain Javascript, and can then be used freely in JQuery calls. Interestingly, this wrap is typed as a pure function, not some monadic action. This is ok assuming that JQuery runs this without doing side effects, and it is convenient when working with existing elements in code, though there’s no harm in being safe and making it a monadic action either.

The style used with each applies to event handlers too: callbacks will take zero or more arguments and return a monadic value, hence an action (or sequence of actions) to be run when the event is triggered. A good example is the calculator from the Fay examples directory. It defines onClick :: Fay Bool -> JQuery -> Fay JQuery to bind the action in its first argument to the click event of elements in the second argument result set, which is covered in more detail below. Just pause a while to consider how monadic values are being used here: when the click occurs on some element, we want some actions to be executed, and the monadic framework provides excellent support for doing this clearly and safely.

Finally, a quick look at the Haskell script that generates the accompanying page. The first few lines arrange for certain Javascript examples to be included in the document, and for the Fay script to be compiled before a deploy. I want to highlight the code starting around Line 71. It uses a Haskell library called Blaze as a DSL for Html documents, very similar to Haml in Ruby. It uses a few tricks with monadic notation and overloading to provide a clean-looking DSL, using types to eliminate certain notational mistakes.

| theheading = do
| div !. "head" $ do
| img !. "head-logo" ! src "logo-large.png"
| div !. "head-text" $ do
| h1 "Fay programming language"
| div !. "subheadline" $ "A proper subset of Haskell
| that compiles to JavaScript"

The above example describes the document’s heading component. Monadic blocks (indented under a do) represent lists of Html elements, e.g. the .head-text block contains a h1 followed by a div. Nesting is provided by $—the simple pipeline operator!—hence the final line indicates a div that has the tagline as its sole contents. The !. and ! operators are used here to set the class names and other attributes on the parent element, e.g. the img line is rendered to

<img class="head-logo" src="logo-large.png">

We’ll return to this library next time, when we look at server-side web programming in Haskell. (Final thought: can types help to prevent people using tables for layout? Hmmmm.)

User-defined Types and Pattern Matching

This (for me) is the killer feature of Fay—followed closely by Haskell’s clean syntax and type checking, of course. It is a key point of these articles that functional programming is about putting data first, and being able to add and use complex data structures flexibly and simply is a huge part of this. Alternatives like CoffeeScript or TypeScript just do not compete.

Fay supports all of the Haskell-98 forms of algebraic data types and some restricted cases of more complex types, hence any mixture of enumerations, union types, records, polymorphic types, recursive types, and nested types. For example, it supports the arbitrary-branching tree used for the search space in the word-chain kata two months ago.

| data Tree a
| = Node { rootLabel :: a, -- label value
| subForest :: Forest a -- zero or more child trees
| }
| type Forest a = [Tree a]

And we can write standard Haskell to manipulate it:

| val1 :: Tree String
| val1 = Node "a" [Node "b" [Node "c" [], Node "d" []],
| Node "e" []]
| showT :: Tree String -> String
| showT (Node s cs)
| = unlines $ s : map (" "++) (concat $ map (lines . showT) cs)
| main_t = putStrLn (showT val1)

When compiling this through Fay then executing via node or similar, the result is what we expect—a nested tree.

Notice that we’re using the list type and several standard Prelude operations. Fay supports Haskell lists as a primitive type, providing direct implementation of several basic operations. Some of the common Prelude operations are written in the Fay subset of Haskell and compiled into Javascript on demand. You can see what Fay currently supports from the files here and here.

Compilation of these data types and pattern matching is simple but effective. Constructors in user-defined types are converted to objects, and provided with curried constructor functions. Where record types have field names (as in Tree above), accessor functions are generated with appropriate names, e.g. rootLabel :: Tree a -> a.

| var $_Main$Node = function(rootLabel, subForest) {
| this.rootLabel = rootLabel;
| this.subForest = subForest;
| };
| var Main$Node = function(rootLabel) {
| return function(subForest) {
| return new $(function() {
| return new $_Main$Node(rootLabel, subForest);
| });
| };
| };

Pattern matching is compiled into if-tests, using instanceof to test the constructor (i.e. Javascript function) that built the (forced) object being passed in. All Haskell constructors are mapped to such objects, hence the instanceof test is appropriate. Nested patterns will result in nested if-statements. When some pattern clause matches, the corresponding block of code is executed and should return an appropriate value. As the nested if-statement is navigated, names in the pattern are bound as Javascript variables and the same names used directly in the appropriate right-hand side. If no pattern matches, then the code will fall through to the final exception line that reports a missing pattern or unhandled case.

| var Main$showT = function($p1) {
| return new $(function() {
| if (_($p1) instanceof $_Main$Node) {
| var s = _($p1).rootLabel;
| var cs = _($p1).subForest;
| return // ... big right-hand side
| }
| throw ["unhandled case in showT", [$p1]];
| });
| };

Another useful detail is that Fay can automatically add support for converting values from such user-defined types to and from Javascript. This happens behind the scenes, but to be explicit about it, the following two lines are needed—the purpose being to keep the type checker happy. After all: we don’t want to—or need to—subvert type checking. With these two lines, we can now run putStrLn (show val1) directly. (Note that Fay doesn’t support full type classes yet, just a few special cases.)

| instance Foreign a => Foreign (Tree a)
| instance Show a => Show (Tree a)

Finally, for the masochists, here’s the actual RHS from the example above. Try to spot the recursive call!

| // unlines $ s : map (" "++) (concat $ map (lines . showT) cs)
| //
| _(_(Language$Fay$Stdlib$$36$)
| (Language$Fay$Stdlib$unlines))
| (_(_(Fay$$cons)(s))
| (_(_(Language$Fay$Stdlib$map)
| (function($p1) {
| var $gen_1 = $p1;
| return _(_(Language$Fay$Stdlib$$43$$43$)
| (Fay$$list(" ")))
| ($gen_1);
| }))
| (_(_(Language$Fay$Stdlib$$36$)
| (Language$Fay$Stdlib$concat))
| (_(_(Language$Fay$Stdlib$map)
| (_(_(Language$Fay$Stdlib$$46$)
| (Language$Fay$Stdlib$lines))
| (Main$showT)))
| (cs)))));

On a technical note, full Haskell compilers use several techniques to make pattern matching much more efficient than cascaded if-statements. For example, a set of patterns can be compiled into a series of multi-way jump tables, much like case statements on a small set of N fixed values choosing a branch in one single step rather than needing N tests. Such techniques could be added to Fay too, if there was sufficient practical justification. Tagless approaches might also help, where the representation of the constructor becomes the code that performs pattern decisions directly.

A Bigger Example

The Fay repository contains several larger examples. Let’s look at the interesting details of a simple calculatorthat uses several other JQuery features. It’s using a monadic style to communicate with JQuery. The code first builds the Html for the calculator using a table for layout, a process that is triggered on the document-ready event. The table is appended to the document body, and the first row is set to contain the display as a simple text box. The remaining buttons are generated from a description in the buttons list, defined elsewhere. Each button has a label and an associated action. A button element is created for each, its text set to the label, and the click event bound to the action. The rest of the code creates these buttons inside rows of cells, using a nested loop.

| ready $ do
| body <- select "body"
| table <- select "<table></table>" & appendTo body
| dtr <- select "<tr></tr>" & appendTo table
| display <- select "<input type='text' value=''>"
| select "<td colspan='4'></td>" & appendTo dtr & append display
| forM_ buttons $ \row -> do
| tr <- select "<tr></tr>" & appendTo table
| forM_ row $ \(text,action) -> do
| td <- select "<td></td>" & appendTo tr
| select "<input type='button' value='' style='width:32px'>"
| & setVal text
| & appendTo td
| & onClick (do action; return False)

The button information is quite simple—basically pairing a label with the various actions. buttons is a list of lists, hence easily mapped to rows of cells. enter is just a shorthand for (show n, add_number n).

| buttons =
| [[enter 7, enter 8, enter 9, ("/",operator (/))]
| ,[enter 4, enter 5, enter 6, ("*",operator (*))]
| ,[enter 1, enter 2, enter 3, ("-",operator (-))]
| ,[("C",clear), enter 0,
| ("=",calculate), ("+",operator (+))]]

Now, a calculator requires some kind of state. The display is one kind of state, holding the current value. But we’ll also need some way of holding the last number and current operation. Fay adopts the technique used for simple mutable values in Haskell’s IO system, whereby a reference may be created, read, and updated under monadic control. The interface is shown below. Behind the scenes the Ref is just a name for a Javascript object. Notice that the three operations are all monadic, i.e. can only be used in a monadic context. Quite right, too—we do need to get reads and writes in the right order, and the Fay monad provides for this.

| data Ref a
| instance Show (Ref a)
| instance Foreign a => Foreign (Ref a)
| newRef :: Foreign a => a -> Fay (Ref a)
| writeRef :: Foreign a => Ref a -> a -> Fay ()
| readRef :: Foreign a => Ref a -> Fay a

The simplest operation is clearing the calculator state: set the display to show 0, forget any pending calculation, and then refresh.

| clear = do
| setVal "0" display
| writeRef operation Nothing
| calculate

Calculation, when the = button is clicked, first checks whether there’s a pending operation. Notice use of a Maybe value to distinguish between “nothing there” and “something useful, which is X” cases. If there’s nothing, do nothing yet. Otherwise, grab the operation and the number currently in the display and perform the pending operation. In good Haskell style, rather than recording the previous number and the previous operator as two pieces of data, we can store just one— the function that the two items actually represent. There’s no problem storing this as a Javascript value either! For example, in 10 + 20, the stored operation will be (\x -> 10 + x), waiting for the 20 to be fed in. The resulting value is written to the display.

| calculate = do
| op <- readRef operation
| case op of
| Nothing -> return ()
| Just maths -> do
| num <- getInput
| setVal (show (maths num)) display
| return ()
| writeRef operation Nothing

Notice the final line is only indented one step. This means that it (as written) must be done after whatever was executed in the case expression, i.e. regardless of what happened before. We could safely move it into the Just branch because the Nothing branch ensures that the result left in that mutable variable is indeed already Nothing.

There’s one possible point of confusion here, on what the return () actions actually do. Beware—it’s not a return from the whole function, as you would expect in imperative languages. Some people prefer to rename return as the less loaded term wrap, and here is makes sense because we want the boring value () to be the result of the case statement, but wrapped up to fit in the monadic context.

And that’s as complex as the code gets! Some initial setup, a few monadic actions to perform the functionality of the calculator (using three state values), binding the actions to appropriate buttons. Go find a similar example in CoffeeScript, and compare!

How Fay Works

Here are some brief pointers to how Fay is implemented, if you fancy browsing a larger Haskell example.

Inside the repository, the src/ directory holds the main code. It’s divided into several namespaced modules, some of which are nested. The important one is Language.Fay— this contains the library definition and the compiler.

First, look at Types.hs, around line 219. These types specify the expected syntactic structure for Javascript constructs, first for statements then for expressions, followed by various ways of representing names and the Javascript type system. Print.hs contains code for converting those Javascript syntax trees to a flat string.

The complex part of Fay is the compiler. Basically, it converts some Haskell syntax into some Javascript syntax, mostly by transforming one tree into another. That’s basically what all compilers do! The fun starts around Line 326, with the code for translating data type declarations. You can see the conversion of expressions around Line 514.

Notice the type of the various compilation functions, e.g. compilePat :: JsExp -> Pat -> [JsStmt] -> Compile [JsStmt]. The arguments are syntactic data (the Javascript expression being scrutinized, the pattern in Haskell syntax, and the body of the clause as a list of Javascript statements), and the core result is a list of Javascript statements—which will be the body wrapped in the various tests required for matching the pattern. There’s also the Compile wrapped around the result list: this is a monad that is used to hide away various bits of compiler plumbing, in this case mutable state, error handling, and access to IO. You hardly notice this in the code, of course—that’s one of the reasons why we use monads.

Where does Fay get the Haskell syntax from? Conveniently, there’s an official Haskell parser with related types in a standard library. Fay thus works by parsing a set of modules using this parser, and then selectively translating parts of the resulting tree to Javascript. It also runs GHC on your code to perform certain type checking operations. It seems there are plans to use other components of GHC as well.

If you’re interested in compiling other languages and using Haskell for it, you might enjoy looking at my MiniJava compiler. This transforms MiniJava (a basic subset) into C, and was written as a demonstration in an undergrad course on compilers. A key feature is that it saves full snapshots of key data structures at each main stage of the compiler pipeline.

Fay Does Async Too

A certain publisher has just released Asynchronous Javascript by Trevor Burnham. The book covers the key ideas behind programming effectively with Javascript in an asynchronous context, and it looks like a useful addition to available material.

However, something is missing: monads.

In a nutshell, the patterns of asychronous programming used in Javascript work via functions called “continuations” as a way of processing some result when and as it arrives. It’s a powerful concept, but can be tricky to use—the danger is that your code ends up like a mass of spaghetti. Some people like to describe lambda (i.e. anonymous functions) as “the ultimate goto” for such reasons. How to manage the complexity? It would be great if we could make the asynchronous program look like it was synchronous. One answer is to use a monadic framework— the structuring ideas of monads will help us hide the continuations plumbing away (for it is plumbing and not the real program!)

Burnham includes an example of finding the plain files in a directory and building the concatenation of the contents. We can write this example inside Fay too. (The full Fay example is here, and for brevity I just show the important details here.) The main block is this:

| main = do all_entries <- readDir "."
| all_files <- filterM isFile all_entries
| all_text <- sequence $ map readFile all_files
| lift $ putStrLn $ concat all_text

Can you tell whether this is executed synchronously or asynchronously? Should it make a difference? And if we changed from one to the other, should the program have to change? Hopefully your answer is “no” on each. This is a big part of the power of good abstractions!

I’ll assume that the code above speaks for itself, and instead will sketch how we link to the underlying operations. Firstly, readdir is provided by the fs library and takes a directory name and a callback or continuation which says how to process the result—a list of strings—when the directory scan is ready. Now, the execution of JS calls needs to be done in sequence, so we’re going to work inside the Fay monad at low level, similar to what we did for JQuery. Hence, we can give readDir_ the following type and definition via the FFI.

| readDir_ :: Foreign b => String -> ([String] -> Fay b) -> Fay b
| readDir_ = ffi "require('fs').readdir(%1,function(_,s){ %2(s); })"

The pattern (a -> b) -> b is the hallmark of continuations. We can string together several continuation operations by manually building the functions, but we can do better—especially when the control flow gets a bit more complex. The key idea is to think of these continuations as computations that eventually produce some value, i.e. to think of them in monad terms. Conceptually, we want the “do something when the result is ready” to be transformed to “do something and pass the result on”.

The magic step is to work out a definition of (>>=) (monadic then) that allows two continuations to be piped together. It might take a bit of hard staring (see the gist) but effectively you’re splicing the first continuation (yielding some a value) with something that expects such a value and should yield a b value, and then together they produce a new continuation which knows what to do with the b value. I’ll let you have the simpler half of the monad definition now: return a = \f -> f a.

Good news: the relevant transformation (from continuation to monad) is already part of the Fay distribution and likely to be moved to a standard library soon, so you don’t need to repeat or adapt the ideas. All you need to turn your continuation-using call into something monadic is just to wrap it in a constructor. The monad behavior is tied to this constructor and the resulting type, e.g. with its definition of (>>=) unpacking the continuations and glueing them together. (Note my use of trailing underscore to mark the continuation code.)

| readDir :: String -> ContinuationM [String]
| readDir s = ContT $ readDir_ s

Having wrapped up our basic continuation calls, we can then start programming with operations like readDir using standard monad techniques, like do-notation and sequence.

I’ve skipped over the details of error handling, but that can be slotted into the framework too. For example, our FFI code could be extended to take a callback that expects a nullable error value plus the return value—though for sanity we would map it to a single Either value! We can then extend the definition of (>>=) to do certain kinds of error handling, e.g. an exception raise or storing handlers for certain kinds of error or... whatever you want. It’s just plumbing, and we can use monads to hide it away when we don’t need to see it.

There are already quite a few blog posts which discuss the use of monads in Javascript, with and without asynchronous calls, and it’s worth a browse. I’ve also included some more explanation on the gist. We can of course rewrite the Javascript example from the book to use monads, but I’ll leave that as an exercise for you. (But I will say, it’s a lot easier to do it via Fay, not least because of the type checker!)

Trampolines not Required

One other detail that might tempt you to use Fay: it’s harder to run out of stack space.

Some people complain about Javascript’s lack of support for tail recursion, i.e. wanting the optimization where certain kinds of recursion can be converted to a loop and thus avoid using tons of stack. Space is short, but be aware that Fay—as a language with a lazy implementation—doesn’t suffer the same problems. First, direct recursion isn’t a problem because all function calls return a thunk (suspended computation). Recursive calls, if present, will only get executed when the thunk is forced, and this forcing only occurs after the first call has returned. (I think this has some similarity to how trampolining works, though I could be wrong.) You can still get into an infinite loop, of course, but it won’t blow the stack.

Second, some functions can generate their results lazily, like the code for fizz buzz a few months back, and you only execute as much as you need. Hence, some kinds of potentially infinite recursion are ok—and encouraged! Finally, the Fay developers are looking at adding tail call optimizations that provide more performance by bypassing the function call mechanism in favor of a loop, hence could lead to better performance. So: you can be recursive again!

Final Thoughts

So, Fay is a useful tool for compiling medium-complexity Haskell programs into Javascript. It’s still a work in progress, but is stable enough, with sufficient features, for interesting experiments—such as different ways to use more powerful abstractions and types on top of common libraries, and looking to write more functionally complex code with fewer headaches. Also worth exploring is the interaction of Fay front-ends with server components written in Haskell. (We’ll look at the server side next time.) I’m really looking forward to using these toys more! Hope a few of you are tempted too.

Dr Paul Callaghan has temporarily run out of motorbike metaphors. Bits of his bio can be seen on earlier articles. Paul also flies big traction kites and can often be seen being dragged around inelegantly on the beaches of North-east England, much to the amusement of his kids. He blogs at free-variable.org and tweets as @paulcc_two.

Send the author your feedback or discuss the article in the magazine forum.

Dealing with the Politics Of a Cloud Move

Overcome Resistance No Matter Where It Comes From

by Jesse Anderson

Last month Jesse showed you how to cost-justify the move to the cloud. But if you’re still getting resistance, here’s how to overcome it.

Some people will oppose your move to the cloud. It might surprise you who they are and why they object. More often than not, these are political fights arising from large-company politics.

Your IT Manager

Your IT manager might be the most surprising person in your organization to oppose a move to the Cloud, but it can happen. I know it surprised me when an IT manager told me of his opposition to a Cloud move. His reasons, as I suggested above, weren’t technical, but political.

“I need to protect my turf,” he told me. “If we start using the cloud, there are going to be layoffs.” I didn’t have an answer for him at that time. I thought about it more, though, and realized that as the IT manager, he needs to set the expectations for his bosses. He needs to make sure that his bosses know that moving to an Infrastructure as a Service (IaaS) provider only moves hardware problems to the provider. In my experience, the majority of your IT problems and time are spent dealing with software issues. Make sure your bosses know this and you will come out looking good in the Cloud move.

A bigger company may have spent millions creating their own data center. This data center often moves at snail’s pace when compared to using an IaaS provider. So when members of the organization start using the cloud, it may come across to IT managers as doing an end run around their domain. In some ways, they are failing at their job, and as a result making their users look at IaaS offerings. But this really is the manifestation of the problem and not the problem itself. Often, IT red tape is what is forcing the users to look at other options. Take a closer look at your IT policies and see if the public and private Clouds can coexist.

Your Developers

Your developers spend a lot of time developing the latest and greatest software. To them, the software is their baby. So it passes QA and it’s time to deploy... to the cloud, you say? That’s their baby you’re talking about tossing out onto the tender mercies of they know not what. So if you’re planning a move to the cloud, involve your developers as soon as possible. Use their valuable experience. You may find out some hidden gotchas or problems with your software on virtual machines. There could be a showstopper or at least some interaction that you didn’t know about.

At other times, the developers may have anecdotal or partial knowledge of the cloud. They may be holding onto ideas of scalability and speed issues that are incorrect. Take some time to educate everyone about the implications of a move to the cloud.

Your Business Users

Most of the time, mentioning cost savings gets your business users on board with the move to the cloud. But give them a few minutes and they will start asking you about Business Continuity and saying things like “I heard such and such provider went down.” That’s when you grin and say you engineered the infrastructure to handle a location going down. If you didn’t, explain how much more cost is associated with redundancy.

Other business types have heard about people running amok and spending too much. Once again, smile and say there is a service you know that helps with that.

Conclusion

The road to the cloud may have some unexpected bumps, but it’s worth it when you get there. Get to know the reason behind the no. More often than not it isn’t a no to the cloud, it’s a no because of the cloud. Figure out the reason first, and then you’ll have a lot more luck trying to resolve it.

Jesse Anderson is a Creative Engineer in Reno with many years of experience in creating products and helping companies improve their software engineering. He works at Cloudera on the Educational Services team as a Curriculum Developer and Instructor. He does both professional and personal projects. Personal projects like the Million Monkeys project went viral and gained international notoriety. His interviews appeared in such prestigious places as the Wall Street Journal and Fox News. To help the local community, he volunteers his time as the President of the Northern Nevada Software Developers Group and he sits on the Technology Advisory Committee at Morrison University. His blog and website is www.jesse-anderson.com.

Send the author your feedback or discuss the article in the magazine forum.

Agile in the Small

How I Changed My Company

by Brian Tarbox

Brian moves from a company where he was one of 40,000 employees to one where he’s one of six. Culture shock ensues.

Most problems these days seem large, or at least most of the interesting ones do. Some of these problems are programming problems and some of them are problems about programming teams.

“How do I scale my architecture to the cloud?”

“How do I scale my team to four continents?”

In this article we’ll look at a small project and a small team and see if we uncover anything helpful.

I Get Googled

Four months ago I left Motorola-Mobility and the world of video on demand. After my company was purchased by Google, I found myself one of over 40,000 employees, a staggering percentage of whom were lawyers. As a Distinguished Member of Technical Staff, one of my primary job functions was to think up ideas to patent. We were scored on how many “disclosures” we generated per quarter. I also served on a board that reviewed our use of open source software, ensuring that all the terms of all the licenses were adhered to. Don’t get me wrong, as the owner of two open source projects I’m in favor of following the license terms. However, it had become another large lawyer-driven part of the business.

Given that we dealt with entertainment content (i.e. movies and TV shows), digital rights management was also a key concern. There was a US court ruling that said if two people recorded the same show, we had to keep two physical copies of the actual bits that were recorded. If ten thousand people all recorded the same show (say, the Super Bowl) we had to store ten thousand separate copies. Naturally we tried to skirt the edges of this ruling while still obeying it. Our design meetings were held with the understanding that anything we said might be repeated as testimony in a future lawsuit.

This did not tend to feel agile.

I spent years trying to institute Scrum and standard best practices like code reviews, static analysis tools, and compiling code before checking it in. (I wish I was making that last item up.) I finally took the advice I heard years ago (though I cannot remember from whom) which was: “change your company or change your company.” Having tried for years to change my company, I decided it was time to change my company.

Changing My Company

My new company has a grand total of six employees, three of whom are programmers. We have one engineer who maintains the existing system while the CEO and I build the new system. To say that this move was a culture shock would be an understatement.

The new place doesn’t use any of the best practices I had tried so hard to implement at the Big Shop. We don’t do formal code inspections, we don’t have a Style Guide printed in gold (and blood). We don’t run PMD, FindBugs, or CheckStyle.

But the thing that shocked me after a few weeks was that I didn’t miss those things. In fact, I’ve come to believe that most best practices are just crutches for having a heterogeneous skill mix in one’s team. Heresy! Let me say that again: best practices are crutches. I am reminded of the comment often made by proponents of modern languages like Ruby and Scala that design patterns are simply compensations for the lack of power in legacy languages like Java. You don’t see Scala programmers talking about the Singleton pattern or the Strategy pattern because we have closures and map reduce built right into the language.

Rather than having team members object to enforcing rules because the rules could not be followed, we have a team that doesn’t need the rules because we wouldn’t dream of not following them.

Every day when we come in, the company president and I sit down and talk about what we’re working on. We talk about the problems we’re trying to solve, show each other how we dealt with yesterday’s problems, and share things we’ve read. We’re both voracious readers and so most days one or the other of us has read a new book or chapter of a book, and we talk about it. We set out a plan for the day and then go back to our offices and execute. That may sound like a daily scrum, but it is far less formal and more organic. You could also describe it as two people working together. (People, not resources.)

What We Don’t Do

We don’t do formal code inspections, but I know that my boss looks at all my checkins, so I make sure he doesn’t find anything to object to. If either of us is going to make a significant change, we talk about it beforehand.

We don’t have an official burn down chart and we don’t use GreenHopper or any such tools. We’ve sketched out our system architecture on a large whiteboard, and as pieces are completed we put check boxes next to them. Problems with a piece are similarly marked on the whiteboard. Again, it is informal and feels organic. It’s hard now to imagine doing it any other way.

I’ll also say that my office configuration rocks. I have an actual (large) office with a door, but the main wall of the office is glass. This gives me sound isolation and heads-down privacy when I need it, but doesn’t make me feel cut off from everyone else. The office is approximately twice the size of my cube at Motorola, which gives me room for double-monitors, desk space, whiteboard, and even a small conference table. It’s as if the company values me as more than a “resource”! I even have a window that opens. In thirty years I’ve never had a window that opens.

In other matters:

We don’t use email at all... we talk to each other.

We don’t hold meetings... we talk to each other.

We don’t design via Design Documents... we talk to each other.

See any pattern here?

Not to paint too rosy a picture, it’s worth mentioning the stress associated with a startup. At Motorola I was creating prototypes of social TV tools that would be used as the basis for new products and for patent-related lawsuits. In both cases the outcome would not occur for years, and many within the company assumed that Motorola would be long gone by then. So any urgency to perform the work had to be self-generated.

At Cabot, by comparison, we’re measuring progress day by day. Every day without the product means another day of sales that didn’t happen. If I don’t build redundancy into our solution, no one but me will be answering the support call. So my MacBook and I are working at the office, on the train, on the couch, etc. I’m tired most of the time, but it‘s tired from working rather than tired from being frustrated, and that makes all the difference. (Dog trainers have a motto that applies to engineers as well: “a tired dog is a happy dog!”)

This Can’t Last

Now, remember that friend I mentioned earlier? He congratulated me on the new position, but also gave me a warning. He said that my company was likely to grow and that I’d get to shape what sort of shop we evolve into. I suspect we’re going to follow the “Joel on Software” philosophy of hiring, where the only two choices about a potential hire are “Hell yes” or “No thanks.” In other words, we aim to hire very selectively.

At the same time, we will in fact grow. I wonder how far this tiny organic process can scale? When we have five developers will we still want to meet in the CEO’s (or my?) office every morning? Will we have to pick a start time for this “meeting”? Will we have to impose a branching strategy for our CMS? Will we have to start writing documents?

This question mirrors the scaling questions we face with programs and hardware. Scaling a database server (especially a traditional SQL server) “up” is simply a matter of getting a bigger box to run it on. This corresponds to hiring really good people and giving them a highly productive environment to work in. At some point, however, one reaches a limit and has to scale “out.” In traditional SQL servers this meant tackling clusters, masters, and slaves and all manner of expensive black arts. In modern databases such as Cassandra, this means just adding another node to the cluster (it’s not really quite that simple, of course, but for this analogy it’s close enough).

Just what the No-SQL-scale-out solution for growing a team is remains to be seen.

Cassandra can scale out because each node is able to do any of the units of work that are sent to the cluster. The cluster is eventually consistent, in that information supplied to one node is propagated to the other nodes. One can configure how many nodes need to have the data before is it considered “saved,” and there are standard protocols for discovering nodes (gossip) and for propagating data between nodes.

How if at all does this apply to teams? After all, in most large companies we fight a constant battle with management not to be considered fungible like some off-the-shelf server box that can be added to increase performance. And yet, perhaps the analogy works, because even off-the-shelf hardware isn’t totally fungible. Sure, just about anything with a CPU will run Java, but will it run well? There is a world of difference between a 64-bit Linux box with multiple fast hard drives and 16 gigs of memory and a stock user desktop machine running Vista. One of my current responsibilities is to design our Amazon EC2 system specifications for a cluster of machines running a collection of server products. Deciding how to balance machine size vs. number of machines, speed vs. cost, CPU vs. disk for a collection of collections is not a trivial task. The trick, of course, is that once you figure out the type of machine you need, you can go buy lots of them. Not so much with engineers.

(The word “fungible” is worth knowing the definition of: “able to replace or be replaced by another identical item; mutually interchangeable.”)

How to Hire

There is a whole industry built around the promise of helping companies find more developers just like “that guy.” Some companies grill candidates on algorithm theory, others do sets of white-board challenges.

An interesting trend is the rise of sites like LinkedIn, StackOverflow, and GitResume. Each is based on the premise that the “interview” for a job occurs in the years prior to applying for the job. If you are connected to lots of smart people, or have invested time in answering questions for others or have participated in group projects, then you pass. The shibboleth here is connection, and long-term connection at that. I think the long-term part is critical.

Prior to a Google interview, I was given the suggestion to re-read Sedgewick’s classic text on Algorithms. This was disappointing, as any test that you can “cram” for seems weak. Software has collaboration and communication at its heart, so selecting candidates for demonstrated skills in those areas seems like a better test than if they can code up a hash algorithm on demand.

I’ve seen teams succeed and I’ve seen teams fail; there are a lot of intangibles. I’ve seen teams with good spirit and so-so skills perform well but I’ve never seen a team with excellent technical skills and no social ones do anything but crater.

So I hope that as we grow we’ll look for a balance of skills. Fingers crossed!

Brian Tarbox is an engineer at Cabot Research in Boston working on financial services software. Prior to that he spent eight years as a Distinguished Member of Technical Staff at Motorola. He writes a blog on the intersection of software design, cognition, music, and creativity at briantarbox.blogspot.com and contributes to a variety of open source projects.

Send the author your feedback or discuss the article in the magazine forum.

Threads

Jack Tramiel

by Michael Swaine

Auschwitz survivor, self-made man, co-founder of the United States Holocaust Memorial Museum, and the founder and driving force behind Commodore, a company that produced not one but several of the most important machines in the history of the personal computer.

Paul Freiberger and I are currently writing the third edition of Fire in the Valley, our history of the personal computer—to be published by The Pragmatic Bookshelf, naturally. As we go back over the material, we keep finding threads that run through the whole narrative. I am sharing some of these as brief history articles here in PragPub.

One thing that we’re particularly concerned with in writing the third edition is that we address readers’ complaints about the previous editions. These generally fall into one of two categories. Because the presentation is thematic rather than strictly chronological, we loop back to topics as they become relevant in different contexts. Personally, I like that, but it did lead us into some awkward repetition. We’re working on eliminating the repetition without losing the important point that certain people and companies and themes play a role in more than one part of the story.

The other thing that we hear is that we didn’t do justice to Commodore and Jack Tramiel. It’s a valid criticism, and we’re addressing it. But in a broader sense, doing justice to Jack Tramiel would take a whole book. Maybe, though, we can do a little justice right here in PragPub. What I’ve been doing in these little essays in the magazine is focusing on exactly the point I was making above: how some people keep coming back in different parts of the personal computer story. Jack Tramiel is definitely one of those people.

Knowing Jack

Let’s get the pronunciation out of the way first. It’s TRA-MELL, not TRA-MEEL. I no longer remember when I got corrected on that or by whom, but I kind of suspect it was at our first interview with Jack. That was a long time ago and the scars have healed by now, but I still remember thinking that Jack was one scary dude.

He was a lot more than that. Auschwitz survivor, self-made man, co-founder of the United States Holocaust Memorial Museum, and the founder and driving force behind Commodore, a company that produced not one but several of the most important machines in the history of the personal computer. He may also be the only major figure in personal computer history who once worked as a New York cab driver.

Jack Tramiel died last spring at the age of 84. This short article is not an obituary, nor is it intended to relate all of his accomplishments, or to place Commodore in its rightful place in personal computer history. Its purpose is simply to point to a few of the places that Jack shows up in that history.

The Calculator Wars

The personal computer was born, I claim, with the Altair computer from MITS, revealed to the world, or at least to an eager audience of electronics hobbyists, in the January, 1975 issue of Popular Electronics. There had been other computers that could be called personal before this, but the Altair took the target audience by storm, and that audience was the engineers and programmers who had the skills and interest to use the Altair as the jumping-off point for starting their own companies and tossing their own inventiveness into the new industry.

What drove Ed Roberts, the head of MITS, was a similar interest in hobby electronics, but there was something else much more exigent.

Roberts had bet his hobby electronics company on the calculator industry back in the early 1970s, and it had been a disastrous bet. At the time Roberts put MITS on the calculator track, calculators sold for hundreds of dollars. But with the new semiconductors that were coming out, all the functionality of a calculator could be put on one chip. Whap a case around it and you’ve got a calculator, the chipmakers figured, and they got into the calculator business themselves. TI in particular jumped in heavily, cutting the cost of a calculator to tens of dollars rather than hundreds. It killed the industry for independent companies like MITS.

So Roberts decided to create and sell a computer. How that was supposed to help is a story for another place, but Roberts wasn’t the only person to react in just this way to this challenge.

Commodore International was a Canadian electronics products firm founded and run by Jack Tramiel. In the early 1970s it was heavily focused on selling pocket calculators using TI chips. When TI jumped into the industry itself, Commodore went from 60 million dollars in annual sales to a five million dollar loss.

Tramiel’s reaction was to move the company to Palo Alto, purchase a chip company and hire its lead designer, and empower him to build a computer. By early 1977, Chuck Peddle’s PET computer debuts, competing well against two other new computers, the Apple ][ and Radio Shack’s TRS-80.

Personal Computers

In 1982, Paul and I were working at InfoWorld, covering this rapidly-changing personal computer industry. For us, that era, when IBM was legitimizing personal computers for the corporate world, and VisiCalc and Lotus 1-2-3 had given business users a reason to buy the things, and the command line still ruled, and mice and windows were still rodents and architectural features, and Jobs and Gates would return our calls, that era still seems like the real personal computer era.

And during that time, the best-selling computer was the Commodore 64. Within a year Tramiel had cut the price to $200. He had different ideas about pricing than, say, Steve Jobs.

Then came the GUIs. After the release of Apple’s Macintosh the command-line interface was dead. Knock-offs of the software behind the Mac were coming out from Microsoft and Digital Research and IBM, among others. And machines designed to leapfrog the Mac came along: the Commodore Amiga and the Atari ST.

And Jack Tramiel was involved, in highly complicated ways, with both. But I’m going to stop now. You get the idea.

The Quiz

Nine-Letter Man

by Michael Swaine

This month we present another Sudoku puzzle with a couple of twists—it uses letters instead of digits, and there is a hidden message. In one of the rows or columns of the solved Sudoku, you will find the name of someone who was in the news recently.

Simply fill in the empty cells with the nine unique letters you’ll find the the grid in such a way that each row, column, and small square contains each of the nine letters exactly once.

X
X
X

O
X
X

A
X
X

X
X
S

X
G
A

X
K
X

X
K
I

X
X
X

X
N
X

G
X
X

X
I
X

X
A
X

X
S
X

X
X
X

X
N
X

X
I
X

X
G
X

X
X
Z

X
N
X

X
X
X

S
G
X

X
A
X

W
I
X

O
X
X

X
X
W

X
X
N

X
X
X

Solution right here next issue. Or on Twitter right now, no doubt.

Solution to Last Issue’s Quiz

The problem was to find the unique assignment of the ten decimal digits to letters that makes this addition correct:

DONALD + KNUTH = OUTPUT

The answer, P=0, N=1, L=2, T=3, A=4, H=5, U=6, K=7, D=8, and O=9, was inspired by Giovani Resta’s puzzles, which you can explore here.

Calendar

Want to meet one of our authors face-to-face? Here’s where they’ll be in the coming months.

Here’s what our authors will be up to in the coming months.

2012-11-29, Raleigh NC

Beautiful and Shiny - The iOS Graphics System

Bill Dudney (author of Creating a Compelling User Interface with Core Animation , Coding in Objective-C 2.0, Using Map Kit, and iOS SDK Development )

2012-11-29, CocoaConf, Raleigh, NC

All-Day Core Audio Workshop

Chris Adamson (author of iOS SDK Development )

2012-11-30, CocoaConf Raleigh

RubyMotion - Ruby and Cocoa Touch Sitting In A Tree...

Jonathan Penn

2012-12-01, CocoaConf, Raleigh, NC

Core Audio in iOS 6

Chris Adamson

2012-12-01, CocoaConf, Raleigh, NC

Mobile Movies with HTTP Live Streaming

Chris Adamson

2012-12-01, CocoaConf Raleigh

UI Automation for iOS Applications: Automation ALL THE THINGS!

Jonathan Penn

2012-12-05, London

Mary Poppins Meets the Matrix. A look at the languages in Seven Languages in Seven Weeks. What was going on when these languages were written, and what are the design principles that distinguish each one? Fans use discount code tate250.

Bruce Tate (author of Seven Languages in Seven Weeks )

2012-12-05, Online

Vim Masterclass Online

Drew Neil (author of Practical Vim )

2012-12-05, Copyright and Technology NYC 2012

DRM and E-Publishing panel; various invited experts discuss DRM in the digital publishing industry from different angles.

Jim Dovey

2012-12-07, DevIgnition

Your Brain & Dart

Chris Strom (author of The SPDY Book and Dart for Hipsters )

2012-12-13, Ann Arbor CocoaHeads

HTTP Live Streaming, Streamed

Chris Adamson

2013-01-08, Boulder JUG

TBD

Venkat Subramaniam (author of Practices of an Agile Developer, Programming Groovy, Programming Scala, and Programming Concurrency on the JVM )

2013-01-08, Triangle.rb

The Rails View: The Junk Drawer Grows Up

John M Athayde (author of The Rails View )

2013-01-09, CodeMash, Sandusky, OH

Building Productive iOS 6 Apps (half-day tutorial)

Chris Adamson

2013-01-09, Denver JUG

TBD

Venkat Subramaniam

2013-01-10, CodeMash, Sandusky, OH

Objective-C Is Not Java

Chris Adamson

2013-01-10, CodeMash 2013

RubyMotion - Ruby and Cocoa Touch Sitting In A Tree…

Jonathan Penn

2013-01-15, Atlanta JUG

TBD

Venkat Subramaniam

2013-01-18, AIPMM Webinar

Effective Project Portfolio Management

Johanna Rothman (author of Behind Closed Doors, Manage It!, and Manage Your Project Portfolio )

2013-02-04, JFokus - Sweden

Workshops and talks on JVM related languages.

Venkat Subramaniam

2013-02-18, DevNexus - Atlanta

Talks on JVM related languages.

Venkat Subramaniam

2013-02-20, RubyConf Australia

Full day Advanced Ruby tutorial

Dave Thomas (author of Programming Ruby (2nd edition), Programming Ruby 1.9 (3rd edition), Agile Web Development with Rails (3rd edition), The Ruby Object Model and Metaprogramming, and Agile Web Development with Rails (4th edition) )

2013-02-21, RubyConf Australia

Keynote

Dave Thomas

2013-02-26, Agile India - Bangalore

Workshop and talks on Agile technical practices.

Venkat Subramaniam

2013-03-01, The Joy of Coding - Rotterdam, the Netherlands

Keynote at a conference focused on developer joy

Chad Fowler (author of The Passionate Programmer (2nd edition) and Rails Recipes )

2013-03-04, SpeakerConf - Aruba

An opportunity to handout with fellow speakers.

Venkat Subramaniam

2013-03-07, AgileIndy Conference

Tutorial: Agile Project Management: Do You Have What it Takes?

Johanna Rothman

2013-03-08, AgileIndy Conference

Keynote: Agile Management

Johanna Rothman

2013-03-13, 33degree - Warsaw, Poland

Various JVM languages related topics.

Venkat Subramaniam

2013-03-28, RubyMotion Conf, Brussels Belgium

Wrapping RubyMotion - Discussing techniques for making Objective-C APIs more pleasant in Ruby

Clay Allsopp

2013-04-21, Problem Solving Leadership Workshop, Albuquerque, NM

5.5 days of leadership training for people who want to learn to be problem solving leaders.

Johanna Rothman

2013-04-22, Railsberry - Krakow, Poland

A talk on something other than Rails. This is a Rails conference about everything except for Rails.

Chad Fowler

2013-05-20, Let's Test Conference, Sweden

Tutorial: Hiring for Your Team: Culture Trumps Skills

Johanna Rothman

2013-05-21, Let's Test Conference, Sweden

Keynote: Becoming a Kick-Ass Test Manager

Johanna Rothman

O’Reilly Events

Upcoming events from our friends at O’Reilly.

2012-12-04, Velocity China Conference, Beijing, China

Velocity China: “Most dynamic website companies face the same challenge: pages must load fast, the infrastructure has to be able to expand, sites and services must be reliable, and you have to do it all in a timeframe the team can handle while keeping it within budget. Velocity is the best place for Web professionals to meet to exchange ideas and share best practices and lessons learned.”

2013-02-12, TOC New York, New York, NY

Tools of Change New York:“For six years, the O’Reilly Tools of Change for Publishing Conference in New York has been the seminal event for professionals and companies engaged with the challenges and opportunities of new publishing technologies and business models.”

2013-02-26, Strata 2013, Santa Clara, CA

O’Reilly Strata Conference: “Tap into the collective intelligence of more than 150 data experts at Strata 2013. Strata gives you the skills, tools, and technologies you need to make data work today.”

USENIX Events

What’s coming from our USENIX friends.

2012-12-03, Middleware 2012, Montreal, Quebec, Canada

ACM/IFIP/USENIX 13th International Conference on Middleware: “a premier forum for the discussion of innovations and recent advances in the design, implementation, experimentation, deployment, and usage of middleware systems.”

2012-12-09, LISA ’12, San Diego, CA

26th Large Installation System Administration Conference: “The annual LISA conference is the meeting place of choice for system and network administrators and engineers; it is the crossroads of Web operations, DevOps, enterprise computing, educational computing, and research computing.”

2913-02-12, FAST ’13, San Jose, CA

11th USENIX Conference on File and Storage Technologies: “FAST '13 brings together storage-system researchers and practitioners to explore new directions in the design, implementation, evaluation, and deployment of storage systems.”

Shady Illuminations

All I Want for Christmas Is a 3D Printer

by John Shade

John looks at the dark side of 3D printing.

All want for Christmas a 3D printer. It would be perfect for my lifestyle: I want to have stuff, but I don’t want to have to leave my house to get it—or have UPS or FedEx drivers come to my house. If I could just download designs and print up all the shoes and hammers and sex toys I need, I’d be far less grumpy. The only problem is, the cheap ones aren’t good enough and the ones that might meet my high standards are like yikes.

So that 3D printer won’t be appearing under my tree this year, because the technology is currently too expensive. I admit I said the same thing about Añejo Tequila last year, and I bought it anyway. Sometimes holiday traditions trump the resolutions. But I really mean it about 3D printers. The price needs to come down and the capabilities need to go up.

Both of these things would happen quickly if the market asked for them loudly enough. Massive demand would bring in economies of scale, driving down costs, and would also result in fierce competition that would in turn bring about rapid growth in features and capabilities. Demand isn’t strong yet, so 3D printing is a technology, but it’s not yet a market. But that may change sooner rather than later. All that’s needed, after all, is a killer app.

And boy howdie, if any market ever had a killer app, it’s the 3D printer market. A literal killer app. Home-made guns. And they exist. They’re already being printed today. Once the word gets out, I think there just might be a spike in the demand for 3D printers in certain circles.

Now, some might feel that the ability for every terrorist, druglord, vigilante, or disgruntled postal worker to print themselves a gun or two or ten in the privacy of their own home is a bad thing. And those people are free to feel that way, but their feelings are irrelevant. The glock is out of the bottle, the colt has bolted the stable.

The desktop armory boom could play out much like the desktop publishing boom, only with more boom. The invention of the laser printer made everyone a publisher. Or maybe it was the invention of the web. And the camera in the phone made everyone a photojournalist. Anyway, now we’re all press, and since freedom of the press belongs to him who owns the press, this is a case of technology bringing about the democratization of the First Amendment.

The line “when guns are outlawed, only outlaws will have guns” isn’t an exact parallel to “freedom of the press belongs to him who owns the press,” but it’s close. 3D printers look like the technology that will democratize the Second Amendment. And when we can all be gun shops, gun laws will become unenforceable. No doubt attempts will be made to suppress gun designs, but they will fail.

Some will consider this good news. Some will consider it a really scary prospect. I find it interesting. So that’s the first point I wanted to make about 3D printers. The technology already has a killer app, and it’s a real killer.

But 3D printers will be used to produce lots of things other than guns. And a lot of those things will hurt people, too. Sometimes products hurt people due to defects in their designs. Or to inadequate documentation. Or to overestimating the intelligence of the consumer. We’re a litigious society, and it’s unreasonable to expect 3D printing to be immune to product liability lawsuits.

When the product hurts you, you sue the manufacturer. If your car blew up in a 5 mph collision, you sue. If the dog chewed up the squeaky toy and swallowed the squeaker, you sue. If the cold medicine, in combination with your martini habit, destroyed your liver, you sue. If your 3D printer-generated coffeemaker made the coffee too hot and it burned your lip, you sue.

But wait a minute, with 3D printing, aren’t you, the consumer, also the manufacturer? And if you are the manufacturer, aren’t you responsible for the product you built (or printed)? Wouldn’t you have to sue yourself?

No. That’s not how it will be interpreted by the courts. You can’t print products from a 3D printer without the data, which is to say CAD design, which is to say software, so you’ll sue the author of the software. If the product was badly designed, that’s not your fault, it’s the fault of the person who wrote the software.

Suing over software that hurts you is nothing new, of course. But there is a non-trivial difference with 3D printing. A 3D printer design is software that implies (entails?) some physical object. It’s software that can fall on your toe and break it. So that’s the second point I wanted to make about 3D printers. There will be 3D printer product liability lawsuits.

But there’s another difference between hardware and software: nobody designs and manufactures and distributes a hardware product for free. But lots of people write software and give it away. Can the user of a 3D printer download some free CAD design for some product, print it, drop it on his foot, and sue the author of the software?

It’s a trick question, of course. In America, anybody can sue anybody over anything. And defending against even a groundless lawsuit can bankrupt a person. So yes, obviously. I just wanted to point out that this little gift that will start appearing under the Christmas tree if not this year then probably next year has some really interesting implications.

Merry Christmas!

John Shade was born under a cloud in Montreux, Switzerland, in 1962. Subsequent internment in a series of obscure institutions of ostensibly higher learning did nothing to brighten his outlook. His favorite holiday is the Winter Solstice. Follow John on Twitter, send him your feedback, or discuss the article in the magazine forum.

But Wait, There’s More...

Coming Attractions

This may be the last page, but that doesn’t mean it’s the end of the conversation. Keep up with what’s going on in the Pragmatic universe by subscribing to our newsletter and drop by the Pub again next month for more Pragmatism. We’ll keep a seat warm and a mug chilled and a candle burning in the window.

Coming Soon in PragPub

If you bought yourself a Raspberry Pi for Christmas and are looking for a fun project to try out with the device, we have something in the works that might fill the bill.

Recent Releases, Betas, and Upcoming Books

Our Pragmatic exPress series is rolling along. Our latest title is Trevor Burnham’s Async JavaScript: Build More Responsive Apps with Less Code. Also in print and shipping, Mac Kung Fu: Over 400 Tips, Tricks, Hints, and Hacks for Apple OS X, 2nd Ed..  

Right. But to really be in the know, you need to subscribe to our weekly newsletter. It’ll keep you in the loop, it’s a fun read, and it’s free. All you need to do is create an account on pragprog.com (email address and password is all it takes) and select the checkbox to receive newsletters.

While you’re waiting for the next issue of the newsletter or of PragPub to come out, you can follow us on twitter at @pragpub, @PragmaticAndy, or @pragdave. Or on Facebook at facebook.com/PragmaticBookshelf. Or email us at michael@pragprog.com.