PragPub 2013-12: Issue #54

Table of Contents

Features

- Exploring the Java Virtual Machine Version of Clojure

by Michael Bevilacqua-Linn

Michael takes you on a whirlwind tour of Clojure’s Java interop.

- Tracking Down Culprit Code in Clojure

by Dmitri Sotnikov

Learning Clojure? Here’s a project that will give you hands-on experience with writing Clojure code.

- Making Music with Clojure

by Sam Aaron

Admit it: your real mission in life is to modify code in real time and have it projected on screens in a nightclub. Welcome to the wild world of Livecoding.

- The Basics

by Michael Swaine and Paul Freiberger

An excerpt from the upcoming Fire in the Valley 3rd edition.

Departments

- On Tap

by Michael Swaine

This issue has a Clojure theme, but there’s lots more in this final offering for 2013.

- Choice Bits

A month recaptured in tweets and news bits.

- HealthCare.Gov

by Robert “Uncle Bob” Martin

Uncle Bob names the culprit for the botched rollout of the government healthcare site: it’s you.

- Rothman and Lester

by Johanna Rothman and Andy Lester

Want a raise? A new chair? Here’s how to get it.

- Pragmatic Bookstuff

Want to meet one of the Pragmatic Bookshelf authors face-to-face? Here’s where they’ll be in the coming months. Also, find out what are the top-selling Pragmatic Bookshelf books and what new books are coming out.

- Antonio on Books

All the new tech books of note.

- Shady Illuminations

by John Shade

John casts a jaundiced eye at the latest announcements from Wolfram Research and IBM.

- Rear Window

The first programmer turns 198 this month.

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

Wrapping Up the Year with Clojure

by Michael Swaine

We’re wrapping up the year with Clojure. Because wordplay is nicotine to editors. Also because Clojure is one of the most interesting languages in use today. (Although see Choice Bits for news about a couple of other contenders.) This issue’s three Clojure articles take you from learning some basics to getting hands-on with a toy project to a look at one of the cooler open source projects in Clojure today.

One of the interesting things about Clojure is how seamlessly it interoperates with Java. In this month’s installment of his popular series on Clojure, Michael Bevilacqua-Linn takes us on a whirlwind tour of Clojure’s Java interop.

The best way to learn a language is to have a project to build in it. Dmitri Sotnikov, whose Web Development with Clojure is releasing soon, walks you through a very practical project: profiling your Clojure code using some nice features of Clojure.

Profiling’s useful, but this next application is decidedly cool. Sam Aaron shows off the power of Clojure libraries and tools to take you into the trendy world of Live Coding. Because you know you want to tweak code live on stage before an audience of screaming fans.

But the issue’s not all Clojure. In a guest essay, Robert “Uncle Bob” Martin tells us who was at fault in the healthcare.gov rollout. Spoiler alert: it was you. Johanna Rothman and Andy Lester continue their career advice column with a look at how to get your boss to do what you want. And John Shade has some thoughts on a new programming language from Wolfram Research.

Our Choice Bits department is evolving; it now includes tech news items we think you’ll be interested in, as well as other odd bits we stumbled across this month. Antonio Cangiano is back with more new tech books. We have another excerpt from the upcoming 3rd edition of Fire in the Valley. And you’ll find an appreciation of the first programmer on the back page.

Anything else? Let’s see, we’re now on the Apple App Store and Google Play. Just search for PragPub. That’s kinda cool. We’ve had an exciting 2013 launching PragPub’s Second Iteration, and we have some cool articles lined up for 2014. We look forward to sharing them with you.

And that, as they say, is a wrap.

Cover, istockphoto.com/muharrem öner; p. 2, istockphoto.com/hrhportia; p. 12, istockphoto.com/IntergalacticDesignStudio; p. 16, istockphoto.com/powerlines; p. 21, istockphoto.com/track5.

Choice Bits

Chosen just for You

A month recaptured in tweets and news bits.

Here’s what we were able to skim off the surface of the newsstream and tweetflood as they rushed by this past month.

The Wolfram Language

Stephen Wolfram and his team at Wolfram Research have come up with some cool stuff over the years. Mathematica. Wolfram|Alpha. CDF. Now they’re putting it all together in a programming language they call the Wolfram Language. Wolfram says it’s a new kind of programming language, a general-purpose knowledge-based language, encompassing the knowledge base built into Wolfram|Alpha. Kind of hard to grok, but definitely sounds interesting.

So where can you get your hands on the Wolfram Language? Turns out they’re putting it on what seems like an unlikely platform: the Raspberry Pi. It’s a pilot release, but you’ll be able to get a taste of what it’s all about before it rolls out more widely. It’ll come bundled with every Pi. Free. On a $25 computer. Yeah. cheers to Stephen Wolfram’s blog

Watson-Powered Apps

IBM made headlines when its Watson “cognitive intelligence engine” took on human contestants in a real-world knowledge test on the TV show Jeopardy. Now IBM is making waves in a smaller pool by opening Watson’s APIs to third-party developers. The deal is described as “a cloud-hosted marketplace where application providers of all sizes and industries will be able to tap into resources for developing Watson-powered apps.” cheers to Ben Woods, from The Next Web

Just told client about my Pig Latin trick for localization. Wondering if I should have patented that. Or blogged it for sake of prior art. — ‪@invalidname‬

The Shape of Digital Journalism

Everybody knows that journalism is undergoing a revolution, and that the old editorial and business models are disappearing, to be replaced by new ones. So far, there has been no lack of examples of the old models crumbling, but it’s been harder to spot the new models that will replace them. Frederic Filloux thinks some truths of digital journalism are finally starting to emerge, and one of them is that investigative journalism is a field in which the subscription model can work. cheers to Frederic Filloux, from The Monday Note, edited by Filloux and Jean-Louis Gassée

This Coding Life

If your agile process has checklists, you’re doing it wrong. — ‪@sarahmei‬

I can’t imagine ‪@marissamayer passing up the chance to nab ‪@bing at a fire sale price. Gamechanger.‬‬ — ‪@‬StevenLevy

Editing ASTs directly means never having to worry about parentheses again. — ‪@KentBeck‬

The German word for “user” is “nutzer,” which sounds about right. — ‪@amyhoy‬

Micro Flashback

How British schoolkids played Space Invaders in 1977: the Research Machines 380Z. You thought I was going to say Acorn’s BBC Micro, right? Turns out there was an earlier micro used in schools, and one look at a picture of it will reveal that this was a rack-mount box rather hilariously repurposed as a desktop computer. Dunno about you, but I love these computer history stories. cheers to Tony Smith, from The Register

Whither Twitter?

The implications of Twitter's Facebook pivot are far-reaching. — ‪@‬davewiner

Post-IPO, Twitter is starting to reshape itself. Custom timelines seems like a pretty radical step, giving the users control over their timelines. I mean radical in terms of all we’ve come to expect from the Twitter experience. And then there are the changes in how it displays photos and videos.... cheers to Twitter Oh, about that IPO. Here are two stories. One tells why the Twitter IPO rocked while Facebook’s rolled: Matt Nesto, from Yahoo Finance The other shows how Forbes got it right: Nathan Vardi, from Forbes

Pause to remember the “Twitter IPO Fails To Fly” or “Twitter IPO Meets Fail Whale” headlines that were written yesterday but never published. — ‪@‬dannysullivan

Turning Down Three Billion Dollars

To thine own selfie be true. — ‪@‬sfmnemonic

Oh, Snapchat. Why would entrepreneurs with a business model that does not presently involve making any money turn down three billion dollars from Facebook? Several possibilities suggest themselves. Like thinking you’re going to be bigger than Facebook someday, or just really, really not wanting to work for Mark Zuckerberg. cheers to Matt Buchanan, from The New Yorker

Nano News

Nanotech has passed another threshold. Researchers have now built the first general-purpose computer constructed solely of carbon nanotube transistors. It runs an OS sufficiently sophisticated to handle multitasking. In a demo, the researchers had it perform counting and integer-sorting simultaneously. cheers to Max M. Shulaker, Gage Hills, Nishant Patil, Hai Wei, Hong-Yu Chen, H.-S. Philip Wong, and Subhasish Mitra, from Nature

Meanwhile in another lab, researchers have used nanoscale antennas to create a holographic display only 30 nanometers thick that floats in space above a surface. Possible applications include 3-D displays and the transmission and processing of data inside chips. cheers to Xingjie Ni, Alexander Kildishev, and Vladimir M. Shalaev, from Purdue University

Dart Hits 1.0

In November, Google’s Dart language for structured web apps went one point oh. Language, tools, libraries, editor. Still requires translation to Javascript to run in most browsers. Lars Bak provides a lot of links, as well as some performance benchmarks. cheers to Lars Bak, from The Cromium Blog

Some Handy Formulas

“O(n**2) is bad, but n just got a whole lot smaller.” -‪@elight (Reminder that big-O only matters in the context of YOUR data.) ‬ — ‪@sarahmei‬

Density follows rails. Resource-squandering slurbs follow highways. — ‪@MrAlanCooper‬

In the future your compensation will be directly tied to your Klout score. — ‪@mims‬

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 folks we followed this month: Chris Adamson, Lars Bak, Kent Beck, Matt Buchanan, Hong-Yu Chen, Alan Cooper, Frederic Filloux, Mary Jo Foley, Mike Godwin, Gage Hills, Amy Hoy, Alexander Kildishev, Steven Levy, Sarah Mei, Christopher Mims, Subhasish Mitra, Matt Nesto, Xingjie Ni, Nishant Patil, Vladimir M. Shalaev, Max M. Shulaker, Tony Smith, Danny Sullivan, Twitter, Nathan Vardi, Hai Wei, Dave Winer, Stephen Wolfram, H.-S. Philip Wong, and Ben Woods.

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

HealthCare.Gov

Rallying for a Software Hippocratic Oath

by Robert “Uncle Bob” Martin

Uncle Bob names the culprit for the botched rollout of the government healthcare site: it’s you.

This is not a political essay. This is an essay about the Software Industry, and the profound effect that its failure is having upon our society.

The Software Industry failed to deliver healthcare.gov. As a result, millions of people are being hurt. We did that, folks. It was our industry, our failure.

The Affordable Care Act (ACA) is one of the most massive public policy initiatives in American history. It was passed through both houses of Congress, and signed into law by the President of the United States. It is The Law of the Land; and it is being thwarted by the incompetence of the Software Industry.

Let me repeat that. A critical public policy is being thwarted, not by the failure of the policy, but by the failure of a website. That’s a software disaster, folks. A big one.

If the media are to be believed, there are four million people whose health plans were cancelled when the ACA went into effect on October 1st. The Software Industry was supposed to have built a website to help those people find new health insurance. By failing to get that website working, the Software Industry has harmed those four million people; and the repercussions of that failure will be felt for decades.

Already, I have spoken to business people who, in the light of this failure, are showing reluctance to build new software. They say: “Will this be like healthcare.gov?" What they are really saying is: “Can the Software Industry be trusted to do anything?”

Perhaps you disagree. Perhaps you think this was a failure of government, or of management. Of course I agree. Government failed and management failed. But government and management don’t know how to build software. We do. We were hired because of that knowledge. And we are expected to use that knowledge to communicate to the managers and administrators who don’t have it.

Challenger

In the hours before the Space Shuttle Challenger blew up, killing seven brave astronauts, a battle was being fought to save their lives. The engineers who knew that it was too risky to launch worked through every official channel to stop that launch. They wrote memos. They held meetings. They raised red flags. They even refused to watch the launch.

But the managers and administrators overrode them, and launched anyway -- for political reasons: Vice President George H. W. Bush was going to be there to observe the launch. By their horrific incompetence, Christa McAuliffe, a school teacher who was poised to conduct the first grade-school lesson from space, was killed before the eyes of millions of school children who were waiting for that lesson.

It’s easy to blame the managers. It’s appropriate to blame the managers. But it was the engineers who knew. On paper, the engineers did everything right. But they knew. They knew. And they failed to stop the launch.

They failed to say: NO!, loud enough for the right people to hear.

Over the Cliff

On the healthcare.gov project, there must have been some programmers who knew that the October 1st launch was going to be a disaster. There must have been some QA people who knew. There must have been architects, project managers, technical leads, and group leaders who knew that we were on the verge of one of the largest, and most public, software failures in the history of the world. Somebody knew!

Why didn’t they say NO!? Why didn’t they say it loud and clear? Why wasn’t the train stopped before it ran off the tracks and plunged over the cliff? Why didn’t somebody pull the emergency cord? Why wasn’t there somebody on Fox News, ABC, MSNBC, or CNN, telling us that nobody had tested the site, that they weren’t ready, that it was going to be a disaster?

Just Following Orders

Perhaps you think I’m being unfair. After all, these folks were just doing their jobs. Their managers told them what to do, and they did it. Some of them may have told their managers that they were uncomfortable with the October 1st launch. Some of them may even have banged on desks, published memos, and raised red flags; only to be overridden by their managers. And so they launched. They were just following orders.

In the U.S. military, you can be sentenced to death for disobeying a direct order. (Article 90). But if you read that article closely you’ll notice a critical word: Lawful. You are not required to obey an unlawful order. Indeed, if you do obey an unlawful order, you can, and should, be prosecuted.

Never do Harm

So what is our law? To what principles do we adhere? What orders must we refuse to follow? It seems to me that the Hippocratic Oath is a good starting place for us. Allow me to slightly reword one stanza of that Oath to fit our purposes:

I will create software for the good of my users according to my ability and my judgment and never do harm to anyone.

Harm has been done to millions of people. We of the Software Industry allowed that harm to take place by following unlawful orders.

Professionalism

If I had to define professionalism in once sentence, I’d say:

Professionalism is the willingness to refuse to obey orders that do harm to others.

Or, perhaps this is a better wording:

A professional has the knowledge and responsibility to say: “No!” as loudly as necessary to prevent harm.

Repercussions

If I were in government right now, I would be leery of starting another big software project. I’d also know that big software projects are going to be necessary as our civilization gets more and more complex. So, if I were in government right now, I’d be thinking about laws to regulate the Software Industry. I’d be thinking about what languages and processes we should force them to use, what auditing should be done, what schooling is necessary, etc., etc. I’d be thinking about passing laws to get this unruly and chaotic industry under some kind of control.

If I were the President right now, I might even be thinking about creating a new Czar or Cabinet position: The Secretary of Software Quality. Someone who could regulate this misbehaving industry upon which so much of our future depends.

This is a warning, not a recommendation! I don't think a czar or secretary is the right solution. And maybe nobody in government has thought of this yet. Maybe. But how many more healthcare.gov debacles will it take before it does?

About the Author

Uncle Bob Martin is 8th Light’s Master Craftsman. He’s an award winning author, renowned speaker, and über software geek since 1970. This essay appeared on his blog.

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

Rothman and Lester

How Do I Get My Boss to...

by Johanna Rothman and Andy Lester

Want a raise? A new chair? Here’s how to get it.

Andy: This month we’re going to tackle that perennial question: “How do I get my boss to do X?”

It’s a pretty common question on reddit and sometimes on StackOverflow. It might be “How do I get my boss to switch to Ruby?” or “get me a better chair?” or “let me work from home?”

In Google autocomplete for “how do I convince my boss,” the four suggestions are “to let me work from home,” “not to fire me,” “to give me a raise” and “to promote me.” The answer is always the same, whether you’re asking for a new chair or a raise: Explain to your boss, clearly and explicitly, how it will benefit him or her, and/or the department and/or the company.

Johanna: It is a common question. In project management and management circles, it’s about “how to stop multitasking,” or “do more with less,” or “get sent to a conference.” But it’s always about convincing the manager of something. Something that’s often in the manager’s best interests.

One of the things I like to suggest is make the problem visual to the boss. I bet there is a good reason for your request. One thing you need to do is make the reason behind your request visual.

Andy: How do you make it visual? 8-x-10 color glossy pictures with circles and arrows and a paragraph on the back of each one?

Johanna: Hehehe. Not quite. Let’s take something you might not consider trivial, but your boss might, like a chair.

You want a chair that fits you, because your back hurts, or your wrist hurts. What you can do is to chart the number of hours you have to spend at physical therapy, or the number of pills you have to take for pain because you don’t have a chair that fits.

You chart that against the cost of time lost, and pretty soon it’s clear that the cost of the chair is negligible. You're speaking management: lost time, money down the tubes.

Andy: Like most things when dealing with management, you have to talk in terms of money, or its equivalent, time. And it has be quantified.

Johanna: Let’s talk about what management cares about.

Management cares about money: coming in and going out, revenue and expenses. Management wants to increase revenue and decrease expenses.

Management cares about customer experience. That’s why agile has such a foothold in organizations. If you provide early product and ask for feedback, the customer experience is likely to be better.

Management cares about schedule, because it affects revenue. Schedule can also affect the customer experience if you’ve made commitments. See what drives projects in Manage It!.

Andy: They care about not having to worry about stuff; not having distractions. Part of what you have to do when you make your case is not give them a problem to solve. Say you’re wanting to use some new programming tool, like a plugin for your editor, and standardize it across the department.

Part of what you have to do is explain why it’s of value to you, and the department, and the company, but you also need to do as much as you can for you to make that happen. Not only do you need to go to the boss and say “The FooCode plugin has these features and will make it easier to navigate source code, especially in the reporting engine which is always a source of pain,” which is a good start, but you also need to say “And here’s my plan for how we can implement it.”

If you ask for something, and you don’t provide that plan at the end, then you’re basically giving your boss another problem to deal with. What you want to do is make it fall-off-a-log simple for your boss to say “Sounds good, make it so.”

Not surprisingly, this is also the core of getting hired. You want to make it incredibly easy and obvious for your boss to say “yes” to your proposal. “How can I convince my POTENTIAL boss to hire me?” is just a special case of what we’re talking about here.

Johanna: We’ll talk about that next month.

Let’s return to this topic. The first step is to make the problem visual. I find that often the manager does not see the problem in the same way that you do.

One common problem I see is the manager not understanding that multitasking may not work for every employee. “How can multitasking be a problem for you? I multitask all the time.” That’s what I see. It’s the same thing with older technology or a schedule commitment or anything else. Help the manager see the problem.

Say the manager asks you to work on five projects. You know you can’t work on five projects and be successful. You have to convince your boss to do something different, like pick one project.

You might not even care which project the boss picks. Any project will do. But the boss knows that he only multitasks, so he doesn’t think it’s a problem. “I multitask all the time.” That’s where you draw a picture of the problem, and show the boss why you can’t deliver anything for weeks. Make it visual..

Show that you won’t be able to deliver anything for a while, so you can’t meet commitments, you can’t recognize revenue, you can’t meet customer commitments, something that the manager might care about.

In this example, you might not be able to pick just one project. You need the manager to pick a project, you most likely can’t make it so.

Andy: Even though the decision is the manager’s to make, you can (and should!) provide suggestions that make the most sense to you. “All things being equal, I think that projects A and C should be able to be knocked out most quickly.”

Much of what you do for your boss is to provide the data for her to make the decisions that need to be made. If you can provide the data that helps what it is you’re looking to have happen, so much the better.

Johanna: So providing data is the second piece. It might be part of making it visual, but linking that data to what management cares about is key. Just providing data without linking it to what your boss cares about won’t make a difference.

Andy: Right, you have to connect the dots for him, because what might seem an obvious conclusion to you might not be to your boss. (Of course, that’s just important for any sort of informative communication.)

Johanna: So, be visual. Provide data. Help your manager by providing potential solutions. What else?

Andy: Don’t let your feelings get into it, because they don’t matter much, if at all. “We need to convert from Subversion to Git because I hate Subversion” is not effective. It’s just opinion, and everyone can have an opinion. Your boss may rightly respond with “Yeah, so?”

Johanna: Explain why one solution is better than another with data. Maybe with source control, you have multi-branch merge in a way with one tool you don’t have with another tool.

Andy: And when you make the case for multi-branch merging, tie it back to reality. It’s one thing to say “we’ll be able to do multi-branch merging,” and quite another to say “we’ll be able to do multi-branch merging, which would have saved us two days on the Foo project, because of those merging problems we had when it was integration time.”

Part of not letting your feelings get into it is to recognize that sometimes, no matter what you research and suggest and how you make your case, the answer to your requests is no, and is going to always be no.

Maybe nothing you can say will convince your boss to let you work from home on Fridays. Or maybe your boss thinks it’s a great idea but knows that his boss won’t allow it. Don’t waste your time and energy being upset about it. Forget about them and move on.

Andy: Is there anything you should never ask for? The only one I can think of is “I don’t want to work with so-and-so” because it reflects even more poorly on you than it does the person you can’t stand.

Johanna: You can say that only if you have provided feedback to that person, and it hasn’t worked. If you have honestly given it your fair shot, and you are not the only one who can’t work with that person, okay. But, that should be a pretty rare occurrence.

Andy: Anything else on the “just don’t ask” list?

Johanna: If you’re going to ask for a raise or a promotion, better make sure you know what your value is. Have a list of accomplishments. Know what it takes to move up in your organization. But: do ask.

Andy: If you want to convince your manager of anything, know what’s important to your manager. Is it money? Time? Customer experience?

Johanna: Then, show your manager the problem visually, and suggest a solution.

So that’s a wrap for this month. Next month, we’ll discuss how you can be the person people think of first, when it comes to being hired.

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.

Exploring the Java Virtual Machine Version of Clojure

Dancing with Java

by Michael Bevilacqua-Linn

Michael takes you on a whirlwind tour of Clojure’s Java interop.

Clojure is a great language, but sometimes it just makes sense to use a library that’s written in Java, or write some Clojure code that can be used in an existing Java project. Clojure has you covered!

In this article, we’ll tour Clojure’s options for Java interop. Let’s start off with the simplest interop feature, calling a method on a Java class. We can do this using the . special form, as below.

=> (. "foo" toUpperCase)

"FOO"

Clojure provides a more convenient macro to do the same: you can prepend the method name with a period.

=> (.toUpperCase "foo")

"FOO"

To access static members in a class, we can use a /. This works both for fields...

=> java.lang.Math/PI

3.141592653589793

...and for methods.

=> (java.lang.Math/abs -100)

100

To create a new instance of a class, we can use the new.

=> (def sb (new StringBuffer))

#'Code.core/sb

Or, we can prepend the class name with a period as we do below. This is more idiomatic.

=> (def sb (StringBuffer.))

#'Code.core/sb

One hiccup with the Clojure interop features we’ve seen so far is that it can make the method chaining that’s so common in Java difficult. The following Java snippet uses method chaining to convert a string to uppercase and then pull out a substring consisting of the first three characters.

"foo".toLowerCase().substring(0, 3);

Written using the interop we’ve seen already, it would be turned inside out, like so.

=> (.substring (.toUpperCase "foobar") 0 3)

"FOO"

The more methods we chain together, the more awkward this looks. Thankfully, Clojure provides the .. macro to smooth things over.

The .. macro takes the object in the second position, in this string "foobar", passes it into the method in the third position, then takes that result and passes it into the method in the fourth position, and so on.

=> (.. "foobar" toUpperCase (substring 0 3))

"FOO"

Now let’s take a look at another feature that helps perform several operations on the same instance of an object. Clojure’s doto can help when we need to mutate the same object repeatedly. For instance, if we wanted to set several properties on a Properties object in Java, we’d do it like so:

Properties p = new Properties();

p.setProperty("url", "http://example.com");

p.setProperty("port", "80");

p.setProperty("timeout", "5000");

In Clojure, we can use doto. It takes an object, then calls a series of methods on it. Unlike .., doto doesn’t thread a value from one method call to another. It just calls the methods on the original object in sequence, so it’s useful for situations like this, where we’re calling the method purely for some side effect. (Also see doto in action in Dmitri�s article in this issue.)

=> (doto (java.util.Properties.)

(.setProperty "url" "http://example.com")

(.setProperty "port" "80")

(.setProperty "timeout" "5000"))

#<Properties {port=80, url=http://example.com, timeout=5000}>

Up until now, we’ve seen how to create new instances of an existing class, and to call methods on them. Clojure also provides several options for creating new classes. Let’s start with a look at proxy.

The proxy macro lets us create a new instance of a class that can inherit from a superclass and implement a set of interfaces. Let’s see how it works, starting with the following Java interface.

public interface DummyInterface {

public String gimmeAString();

}

We can use proxy to implement this interface in Clojure. proxy’s first argument is a vector that consists of a subclass to extend and interfaces to implement. Its second argument is a vector of arguments to the superclass constructor. Finally, we implement the needed methods using the same syntax as we do for Clojure functions.

Here, we’re only implementing a single interface so our first argument is [DummyInterface], and we have no arguments for a superclass constructor. We implement the gimmeAString method to just return the string "aString".

=> (def aStringGiver

(proxy [DummyInterface] []

(gimmeAString [] "aString")))

#'Code.core/aStringGiver

Now, we can call gimmeAString using the syntax we saw earlier.

=> (.gimmeAString aStringGiver)

"aString"

proxy allows us to extend an existing class or implement an existing interface, but what if we want to create a new class entirely? For that, we can use gen-class. While there are several ways to do so, the most common is to incorporate it into the ns macro.

To do so, we need to include :gen-class into the namespace macro. There are many options that we can use here, but we’ll just go over the simplest one: :methods. This allows us to list the methods in the class. Each method consists of a name, followed by an argument list and return type. The methods themselves are implemented in the body of the namespace. They correspond to the names in the method, prepended with a dash. Here, we’ve implemented a simple class.

(ns foo.GenclassExample

(:gen-class

:methods [[exampleMethod [] String]]))

(defn -exampleMethod

[this]

"anExampleMethod")

We need to compile it before we can use it. One way to do so is to use compile in the REPL.

=> (compile 'foo.GenclassExample)

foo.GenclassExample

Now we can instantiate and use it, just like any other Java class!

=> (def ge (foo.GenclassExample.))

=> (.exampleMethod ge)

"anExampleMethod"

This shows the basics of how to create a brand new class in Clojure. While we’ve experimented with our new class in the Clojure REPL here, we could have just as easily used it from Java code, and Clojure’s genclass is flexible enough to create just about anything we’d need for Clojure-to-Java interop.

Thanks for reading this whirlwind tour of Clojure’s Java interop features. Next up, we’ll dive into Extensible Data Notation, or EDN. This is a data notation that’s a subset of Clojure, something like Json or YAML. However, it has some unique and useful features. Hope to see you then!

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. He tweets occasionally at @NovusTiro. Send the author your feedback or discuss the article in the magazine forum.

Tracking Down Culprit Code in Clojure

An Exercise in Profiling

by Dmitri Sotnikov

Learning Clojure? Here’s a project that will give you hands-on experience with writing Clojure code.

Clean code is easier to read and maintain. Therefore, a good rule of thumb is to prefer clarity to optimization when writing it. When we hit a point where the code is not performing as desired then we can optimize it as needed.

Of course, the question is how to find the code that needs optimizing. Most applications will encompass a few small areas that have a significant impact on the overall performance. One way to figure out where they are is by reasoning about the code. However, this can be difficult to do for a complex application and in some cases things that appear to be completely innocuous turn out to be a major source of trouble.

A better way to identify which code needs tuning is to use a profiler. The profiler can tell us precisely where the CPU time is being spent, allowing us to quickly zero in on the offending code.

In this article, we’ll take a look at profiling Clojure applications, locating the problem areas, and using type annotations to avoid reflection calls at runtime. We will use a naive metaballs visualization to illustrate the problem:

To get the above effect we simply calculate the influence of each metaball on each point on the screen based on the distances to each ball’s center and its radius:

imp = rmp / √ (δxmp^2 + δymp^2)

where r is the radius of the metaball and δxmp and δymp are the x and y distances from the center of the metaball m to the point p. The resulting color cp of the point is the sum of all the influences:

cp = Σ imp

The algorithm is on the order of n^2, given a small number of metaballs relative to the number of pixels and a square viewport.

The code to accomplish this is as follows. We first write functions to compute the direction of each ball and to move it.

;;reverse direction if we hit the edge of the screen

(defn direction [p v]

(if (or (> p SIZE) (neg? p)) (- v) v))

;;compute the position and velocity of the ball

(defn move [{:keys [x y vx vy] :as ball}]

(let [vx (direction x vx)

vy (direction y vy)]

(assoc ball :x (+ x vx) :y (+ y vy) :vx vx :vy vy)))

We then compute the influence of each ball on each pixel and compute the resulting RGB values based on it.

;;compute influence of each metaball

(defn influence [{:keys [x y radius]} px py]

(let [dx (- x px)

dy (- y py)]

(/ radius (Math/sqrt (+ (* dx dx) (* dy dy))))))

;;compute the resulting RGB values based on influence

(defn compute-color [x y rgb ball]

(let [influence (influence ball x y)

[r g b] (:color ball)]

(map #(+ %1 (* influence %2)) rgb (:color ball))))

In our draw function we call compute-color for each pixel:

;;for each x,y coordinate compute the color

(reduce (partial compute-color x y) [0 0 0] balls)

Finally, we have a loop to render each frame:

;;run this in a loop where we move the

;;balls around and render them

(loop [balls (repeatedly (or num-balls 2) metaball)]

(draw canvas balls)

(recur (map move balls)))

Unsurprisingly, this runs quite slowly without optimizations. Let’s see if we can locate the culprit code and figure out if we can do anything about it.

To get an idea of the performance we’ll time our loop. To keep things simple we’re using the time macro from clojure.core. For any serious performance measurement I recommend taking a look at the excellent Criterium library instead.text.

(loop [balls (take 2 (repeatedly metaball))]

(time (draw canvas balls))

(recur (time (map move balls))))

"Elapsed time: 250.345 msecs"

"Elapsed time: 0.004 msecs"

"Elapsed time: 171.136 msecs"

"Elapsed time: 0.005 msecs"

"Elapsed time: 212.646 msecs"

"Elapsed time: 0.004 msecs"

We can immediately see that the draw function eclipses the move function. So we’ll focus on what’s happening in our rendering code and see where the CPU time is being spent. Let’s open up JVisualVM, which should already be bundled with your JVM, to see what’s happening.

We can see that the vast majority of the CPU time is being spent in the color function and the clojure.lang.Reflector class. Since Clojure uses dynamic typing, the class instance needs to be looked up at runtime. When this happens inside a tight loop, such as the one we have for painting each pixel, the impact on performance is non-negligible.

Luckily for us, Clojure provides a way to get around the problem by using type annotations. The compiler will use these annotations to resolve the types at compile time, removing the need for reflection calls.

There is also an easy way to identify where reflection is happening in the code by setting the *warn-on-reflection* flag. When we add the following line to our namespace and run it in the REPL, we’ll see the following warnings printed:

(set! *warn-on-reflection* true)

Reflection warning, metaballs.clj:28:3

- call to java.awt.Color ctor can't be resolved.

Reflection warning, metaballs.clj:46:3

- call to setColor can't be resolved.

Reflection warning, metaballs.clj:46:3

- call to fillRect can't be resolved.

Reflection warning, metaballs.clj:51:16

- reference to field getBufferStrategy can't be resolved.

Reflection warning, metaballs.clj:52:16

- reference to field getDrawGraphics can't be resolved.

Reflection warning, metaballs.clj:66:16

- reference to field dispose can't be resolved.

Reflection warning, metaballs.clj:67:13

- reference to field contentsLost can't be resolved.

Reflection warning, metaballs.clj:68:7

- reference to field show can't be resolved.

The first warning in the list confirms what we already learned from the profiler. Let’s take a look at what’s happening in our color calculation code:

(defn color-in-range [c]

(int (if (< c 0) 0 (if (> c 255) 255 c))))

(defn color [r g b]

(Color. (color-in-range r) (color-in-range g) (color-in-range b)))

Even though we cast the result inside the color-in-range function, the color function is not aware of it. This causes it to use reflection to resolve the constructor for Color. We’ll explicitly add the type annotation to each parameter to prevent that:

(defn color-in-range [c]

(if (< c 0) 0 (if (> c 255) 255 c)))

(defn color [[r g b]]

(Color. ^int (color-in-range r)

^int (color-in-range r)

^int (color-in-range r)))

The next couple of warnings come from the paint-square function. This function also gets called each time a pixel is rendered and so we’ll annotate it as well.

(defn paint-square [^Graphics g ^Color color x y size]

(doto g

(.setColor color)

(.fillRect x y size size)))

Finally, we’ll need to cast our distances to doubles when we compute the influence:

;;compute influence of each metaball

(defn influence [{:keys [x y radius]} px py]

(let [dx (double (- x px))

dy (double (- y py))]

(double (/ radius (Math/sqrt (+ (* dx dx) (* dy dy)))))))

;;compute the resulting RGB values based on influence

(defn compute-color [x y rgb ball]

(let [influence (influence ball x y)

[r g b] (:color ball)]

(map #(+ %1 (* influence %2)) rgb (:color ball))))

Let’s see if the performance is improved by our strategic annotations. Indeed it is, we went from ~200ms to ~55ms: A 4X improvement in speed!

"Elapsed time: 55.424 msecs"

"Elapsed time: 55.399 msecs"

"Elapsed time: 55.373 msecs"

"Elapsed time: 55.482 msecs"

Although we haven’t addressed all the reflection warnings, we can see from the profiler that they no longer constitute a significant portion of the CPU time.

As we saw in this article, the profiler allows us to quickly zero in on the code that actually needs optimization. This approach eliminates any guesswork as to what parts of the code are causing us problems.

While this is a toy project, the technique is equally effective for large projects where it might be much more difficult to guess which functions need tuning.

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.

Making Music with Clojure

Live Coding is all the Rage at Raves

by Sam Aaron

Admit it: your real mission in life is to modify code in real time and have it projected on screens in a nightclub. Welcome to the wild world of Livecoding.

The laser beams sliced through the wafts of smoke as the subwoofer pumped bass deep into the bodies of the crowd. The atmosphere was ripe with a heady mix of synths and dancing. However something wasn’t quite right in this nightclub. Projected in bright colors above the DJ booth was futuristic text: moving, dancing, flashing. This wasn’t fancy visuals, it was merely a projection of a terminal containing Emacs. The occupants of the DJ booth weren’t spinning disks, they were writing, editing, and evaluating code. This was a Meta-eX gig. The code was their musical interface and they were playing it live.

And this wasn’t a scene from a cheesy sci-fi film. Coding music like this is a growing trend and is often described as Live Coding. One of the recent directions this approach to music-making has taken is the Algorave — events where artists code music for people to dance to.

However, you don’t need to be in a nightclub to Live Code music — you can do it anywhere you can take your laptop and a pair of headphones. In this article, we’ll explore one of the most powerful Live Coding toolkits available: Overtone. (Note: I’m the lead developer on this open source tool.) Once you master Overtone, you’ll be programming your own beats and modifying them live. Where you go afterwards will only be constrained by your imagination.

Installation

To follow along, you’ll need a couple of dependencies installed. First, you’ll need a JVM (v1.6+); and you’ll also need a handy tool called Leiningen (v2.0+). Both links provide installation instructions, but ultimately you’ll want to be able to run the lein command on a terminal/command window and see a list of options.

Once you have a JVM and lein, create a new project with:

lein new insane-sounds

You then need to fire up your trusty text editor, open insane-sounds/project.clj and add Overtone as a dependency. The file should look as follows:

(defproject foo "0.1.0-SNAPSHOT"

:description "FIXME: write description"

:url "http://example.com/FIXME"

:license {:name "Eclipse Public License"

:url "http://www.eclipse.org/legal/epl-v10.html"}

:dependencies [[org.clojure/clojure "1.5.1"]

[overtone "0.9.1"]])

Save the file, then cd into the insane-sounds directory and run:

lein repl

This may take some time, depending on the speed of your internet connection as it will download all of Overtone’s dependencies (including the SuperCollider synthesis server) and then boot you into a Clojure REPL. You should see the following prompt:

user=>

Now you can start and boot Overtone by typing and entering:

(use 'overtone.live)

Evaluating this will start up an audio synthesis server and connect to it for you. Once this process has finished, you should see the following on your console:

--> Loading Overtone...

--> Booting internal SuperCollider server...

_____                 __

/ __  /_  _____  _____/ /_____  ____  ___

/ / / / | / / _ \/ ___/ __/ __ \/ __ \/ _ \

/ /_/ /| |/ /  __/ /  / /_/ /_/ / / / /  __/

\____/ |___/\___/_/   \__/\____/_/ /_/\___/

Collaborative Programmable Music. v0.9.1

Hello Sam. Do you feel it? I do.

Creativity is rushing through your veins today!

Let’s make a simple sound:

(demo (pan2 (sin-osc)))

Beeep! Testing, testing, 1, 2, 3! We can go crazy and change the frequency:

(demo (pan2 (sin-osc 220)))

Play around with changing the frequency to different values. How high can you go and still hear it? How low can you go? Try it with some decent headphones/speakers and hear the deep bass pump out ...

We can even swap out the oscillator generator. Try replacing sin-osc with the following: saw, square, and lf-tri. Additionally, try removing the pan2 and replacing the frequency number with a vector of two values:

(demo (saw [55 55.2]))

Try different values for saw, 100, and 101. Don’t worry too much about what any of this means, just experiment and have fun! Come back when you’ve finished giving all your friends a headache ...

Hello again. Enough with that new-fangled synth nonsense. Let’s play something more traditional. Pull in the piano synth:

(use 'overtone.inst.piano)

We can now trigger a piano sound by calling the piano function:

(piano)

We can even call it with a MIDI number as an argument to specify the piano note to play:

(piano 63)

Luckily, for those who haven’t memorized all the MIDI numbers, Overtone provides a handy function:

(note :C4)

This then brings us to our first use of Clojure’s data structures for music — we can represent a chord using a vector:

(def c4-minor [(note :C4) (note :Eb4) (note :G4)])

This can easily be rendered as audio:

(doseq [note c4-minor]

(piano note))

Or played as a simple arpeggio:

(doseq [note c4-minor]

(piano note)

(Thread/sleep 200))

With the information provided so far in this section, it is completely plausible to imagine piano compositions that consist of interposed calls to piano and Thread/sleep:

(do

(piano 50)

(Thread/sleep 100)

(piano 72)

(Thread/sleep 50)

(piano 49)

(Thread/sleep 190)

(piano 68)

;.

;.

;. etc...

)

The main drawback to defining our composition in such a procedural manner is not only inelegant but also restricts creative flexibility and freedom. Instead, it’s often better to use Clojure’s data structures to represent the composition in a declarative style. This then opens us up to using Clojure’s powerful set of higher order functions to directly manipulate our compositions. This is something which is explicitly explored in Chris Ford’s Leipzig library which can be used to succinctly represent Bach’s canons at a very high level. However, rather than look towards Bach, today we’re going to consider more contemporary electronic music — live dance and dubstep.

Let’s drop our piano and introduce some drums. First up, the mighty kick drum:

(def dirty-kick (freesound 30669))

You will notice that evaluating this form for the first time may take a few moments to complete. This is because this kick drum is actually a recording of a kick drum in wav format which is available on the fantastic Freesound website and released under a creative commons license. The freesound function takes the unique ID of the sound (in this case 30669) and then downloads it on a separate thread caching the file to your hard drive under ~/.overtone. Therefore the next time you access this particular sound, it will retrieve it from your local file system rather than from the Freesound server.

Once this form has completed evaluation, the var dirty-kick now references a function which can be used to trigger the sound:

(dirty-kick)

Let’s define a few more sounds:

(def ring-hat (freesound 12912))

(def snare (freesound 26903))

(def click (freesound 406))

(def wop (freesound 85291))

(def subby (freesound 25649))

Feel free to add some of your own. Just navigate to freesound.org, search around for a sound, make sure it’s either a wav or aiff find the ID of the sound (you can see it in the URL) and then pass it as a parameter to the freesound function.

Let’s make a driving beat:

(defonce cont? (atom true))

(future

(while @cont?

(subby)

(Thread/sleep 300)

(snare)

(Thread/sleep 300)))

OK, so it’s more like something out of a marching band than a driving dubstep beat, but it’s a good start. To stop it, just reset the atom to false:

(reset! cont? false)

There’s a significant technical issue with this approach related to timing: Thread/sleep can never be relied on for strongly timed programs. The main issue here is that it defines a minimum amount of time for the current thread to pause not the precise amount of time. So, a call to Thread/sleep actually pauses the current thread for (+ 200 delay-t) milliseconds where delay- is dependent on the internal behavior and workload of the scheduler and any GC (garbage collector) pauses. It can therefore be assumed that delay-t is non-deterministic. This means that basing timing on top of Thread/sleep will cause temporal drifting which is less than ideal if you want to generate a steady rhythm or beat.

Overtone has an excellent solution for this issue — temporal recursion. This is similar to recursion, except for applying the current function at the tail position, we instead schedule it to execute at some future time:

(defn scheduled-hello-world [curr-t sep-t]

(println "hello world")

(let [new-t (+ curr-t sep-t)]

(apply-at new-t #'scheduled-hello-world [new-t sep-t])))

Here we create a standard Clojure function which accepts two arguments, the current time and a separation time. The function greets the world and then schedules itself to be executed in the future where the time for execution is the current time plus the separation time. This new time is then passed on to the new function invocation along with the unmodified separation time. When we run this function, with (now) and 200 as parameters we’ll immediately see our friendly greeting appear on the console every 200ms:

(scheduled-hello-world (now) 200)

Luckily this scheduled function honors the stop function, so to cease the persistent and repeated friendliness just issue:

(stop)

Of course, we can perform any action inside this function, so instead of printing to the console, let’s make some sound. However, before we do this, we need just one more time-related concept: the at macro. As we saw above, apply-at will apply the specified function at the specified time. However, this approach is completely susceptible to similar timing issues as Thread/sleep. Through the explicit handling of time, we won’t see any cumulative drift effect. However, each individual execution of the scheduled function itself is arbitrarily delayed due to our non-deterministic friend delay-t. Luckily we can combat this issue via a two-pronged attack. First, we can use apply-by in place of apply-at; this will execute our function slightly ahead of our specified time to give room for any execution delay. We then wrap any sound-making triggers or controls within the at macro, which then instructs the audio server to enact the trigger exactly at the specified time:

;; Play the piano 2 seconds from now

(at (+ (now) 2000) (piano))

Because the audio server is written in highly optimized C++, it can do a far better job of ensuring the action is performed at precisely the correct moment. Therefore, by calling our at macro sufficiently ahead of time, we can ensure that we suffer no time delays or drift:

(defn beat [curr-t sep-t]

(at curr-t (subby))

(let [new-t (+ curr-t sep-t)]

(apply-by new-t #'beat [new-t sep-t])))

(beat (now) 600)

Again we can stop this by calling the stop fn:

(stop)

Given this sound-playing and strongly-timed scheduling functionality, we now have the full power of Clojure to build the sound system of our dreams. Let’s start by building a simple 8-step sequencer. We can represent the state of a single sequence with a simple vector:

[1 0 0 0 0 0 0 0] ;; One beat at the start of the bar

[1 1 1 1 1 1 1 1] ;; Eight beats per bar

[1 0 1 1 0 0 0 1] ;; A more interesting rhythm

(defn simple-sequencer [curr-t sep-t pattern]

(at curr-t (when (= 1 (first pattern))

(subby)))there

(let [new-t (+ curr-t sep-t)]

(apply-by new-t #'simple-sequencer [new-t sep-t (rest pattern)])))

(simple-sequencer (now) 200 (cycle [1 1 0 1 0 1 0 0]))

(stop) ;; Stop the beat

Our simple sequencer lets us play different patterns represented by Clojure vectors. We also take advantage of laziness by creating an infinite lazy sequence of cycles of the pattern to keep the beat rolling on. However, there are a few limitations to this approach: For example, we can only play one pattern at a time; it’s hard-coded to play the subby sound; and we can’t modify it at run-time. Let’s tackle each of these issues.

One way of representing multiple patterns with arbitrary sounds is to use a map for our representation. For example, the vals within our map could be the patterns and the corresponding keys to the sound functions themselves:

(def pats {subby [1 1 0 1 0 1 0 0]

snare [1 0 0 1 0 0 1 0]

wop   [1 0 0 0 0 0 0 1]})

For this, we can modify our simple sequencer to work with arbitrary sounds:

(defn play-pattern [curr-t sep-t pattern sound]

(at curr-t (when (= 1 (first pattern))

(sound)))

(let [new-t (+ curr-t sep-t)]

(apply-by new-t #'play-pattern [new-t sep-t (rest pattern) sound])))

We can then create a multi-patterned sequencer:

(defn sequencer [sep-t sequences]

(let [t (+ (now) 200)]

(doseq [[sound pattern] sequences]

(play-pattern t sep-t (cycle pattern) sound))))

(sequencer 200 pats)

(stop)

In order to allow us to live-modify the patterns whilst the sequencer is playing, we need to make some modifications. The key change is to store our patterns in an atom.

We also need to move away from representing our patterns as an infinite lazy sequence which is defined when the sequencer is created and closed for modification. Instead, we can explicitly store the current beat number and on each temporally recursive call into the scheduling function, we can look up the appropriate pattern index (which is a mod of the beat number and the size of the pattern). If the value of the pattern at this index is 1 we can then schedule the matching sound to be played. Each time round the temporal recursion, we simply need to update the schedule time and increment the beat count.

(def live-pats (atom pats))

(defn live-sequencer

([curr-t sep-t live-patterns]

(live-sequencer curr-t sep-t live-patterns 0))

([curr-t sep-t live-patterns beat]

(doseq [[sound pattern] @live-patterns

:when (= 1 (nth pattern (mod beat (count pattern))))]

(at curr-t (sound)))

(let [new-t (+ curr-t sep-t)]

(apply-by new-t #’live-sequencer

[new-t sep-t live-patterns (inc beat)]))))

Once we have implemented this new live-sequencer function, we can trigger it and then start modifying our live-pats atom:

(live-sequencer (+ 200 (now)) 200 live-pats)

(swap! live-pats assoc subby [1 1 0 1 0 0 1 1])

(swap! live-pats assoc snare [1 1 0 0 0 1 0 0])

(swap! live-pats assoc wop   [1 0 1 0 0 0 1 1])

(stop)

Try changing the pattern vector (swapping 1s for 0s and vice versa) and have fun live jamming! When you’ve had enough, just issue a (stop) command.

So, how can we have more fun than this? Typically in Overtone land, the feeling that more fun could be had usually indicates that there’s an opportunity for us to add more control. One obvious way to give us greater control is to allow our patterns to convey information richer than just 1s and 0s to represent on and off. For example, we might want to specify the amplitude or the rate of each individual beat. Luckily our sound function already provides this via keyword arguments:

(subby :rate 2 :amp 0.5)

Given this new knowledge, we can now increase our pattern representation from using just 1s and 0s to also include argument maps through the use of the following simple helper fn:

(defn flatten1

"Takes a map and returns a seq of all the key val pairs:

(flatten1 {:a 1 :b 2 :c 3}) ;=> (:b 2 :c 3 :a 1)"

[m]

(reduce (fn [r [arg val]] (cons arg (cons val r))) [] m))

We can now call our synth fn using apply and our flattened arg list:

(apply subby (flatten1 {:rate 2 :amp 0.5}))

Armed with this, let’s improve our sequencer yet again:

(defn live-sequencer

([curr-t sep-t live-patterns]

(live-sequencer curr-t sep-t live-patterns 0))

([curr-t sep-t live-patterns beat]

(doseq [[sound pattern] @live-patterns

:let [v (nth pattern (mod beat (count pattern)))

v (cond

(= 1 v)

[]

(map? v)

(flatten1 v)

:else

nil)]

:when v]

(at curr-t (apply sound v)))

(let [new-t (+ curr-t sep-t)]

(apply-by new-t #'live-sequencer

[new-t sep-t live-patterns (inc beat)]))))

(def a {:rate 0.5})

(def b {:rate 3})

(def c {:rate 10})

(live-sequencer (+ 200 (now)) 200 live-pats)

(swap! live-pats assoc subby [1 1 0 b 0 1 a c])

(swap! live-pats assoc snare [1 1 c c 1 a b c])

(swap! live-pats assoc wop   [c c 1 0 0 0 a c])

(stop)

This creates a much richer and more interesting rhythm and is already a lot more fun to play with. Let’s control one more dimension: Time.

So far, each sequencer implementation has maintained a constant timed delay between each beat. What if the time for a whole pattern was constant, and the time between each beat a division of that time over the number of beats in the pattern. For example, we could represent a pattern with three beats per bar with:

(def three-beats-per-bar [1 1 1])

and a pattern with 9 beats per bar with:

(def nine-beats-per-bar [1 1 1 1 1 1 1 1 1])

Therefore, an alternative yet semantically identical version of three-beats-per-bar could be:

(def three-beats-per-bar-alt [1 0 0 1 0 0 1 0 0])

Let’s modify our live-sequencer function to support this new behavior. First, we need to move to passing the time the full pattern should take to play rather than the separation time between beats. This separation time can them be calculated by dividing the full pattern time by the number of beats within it. We also no longer need to thread a beat count through the temporal recursion as we’ll now schedule a whole pattern at once.

(defn normalise-beat-info

[beat]

(cond

(= 1 beat)         {}

(map? beat)        beat

(sequential? beat) beat

:else              {}))

(defn schedule-pattern

[curr-t pat-dur sound pattern]

{:pre [(sequential? pattern)]}

(let [beat-sep-t (/ pat-dur (count pattern))]

(doseq [[beat-info idx] (partition 2 (interleave pattern (range)))]

(let [beat-t    (+ curr-t (* idx beat-sep-t ))

beat-info (normalise-beat-info beat-info)]

(if (sequential? beat-info)

(schedule-pattern beat-t beat-sep-t sound beat-info)

(at beat-t (apply sound (flatten1 beat-info))))))))

(defn live-sequencer

[curr-t pat-dur live-patterns]

(doseq [[sound pattern] @live-patterns]

(schedule-pattern curr-t pat-dur sound pattern))

(let [new-t (+ curr-t pat-dur)]

(apply-by new-t #'live-sequencer [new-t pat-dur live-patterns])))

(live-sequencer (now) 2000 live-pats)

(swap! live-pats assoc subby [1 1 0 b 0 1 [1 1 1] [1 1 1 1 1 1 1]])

(swap! live-pats assoc snare [1 1 c c 1 a [1 a c 1] c])

(swap! live-pats assoc wop   [c a 0 0 a c c c])

(stop)

Finally we need a wobbly bass sound:

(defsynth wobble-bass [amp 1 note 52 wobble 1

detune 1.01 wob-lo 200 wob-hi 20000 pan 0]

(let [saws          (mix (saw [note (* note detune)]))

wob-freq      (lin-exp (lf-saw wobble) -1 1 wob-lo wob-hi)

wob-freq      (lag wob-freq 0.05)

filtered-saws (lpf saws wob-freq)

normalized    (normalizer filtered-saws)

amplified     (* amp normalized)]

(out 0 (pan2 amplified pan))))

Before you freak out too much, we don’t expect you to understand how this works in any detail. Suffice it to say that defsynth is a macro which represents a synthesizer design. If you’re interested in further details, you can look at the figure, which provides a more traditional visual representation of this design.

The first detail about the defsynth macro that is useful to know is that it creates a function in the current namespace with the same name as the synth: in this case, wobble-bass. We can use this function to create new running (and therefore audible) instances of the synth:

(wobble-bass)

To stop this (and all other running synths) you can use the stop function:

(stop)

The second useful detail is the vector of symbol value pairs immediately after the synth name represents the controllable parameters. Our wobble-bass function allows us to specify these using a named-argument style:

(wobble-bass :amp 0.5 :note 30 :wob-hi 2000)

(stop)

The final handy piece of knowledge is that the return value of the wobble-bass function is a record which represents the running synth created via the call. This record can be used to directly manipulate the synth live whilst it is running using the ctl function which is short for control:

(def wb (wobble-bass))

(ctl wb :amp 0.5 :note 50 :wobble 2)

(ctl wb :amp 0.5 :note 62 :wobble 1)

(ctl wb :note 40)

(ctl wb :wobble 0.1)

(ctl wb :amp 1)

(ctl wb :wob-hi 5000)

(ctl wb :wob-lo 100)

bring back the beats!

(live-sequencer (now) 2000 live-pats)

(swap! live-pats assoc subby [1 1 0 b 0 1 [1 1 1] [1 1 1 0 1 1 1]])

(swap! live-pats assoc snare [1 1 c c 1 a [1 a c 1] c])

(swap! live-pats assoc wop   [c a 0 0 a c c c])

(stop) ;; stop the insanity!

So, there you have it! We just coded from scratch a mini live-modifiable drum pattern DSL (Domain Specific Language). How fun is that? This was clearly just a small taste of the fantastic power that the heady combination of Clojure and SuperCollider can offer you. Try playing with different rhythms, different samples (any wav file from Freesound is just but a call to freesound away) and let your imagination run riot. If you stick at it, perhaps you’ll find yourself programming in a nightclub too...

For updates on projects like this check out Overtone and Meta-eX on Twitter.

Sam Aaron is a live coder who, through considering programming as performance, focuses on enhancing the productivity and power of modern programming languages and environments. Sam is the lead developer on a suite of open source tools: Overtone, a collaborative programmable music environment; Quil, an enhanced Clojure version of the visual language Processing; and Emacs Live, a curated suite of Emacs tools, placing strong emphasis on live feedback and visual cues. Send the author your feedback or discuss the article in the magazine forum.

The Basics

A Story from Personal Computing’s Early Days

by Michael Swaine and Paul Freiberger

In the beginning was Basic. But even getting the Basic programming language onto those first microcomputers was a challenge. (The open letter from Bill Gates appeared in the Homebrew Computer Club newsletter in 1976 and appears courtesy of Bob Reiling.)

While it’s true that the microprocessors and the crude microcomputers built by hobbyists/entrepreneurs gave computing power to the people, it was the BASIC programming language that let them harness that power. Two professors at Dartmouth College, seeking a better way of introducing their students to computers, used their grant from the National Science Foundation to give birth to BASIC in 1964. The language John Kemeney and Thomas Kurtz created was an instant success. Compared with the slow, laborious, and complex process of programming in FORTRAN, the comparable computer language in common use at the time, BASIC was a winged delight.

During the following two years, the National Council of Teachers of Mathematics debated over whether to support FORTRAN or BASIC as the standard educational language. FORTRAN, widely used in scientific computing, was considered better for large computational tasks; however, BASIC was far easier to learn.

Think of the Children

Bob Albrecht was a prominent supporter of BASIC. As a pioneer of computer education for children, he had been frustrated with FORTRAN. The Council’s ultimate selection of BASIC was a watershed. The personal computer and the BASIC language would be the two most important products in the effort to convince educators that computers could help students learn. Bob Albrecht wanted to create software for reasons other than personal ambition. Always interested in turning kids on to computers, when the Altair came out, Albrecht asked himself, “Wouldn’t it be nice to have something called Tiny BASIC that resided in 2K and was suitable for kids?” Such a program would fit within the Altair’s limited 4K memory and could be used immediately.

Albrecht pestered his friend, Stanford computer science professor Dennis Allison, to develop Tiny BASIC. Reports of progress on the program appeared in the People’s Computer Company (PCC) newsletter and its offshoot, Dr. Dobb’s Journal. “The Tiny BASIC project at PCC represents our attempt to give the hobbyist a more human-oriented language or notation with which to encode his programs,” wrote Allison. In an early issue of PCC, Allison “& Others” (as the cryptic byline read) explained their goal:

“Pretend you are seven years old and don’t care much about floating-point arithmetic (what’s that?), logarithms, sines, matrix inversion, nuclear-reactor calculations, and stuff like that. And your home computer is kind of small, not too much memory. Maybe it’s a Mark-8 or an Altair 8800 with less than 4K bytes and a TV Typewriter for input and output.

“You would like to use it for homework, math recreations, and games like NUMBER, STARS, TRAP, HURKLE, SNARK, BAGELS. Consider, then, Tiny BASIC.”

“It’s Going to Happen!”

Many of Dr. Dobb’s and PCC’s readers did more than consider Tiny BASIC. They took Allison’s program as a starting point and modified it, often creating a more capable language. Some of those early Tiny BASICs allowed large numbers of programmers to start using the microcomputers. Two of the most successful versions came from Tom Pittman and Li-Chen Wang. Pittman, for one, knew microprocessors as well as anyone, including the engineers at Intel, because he had written one of the first programs for the 4004. Pittman and Wang were “successful” in terms of the stated goal for Tiny BASIC—to give users a simpler language. The Tiny BASIC authors were not trying to use it as a path to wealth. Another, more ambitious BASIC was also in the works.

In the fall of 1974, Bill Gates had left the state of Washington for Harvard University. Gates’s parents had always wanted him to go to law school, and now they felt finally he was on the right track.

But as precocious as he may have been, Gates found himself rooming with a math student who was even sharper than he was, and Gates was shocked when his roommate told him he had no intention of majoring in math but planned to study law. Gates thought, “If this guy’s not going to major in math, I’m sure not.” Examining his options, he immersed himself in psychology courses and graduate courses in physics and math. And long nightly poker games.

Then the January 1975 issue of Popular Electronics appeared featuring a cover article on the MITS Altair. Gates’s friend Paul Allen ran through Harvard Square with the article and waved it in front of Gates's face, saying, “Look, it’s going to happen! I told you this was going to happen! And we’re going to miss it!” Gates had to admit that his friend was right; it sure looked as though the “something” they had been looking for had found them.

Gates phoned MITS immediately, claiming that he and his partner had a BASIC language usable on the Altair. When Ed Roberts, who had heard a lot of such promises, asked Gates when he could come to Albuquerque to demonstrate his BASIC, Gates looked at his childhood friend, took a deep breath, and said, “Oh, in two or three weeks.” Gates put down the phone, turned to Paul Allen, and said, “I guess we should go buy a manual.” They went straight to an electronics shop and purchased Adam Osborne’s manual on the 8080.

For the next few weeks, Gates and Allen worked day and night on the BASIC. As they wrote the program, they tried to determine the minimal features of an acceptable BASIC—the same challenge Albrecht and Allison faced except that Tiny BASIC was to be usable on a variety of machines. Gates and Allen didn’t have this restriction. They were free to make their BASIC whatever they wanted. No established industry standard existed for BASIC or for any other software, mostly because there was no industry. By deciding themselves what the BASIC required, Gates and Allen set a pattern for future software development that lasted for about six years. Instead of researching the market, the programmers simply decided, at the outset, what features to put in their software.

Both men threw themselves completely into the project, staying up late every night doing programming. Gates even made the ultimate sacrifice and abandoned some of his nightly poker games. They sometimes worked half-asleep. Paul Allen once observed Gates nod off, head on the keys, wake up suddenly, glance at the screen, and immediately begin typing. Allen decided that his friend must have been programming in his sleep and just kept right on when he woke up.

The two slept at their terminals and talked BASIC between bites of food. One day while in the dining hall at Gates’s Harvard dorm, they were discussing some mathematics routines—subprograms to handle non-integer numbers that they felt their BASIC needed. These floating-point routines were not especially difficult to write, but they weren’t very interesting either. Gates said he didn’t want to write them; neither did Allen. From the other end of the table a voice called out hesitantly, “I’ve written some floating-point routines.” Both of their heads turned in the direction of the strange voice, and that was how Marty Davidoff joined their programming team over lunch in the college cafeteria.

At no time during the project did Gates, Allen, or Davidoff ever see an Altair computer. They wrote their BASIC on a large computer, testing it with a program Allen had written that made the large machine simulate the Altair. At one point when Gates phoned Ed Roberts to ask how the Altair processed characters typed on a keyboard, Roberts must have been surprised that they were actually pursuing the project. He turned the call over to his circuit board specialist, Bill Yates, who told Gates that he was the first to ask this obviously essential question. “Maybe you guys really have something,” he told Gates.

After six weeks, Gates and Allen thought the project was nearing an end. When they called Ed Roberts, he invited them out to demonstrate what they had. Paul Allen booked a plane reservation as he and Gates scrambled to finish up the BASIC. On the night before Allen was scheduled to catch a 6 A.M. flight for Albuquerque, they were still working. At about 1 A.M., Gates told his friend to get a few hours of sleep, and when he awoke, the paper tape with the BASIC would be ready. Allen took him up on the offer, and when he did wake up, Gates handed him the tape and said, “Who knows if it works? Good luck.” Allen crossed his fingers and left for the airport.

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 authors your feedback or discuss the article in the magazine forum.

Pragmatic Bookstuff

Here’s what’s up with the Pragmatic Bookshelf and its authors.

All of us here at Pragmatic Bookshelf would like to extend a very hearty thank you to all of you who bought so many books on Monday and Tuesday of our Thanksgiving week sale that you crashed our servers. The traffic was so heavy that you melted them right down into a quivering pile of steaming silicon. Even though we had brought extra resources online, your unprecedented enthusiasm overwhelmed us. Truly a great problem to have.

We’re better now.

Recently Released: Crafting Rails 4 Applications: Expert Practices for Everyday Rails Development, Minecraft Plugins for Kids!, Remote Pairing: Collaborative Tools for Distributed Development, Programming Google Glass, The Agile Samurai—AUDIO BOOK.

Coming Up Next: Node.js the Right Way: Practical, Server-Side JavaScript That Scales, Build Awesome Command-Line Applications in Ruby 2: Control Your Computer, Simplify Your Life, Developing Android on Android: Automate Your Device with Scripts and Tasks, The Dream Team Nightmare: Boost Team Productivity Using Agile Techniques.

What’s Hot

Most lists only go to 10. Ours goes to 11!

1^

NEW

Node.js the Right Way

2^

NEW

HTML5 and CSS3

3v

1

Agile Web Development with Rails 4

4^

NEW

Functional Programming Patterns in Scala and Clojure

5^

NEW

Build Awesome Command-Line Applications in Ruby 2

6v

3

Seven Concurrency Models in Seven Weeks

7v

2

Programming Ruby 1.9 & 2.0

8^

NEW

Crafting Rails 4 Applications

9v

4

Programming Erlang

10v

7

Web Development with Clojure

11v

6

Programming Elixir

Who’s Where When

- 2013-12-03, Codemesh, London

An intimate half day Elixir tutorial

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

- 2013-12-05, Core Vim Class Online

Core Vim Class Online

Drew Neil (author of Practical Vim )

- 2013-12-05, Codemesh, London

Keynote with José Valim

Dave Thomas

- 2014-01-08, CodeMash 2014

Introduction to the Roku SDK (Half-Day Class)

Chris Adamson (author of iOS SDK Development )

- 2014-01-09, Codemash

Are branching, null, and attributes all that OO? Let's get weird!

David Copeland (author of Build Awesome Command-Line Applications in Ruby and Build Awesome Command-Line Applications in Ruby 2 )

- 2014-02-26, Agile India, Bangalore

Keynote on Tacit Knowledge

Dave Thomas

What’s Happening

But to really be in the know, you need to subscribe to the 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.

Antonio on Books

All the new tech books of note.

In coming up with a list of 20 books this month, I felt like I was shortchanging you a bit. As the holiday season approaches, publishers have been busy pushing out plenty of good titles related to programming (certainly far more than 20). Nevertheless, the following list is a good representative selection with quite a bit of variety in it.

My pick for the month is the second edition of the well-reviewed Big Nerd Ranch guide to Objective-C programming. iOS programming is still much in demand, and a deeper understanding of the main language behind Cocoa Touch (and Cocoa for Mac OS X programmers) can really serve you well.

For lovers of functional languages, Real World OCaml was just released and it appears to be as promising as its well-known Haskell counterpart (Real World Haskell, first published five years ago). An honorable mention also goes to Ruby Under a Microscope, which dives deeper into Ruby internals.

Antonio's Pick: Objective-C Programming: The Big Nerd Ranch Guide (2nd Edition) By Aaron Hillegass, Mikey Ward • ISBN: 032194206X • Publisher: Big Nerd Ranch Guides • Publication date: November 28, 2013 • Binding: Paperback • Estimated price: $24.47

Real World OCaml: Functional programming for the masses By Yaron Minsky, Anil Madhavapeddy, Jason Hickey • ISBN: 144932391X • Publisher: O'Reilly Media • Publication date: November 22, 2013 • Binding: Paperback • Estimated price: $32.59

Designing for Behavior Change: Applying Psychology and Behavioral Economics By Stephen Wendel • ISBN: 1449367623 • Publisher: O'Reilly Media • Publication date: November 22, 2013 • Binding: Paperback • Estimated price: $22.67

Heroku: Up and Running By Neil Middleton, Richard Schneeman • ISBN: 144934139X • Publisher: O'Reilly Media • Publication date: November 21, 2013 • Binding: Paperback • Estimated price: $7.19

Developing Android on Android: Automate Your Device with Scripts and Tasks By Mike Riley • ISBN: 1937785548 • Publisher: Pragmatic Bookshelf • Publication date: November 22, 2013 • Binding: Paperback • Estimated price: $24.01

DB2 Essentials: Understanding DB2 in a Big Data World (3rd Edition) By Raul F. Chong, Clara Liu • ISBN: 0133461904 • Publisher: IBM Press • Publication date: November 9, 2013 • Binding: Hardcover • Estimated price: $46.76

Ruby Under a Microscope: An Illustrated Guide to Ruby Internals By Pat Shaughnessy • ISBN: 1593275277 • Publisher: No Starch Press • Publication date: November 19, 2013 • Binding: Paperback • Estimated price: $22.24

Android Programming: Pushing the Limits By Erik Hellman • ISBN: 1118717376 • Publisher: Wiley • Publication date: November 4, 2013 • Binding: Paperback • Estimated price: $26.69

Python Programming for Raspberry Pi, Sams Teach Yourself in 24 Hours By Richard Blum, Christine Bresnahan • ISBN: 0789752050 • Publisher: Sams Publishing • Publication date: November 9, 2013 • Binding: Paperback • Estimated price: $19.14

Mobile ASP.NET MVC 5 By Eric Sowell • ISBN: 1430250569 • Publisher: Apress • Publication date: November 20, 2013 • Binding: Paperback • Estimated price: $30.75

Expert JavaScript By Mark E. Daggett • ISBN: 1430260971 • Publisher: Apress • Publication date: November 13, 2013 • Binding: Paperback • Estimated price: $32.24

HTML5 and CSS3: Level Up with Today's Web Technologies By Brian P. Hogan • ISBN: 1937785599 • Publisher: Pragmatic Bookshelf • Publication date: November 6, 2013 • Binding: Paperback • Estimated price: $21.47

Product Design for the Web: Principles of Designing and Releasing Web Products By Randy J. Hunt • ISBN: 0321929039 • Publisher: New Riders • Publication date: November 8, 2013 • Binding: Paperback • Estimated price: $18.76

Microsoft Visual C# 2013 Step by Step By John Sharp • ISBN: 073568183X • Publisher: Microsoft Press • Publication date: November 20, 2013 • Binding: Paperback • Estimated price: $30.93

iOS Auto Layout Demystified (2nd Edition) By Erica Sadun • ISBN: 0321967194 • Publisher: Addison-Wesley Professional • Publication date: November 9, 2013 • Binding: Paperback • Estimated price: $21.64

Python and HDF5 By Andrew Collette • ISBN: 1449367836 • Publisher: O'Reilly Media • Publication date: November 8, 2013 • Binding: Paperback • Estimated price: $18.54

iOS Components and Frameworks: Understanding the Advanced Features of the iOS SDK By Kyle Richter, Joe Keeley • ISBN: 0321856716 • Publisher: Addison-Wesley Professional • Publication date: November 14, 2013 • Binding: Paperback • Estimated price: $29.74

Microinteractions: Full Color Edition: Designing with Details By Dan Saffer • ISBN: 1491945923 • Publisher: O'Reilly Media • Publication date: November 1, 2013 • Binding: Paperback • Estimated price: $16.60

Java Programming for Android Developers For Dummies By Barry Burd • ISBN: 1118504380 • Publisher: For Dummies • Publication date: November 4, 2013 • Binding: Paperback • Estimated price: $15.84

The Dream Team Nightmare: Boost Team Productivity Using Agile Techniques By Portia Tung • ISBN: 1937785718 • Publisher: Pragmatic Bookshelf • Publication date: November 15, 2013 • Binding: Paperback • Estimated price: $19.58

Antonio Cangiano is the author of the excellent Technical Blogging and you can subscribe to his reports on new books in technology and other fields here.

Shady Illuminations

A Few Wild Shots from the T-Shirt Canon

by John Shade

John casts a jaundiced eye at the latest announcements from Wolfram Research and IBM.

Snappy Michael Scott-ish comeback at tech conference:

“That’s what the compiler said.”

Except of course at a tech conference it wouldn’t be delivered in conversation, it would be printed on a t-shirt.

I base most of my opinions about tech topics on things I read on t-shirts at tech conferences. I figure the collective body of wisdom on tech conference t-shirts forms a coherent T-Shirt Philosophy, or at least a pithy T-Shirt Manifesto. The best of them, I state as a corollary, constitute the T-Shirt Canon.

The following observations might not fit on a t-shirt, but that is the precise literary and philosophical level at which they hope to tread water.

The Most Amazing Thing Ever

Over the digital transom is flung with some force an announcement so gigantic in scope that it can only be encompassed by Stephen Wolfram’s ego. From the same genius who brought you computation-powered bags of knowledge and a new kind of science because he’d finished the old one and was bored, comes the Most Amazing Thing Ever. It would be pointless for me to even try to describe this transcendent achievement. Only one man can do it justice. Here in his own words, as I no doubt imperfectly remember them, is Stephen Wolfram on the Most Amazing Thing Ever:

“After twenty-five years of amazing achievements, I have come up with the most amazing achievement of my amazing life. And yet even I, Stephen Wolfram, did not immediately fully understand how universe-shaking this achievement is. Let me try to simplify it for your little minds.

“We have taken all the world knowledge in our know-it-all search engine, Wolfram Alpha, added a bunch of other amazing stuff we had lying around, and blended it all into our amazing omni-paradigmatic programming language Mathematica on high speed, and the result is a programming language that knows the capital of North Dakota.

“And we’re debuting this incredibly powerful tool that is so much more than a tool, a world unto itself, really, we’re debuting it on one of the most interesting computing platforms today, the analog, really of the NeXT machine on which we debuted Mathematica and changed the world. That’s right, the Rasperry Pi. Effective immediately, you will one of these days be able to use a crippled version of this world-changing tool on the Pi so long as you don’t require any memory or other resources. Yes, there are some limitations, but even so, it’s pretty amazing that all this wonderfulness can run on this crappy little toy at all.”

I probably didn’t quote him very accurately. Listening to Stephen Wolfram is above my pay grade. There’s no denying that Wolfram is a smart guy, and he and his anonymous collaborators have done some neat stuff. Like Mathematica. I lie awake nights imagining what Tim Berners-Lee might have accomplished if he’d stuck with writing Mathematica code on his Next Machine rather than getting distracted with that other project. Well, I don’t, actually, but I think Stephen Wolfram does.

So there’s that. Apparently the new thing is to invest code with real-world knowledge. This gives you bragging rights. You can sneer at a colleague, “Your compiler doesn’t know the capital of North Dakota? Aw, I’m so sorry.”

Potent Potables for 100

Meanwhile IBM has caught the fever. The latest brick thrown over the digital transom had the news wrapped around it that IBM is deconstructing its Jeopardy-playing AI technology into a set of APIs your programs can tap into.

So how would that work? I figure you supply two parameters, Category and Answer (“Presidential Pets”, “Checkers”) or optionally, (“Presidential Pets for 200, “Checkers”), and it returns a Question (“What was Tricia Nixon’s dog’s name?”) Handy, in the right context. I can’t wait to tap into the rich repository of knowledge on Yiddishisms, Equine Adages, One-Word Musicals, and All Fowled Up.

So real-world knowledge has unseated coding skill. “What” is the new “How”. Who knew?

Not to be outdone, Marissa Mayer has announced a new Yahoo API that will let developers tap into Katie Couric’s brain.

I’d like Fictional Mice for 500, Katie.

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 knows all the answers but none of the questions. Follow John on Twitter, send him your feedback, or discuss the article in the magazine forum.

Rear Window

A Parting Shot

The first programmer turns 198 this month. Photo courtesy of John Murray (Publishers) Ltd.

Ada Lovelace was born on December 10, 1815.

Ada was the world’s first programmer—for a particular definition of programming. She wrote detailed documentation for Charles Babbage’s Analytical Engine. These included step-by-step instructions for calculating a sequence of Bernoulli numbers that constituted the first algorithm intended to be processed by a machine.

The Analytical Engine was the world’s first computer. For a particular definition of first. It was never built during Babbage’s lifetime, but between 1989 and 1991, former curator at the London Science Museum Doron Swade led a team that actually built Babbage’s Difference Engine using only materials and techniques available to Babbage, and is now pursuing a plan to do the same for the Analytical Engine. When completed, this will demonstrate that Babbage had in fact designed the world’s first computer.

And you want to consider Ada the first programmer, because her history is so perfect. Her mother was an amateur mathematician in Victorian England and her father was a Romantic poet, no less than Lord Byron. Isn’t that exactly the ancestry you want programming to have?

Table of Contents

PragPub 2013-12: Issue #54

On Tap

Choice Bits

HealthCare.Gov

Rothman and Lester

Exploring the Java Virtual Machine Version of Clojure

Tracking Down Culprit Code in Clojure

Making Music with Clojure

The Basics

Pragmatic Bookstuff

Antonio on Books

Shady Illuminations

Rear Window