Programming Literate Manifesto

Late last year, I decided to set up a second blog, focusing on exploring the world of academic literature relevant to our work as people who make software. The tone and content was very different to what I usually write here. I’ve now decided that while it’s interesting to explore this material, it was a mistake to try creating a second identity for this. I want to write about it, this is where I write, it belongs here. There are currently only a few posts at the other blog, so I’m going to import them all. If you’ve already read them or this content doesn’t interest you, filter the “academia” category.

This first one set the stall for the remaining posts. One thing made clear in the manifesto was that I wanted to encourage discussion: I’m not convinced blog comments are the place for that so comments remain off for the time being.

Programming Literate Manifesto

This blog is written by what you might call a “practising software engineer”, working in the field of mobile software. I’m hoping for a few things from the articles here, which fall into three main categories:

  • introduce more of “the primary literature” to people at the software coal face. Explore the applicability of research material to what we’re doing. Bring some more critical appraisal to the field. Invite discussion from working programmers about the relevance of the articles discussed.
  • get input from academics about related work, whether the analyses here are balanced, and how the researchers see the applicability of the work covered here to current practice. Welcome academics to the discussions on the articles – in other words to make this blog part of the interface between research and practice.
  • find out about some interesting work and have fun writing about it.

Sources

Papers and articles in this blog have to come from where I can find them, obviously. Largely that’s going to mean using the following resources:

Where the articles I cover are available online I’ll be linking to them, preferring free downloads over paywalled sites. Yes, IEEE, I’m looking at you.

Sandbox

I don’t know how easy it is to be truly dispassionate when writing, so it makes sense to lay out my stall. Hopefully that means intrinsic biases can be uncovered.

In my opinion, “software engineering” is the social science that describes how people involved in making software work and communicate with each other—and to some extent how they communicate to the computers too, at least so far as the created software and source code are tools that enable collaboration and are also the result of such.

That makes it quite a wide discipline (perhaps actually an interface discipline, or multiple disciplines looking for an interface). There’s some sociology and ethnography involved in identifying and describing the culture or cultures of software teams and communities. There’s the management science side, attempting to define “success” at various activities related to making software, trying to discover how to measure for and maximise such success. Questions exist over whether programming is best taught as an academic or vocational discipline, so education science is also on-topic. Then there’s the usability/HCI side related to the tools we use, and the mathematics and computer science that go into the building of those tools.

Just because a field is not a “hard” science, does not mean that useful results cannot be derived. It means that you have to be quite analytical about how someone else’s results apply to your circumstances, perhaps. That’s not to dismiss evidence-based software engineering out of hand, but to say that any result that is said to apply to all of software engineering in general needs to be peered at quite closely.

About the name

It’s quite simply a pun on Donald Knuth’s Literate Programming.

How I got root on my University’s UNIX network

Back when I was a student, the way you talked to other people on the internet was via Usenet. The language we used, while still called “English”, was slightly different from the language we use today. One small example of this difference is that there was still an outside chance that the word “hacker” could be a badge of honour, an indication of one who wanted to understand the principles of a system and how they could manipulate it. People who identified themselves as hackers in this sense had their Usenet groups, and they had their identifying mark: the Glider from Conway’s game of life.

hacker emblem

I was studying Physics, because there could be no grander system to hack than the Universe. But I also hacked computers. I wanted to understand how people made them do certain things, and how I could make them do the things I wanted. Other people hacked for different reasons: they wanted to make other people’s computers do certain things, they wanted to show off what they could make computers do, they had other motivations still.

A meme that went around the Usenet groups for computer hackers was that if you truly wanted to understand computers, you should learn UNIX. So I did. I had a cheap PC in my room, and I installed Linux, FreeBSD, Darwin, and other UNIX variants to learn about UNIX. I learnt about shell scripting, and Perl scripting, and C programming. I had shell accounts on Solaris systems and NeXT systems and Tru64 systems, and I learnt about the differences and the similarities and the UNIX wars. I built a small collection of other systems (an ugly beige PowerMac, a few more PCs, and a couple of sleek Sun pizzaboxes) and learnt about TCP/IP, ICMP, HTTP, X11 and other network protocols.

Some of the hackers who wanted to make other people’s computers do things believed that the ultimate goal was to get root on someone else’s computer. If you got root, you could make their computer do whatever you wanted. It happened that even though I had root on my own computers, I managed to get root on some of the University’s computers.

I was called in to talk to a sub-department head in my department: there was someone from administration and someone from central IT too. They sat on one side of a desk, I was on the other. I was pretty nervous. I told them about what I’d learned about UNIX, and scripting, and networking, and about the root user. They asked me to show them some of what I’d learned, and there was a Mac on the desk between us which I used for this purpose.

A few days later, I got a phone call from the admin person. I had got the job, and when I started the outgoing sysadmin would give me the root password. And that’s how I got root on their UNIX network.

Compatibility

Solaris 10, scheduled to be supported until January, 2021, can still run BSD binaries built for Solaris 1 (a retroactive name for SunOS 4.1), released in 1991. I wonder for how long the apps we wrote for our iPhones back in 2008 – the ones we had to pay $99 even to run on our own devices – will last.

AJAX via jQuery in an Objective-C WebObjects app

As with using jQuery for DHTML, this was surprisingly easy. To make it simple to follow along I’ve published the source code to SignUp, a sample app.

SignUp’s default page is comprised of two WebObjects components: Main is the top-level page (including the jQuery script) and SignUpForm implements the form. As described in the previous post on this topic, the form’s email field is only enabled and populated if you tick the ‘contact me’ button.

ScreenShot of SignUp.gswa's main page

We can submit the form via an AJAX request, rather than by making the browser do a full request-response cycle. To do this, install a handler on the form’s submit event that does an AJAX post of the form then cancels the default behaviour.

   var signUpForm = $("#signUpForm");
    signUpForm.submit(function() {
        $.post(signUpForm.prop("action"), signUpForm.serialize(), function(data) {
            $("#formwrapper").html(data);
        });
        return false;
    });

As I’ve said before, I’m a jQuery newbie, there might be an easier way to do the above but this is definitely easy enough. One thing to notice is that the form’s own action is used as the POST URL, meaning that the WebObjects code is still responsible for expressing the control flow through the app.

The handler’s completion function replaces the form’s content with the data it receives from the POST action. That’s going to be another component, specified in the action handler:

- (GSWComponent *)registerInterestAction
{
  GSWRequest *request = [self request];
  [SignUpForm processSignUp: request];
  return [self pageWithName: @"Thanks"];
}

The request object provides access to the form values which are used in the app to populate an Add Person command, which is handled by adding the user’s details to the database. Finally the action handler loads a component called Thanks and returns that, which will replace the form in the web page.

Capture of SignUp.gswa after filling in the form

One thing to notice is that the server side is stateless; unlike many WebObjects apps that use a WOSession subclass (and have fugly URLs incorporating the session ID, if badly configured) everything is done via Direct Actions in this app, there’s no server-side state, and no session should get created. This conveniently avoids a big lock in the WebObjects framework, where the WOApplication instance has to synchronise access to the session table.

A stateless server satisfies one of the REST constraints; obviously we’re also using code-on-demand via JavaScript and have a client–server, layered system. Resources can be cacheable by setting the appropriate HTTP headers, not shown here but certainly doable. The only constraint not satisfied is the uniform interface and even that is partially present as WebObjects is by its very nature a HATEOAS system. Indeed this application arranged to observe HATEOAS by allowing the form object to express its own action URI, rather than “knowing” the form destination in the client code. The only part that’s missing is a resource identification and manipulation interface: instead of POSTing a form as done here a client would PUT a new person.

What’s the mobile app market up to, then?

While this post is obviously motivated by Recent Events™, it’s completely not got anything to do with employers past, present or future. Dave has posted what next for Agant which explains how that company’s path through the market has gone:

Over the past few years, the App Store has become more and more competitive, and more and more risky with it. Agant’s speciality has been high-quality, higher-value apps, often published in collaboration with our clients. Typically these are paid (rather than free or freemium) apps. Unfortunately, the iOS App Store’s set-up just does not seem to support the discovery, trialling and long-term life of these kinds of high-value apps, making it difficult to justify the risk of their development.

This is not that story. This is my story. It is a different story, though I agree with the paragraph above. It’s a story that doesn’t discuss games because I really don’t know a lot about them.

Something I’ve learned from going to conferences like QCon is that outside the filter bubble of the ObjC conferences I spend a lot of time in, there’s a lot more interest in “the mobile web” (or as we should probably call it these days, “the web”) in the general IT community. This makes sense in the enterprise world: it avoids backing a single horse and tying your company’s IT to one supplier, something they’re rightfully afraid of. Companies that were in the Microsoft camp had to deal with Vista and Windows 8; companies that backed Sun are now Oracle vassals; companies that backed Apple no longer have any servers. Given that mindset, developing javascript apps makes perfect sense. Even if you deliver them now as Cordova apps for a single platform, you’ve got the ability to do something else really quickly if you need to.

This is also something that’s carried over into the world of SaaS apps, where you don’t care what UI people are looking at as long as they subscribe to your service. Whether it’s delivered as a native-wrapped JS app (which is a first-party option for Windows Phone 8 and Windows 8) or a web app (which then lets you add platforms like Chrome OS and Firefox OS), targeting JavaScript lets these developers increase their prospective customer bases from a single code base. Not, perhaps, without some rework of views for different platforms: but certainly without maintaining separate Objective-C, Java and C# projects.

While I’m talking about JavaScript, let me add another relevant datum, particularly for companies working in or with the publishing industry: another word for a bundled JS app is “iBook”.

I think there are also still reasons for having native apps.

Some people want the “most ${platform}-like” experience, and are willing to pay for that. These are, quite frankly, the people who kept Mac software houses going through the 1990s. They’re the people who demanded Cocoa versions of their Carbon apps in the 2000s. You can focus on these people, ignoring the “should be free” masses and getting to the sort of people who buy the Which iPad Format User app of the month because it was the app of the month.

People who have invested money or time into something may be willing to spend a bit in order to increase the value of that investment. This is going to cover both tradespeople and hobbyists. Look at how much you can sell golf swing software for. One of my own hobbies is astronomy: having spent around a grand on my telescope I’m not going to miss £20 dropped on an app that helps me get more value from that purchase. The trick here is not to rely on gaming the “astronomy” keyword in the app store, but to become known in that world. Magazines are more relevant than you might give them credit for, when looking at these markets. Astronomy Now, one of the UK’s astronomy mags, has a circulation of 24,000 (publishers then have an “estimated number of readers per sale” fiddle factor that’s relevant to advertising, so there might be 24-50k monthly readers). These people will read about your product, like it (if you’re doing it right) and will then go out to their user groups and meet-ups and tell those people about your product.[*]

[*] This paragraph owes a lot to Dave Addey, who referred to such audiences as broad niches.

The difficulty is that two forms of advertising no longer work: you can no longer rely on being on the app store as a way to get your app known, and similarly saying to an existing audience “hey, we’re on the app store” is also insufficient. Apps are no longer a novelty in and of themselves, so having a thing that does a thing is not a guaranteed retirement plan.

This points us to a couple of things that definitely are not reasons for having apps. Mass-market apps are now a very hard sell. They can be hard to differentiate on, hard to price reasonably and hard to generate awareness of. This awareness issue brings us into contact with the most powerful businesses in the app market: the platform vendors. No platform is going to allow a “killer app” to surface. Think back, for a moment, to the days of Visicalc. People bought Apple II computers so that they could run Visicalc. That’s fine when Visicalc is Apple-only; not so good when it gets ported to Tandy, IBM and other architectures. It’s also not good when someone else comes out with a better Visicalc for the other platform: 1-2-3 and your customers are gone. Apple (and other OEMs) want control over their customers: they’re not about to cede that control to some ISV with a good idea.

The other thing it’s not a good idea to do is to plug a gap in the OEM software. In smartphones, though not in hi-fis, printers or other electronic devices, the OEM companies are actually pretty good at executing on software features so if you’re doing “the missing ${X} for ${platform}”, as soon as it becomes at all popular the OEM vendor will fill in their version of ${X}. It might not be as featureful, it might not even be better but it’ll probably be good enough to stop the third-party ones from selling.

Notice that I haven’t said “native is better”, or “mobile web is better”. There are apps that you can only build as native apps because the technology limits you to that: this does not mean that you must build them as native apps. There’s no reason you must build them at all. Decide who you’re building for, and what you can offer them that they’d consider to be a valuable experience. Having done that, decide on the best way to build and deliver it.

There is no longer any value in having “an app for that”. There is value in a beneficial experience, which it might make sense for you to build as an app.

What Graham did next

There’s been quite a lot of reaction to this notice on Agant’s website, that Dave is taking the company back to a one-person shop. Indeed that means that I and all of my colleagues (except Dave) are now redundant.

Sad is not the right word. I’m disappointed that this isn’t going to continue, but it’s hard to be sad about getting onto this billing:

Discworld app credits

Thanks for all your concern. I’ve already got my next thing lined up: I’m really excited to be programming and training for the Big Nerd Ranch, starting in August. I’ve known Aaron and a few other big nerds for years and I’m sure this is going to be a great opportunity for me.

In the even shorter term, though, hopefully the experience I’ve built with having more jobs than birthdays since graduation can be helpful to our other developers as we collectively discover what comes next.

At the old/new interface: jQuery in WebObjects

It turns out to be really easy to incorporate jQuery into an Objective-C WebObjects app (targeting GNUstep Web). In fact, it doesn’t really touch the Objective-C source at all. I defined a WOJavascript object that loads jQuery itself from the application’s web server resources folder, so it can be reused across multiple components:

jquery_script:WOJavaScript {scriptFile="jquery-2.0.2.js"}

Then in the components where it’s used, any field that needs uniquely identifying should have a CSS identifier, which can be bound via WebObjects’s id binding. In this example, a text field for entering an email address in a form will only be enabled if the user has checked a “please contact me” checkbox.

email_field:WOTextField {value=email; id="emailField"}
contact_boolean:WOCheckBox {checked=shouldContact; id="shouldContact"}

The script itself can reside in the component’s HTML template, or in a WOJavascript that looks in the app’s resources folder or returns javascript that’s been prepared by the Objective-C code.

    <script>
function toggleEmail() {
    var emailField = $("#emailField");
    var isChecked = $("#shouldContact").prop("checked");
    emailField.prop("disabled", !isChecked);
    if (!isChecked) {
        emailField.val("");
    }
}
$(document).ready(function() {
    toggleEmail();
    $("#shouldContact").click(toggleEmail);
});
    </script>

I’m a complete newbie at jQuery, but even so that was easier than expected. I suppose the lesson to learn is that old technology isn’t necessarily incapable technology. People like replacing their web backend frameworks every year or so; whether there’s a reason (beyond caprice) warrants investigation.