PragPub 2013-10: Issue #52

Table of Contents

Features

Clojure and Polymorphism

by Michael Bevilacqua-Linn

Java and Clojure have different approaches to polymorphism. Understanding how Clojure uses polymorphism is critical to Clojure mastery.

The Luminus Framework

by Dmitri Sotnikov

How to build a web application quickly using Clojure and the Luminus micro-framework.

Game Plan

by Chris Crawford

A legend in computer game design offers a project that could make games better.

Mobile Applications vs. Web Pages

by Brian Tarbox

Are there service for which you have both the mobile app and a link to the web site? Is there a hint there that something is not right?

Creating the Apple ][

by Michael Swaine and Paul Freiberger

Jobs in tears, Woz playing pranks, and the ad in Playboy: the crazy days leading up to the release of the Apple ][.

Departments

On Tap

by Michael Swaine

What’s in this issue.

Choice Bits

This month Choice Bits expands to include Antonio on Books.

Rothman & Lester

by Johanna Rothman and Andy Lester

Johanna and Andy share tips on career development and becoming a T-shaped person.

Puzzle

by Michael Swaine

Solution to last month’s puzzle.

Shady Illuminations

by John Shade

John gives career advice, which you are well advised to ignore.

Rear Window

Wayne Green and the birth of Byte Magazine

Except where otherwise indicated, entire contents copyright © 2013 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

On Tap

Polymorphism

by Michael Swaine

Chris Crawford is a legend. He wrote the book on computer game design. Literally. Chris wrote The Art of Computer Game Design. The Game Developers Conference started in Chris’s living room. He has always pushed for humanity in games. In his best-seller Balance of Power, if you messed up and started a nuclear war, the game ended instantly with the following message: “You have ignited a nuclear war. And no, there is no animated display of a mushroom cloud with parts of bodies flying through the air. We do not reward failure.”

In this month’s issue, Chris sketches out a program for exploring what people really value in the games they play. Rather than imitating successful games, what if we did the research to discover the natural dimensions of game appreciation? Chris describes a tool for doing just that.

Clojure has polymorphism, Java has polymorphism, but if you think about Clojure polymorphism the way you think about Java polymorphism, you’ll get mental whiplash. In his latest article on Clojure, Michael Bevilacqua-Linn shows how to think polymorphically in Clojure.

Frameworks are big in Web development, but in Clojure, frameworks are small. That is, Clojure Web developers tend to rely more on libraries than frameworks. But that doesn’t mean that Clojure and frameworks can’t work together, as Dmitri Sotnikov shows in his article introducing the Luminus micro-framework.

Also in this issue: Antonio Cangiano looks at books, Brian Tarbox looks at the dynamic between Web and mobile development, the editor looks back on the Apple ][ and the birth of Byte, John Shade offers career advice to Steve Ballmer, and Rothman and Lester offer career advice for the rest of us.

Gatekeepers vs. Filters

Car dealers in California are upset that Tesla Motors is selling cars online. They think people who want to buy cars should have to go to a showroom. They invested a lot in that real estate.

I feel their pain. Publishing used to be built on a gatekeeper model, too. We locked up good stuff and you paid us to get at it. In retrospect, it was a stinko business model. And it won’t work in the Age of Access.

We don’t do that now. If you write for PragPub, we won’t lock up your content. We’ll encourage you to publish it on your blog, or wherever. We’ll even link to it. We want to increase your reach, not limit it.

In terms of a business model, it means that we’re selling filtering. Anybody could go out and find this particular article on the Web. Maybe. And that one. And that one. But that’s a job. Our challenge is to do that job for readers, help them with the tmi problem, put together a package of known good stuff. And to do it reliably, every month. Kinda scary.

But it’s a good kind of scary.

Have you got a great article the world needs to see? We want to publish that article. And we won’t lock it up.

What’s Next?

We’re still in exploratory mode with the magazine and we have been listening carefully to you about the features you want in PragPub. You’ve made it clear that you want more delivery models: direct to Kindle, to your Dropbox, and other options. You also want to be able to subscribe without PayPal.

All perfectly reasonable requests, and we ought to have some of them in place by next issue.

If you like to read about food and wine, you may have come across Derrick Schneider’s writing in The San Francisco Examiner, The Wine News, Edible East Bay, or The Art of Eating. In his day job, though, Derrick is a software developer skilled in Erlang, R, Python, Ruby, and Objective-C. Recently he’s been rediscovering the power and—dare we say—elegance of an ancient and rarely-mentioned language that does not deserve to be forgotten: AWK. He’ll share some of his discoveries next issue. Also in the next issue you can look forward to further exploration of Clojure by Michael Bevilaqua-Linn, career development advice from Rothman and Lester, John Shade, and more.

Cover and p. 11, istockphoto.com/RUSSELLTATEdotCOM; p. 17, istockphoto.com/Electric_Crayon; p. 24, istockphoto.com/STEEX; p. 27, istockphoto.com/Alex Slobodkin; p. 30, istockphoto.com/kcline.

Choice Bits

Antonio on Books and Drips from the Twitterstream

Antonio Cangiano joins the Choice Bits lineup with all the new tech books.

This month Choice Bits expands to include Antonio on Books in addition to our customary drawing of bits of wit from the well of twit.

What a Month

Sure, Apple sold more iPhones than there are people on Earth, but I’m sure we can all agree that the biggest news of the month was Yahoo’s logo redesign:

OK, so Yahoo redesigned its logo. Perfectly understandable, given that its CEO is refocusing the company to try to keep it relevant and profitable. Oh wait, not that CEO, this CEO. Anyway, logo design is always a big deal for the company involved, and some genius designers have come up with some truly inspired logos to represent companies. But it doesn’t usually inspire quite this level of kibitzing. Yahoo’s logo was always kind of goofy looking, but arguably charming. The latest version is still goofy, but without the charm, might be the general sentiment. The CEO explained the thinking behind the redesign, and that may not have been such a great idea. Glenn Fleishman came up with what I think is the clearest analysis of what’s wrong with both the logo and the process—and what it implies about Yahoo’s ability to reinvent itself. [from Swaine’s World]

There were a few other developments of note...

Twitter plans to use the proceeds [from its IPO] for acquisitions, general corporate purposes, and to expand into the 141-149 character messaging market. — @ inafried

...and developers continued to take to Twitter to share their experiences.

This Coding Life

Accidentally followed a link to some Perl code, and now I’m all nostalgic. — @emckean

Had a great meeting today where I closely resembled a mad scientist flying back and forth waving my arms. — @mtnygard

Flew AR Drone on new 1500 battery. Much longer flt. Same behavior of dropping rapidly from 30% to 0. Crashed into everything. Did not break. — @RonJeffries

After conducting a carefully controlled experiment, I have concluded that whisky tastes a lot better on the playa. #burningman — @doctorow

I really love it when the air in IL1 is scented with blown capacitors. It reminds us of our roots. — @cdespinosa

It’s always step 57 of 59 that trips me up when submitting an app to the iOS App Store. — @ginatrapani

EBay tried to use PayPal to buy Braintree, but it tripped a fraud alert and the payment failed. — @benrady

I don’t want to jinx it, but I think Designer News has finally shut up about flat design. Everyone, stay quiet. Don’t scare them out of it. — @antiheroine

I just love that new programming language smell. — @benrady

Women need to understand that “boys will be boys”? No. Men need to understand that pass expires when you’re no longer a boy. — @ginatrapani

I mean, Google already knows how to beat taxes, so why not beat death! :) http://techland.time.com/2013/09/18/google-vs-death/ — @dannysullivan

Email from PayPal saying I should tell customers that my checkout includes financing. I didn’t raise the price by that much, did I? — @noelrap

Java has become COBOL. — @bdudney

Now realizing that my discussion of the nuts and bolts of LSD use may be old news to a Boulder audience. @rockymtnruby — @marick

Antonio on Books

Hi there, I'm Antonio Cangiano, an author and developer who runs Any New Books, a weekly new book notification service. Starting this month, I’ll be sharing a selection of some of the most interesting newly released programming books with PragPub readers specifically in mind.

This month I’d like to single out Ilya’s book on web performance. Those who are familiar with his blog know how insightful and clear his explanations are. Leveraging his experience and clarity to gain a deeper understanding of web and browser networking performance seems like a worthwhile investment for anyone interested in web development.

Antonio's Pick: High Performance Browser Networking: What every web developer should know about networking and web performance By Ilya Grigorik • ISBN: 1449344763 • Publisher: O'Reilly Media • Publication date: September 27, 2013 • Binding: Paperback • Estimated price: $22.98

Learning R By Richard Cotton • ISBN: 1449357105 • Publisher: O'Reilly Media • Publication date: September 23, 2013 • Binding: Paperback • Estimated price: $23.50

Java Web Services: Up and Running By Martin Kalin • ISBN: 1449365116 • Publisher: O'Reilly Media • Publication date: September 25, 2013 • Binding: Paperback • Estimated price: $21.42

Murach's Android Programming By Joel Murach • ISBN: 1890774715 • Publisher: Mike Murach & Associates • Publication date: September 23, 2013 • Binding: Paperback • Estimated price: $37.88

Pro ASP.NET Web API: HTTP Web Services in ASP.NET By Tugberk Ugurlu, Alexander Zeitler, Ali Kheyrollahi • ISBN: 1430247258 • Publisher: Apress • Publication date: September 25, 2013 • Binding: Paperback • Estimated price: $42.55

Game AI Pro: Collected Wisdom of Game AI Professionals By Editors at A K Peters/CRC Press • ISBN: 1466565969 • Publisher: A K Peters/CRC Press • Publication date: September 11, 2013 • Binding: Hardcover • Estimated price: $71.96

C# in Depth, 3rd Edition By Jon Skeet • ISBN: 161729134X • Publisher: Manning Publications • Publication date: September 28, 2013 • Binding: Paperback • Estimated price: $31.98

RESTful Web APIs By Leonard Richardson, Mike Amundsen, Sam Ruby • ISBN: 1449358063 • Publisher: O'Reilly Media • Publication date: September 27, 2013 • Binding: Paperback • Estimated price: $22.98

Single Page Web Applications: JavaScript end-to-end By Michael Mikowski, Josh Powell • ISBN: 1617290750 • Publisher: Manning Publications • Publication date: September 28, 2013 • Binding: Paperback • Estimated price: $28.98

SQL For Dummies By Allen G. Taylor • ISBN: 1118607961 • Publisher: For Dummies • Publication date: September 3, 2013 • Binding: Paperback • Estimated price: $16.12

Beginning HTML5 and CSS3 For Dummies By Ed Tittel, Chris Minnick • ISBN: 1118657209 • Publisher: For Dummies • Publication date: September 3, 2013 • Binding: Paperback • Estimated price: $16.44

Amazon Web Services For Dummies By Bernard Golden • ISBN: 1118571835 • Publisher: For Dummies • Publication date: September 10, 2013 • Binding: Paperback • Estimated price: $15.90

Head First C# By Jennifer Greene, Andrew Stellman • ISBN: 1449343503 • Publisher: O'Reilly Media • Publication date: September 13, 2013 • Binding: Paperback • Estimated price: $28.21

Professional Hadoop Solutions By Boris Lublinsky, Kevin T. Smith, Alexey Yakubovich • ISBN: 1118611934 • Publisher: Wrox • Publication date: September 23, 2013 • Binding: Paperback • Estimated price: $26.48

Java Coding Guidelines: 75 Recommendations for Reliable and Secure Programs By Fred Long, Dhruv Mohindra, Robert C. Seacord, Dean F. Sutherland, David Svoboda • ISBN: 032193315X • Publisher: Addison-Wesley Professional • Publication date: September 9, 2013 • Binding: Paperback • Estimated price: $28.30

Guide To: Learning Python Decorators By Matt Harrison • ISBN: 1492325619 • Publisher: CreateSpace Independent Publishing Platform • Publication date: September 1, 2013 • Binding: Paperback • Estimated price: $8.07

Beginning Rails 4 By Adam Gamble, Cloves Carneiro Jr., Rida Al Barazi • ISBN: 1430260343 • Publisher: Apress • Publication date: September 11, 2013 • Binding: Paperback • Estimated price: $35.95

tmux: Productive Mouse-Free Development By Brian P. Hogan • ISBN: 1934356964 • Publisher: Pragmatic Bookshelf • Publication date: September 19, 2013 • Binding: Paperback • Estimated price: $13.31

Pro Objective-C By Keith Lee • ISBN: 143025050X • Publisher: Apress • Publication date: September 4, 2013 • Binding: Paperback • Estimated price: $29.86

Beginning Arduino By Michael McRoberts • ISBN: 143025016X • Publisher: Apress • Publication date: September 18, 2013 • Binding: Paperback • Estimated price: $26.29

We All Live in the Future Now

Cafe waiter just came over to offer WiFi password, excitedly exclaimed “Are you using Ubuntu? I love it—been using it for years!” — @doctorow

Did I seriously just see an ad for something called http://farmersonly.com ? — @invalidname

Tulsa nurse’s new cellphone EKG technology, AliveCOR, alerts woman to own heart problem. More of this will happen! http://bit.ly/16aiIsz — @vkhosla

Life In 2013: “Baby making loud irritating noises in public space” refers to the iPad Mini game she’s playing. — @Ihnatko

Conducting interviews via Twitter DM is the new meeting in a darkened parking garage. — @mims

“Pretty sure Burning Man is the new golf,” Christopher Mims said in a Twitter message. — @davewiner

Who Are Those Guys?

First, they’re not all guys. Second, we have to confess that we cleaned up the punctuation and stuff in the tweets. Here’s the list of tweeters we followed this month:

Chris Adamson, Cory Doctorow, Bill Dudney, Chris Espinosa, Ina Fried, Andy Ihnatko, Ron Jeffries, Vinod Khosla, Brian Marick, Erin McKean, Christopher Mims, Jen Myers, Michael Nygard, Ben Rady, Noel Rappin, Danny Sullivan, Gina Trapani, and Dave Winer.

Antonio Cangiano does our books; he also wrote the excellent Technical Blogging and you can subscribe to his reports on new books in technology and other fields here.

Nancy Groth and Michael Swaine are responsible for the news, or really just for reporting it.

Fair’s fair. You can follow us at www.twitter.com/pragpub.

Rothman & Lester

The Nuts and Bolts of Career Development

by Johanna Rothman and Andy Lester

Johanna and Andy share tips on career development and becoming a T-shaped person.

Johanna: I was thinking about something you said in the June article, Andy. You said, “I know one piece of advice I give is that you should be able to add one new interesting, sellable thing to your resume every quarter."

Did you see the article in IEEE Spectrum this week, titled “The STEM Crisis is a Myth?”

The main point is that there are plenty of STEM (science, technology, engineering and mathematics) workers, but no one wants to pay for training. Robert N. Charette says, “[u]nlike in decades past, employers seldom offer generous education and training benefits to engineers to keep them current, so out-of-work engineers find they quickly become technologically obsolete.”

Andy: That sounds about right to me. Especially when times get tough, budgetary “extras” like training are the first line items to get redlined.

Johanna: I thought we could take your idea and Charrette’s idea and help people with action plans and help them figure out how to plan their next steps for their career.

Andy: I think the first steps has to be to realize that you need a plan, and that nobody is going to improve your saleability for you. If you learn new stuff on the job, or you get training, it’s for the company’s benefit, not yours. If you get some benefit from it, good for you, but that’s coincidental.

Johanna: Your job is to keep learning. I talk about four dimensions of technical skill in Hiring Geeks That Fit: functional skill, domain expertise, tools and technology, and industry expertise.

You have to decide which areas you’re going to learn about and when. And you can’t neglect the non-technical skills. If you forget your influence and negotiation skills, how can you get anything done?

Early in my career, I focused a lot on functional skill. I wanted to be the best developer and designer I could be. I also learned a lot of tools and technology along the way. But if you only focus on tools and technology, and don’t go deep into a domain or functional skills, you don’t add saleability, your value. You won’t think in the terms that let you add a line to your resume that says something like, “Created build scripts that reduced build time from 2 days to one hour. That saved the team 6 person-weeks every day.”

Andy: I think part of it also is that we don’t think in terms of the details. We think big words like “Linux” and “Ruby” and “Oracle” as our skills, and they are. But if you’ve set up Nagios to monitor a server, you have Nagios skills. If you’ve used Amanda to do automated backups, then you have Amanda skills. Not only are those good keywords to have on your resume, they also show that you’re not just a programmer.

On the other hand, you don’t want your resume to include everything you’ve ever done. I cringe when I see “Microsoft Office” or “Firefox” on a resume. Those are givens. I don’t think it’s a given, however, that because you know Linux you can write significant bash scripts. It’s also worth thinking of your skills in terms of subfeatures of the language, especially languages like Ruby and Perl where there is such a wealth of modules that make the base of many modern shops. If you know Perl and you use Moose (an object framework) and Catalyst (an app framework), then put Moose and Catalyst on your resume. Don’t sell yourself short in what you know.

Johanna: Be ready to explain what these skills are in the interview. As a hiring manager, I might not know what Nagios or Amanda are, but I want to hear you talk about them. If someone tells me they have version control, or Git or SVN, or ClearCase skillsets, I have many questions I can ask them.

If you want to keep learning, what areas do you think people should learn about, Andy?

Andy: I think it’s not so much as what they should learn about specifically, like "Go learn Ruby or Scala” as much as it is “Go learn something that is dissimilar to what you do now.”

Johanna: So you become more of a T-shaped person? A T-shaped person is someone who has a main skill, maybe programming/development. Maybe even in one specific area. Think of that as a stick. Now, the T part is a bar on top of that stick. That’s where you hang the other skills.

Andy: That’s part of it, but it doesn’t necessarily have to be a different skills.

Johanna: Maybe you’ve learned a fair amount about automated testing. Maybe you’ve got some SQL skills. Maybe you’ve got some DevOps. You don’t have to be an expert in the other skills. You have to know enough to be helpful and useful.

Andy: That could be it, but it could also still be in your main area of expertise. Maybe you’re a Linux sysadmin, and what I’m suggesting is not that you go learn programming, but that you go do a BSD install and explore the differences between the Linux you know and this BSD that can be radically different. Similarly, if you’ve done PHP all your life, go learn Java, or better yet, C.

And by all means, if you’re a programmer who’s never delved into functional programming languages like Haskell or Erlang, go do so. They have an entirely different way of looking at problems. None of this is so that you can say “Hey, look, I learned some Haskell, so now I can put Haskell on my resume.” It’s about actually becoming a better, more widely-read worker.

Johanna: One of the ways I learned to be a better programmer was to read more. Period. The more I read about science, not just science fiction and fantasy, the more I read about management and economics, the better my code got.

Andy: That’s my other suggestion. Go learn something new about something.

Johanna: I’m not exactly sure why. But the serendipity of taking ideas from around the world and across many disciplines changed the way I thought.

Andy: I especially think that it serves all of us IT people well to learn more about business. Some of the best time I’ve ever spent was in a couple of Tuesday night community college business classes for a few months. I don’t know how much business coursework universities are requiring of their IT/CS graduates these days, but it can’t hurt to get more. Remember: We are in IT to help business. Period.

Johanna: Right.

Andy:If you’re getting paid for it, it’s a business that’s paying for you. You work for a non-profit? They’re still a business. Here’s a big idea: Go take a marketing class. gasp. Yes, IT people, go take a marketing class. Learn about product lifecycles and pricing and how to communicate about the products. Every project you work on is effectively a product in itself.

Learn to think product. Even in the world of open source, each project is a product that presumably you want people to use and find out about. That’s product management and marketing. (And I just wrote about it in this new article I just wrote.

Johanna: To plan your next steps for your career, you need an action plan. Action plans are small concrete steps that begin with verbs. I like to make action plans small enough that I can finish something inside of a week. That way, I can tell if I’m making progress on the plan. This is especially true if you have a full-time job, since you want something you can see progress on even though it’s not the primary focus of your day.

Andy: How do you suggest you make a plan?

Johanna: You can use personal kanban, which I like. You can use a grid. If you do an action plan with your manager, you can create some small steps where both of you decide what your next steps are. But I see all too often, that the manager is not engaged. But you are engaged. So do it yourself, no matter what. You need an action, and a due date. That’s the minimum. As long as the action is small enough, you’ll do it. In a personal kanban, you make a todo list that’s small enough and you’re fine.

Andy: Do you actually suggest involving your manager? Do you see managers being useful in this? Because I can’t imagine any manager saying “Yeah, that’s great, let me help you learn a language unrelated to the work we do here” (any but the most enlightened). Say you do want to get your manager on board. How do you sell her on the idea?

Johanna: Well, in Behind Closed Doors, Esther Derby and I suggest you do career development with your manager. And you’re right. Most managers have never had anyone do career development with them, so they have no idea how to do career development with anyone else. And the idea of doing career development that’s not focused on something for this job? Horror of horrors! As long as the development is for your job, you explain what’s in it for the manager. You ask for the one-on-one if you’re not having them once a week or every other week. If the development is not for your job, do it yourself, outside of work time.

Andy: Can you give examples of a specific goal or set of goals?

Johanna: When I was transitioning into project management and people management, I told my manager I wanted to gain more interpersonal and project management skills. I thought I had the rough skills, but not enough interpersonal skills. She agreed. I told her I would work on my negotiation and influence skills. I had an action plan. I made a list of books to read. I practiced on her. I practiced on other people, all of which were on my list. She finally told me to stop practicing. My influence skills were just fine. :-)

Review your current career. Where do you think you are? What skills do you have, if you think about my concept of dimensions of technical skills and non-technical skills? Where are you solid? Where are you light? Think about which skills you want to improve. Now, think about Andy’s idea of “Improve one skill a quarter.” What do you want to make an action plan for?

Andy: Think about where you want to be in a year, in the next five years. Do you want to be doing the same thing five years down the road?

Johanna: Create an action plan that will get you there, one quarter at a time. You’ll change this action plan. This is a start. Let us know how it goes.

Johanna Rothman helps leaders solve problems and seize opportunities. She consults, speaks, and writes on managing high-technology product development. She enables managers, teams, and organizations to become more effective by applying her pragmatic approaches to the issues of project management, risk management, and people management. She writes the Pragmatic Manager email newsletter and two blogs on www.jrothman.com.

Andy Lester has developed software for more than twenty years in the business world and on the Web in the open source community. Years of sifting through résumés, interviewing unprepared candidates, and even some unwise career choices of his own spurred him to write his nontraditional book on the new guidelines for tech job hunting. Andy is an active member of the open source community, and lives in the Chicago area. He blogs at petdance.com, and can be reached by email at andy@petdance.com.

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

Clojure and Polymorphism

Taking on Different Forms

by Michael Bevilacqua-Linn

Java and Clojure have different approaches to polymorphism. Understanding how Clojure uses polymorphism is critical to Clojure mastery.

Welcome again to the Pragmatic series on Clojure!

Last month, we took a brief look at Clojure’s facilities for concurrent programming. We saw how Clojure’s immutable data structures, software transactional memory, and managed reference types combine to provide a high-level framework for concurrent programming.

This time around we’ll examine Clojure’s take on another mainstay of modern programming languages, polymorphism.

Most programmers have an intuitive idea of what polymorphism is but I’ve always found it a bit hard to explain, mainly because it isn’t a single concept. Rather, it’s a family of related programming language concepts that have to do with a function, method, or data type taking on different forms, depending upon its arguments.

Java has several different forms of polymorphism. The one that’s most commonly mentioned in explanations of polymorphism in Java is subtype polymorphism. This is a familiar feature of object oriented languages that allows a method to be overridden in a subclass. The method implementation that’s invoked depends on the runtime type of the object that the method is called on.

Java’s generics implement another kind of polymorphism, parametric polymorphism. With parametric polymorphism, a function or data type takes type parameters. For instance, Java’s Map interface takes type parameters that indicate what types the keys and values are for a particular map instance.

Finally, method overloading, the ability to have multiple methods with the same name but different arities and argument types, is a form of polymorphism known as ad-hoc polymorphism.

These forms of polymorphism have different goals. Subtype polymorphism allows us to program to interfaces, or to create specialized versions of a type. Generics, or parametric polymorphism, let us create data structures and functions that can handle many different types without compromising static type safety.

Finally, method overloading, or ad-hoc polymorphism, allows us to create different implementations of the same method that take different arguments. Taken together, these forms of polymorphism make Java quite a bit more flexible than it would otherwise be.

Clojure also supports several types of polymorphism. Since Clojure is dynamically typed, it has no need for parametric polymorphism. Similarly, since it’s dynamically typed it’s not possible to override methods in the same was as it is in Java, though Clojure does provide support for the same function to take varying numbers of arguments.

Clojure does let us create new classes and subclasses directly using its Java interop features; however this is only common when writing code that needs to rely on existing Java code. Instead, Clojure relies on two other features for polymorphism, multimethods and protocols.

These forms of polymorphism are more flexible than the polymorphism in Java. To see how, let’s examine the Expression Problem, a fancy name for a familiar problem. Briefly, if we’ve got an interface, there are two directions we might want to extend it along. We might want to add new implementations of it, or we might want to add new operations to it, as the following chart shows.

We often need to be be able to do this without modifying the original source, for instance, when we’re working with a third party library. In traditional object oriented languages, subtype polymorphism makes it possible to add new implementations of an existing interface, but next to impossible to add new operations.

According to The Expression Problem’s original definition, in a short paper by Philip Wadler while he was working at Bell Labs, the Expression Problem only applies to statically typed languages. Many of the difficulties in solving it are around doing so in a way that doesn’t involve working around static typing with casts or other hacks.

However, there’s still plenty of complexity surrounding solving the Expression Problem cleanly even in the absence of static typing, as anyone who has monkeyed around with Ruby’s open class system can attest. Clojure’s approach to polymorphism provides some very clean options to help solve the problem.

Let’s take a look at the more flexible of the two options first, Clojure’s multimethods. Multimethods let us specify an arbitrary dispatch function. When a multimethod is called, its arguments are first passed into the dispatch function and the value of the function invocation is used to determine which method is called.

This might seem a bit abstract, so let’s take a look at a simple concrete example. We can create a multimethod using defmulti, which takes a method name and a dispatch function. Here, we create a multimethod named test-multimethod, which uses the identity function as its dispatch function.

| (defmulti test-multimethod identity)

As we can see from the following snippet, the identity function simply takes a value and returns it.

| => (identity :foo)
| :foo

Now we can define individual methods of the same name, test-multimethod. Methods must take the same number of arguments as their corresponding dispatch function and each method definition is associated with a value that the dispatch function is expected to return. When a method is called, the associated dispatch function is first invoked and its return value is used to determine the correct method to call.

Here, we create two methods both named test-multimethod. The first will be called when the associated dispatch function returns :foo, the second when it returns :bar. We don’t care about the parameter being passed to the method in this simple example outside of the dispatch function, so in the method definitions we use an underscore for its name. This is idiomatic in Clojure.

| (defmethod test-multimethod :foo [_]
| "foo-method was called")
| (defmethod test-multimethod :bar [_]
| "bar-method was called")

If we call test-multimethod with :foo and then :bar, we can see the corresponding methods are called.

| => (test-multimethod :foo)
| "foo-method was called"
| => (test-multimethod :bar)
| "bar-method was called"

If we call it with a value for which there’s no corresponding method, we get an exception.

| => (test-multimethod :baz)
| IllegalArgumentException No method in multimethod 'test-multimethod'
| for dispatch value: :baz clojure.lang.MultiFn.getFn (MultiFn.java:121)

Let’s take a look at a more involved use of multimethods. We’ll create a couple of shapes using maps, and then define a multimethod that calculates their perimeter. The definition for our multimethod is below.

| (defmulti perimeter (fn [shape] (:shape-name shape)))
| (defmethod perimeter :circle [circle]
| (* 2 Math/PI (:radius circle)))
| (defmethod perimeter :rectangle [rectangle]
| (+ (* 2 (:width rectangle)) (* 2 (:height rectangle))))

Here, we’ve got a vector that has a circle and a rectangle in it.

| (def some-shapes [{:shape-name :circle :radius 4}
| {:shape-name :rectangle :width 2 :height 2}])

And here we map the multimethod over our shapes.

| => (map perimeter some-shapes)
| (25.132741228718345 8)

Now if we want to add an area operation over our existing shapes, we can create a new area multimethod.

| (defmulti area (fn [shape] (:shape-name shape)))
| (defmethod area :circle [circle]
| (* Math/PI (:radius circle) (:radius circle)))
| (defmethod area :rectangle [rectangle]
| (* (:width rectangle) (:height rectangle)))

Which we can map over the shapes we’ve got.

| => (map area some-shapes)
| (50.26548245743669 4)

To add a new shape we implement new methods that cover our existing operations. In the following, we add support for squares.

| (defmethod perimeter :square [square]
| (* 4 (:side square)))
| (defmethod area :square [square]
| (* (:side square) (:side square)))

Now we can add a square to our test shapes, and we can treat squares as we did our existing shapes.

| (def more-shapes (conj some-shapes
| {:shape-name :square :side 4}))
| => (map perimeter more-shapes)
| (25.132741228718345 8 16)
| => (map area more-shapes)
| (50.26548245743669 4 16)

Multimethods are very flexible, but every method call requires two function calls, the first to the dispatch function and the second to the actual method. Clojure has another polymorphic feature, protocols, that are able to piggyback directly onto Java’s method calls.

Protocols are less flexible than multimethods, as they can only dispatch on type, much like Java’s methods do. However, this is often all we need as Clojure also gives us a way to create new types, defrecord.

Let’s take a look. Here we’ll define a protocol NameExtractor that has a single operation, extract-name. Notice how there are no implementations, a protocol simply defines a set of operations.

| (defprotocol NameExtractor
| (extract-name [this] "Extracts a name from a person."))

Now we can create a new SimplePerson type using defrecord.

| (defrecord SimplePerson [first-name last-name house-num street])

Clojure’s records give us several handy features. Clojure automatically creates a constructor that’s the name of the record prepended with ->. Here, we use the constructor to instantiate a new person.

| => (def a-person (->SimplePerson "Mike" "Linn" "123" "Fake St."))
| #'ArticleCode.core/a-person

As we can see, this creates a new type, much as creating a Java class would.

| => (type a-person)
| ArticleCode.core.SimplePerson

However, we can also treat records as if they were maps. Here, we look up the first-name field just as we could with a Clojure map.

| => (:first-name a-person)
| "Mike"

Now, we can extend the SimplePerson type we just created to support the NameExtractor protocol using extend-type, as we do below.

| (extend-type SimplePerson
| NameExtractor
| (extract-name [this]
| (str (:first-name this) " " (:last-name this))))

At first glance, this may seem a bit like creating an interface in Java and having a class extend it. However, there’s a crucial difference. Creating protocols using defprotocol is completely decoupled from creating a new type using defrecord.

This can independently create both protocols and types. More importantly, we can extend any type to support any protocol that makes sense for it to support and we can do this after they’re both created, which means we can use them to solve The Expression Problem.

As a convenience, Clojure lets us extend a protocol to a record when we create it. Here, we create a new record that has a bit more internal structure, it uses maps to represent names and addresses. At the same time, we extend it to support our NameExtractor protocol.

| (defrecord ComplexPerson [name address]
| NameExtractor
| (extract-name [this]
| (str (-> this :name :first) " " (-> this :name :last))))

This shows how we can extend an existing protocol to support a new type. Creating a new protocol that supports existing types is just as easy. In the following code, we create a new protocol AddressExtractor, and then use it to extend our existing person types.

| (defprotocol
| AddressExtractor
| (extract-address [this] "Extracts and address from a person."))
| (extend-type SimplePerson
| AddressExtractor
| (extract-address [this]
| (str (:house-num this) " " (:street this))))
| (extend-type ComplexPerson
| AddressExtractor
| (extract-address [this]
| (str (-> this :address :house-num)
| " "
| (-> this :address :street))))

That completes our whirlwind tour of Clojure’s polymorphic features! Join us again next month when we discuss organizing code into larger units using Clojure’s namespaces.

Michael Bevilacqua-Linn has been programming computers ever since he dragged an Apple IIGS that his parents got for opening a bank account into his fifth grade class to explain loops and variables to a bunch of pre-teenagers. He currently works for Comcast, where he builds distributed systems that power infrastructure for their next generation services, and wrote Functional Programming Patterns for the Pragmatic Bookshelf. He tweets occasionally at @NovusTiro.

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

The Luminus Framework

This Clojure-based Micro-framework Cuts to the Chase

by Dmitri Sotnikov

How to build a web application quickly using Clojure and the Luminus micro-framework.

You might have heard of Clojure, a relatively new Lisp dialect that runs on the JVM. The primary driving forces behind the language are its simplicity and pragmatism. As such, it has quickly gained attention from developers and its popularity continues to grow.

In this article we’ll see how we can quickly build a Clojure web application using the Luminus micro-framework.

Where Are the Frameworks?

The Clojure community eschews heavy frameworks such as Rails or Django. Instead, Clojure developers are encouraged to assemble their applications by leveraging the specific libraries needed for their application.

The rationale behind this approach is that the use of behemoth frameworks add unnecessary complexity and restrictions whereas using libraries puts control squarely in the hands of the developer.

This approach works well for experienced Clojure developers who are familiar with the ecosystem, know what libraries to use, and have honed their own preferred best practices.

Unfortunately, if you’re new to Clojure this can all be rather overwhelming. How do you locate quality libraries? What’s the best way to structure your applications? How do you accomplish basic tasks, such as HTML templating or routing your requests?

This is where Luminus comes in. The project site not only provides documentation with many examples of how common tasks can be accomplished, it also lists many popular libraries that work well together.

Clojure applications are commonly built using the Leiningen build tool (tagline: for automating your Clojure projects without setting your hair on fire). Leiningen is the Clojure equivalent of the popular Java build tool called Maven. Leiningen handles many aspects of the application lifecycle such as managing dependencies, running tests, and packaging the application for deployment.

Leiningen also supports creating project templates that can be used to quickly instantiate a particular type of application. Luminus provides such a template for creating web applications. The applications created using this template will have all the boilerplate configured for you and demonstrate a good way to structure your code. In the next section, we’ll take a look at using Luminus to initialize our application and explore its contents.

Creating a Luminus Application

If you’d like to follow along, you’ll need a few things installed first. Clojure applications are hosted on the JVM and, as such, you’ll need a working JDK. You’ll also need to set up Leiningen to create the project. Finally, I recommend using a Clojure-aware editor with REPL support. Light Table is a good option for starting out.

Assuming that we have all of the above set up, we can go ahead and create our application. This is done by running the following command in the terminal:

| lein new luminus hello

If the above ran successfully, then you should have a new directory called hello that contains your new application.

Luminus applications are built on top of Ring. Ring is an HTTP routing library inspired by Python’s WSGI and Ruby’s Rack. It provides a Leiningen plugin for running the application. Let’s navigate to the application folder and run the following command there:

| lein ring server

This will start our application in development mode and open a browser pointing to the home page. The page is set up with a basic Bootstrap UI and contains some useful links to get you started.

Let’s open the project in Light Table and see what’s inside. To do that, navigate to the workspace tab, select the folder in the menu and navigate to the root directory of the project. As you can see, the project contains a number of files and directories. Let’s see how they’re organized.

In the root directory we have a project.clj file. It is used to build the application and track its dependencies.

| (defproject hello "0.1.0-SNAPSHOT"
| :description "FIXME: write description"
| :url "http://example.com/FIXME"
| :dependencies [[org.clojure/clojure "1.5.1"]
| [lib-noir "0.6.9"]
| [compojure "1.1.5"]
| [ring-server "0.3.0"]
| [selmer "0.4.2"]
| [com.taoensso/timbre "2.6.1"]
| [com.postspectacular/rotor "0.1.0"]
| [com.taoensso/tower "1.7.1"]
| [markdown-clj "0.9.31"]]
| :plugins [[lein-ring "0.8.7"]]
| :ring {:handler hello.handler/war-handler
| :init hello.handler/init
| :destroy hello.handler/destroy}
| :profiles
| {:production {:ring {:open-browser? false
| :stacktraces? false
| :auto-reload? false}}
| :dev {:dependencies [[ring-mock "0.1.5"]
| [ring/ring-devel "1.2.0"]]}}
| :min-lein-version "2.0.0")

The project also generates the ring configuration for our handler. Ring will use this to bootstrap our application in the servlet container when it runs.

The src directory contains the Clojure source files and HTML templates. The resources directory contains the static resources such as CSS and JavaScript files while the test directory is reserved for any test code. When the application is packaged for production only the content of the src and resources directories will be included.

All the application logic lives in the namespaces under the src directory. Clojure namespaces follow the Java directory structure. The core namespace of the application is hello, so all the namespaces will be found under the hello directory.

The Application Handler

The hello.handler namespace is used to bootstrap the application. It contains the init and destroy functions:

| (defn init
| "init will be called once when
| app is deployed as a servlet on
| an app server such as Tomcat
| put any initialization code here"
| []
| (timbre/set-config!
| [:appenders :rotor]
| {:min-level :info
| :enabled? true
| :async? false ; should be always false for rotor
| :max-message-per-msecs nil
| :fn rotor/append})
| (timbre/set-config!
| [:shared-appender-config :rotor]
| {:path "hello.log" :max-size (* 512 1024) :backlog 10})

| (defn destroy
| "destroy will be called when your application
| shuts down, put any clean up code here"
| []
| (timbre/info "hello is shutting down..."))

The init function is called once when our application starts up. By default it sets up a sensible logging configuration. The destroy function is called when our application is shutting down. Any cleanup logic you might have would go there.

The handler also creates an app definition. Luminus uses the app-handler helper function from github.com/noir-clojure/lib-noir to wrap the application routes using the standard middleware. It also provides keys for specifying custom middleware and access rules.

| (def app (middleware/app-handler
| ;;add your application routes here
| [home-routes app-routes]
| ;;add custom middleware here
| :middleware []
| ;;add access rules here
| :access-rules []))

This handler will be used for standalone deployment. We also have a war-handler defined. It wraps our app with additional middleware needed for application server deployment.

| (def war-handler (middleware/war-handler app))

Application Routes

The routes represent the public interface of the application for interacting with the clients. Each route defines a URI that is associated with a handler function. If we navigate to the hello.routes.home namespace we’ll see where the / and /about routes are defined.

| (defroutes home-routes
| (GET "/" [] (home-page))
| (GET "/about" [] (about-page)))

These routes respond to HTTP GET requests and use the home-page and about-page handler functions to render the home and about pages.

If we look at the home-page function, we can see that it calls the render function from the hello.views.layout namespace to generate an HTML response from the home.html template.

| (defn home-page []
| (layout/render
| "home.html" {:content (util/md->html "/md/docs.md")}))

The template is rendered using a context map containing the dynamic data. In this case, the data contains the HTML documentation parsed from the file resources/public/md/docs.md. This file contains some helpful links for getting started.

HTML Templating

Luminus uses Selmer as its default templating engine. Selmer is based on Django templates and should be quite familiar to anyone who’s used Django style templates. The HTML templates are found under src/hello/views/templates. The home.html template can be seen below:

| {% extends "hello/views/templates/base.html" %}
| {% block content %}
| <div class="hero-unit">
| <h1>Welcome to hello</h1>
| <p>Time to start building your site!</p>
| <p><a class="btn btn-primary btn-large"
| href="http://luminusweb.net">Learn more &raquo;</a></p>
| </div>
| <div class="row-fluid">
| <div class="span8">
| {{content|safe}}
| </div>
| </div>
| {% endblock %}

The home.html template contains a block that renders the home page and extends the base.html template to render the rest of the page layout:

| <!DOCTYPE html PUBLIC "">
| <html>
| <head>
| <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
| <title>Welcome to hello</title>
| <link href="{{servlet-context}}/css/bootstrap.min.css"
| rel="stylesheet" type="text/css">
| <link href="{{servlet-context}}/css/bootstrap-responsive.min.css"
| rel="stylesheet" type="text/css">
| <link href="{{servlet-context}}/css/screen.css"
| rel="stylesheet" type="text/css">
| <script type="text/javascript"> var context = "{{servlet-context}}";
| </script><script src="//code.jquery.com/jquery-1.10.1.min.js"
| type="text/javascript">
| </script><script src="{{servlet-context}}/js/bootstrap.min.js"
| type="text/javascript"></script>
| </head>
| <body>
| <div id="wrap">
| <div class="navbar navbar-fixed-top navbar-inverse">
| <div class="navbar-inner">
| <ul class="nav">
| <li>
| <a href="{{servlet-context}}/">Home</a>
| </li>
| <li>
| <a href="{{servlet-context}}/about">About</a>
| </li>
| </ul>
| </div>
| </div>
| <div class="container">
| {% block content %}
| {% endblock %}
| </div>
| <div id="push"></div>
| </div>
| <div id="footer">
| <div class="container">
| <p class="muted footer-text">Footer content.</p>
| </div>
| </div>
| </body>
| </html>

The base template includes the CSS and Js resources and sets up the header and the footer of the page. The contents of the home template are populated in the content block anchor.

This concludes our whirlwind tour of creating Luminus applications. Please visit the official site for further examples and documentation.

About the Author

Dmitri is the author of Web Development With Clojure and an active member of the Clojure community, you can follow him on GitHub and his blog for news about his current projects. Dmitri currently works at the University Health Network where he develops Clojure projects for the Toronto General Hospital.

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

Game Plan

How to Discover the Natural Dimensions of Game Appreciation

by Chris Crawford

A legend in computer game design offers a project that could make games better.

Here’s something that an eager academic could benefit from. I could do it, but it seems a shame for me to hog such an opportunity that would do me no benefit, when it could definitely advance the career of a graduate student or academic. Besides, I already have too many things to do before I die. I just gave up my 1961 VW truck because I sadly realized that I will never have the time to get the old engine up and running. Sniffle, sniffle.

So here’s the project.

Step 1: Set Up Web Pages for Collecting Data

The subject starts with a page listing lots of games; the subject is then asked to check off the games that s/he is familiar with, including ONLY games that the subject has actually played.

Next, the subject is presented with a list of the games s/he has checked and asked to check the two games that are most unlike each other. This defines “9” for the next step.

The subject now sees a page cross-tabulating the selected games against each other: each game has one column and one row of a table. At the intersections of the rows and columns, the subject is asked to enter a digit from 0 to 9 indicating how similar the two games (one in the row, the other in the column) are. For calibration purposes, “9” is declared to be equal to the distance between the two most distant games that the subject previously specified.

The subject need only fill in half the matrix, as the similarity value is symmetric. Also, the subject will, obviously, not fill in the cell with the intersection of a game’s row with its column. That’s pre-filled with a “0”.

Step 2: Collect the Data

Use whatever protocol you think appropriate for recruiting subjects. Get lots of them. Collect all their data. For each and every pair of games, calculate the mean and standard deviations of the similarity values.

You now have a 2D matrix containing mean and standard deviations for every pair of games in the study.

Step 3: Relaxation Algorithm in Two Dimensions

Now randomly assign each game an (X,Y) position in a 2D space with bounds ranging from, oh, ±50 in each dimension. Then begin a relaxation loop:

| set a net energy scalar to zero
| while (net energy > previous net energy * 1.001)
| For each game i {
| For each game j {
| set a "net force vector" to zero
| calculate Pythagorean distance in the (X,Y) space.
| calculate the difference between that distance
| and the similarity value.
| divide that difference by the standard deviation
| for that pair of games.
| That's the length of a vector. Resolve that vector
| into X and Y values.
| Accumulate the vector into the net force vector
| add to the net energy scalar:
| the square of the difference value divided by
| the square of the std deviation
| }
| move game i by a small fraction of the net force vector.
| }

This will yield the best positions of the games in a 2D space, along with a minimum net energy. Graph the positions of the games on a plane. You will note that they form clusters, with similar games clustering together.

Step 4: Extend to Many Dimensions

Repeat Step 3 using N dimensions, N ranging from 3 to, oh, maybe 10. Record the minimum net energy obtained for each dimension. Graph net energy against N. You’ll get something looking vaguely like this:

In general, the point values will fall with increasing N because more dimensions give the points on the map more room to spread out. What’s interesting here is the fifth data point from the left, representing N = 6. Notice that it is abnormally lower than the rest of the curve. Ta-da! You’ve discovered something: there are six basic traits that most strongly affect peoples’ perceptions of games. Look at the final positions of the games in the six-dimensional space. Sort all the games by its value in each of the six dimensions; this gives you six different lists of games. For each list, look at the top of the list and the bottom of the list and ask, what is most salient about this difference? You should be able to identify some factor that all the games high in the list possess and none of the games low in the list possess. That’s a “natural” dimension of game appreciation.

Step 5: Write It Up and Publish It

Sit back and wait for that Nobel Prize to roll in.

If you need help with any of these concepts, contact me and I’ll explain it in more detail.

Chris Crawford earned a Master of Science degree in Physics from the University of Missouri in 1975. He has published fifteen computer games and five books. He created the first periodical on game design, the Journal of Computer Game Design, in 1987. He founded and served as Chairman of the Computer Game Developers’ Conference, now known as the Game Developers’ Conference. Crawford has given hundreds of lectures at conferences and universities around the world, and published dozens of magazine articles and academic papers. He served as computer system designer and observer for the 1999 and 2002 NASA Leonid MAC airborne missions. His current work concerns interactive storytelling technology. He lives in southern Oregon with his wife, 3 dogs, 7 cats, and 10 ducks.

This article also appears on Chris’s blog. That’s the best place to continue the discussion.

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

Mobile Applications vs. Web Pages

Competing Interests vs. User Experience

by Brian Tarbox

Are there service for which you have both the mobile app and a link to the web site? Is there a hint there that something is not right?

One of the major battles going on in the mobile space is apps versus web pages. You can, for example, get to Facebook by loading www.facebook.com in your mobile device’s web browser or you can run a dedicated application. It seems like a simple choice, with both options providing a fine experience, but it’s actually a battleground with substantial implications, both for you as a consumer and for the usual set of tech giants.

As always, the trick is to follow the money.

You as the Product

When you stay in the browser you remain in the land of web advertising, i.e., Google. Every page that gets loaded is an opportunity for the buying and selling of advertising on the prime and limited space of your browser window. So that’s good for Google.

Many, if not most services, now also provide a dedicated mobile application with various levels of tailoring to specific devices. The upside to the user is that the application will often provide features that are not available on the web page (though this is a very dynamic space).

The upside to the service provider is lock-in. Once you launch the mobile application you are entirely under their control and can not simply click away to another web page. You can, of course, switch to a different app but that is a conceptually larger switch than simply changing pages within a browser... and so there is cognitive inertia to remain within the application. This is all good for the service provider such as Facebook or LinkedIn. To the degree that the app exploits the capabilities of the particular mobile device, it’s also good for the device maker (Apple, Samsung, etc.), though likely more work for the developer.

So, there are a range of competing interests and agendas lying just under the surface of our simple web page versus app decision.

Your Experience May Vary

Stepping back from the question of which company benefits from our choice we can look at how the choice affects us as mobile-device users. If you regularly use 10, 20, or 40 services, ask yourself if you’re more comfortable with that many separate apps living on various home screens and/or folders, and/or do you prefer to manage them with web bookmarks and tabs?

That’s a real question that can have different ‘right’ answers for different people (i.e., this isn’t a religious question like where the braces go in a Java program).

Part of the answer has to do with your level of commitment to a service. Browsing to a web page is perhaps the lowest level of commitment possible... whereas installing and then running an application indicates significantly more interest.

Of course, many websites aggressively ‘invite’ you to download and use their app... which is fine if you want to be a regular at their site, but extremely annoying otherwise. It sometimes feels like when Radio Shack wants your zipcode and email address to complete a simple purchase.

"I’m just buying some batteries... leave me alone!"

There are, of course, other considerations, such as whether or not your service works when out of WiFi range (there are still such spots even in major cities).

For things like Facebook, LinkedIn, and the like, the answer is mostly no; so you lose little by just using a web page. For the many other programs that can operate just fine while disconnected, going the app route may make more sense.

Yet another area of difference, at least on Apple devices, is the whole issue of in-app purchases. Apple requires a 30 percent cut of any purchases made from within one of their applications. Many apps, most notably Amazon’s Kindle reader application, removed the ability to purchase books from within their application rather than hand over 30 percent of their revenue to Apple. They instruct you to go to Amazon’s website to make purchases... which you can then download for free to your Kindle reader on the ‘i’ device of your choice.

Something Here Is Broken

One area that bothers me about all of this is the poor integration of apps with web links. As a software developer, I spend a fair bit of time on LinkedIn, reading articles, maintaining connections, and building my profile. It’s a service I use a lot so I’m happy to have installed their application on my various devices. I can simple launch the app, bypass the usual login nonsense, and start productively using the service. And then someone sends me an email with a link to LinkedIn.

Often these emails come from LinkedIn itself... inviting me to go read some article... which I actually want to do. But since it’s a web link it tries to take me to their website rather than their application... whereupon it asks me to log in. Which I do not want to do... because I’ve already authenticated on their app (and may not even currently remember my password). So their own integration is broken.

Perhaps no one else is bothered by this but I find a lot wrong with it. First, it shows a lack of attention to detail. Second, it subverts the service’s own intention: which is to get you inside the walls of their application. Third, it causes me to use more of scarce resources on my mobile device to inevitably have both the service’s app and their web page open at the same time. Fourth, it’s unnecessary since it’s entirely possible to create a link that launches the app if it’s available, or a web page if it’s not.

One last bit of unnecessary discord has to do with notifications. I have email notifications turned on for LinkedIn so I get an email when various events happen. I suppose I could turn this off but I don’t run the LinkedIn app every day so it is handy to know when a contact has an update. But now I have to read the notification in both my email and in the LinkedIn app. Neither of them knows about the other, even though at the logical level they are the same notification.

All of which leads me to more often than not decline to install applications that have acceptable websites. Since at least some companies don’t want me to do this, perhaps they could address these issues.

Your thoughts?

As I was writing this article I got a notification of an article on LinkedIn... the article jumped to a blog post by TypeSafe... which I could then comment on by logging in with Facebook! To quote Buckaroo Bonzai ‘it do make the ganglia twitch!’

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.

Creating the Apple ][

A Story from Personal Computing’s Early Days

by Michael Swaine and Paul Freiberger

Jobs in tears, Woz playing pranks, and the ad in Playboy: the crazy days leading up to the release of the Apple ][.

The Apple ][ (Apple spelled II that way) was one of the most significant early personal computers. But its significance to Apple was greater than to the users or the industry. After the Apple ][ came out, Apple was on its way to becoming the most-watched computer company, and eventually the most-watched company of any kind.

Before the Apple ][—well that’s a story worth telling.

Here’s part of it.

The Cast, in Order of Appearance:

The Prankster: Stephen Gary Wozniak. He didn’t want to start a company, he just wanted to build computers.

The Evangelist: Steven Paul Jobs. He got people to do things.

The Gamester: Al Alcorn. Personal computers were toys, the real business was in game machines.

The Everything-else Guy: Rod Holt. From another generation and the opposite coast, he couldn’t say no to Jobs.

The Gambler: A. C. “Mike” Markkula. He was retired when he decided to roll the dice with two kids in a garage.

The Link: Bill Fernandez. If he hadn’t introduced the two Steves....

The Kid: Chris Espinosa. He rode to work on his bike.

The Other Kid: Randy Wigginton. He loved hanging out with Chris and Woz at Homebrew.

The Byte Shop Owner: Paul Terrell. Computer hobbyists used to hang out at his shop.

The Ad Man: Regis McKenna. Jobs wanted only the best, and McKenna saw past the bare feet and scruffy beard.

The Logo Designer: Rob Janov. He gave Apple its image.

Scotty: Michael Scott. Apple’s first President was in charge of the playground that was Apple.

The Frenchman: Jean-Louis Gasseé. He understood Apple’s anarchic genius.

The Ringmaster: Jim Warren. His inspiration for the West Coast Computer Faire was the Renaissance Faire.

Computer Libber: Theodore Holme Nelson. The revolution’s Tom Paine.

Woz

By the fall of 1976, Woz had already made progress on the design of his new computer. The Apple ][ would embody all the engineering savvy he could bring to it. It would be the embodiment of Steve Wozniak’s dream computer, one he would like to own himself. He had made it considerably faster than the Apple I. There was a clever trick he wanted to try that would give the machine a color display, too.

Wozniak was skittish about forming a company from the start, and now he was worried about working full-time for it. He had always enjoyed his job at Hewlett-Packard. HP was legendary among engineers for its commitment to quality design. It seemed crazy to give up a job at HP. Still....

Woz had shown his Apple I design to the managers at Hewlett-Packard with the hope that he could convince the company to build it. But they told him that the Apple was not a viable product for HP, and gave him a release to build the machine on his own. He’d also attempted, twice, to join computer development projects at HP—the project that eventually developed into the HP 75 computer and a handheld BASIC machine—and, lacking the experience and the academic credentials HP expected, was turned down for both.

Wozniak was unarguably an outstanding engineer, but he really wanted to work on projects that interested him, and then only for as long as they interested him. Jobs understood his friend’s restless genius better than anyone. He constantly urged Woz on, and the pressure sometimes led to arguments.

Woz had no interest in designing the connector for hooking the computer up to the television set, nor did he want to design the power supply. Both jobs required skill in analog electronics. The digital circuitry of a computer basically comes down to power on or off, a 1 or a 0. To design a power supply or send a signal to a television set, an engineer has to consider voltage levels and interference effects, things Woz didn’t know or care about.

The Everything-Else Guy

Jobs turned to Al Alcorn, his boss at Atari, for help, and Alcorn suggested that Jobs talk to Rod Holt, a sharp analog engineer at Atari. When Jobs phoned Holt in the fall of 1976, Holt was feeling dissatisfied with his position. “I was a second-string quarterback,” he said. Holt suspected he had been hired just in case his manager, whose hobby was racing motorcycles, got hurt. But Holt was sceptical about Jobs. He had a daughter older than Steve Jobs. And he had trouble understanding the West Coast culture that shaped Apple’s founders.

Holt told Jobs that as an Atari engineer, his helping Apple represented a conflict of interest. Besides, he added, he was expensive. His services ran at least $200 a day. That didn’t faze Jobs. “We can afford you,” he said. “Absolutely.” Holt liked the brashness. Regarding the conflict of interest, Jobs told him to check with his boss.

Alcorn told Holt, “Help the kids out.”

Holt started working after hours at Atari on Apple’s television interface and power supply, concentrating especially on the latter. He persuaded Jobs not to challenge FCC regulations by trying to build an interface for a television set. Holt knew that the FCC would hassle them over interference. Jobs was frustrated at first, but then hit on a clever way out of the problem. Just make it easy for someone else to design the modulators to link the computer to a television set. If regulations got bent, the culprit wouldn’t be Apple.

Soon Holt was on board full-time. Wherever noone else had the technical or managerial expertise to solve a problem, Holt took care of it. “I was the everything-else guy,” he said. As the company began growing faster than even Mike Markkula had hoped, Holt found that he was overseeing the quality control department, the service department, the production engineering department, and the documentation department. Things got so stressful that Holt threatened to resign several times. But he couldn’t do it. Apple was just too interesting to leave.

Rod Holt was one of the first employees of Apple once Markkula came aboard, but the real first employees date back to the Apple 1 era. Bill Fernandez, the friend who had introduced Jobs and Woz several years earlier, was the first hire. As a formality, Jobs tested Fernandez with a series of questions about digital electronics before officially hiring him to manufacture Apple I computers. Fernandez practiced the Bahai faith and he and Jobs spent many hours discussing religion in Jobs’s parents’ garage that doubled as their workshop.

Other early employees included high-school students Chris Espinosa and Randy Wigginton, Woz’s friends from the Homebrew meetings. After the meetings, the trio routinely headed to Woz’s house to continue discussing ways to improve the capabilities of the Apple I to turn it into something more powerful.

Espinosa and Wigginton were software hackers. They had no special expertise in designing machines. Instead, they loved writing programs. Whenever Woz brought the Apple I to the Homebrew meetings, Espinosa and Wigginton would knock off some programs on the spot to demonstrate the machine to club members. Woz had built a working prototype of the Apple ][ by August of 1976, and loaned one to Espinosa, who began developing games and demonstration software for the computer. By actually using the new computer, the self-confident teenager was able to suggest ways to better its design.

Before he went to work for Apple, Espinosa spent a lot of time at Paul Terrell’s Byte Shop. He recalled that a “tall, scraggly looking guy would come in every day and say, ‘We got a new version of the BASIC!’” That was how Espinosa met Steve Jobs.

Later, at Homebrew, Jobs noticed a demo program running on the Apple I. He asked Espinosa, “Did you do that?” Shortly thereafter, Espinosa was working for Apple.

Espinosa spent Christmas vacation of his sophomore year of high school in Jobs’s garage, helping debug the BASIC that would be sold with the Apple ][. Jobs took him under his wing, although Espinosa’s early impression of Jobs was as something other than a paternal figure. “I thought he seemed dangerous,” Espinosa said about Jobs. “Quiet, enigmatic, almost sullen, a fierce look in his eyes. His powers of persuasion are something to be reckoned with. I always had this feeling that he was shaping me.”

Woz Waffles

Jobs then faced the biggest obstacle thus far to his legendary powers of persuasion. By this time, Markkula had agreed to help Jobs and Woz build a real company. The final hurdle was convincing Woz to leave his job at Hewlett-Packard to work full-time for Apple. Markkula would have it no other way.

Woz wasn’t sure he wanted to make the move. Jobs was panicking. All of his carefully wrought plans depended on Woz. Then, one day in October 1976, Woz said that he would not leave his great job at HP, and that his decision was final. “Steve went into fits and started crying,” Woz recalled. Soon Jobs began lobbying Woz’s friends, having them call Woz to persuade him to change his mind.

Woz was afraid that designing computers full-time would be drudgery, unlike the efforts he put into designing the Apple I and ][. Somehow his friends convinced him otherwise, and he finally agreed to leave his job at HP and join Apple full-time. It was a brave move given that Woz imagined that they would, at best, sell no more than a thousand Apple ][ computers.

But Jobs had an entirely different vision and aggressively set out to get people who could help him achieve it—people like Regis McKenna, owner of one of the most successful public relations and advertising firms in Silicon Valley.

Creating an Image

Jobs had placed an ad in the computer magazine Interface Age. He’d also seen the Intel ads in various electronics magazines and was impressed enough to call the semiconductor company and ask who had done them, and got McKenna’s name. Jobs wanted the best for Apple, and, deciding that McKenna was the best, set about getting his firm to handle Apple’s PR.

McKenna’s ads had been very good for Intel, as well as for McKenna himself, whose office decor spelled success. Customarily dressed in a natty suit, McKenna sat behind a large desk backed by photographs of his favorite Intel ads. He spoke softly and reflectively, in sharp contrast to the unkempt and pushy kid who walked into his office one afternoon in cutoffs, sandals, and what McKenna called a “Ho Chi Minh beard.” McKenna was accustomed to taking start-up companies as clients, so Jobs’s garb didn’t put him off. “Inventions come from individuals,” he reminded himself, “not from companies,” and this Jobs was certainly an individual. McKenna listened.

At first McKenna said no, but that didn’t stop Jobs. “I don’t deny that Woz designed a good machine,” said McKenna. “But that machine would be sitting in hobby shops today were it not for Steve Jobs. Woz was fortunate to hook up with an evangelist.”

McKenna eventually succumbed to Jobs’s persistence, and his agency became Apple’s PR firm. The agency immediately made two major moves.

The first was its logo—a rainbow-striped apple with a bite taken out of it. The logo was designed by Rob Janov and with variation, served as the company’s trademark ever since. From a printing standpoint, there was some initial fear that the multiple colors would run together. Jobs vetoed the addition of lines to separate the colors, making the cost of printing the logo very high. Apple president Michael Scott called it “the most expensive bloody logo ever designed.” But when the first foil labels arrived for the Apple ][, everyone loved the look of the design. Jobs made one change: he rearranged the order of the colors to put the darker shades at the bottom. A later president of Apple products, Jean-Louis Gassee, would say that the logo was perfect for Apple: “It is the symbol of lust and knowledge, bitten into, all crossed with the colors of the rainbow in the wrong order... lust, knowledge, hope, and anarchy.”

McKenna also decided to run a full-color ad in Playboy magazine. It was a bold, expensive grab for publicity. A cheaper ad in Byte would have reached virtually all the microcomputer buyers of that time, and Playboy seemed an off-the-wall choice given that there were no demographic studies to support it. “It was done to get national attention,” said McKenna, “and to popularize the idea of low-cost computers.” Other companies had been selling microcomputers for two years, but no one had yet tried to capture the public’s imagination in this way. Apple’s publicity campaign resulted in follow-up articles in national magazines, and not just about Apple, but about small computers in general.

Apple was bringing the idea of a personal computer into the mainstream consciousness.

Jobs’s persistence persuaded McKenna to buy into the Apple dream as it had with Woz, Markkula, and Holt. Woz invented the machine, Markkula had the business sense, McKenna provided the marketing talent, Scotty ran the shop, and Holt was the everything-else guy, but the pushy kid with the scraggly beard was the driving force behind it all.

By February 1977, Apple Computer had established its first office in two large rooms a few miles from Homestead High School in Cupertino. Desks were hauled in and work benches were trundled over from Jobs’s garage. The night before they were to begin working in their new suite, Woz, Jobs, Wigginton, and Espinosa scattered around the 2000-square-foot office playing telephone games, with each trying to buzz one of the other extensions first. The whole thing felt like play. It was hard to imagine that they were starting a real business. “We never thought that we’d grow up to be battling one-on-one with IBM,” said Espinosa.

The Debut

The young company faced a more modest challenge than tackling the company that had defined computer for generations: they had to finish the Apple ][ design in time for Jim Warren’s first West Coast Computer Faire in April and get it ready for production shortly thereafter. Markkula was already signing up distributors nationwide, many of whom were eager to work with a company that would give them greater freedom than microcomputer manufacturer MITS had, as well as provide a product that actually did something.

Steve Wozniak is justly credited with the technical design of the Apple I and Apple ][. Nevertheless, an essential contribution to making the Apple ][ a commercial success came from Jobs. Early microcomputers were typically drab and ugly metal boxes. Steve Jobs decided to spruce up the look of the product. He would encase the device in a lightweight beige plastic shell that melded the keyboard and computer together in a modular design. Woz could design an efficient computer, but he cheerfully admitted that he didn’t care whether or not wires were left dangling out of it. Jobs realized that the Apple had to look presentable to better the competition.

It took a gargantuan effort to ready the Apple ][ for the West Coast Computer Faire. Woz worked day and night, as was his modus operandi, until it was done. Jobs made sure that nobody would miss it. He arranged to have the biggest and most elegant booth at the show. He brought in a large projection screen to demonstrate programs and placed Apple ][ computers on either side of the booth. Jobs, Mike Scott, Chris Espinosa, and Randy Wigginton manned the booth while Mike Markkula toured the auditorium signing up dealers for the company. Woz walked around checking out other machines. All in all, the Computer Faire was a big success for Apple. Everyone seemed to like the Apple ][, although Computer Lib author Ted Nelson complained that it displayed only uppercase letters.

Woz couldn’t resist playing one of his practical jokes. MITS was absent from the show, and with the help of Randy Wigginton, Woz whipped up a brochure on the “Zaltair,” supposedly an enhanced Altair computer.

“Imagine a dream machine. Imagine the computer surprise of the century, here today. Imagine BAZIC in ROM, the most complete and powerful language ever developed,” the fake advertisement purred. Woz was satirizing the marketing hype that he’d learned from Jobs. The brochure gushed on, “A computer engineer’s dream, all electronics are on a single PC card, even the 18-slot motherboard. And what a motherboard....” On the back of the brochure was a mock performance chart comparing the Zaltair to other microcomputers—including the Apple.

Jobs, knowing nothing of the joke, picked up one of the brochures and read it in dismay. He took a quick, nervous scan of the performance chart, and a look of relief came over his face. “Hey,” he said, “We came out okay on this.”

Paul Freiberger and Michael Swaine wrote Fire in the Valley, the seminal history of the personal computer and the source for the movie Pirates of Silicon Valley. This article is adapted from the upcoming Third Edition from the Pragmatic Bookshelf.

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

Puzzle

A Sudoku-Anagram Mashup Solution

by Michael Swaine

Solution to last month’s puzzle.

No puzzle this month, but we do have the solution to last month’s puzzle.

The puzzle was a Sudoku that used letters rather than numbers, but otherwise worked just the way you’d expect. Your task was to fill in the empty cells so that every row, column, and each of the 3x3 squares contained one each of the nine letters you found in the cells already filled in. When you finished, you were to arrange those nine letters to form a secret word related to programming

And here’s the solution:

S
P
A

F
N
I

Z
R
L

N
F
R

Z
A
L

I
P
S

Z
I
L

S
P
R

F
N
A

A
S
F

P
I
Z

R
L
N

R
L
N

F
S
A

P
I
Z

I
Z
P

R
L
N

A
F
S

N
A
S

I
F
R

L
Z
P

L
Z
I

A
N
P

S
R
F

P
R
F

L
S
Z

N
A
I

And the secret word is: FRANZLISP, i.e. Franz Lisp.

Shady Illuminations

Career-View Mirror

by John Shade

John gives career advice, which you are well advised to ignore.

Remember that old Saturday Night Live Weekend Update bit about Generalissimo Francisco Franco still being dead? Yeah, me neither. Way before my time. But Swaine told me about it. He claims it was a laugh riot. But you know. Swaine.

Turns out, though, that “Generalissimo Francisco Franco Is Still Dead” is still alive and well. It lives on in the thriving market of t-shirts, laptop skins, hoodies, pajamas, trucker hats, buttons, mugs, bags, iPhone cases, blankets, bumper stickers, dog clothing, and refrigerator magnets.

Anyway, I got to thinking about that bit and I decided there should be a similar Tim Cook alert every time Apple has a press conference. “Tim Cook: Still Not Steve Jobs.” “Tim Cook: still valiantly holding on in his fight to remain not Steve Jobs.”

Yeah, I know. Hard to understand how Cook keeps his job.

Speaking of jobs (lowercase j), I just noticed that Johanna Rothman and Andy Lester are doing a career column for this magazine. I have to admit I respect those guys. And the column looks pretty useful. So naturally, that makes me uneasy. Surely I can find a way to make fun of it. Let’s see....

Career-View Mirror

Let’s see if there’s some way to mine some parody gold out of the idea of a career column.

Welcome to “Career-View Mirror,” the career advice column in which I try to make a living telling people how to make a living. This month I consider the question: “What career advice can we derive from the experience of some folks who have recently transitioned out of high-profile positions in terrifyingly powerful operations?”

For example, what opportunities is Steve Ballmer exploring now that he’s giving up the wheel on the ship of tools? He’s a high-energy guy, he’s not going to rest on his laurels. Although according to the Woz, those would be Bill’s laurels. Woz doesn’t think Steve has any of his own.

And come to think of it, that’s a pretty stupid expression. “Laurels” refers to a wreath of laurel leaves awarded to the winner of a competition. So the laurels part makes sense, but the “rest on” part is screwy. Laurel leaves are spiky evergreens, a lousy sort of bed even when fresh, and after being made into wreath and worn through the victory ceremony and motivational sales team group chanting session and whatnot, they would be dried laurels. Nobody would want to rest on those things, least of all a fidgety guy like Steve Ballmer. “Rest on his laurels” my eye.

But that’s a side issue. The question is, what should Steve Ballmer do next? Become a venture capitalist? Start a charity? Nah, those are the things every ex-CEO does. Ballmer needs to do something worthy of his edge-of-crazy enthusiasm. Something radical and different and exciting. Something that involves screaming.

It’s not like there aren’t knuckle-whitening jobs out there on the cutting edge of science and technology. I’ve never seen any evidence that Steve has any design skills, but there is precedent for Microsoft executives leaving the planet in their search for the next gig, so maybe Steve could answer SpaceX's job listing for “Space Suit Design Engineer.”

Or how about Jean Baptiste Quéru?

Nobody can milk a gag like The Register. They’ve been putting exclamation marks in titles of stories about Yahoo (sorry, Yahoo!) since about 1945. Like this:

“Former! Android! Open! Source! Boss! Takes! Job! At! Yahoo!” Dude, why would you move from Google to Yahoo? Could it be because your title at Google was Technical Lead, Android Open Source Project and your title at Yahoo is Architect, Senior Principal Engineer, Mobile? Cause that does sound like a step up.

Let’s stipulate that he may know what he’s doing. There’s another career strategy. Google to Yahoo.

What if your former job involved denying the Holocaust and not having a nuclear weapons program, no really??

Apparently Mahmoud Ahmadinejad has taken a job as a professor. He’s riding a bus to work. So there’s another interesting career path.

Well That Sucked

Yeah, as parodies go, that was awful. Dreadful. Johanna and Andy can relax. I won’t be taking their job. You, on the other hand, can’t relax.

Your plan to retire an live out your golden years developing a world-class paunch on the beach at Denigomodu is going to need a rethink, because of Google’s ambitious plan to extend human life. Why? Think about it. Let’s see a show of hands of all those who think that more years of life mean more years in retirement on a Pacific island. And those who think it means more years working? Yeah. Google’s determined that you’ll never get out of that cubicle.

And even worse, your default not-exactly-retirement career probably needs a rethink, because of this disturbing story: Robotic Bartender Programmed To Recognize When You Are Ready For a Drink.

I just noticed: I’m ready for a drink. Later.

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. He is frequently in retirement, having been retired from several jobs. Follow John on Twitter, send him your feedback, or discuss the article in the magazine forum.

Rear Window

A Parting Shot

Wayne Green died this summer, and with his death closes a chapter in personal computer history. Here, in brief, is the story of the birth of Byte magazine. Photo courtesy of Wayne Green. Text adapted from Fire in the Valley, a book by a couple of guys.

Wayne Green had been publishing 73, a magazine for ham radio enthusiasts, and in 1975 he was looking to computerize his circulation department. He called the major minicomputer firms, each of whom sent a representative. Every rep warned him of the dangers in buying a rival’s machine. Green found all their warnings convincing.

Being a technical hobbyist, he was attracted to these new microcomputers that were emerging, like this Altair he’d heard about. He looked for a magazine that could explain the machines, but couldn’t find any. So he hired Carl Helmers, the editor of one of the best computer club newsletters, and launched Byte, the first personal computer magazine.

Byte was immediate, chatty, and enthusiastic. It caught the flavor of the computer and electronics hobbyist newsletters, and spoke directly to the people building and buying and lusting for their own microcomputers. It was the right formula, and it was wildly successful. By January 1977, Byte had a readership of 50,000 and was the premier magazine in the field. In its field it had the stature of Scientific American and the in-crowd feel of The Village Voice in the beat era.

Wayne Green started many magazines, but Byte is his legacy.