Category Archives: Technology

Digital Nostalgia

Some time in 1992, the inspirational Bruce Anderson told me I needed to learn Smalltalk. The web was in its infancy and with little information in the University of Essex library my only resources on this quest were a 720Kb 3.5″ disk with Smalltalk/V on it and a videotape. Being an impoverished student I first had to borrow a video recorder and then my introduction to a programming language still more advanced than most of what is out there began.

The video is only twenty minutes long but I had to watch it in two parts due to the headache induced by the lack of vertical sync between the video camera and screen. Bruce tells me the video was made in 1985 at Queen Mary College, London on a Tektronix 4400 series.

Many thanks to Bruce for giving me permission to publish this small but pivotal part of my programming history

Optimising Custom Applications on Force.com

One of the greatest challenges of developing on someone else’s PaaS offering is performance optimisation. When I built large-scale enterprise web systems from the ground up there were so many levers we could pull to improve performance without changing a single line of code: more/better CPUs, more memory, more/better use of indexing/caching/threading, and so on. And if we wanted to optimise code we could choose where to apply our efforts, from the lowest of the low-level infrastructure code to the client code running in the browser.

But when you build code that runs on someone else’s platform you have only one thing you can optimise: your own code.

One of the things that amazes me about building on force.com is how infrequently we need to do performance optimisation. Create a simple custom page with a record or two’s worth of data and a smattering of dynamic client-side functionality and an end user will be hard pushed to tell that its not a native force.com tab. Even more complex pages, with more than a couple of records and more than just a smattering of client-side functionality render pretty damn quickly and are perfectly usable. But the Singletrack system also has a few pages that are really very complex, cover a few hundred records and provide a lot of client-side tools. This post covers the specific topic of how we optimised a custom force.com page that took ~40s to render in its first version and got this down to < 2s.

The problem

Deliver information about a list of contacts, usually around 150-300 in length. Which contacts are returned may be manually set or may be dynamically chosen using a set of non-trivial criteria. What information is delivered is configurable on a per-user basis but typically consists of ~20 fields covering the Contact, its Account, and recent Activity History. Add in a number of tools for manipulating and interacting with the information on the list. If it helps, think of it as a Salesforce list view on steroids.

The first solution

Work out what information the user wants to see about each contact (from Custom Settings). Work out the criteria for selecting the contacts (stored on the record underpinning the view). Dynamically construct the query string and execute. Render as a table using Visualforce (think JSP/ASP/ERB for none-force.com’ers) along with embedded Javascript for all the client-side functionality. The result: ~40s from request to availability in Chrome.

The first optimisation … and some lessons learned

Rule #1 of optimisation; profile the shit out of the system and work from facts not opinions. But profiling isn’t well supported in force.com (basically, debug statements with timestamps are required) so we made some guesses as to where we thought the problem was likely to be in order to focus our instrumentation efforts. Given we were still quite new to force.com at the time we were probably a bit too influenced by our fears and immediately set about instrumenting all the querying. Waste of time, even increasing the number of contacts tenfold the querying accounted for less than 300ms of the request. And in general the server processing was really very fast.

Lesson #1 of optimising in the cloud: profile the shit out of the system and work from facts not opinions.

Instead we turned our attention to the page rendering and this turned up a surprising result. We needed two <apex:repeat /> loops to construct the table; one for the rows and one for the columns. Rendering a table of 3000 rows (requiring 2000 iterations in one loop) was pretty fast, rendering a table of 400 rows with 5 columns (also requiring 2000 iterations but two loops) was not. In fact it was 10 times slower and rendering 200 rows with 10 columns – our most typical use case – was much slower still.

This is when lesson #2 of optimising in the cloud really hit home: you can either do less or you can do differently, you don’t have the option of adding more of a vital resource. We could remove the ability of users to choose which columns they saw (making the column set fixed and removing the need for the nested loop) or we could change the way we rendered the table. In the end we decided to do differently and return all the results as JSON data and construct the table in Javascript on the client. Our first version of this approach gave us a 100% improvement in performance: 20s from request to availability.

However we also quickly worked out that our JSON based solution (this was before force.com released native support for JSON) was still pretty slow due to using ‘+’ for String concatenation in creating the JSON string. Replacing this with extensive use of String.format() gave us another 100+% performance improvement: 8.5s.

The second optimisation … and more lessons

We lived with this for a while. 10s wasn’t great but it was no slower than opening up an Excel spreadsheet (what users had been doing before they used our system) and general consensus was 10s was okay. Of course, what seems acceptable on day one rapidly becomes irritatingly slow and within a couple of months there was a lot of grumbling about performance especially as some people were reporting that the page ‘regularly’ took 20+s to load. This turned out to be rooted in some environmental issues: i) browser caches were being cleared out every time the browser was closed – a not uncommon admin setting in our customers’ domain and ii) the ISP routing for salesforce.com subdomains (used for accessing custom code in managed packages) turned out to be less than optimal – sometimes adding 6-8s to a request. The latter was a real eye-opener and we still haven’t got to the bottom of why that was the case but switching to a back-up ISP and resolving the browser cache issue ensured the customers’ were getting consistent 10s response times.

Once we’d resolved these problems we noticed that the latency in requesting Static Resources from force.com could be pretty high: ~1.5-2s in some cases (as is commonly the case all our Javascript and CSS files were packaged up as a zip file and deployed to force.com as a Static Resource). By moving our Javascript and CSS outside the package and delivering it via Amazon Cloudfront we won’t improve performance in the common circumstance of someone accessing the system via a browser with a fully populated cache but, we can shave a second or two off the overall response time for a browser with an empty cache as well as isolating ourselves from whatever the circumstances that cause force.com to update the timestamps for Static Resource caching (it seemed that every new force.com release required all browsers to completely repopulate their caches causing a rash of performance complaints directly after a major Salesforce upgrade).

Lesson #3 of optimising in the cloud: there’s not much you can optimise outside your own code, but there is more than nothing.

This round of work got us looking at our implementation again. One thing that really stood out was the amount of time we had a ‘blank page’ before any of our data was being downloaded, even ignoring client-side processing of it: 4s. Create a custom Visualforce page with just some text in it and it will have sub-second response time. Given we knew that querying and processing the data took only ~300ms it seemed surprising that it was taking ~3s to download the data. Some investigation here turned up a very surprising result – that the viewstate for the page was huge even though there wasn’t much real state within the page. By ensuring that the scope of the <apex:form/> tags was as narrow as possible (just encompassing the fields and actions within the form) and judicious use of transient variables we were able to significantly reduce the size of the viewstate and this brought the ‘blank page’ time down to below 2s and overall response times of ~4.5s. Additionally, the psychological effect of not staring at a blank page for a few seconds meant that people felt the page was a lot faster than you might expect from a 60% improvement.

Something else we looked at here, after realising that Static Resources can be a bit slow, was how long it took for force.com to download its own Javascript and Stylesheets. By removing the Salesforce header and sidebar, and opting not to load standard style sheets we took another 0.5s off the page load.

Lesson #4 of optimising in the cloud: a bit of understanding about how the platform works goes a long way to spotting areas for optimisation even when you think your actual code doesn’t have a lot of room for improvement.

With the use of the new native support for JSON (worth ~1.5s over our homegrown implementation, and resulting in vastly simpler code) and a few other minor tweaks we’re now down to a steady 2s for page load; a whopping 2000% improvement over that first, not-too-naive implementation.

Summary

Far from just having whatever performance you get out of force.com on your first effort, there is plenty of opportunity for optimisation if you find you need to do it. However, don’t look too much to the platform for bottlenecks (apart from a few specific cases mentioned) the answer lies in your use of the platform and in your custom code. String concatenation and viewstate in particular seem to be areas where you can gain some quite significant improvements with relatively little effort and, with the new support for JSON, shipping compact JSON strings that you then render on the client rather than having Visualforce do all your rendering on the server side for you is definitely a good option even if you don’t need nested <apex:repeats />. And if you see inconsistent performance in your customers’ environments there are certain things to go looking for there that can make a dramatic improvement.

What will be the programming language of the Cloud?

When I used to be responsible for building on-premise enterprise systems I railed against heterogeneity. I understood that architectures based on ‘best of breed’ solutions were typically less than the sum of the parts (if they worked at all). I believe in collective code ownership but that means that when the resident Python guru says “I could easily knock up a quick script to do that” or the long-time Smalltalker says “this bit of the system would be so much better built in Seaside” the implication is that the whole team has to learn Python or Seaside. I believe in simplicity, and whilst using “the best tool for the job” is a form of simplicity getting even just two techies to agree what the best tool for any given job actually is is a task in itself. Having a small, well-defined set of technologies is, to my mind, far simpler than having an ever-growing morass of different tools, languages, applications and libraries.

After twelve months of doing serious development on force.com we have a relatively small and well-defined set of technologies:

  • All application code and unit tests written in Visualforce and Apex – the languages of the force.com platform – plus JQuery/Javascript for added client-side dynamism
  • System test code written in Java (we could use any other language that has a binding for Selenium WebDriver but all the dev team has a lot of Java experience behind them)
  • Build written in Ant running via Bash scripts on EC2
  • Force.com IDE

And that’s it.

But something is threatening my nice safe, sanitised and homogenous Utopia: pesky customers. Because one customer needs to have some of the data from our service appear in their Microsoft Office suite we now have a small utility written in C# and WPF. And because other customers love the idea of accessing some services and data from within MS apps this is going to get bigger and more complicated. Because another customer wants a feature that the force.com platform can’t support, and we think this is going to be a good core feature to offer other clients, we’re going to have to build it using Google App Engine, or maybe in Java/Tomcat on EC2, or maybe in Ruby or …

All of which got me thinking: what might become the dominant programming language of the cloud? Apex is syntactically similar to Java and Google AppEngine is effectively a cut-down version of Java. But the ever growing complexity of the language and the shenanigans of Sun and now Oracle (not to mention Apple) lead me to think Java will not too shortly be appearing in various lists of legacy technologies. Ruby is simpler than Java but I never got the feeling that it was that much better and, if it wasn’t for Rails, would probably be nothing more than vaguely interesting. The various functional programming languages genuinely do offer something different to Java or Ruby but, at the moment, their support for some of the fundamentals of cloud computing are a bit limited: web services in Haskell anyone?

I even went so far as to start to draw up a list of the characteristics for my perfect cloud language before realisation dawned:

I’m asking the wrong question.

Because one of the great things about coding in the cloud is the incredible variety of platforms and services offered and their different strengths and weaknesses. Want to store and distribute files in the cloud? Use Amazon S3 … there is no language to learn as such, just a simple REST API. Need to run your build process in the cloud? Use whatever your favourite technology is and spawn up an EC2 instance to run it in. Need an application for capturing, managing and reporting on information? Force.com is a great bet.

I can’t wait for the first functional programming cloud platform that will allow us to write functional transforms and drop them in such that we can call them with a URL and get the results back in XML or JSON form. Amazon Hadoop offers some basic data transformation and calculation services in the cloud and I’m sure many other types of calculation and data manipulation engines will start to appear. When vector processing becomes truly cloud-based we’ll have many further options for data processing.

The idea that one language could support all, or even a significant majority, of these types of service is patently ludicrous and the only conclusion I can make is that the principle of homogeneous technology stacks belongs with a lot of the other principles I used to apply to building large systems: in the past. Its going to be a challenge to embrace the heterogeous future of Apex + Java + C# + Javascript + Ruby(?) + Scala(?) + Pig + ???, plus the different platforms they support or are supported by, but I’ve come to believe that this old dog is going to have to learn a lot of new tricks if he’s to get the most out of the cloud.

Cloud Computing: Its a revolution not evolution

When I was a student some <mumble, mumble> years ago I decided I wanted to try ‘proper’ photography. I bought a second-hand SLR and got some books out of the library. I quickly grasped the basics of shutter speed, aperture, light metering and so on and went and did what all the books told me: I took lots of photographs, carefully logging what settings I’d used as I went. Once a film was full I’d send it off to the processing lab, wait a week or so, and then check the results against my notes in an attempt to learn more about how different settings affect the quality of the resulting photograph.

When the first digital cameras came out, my initial reaction was kind of “so what”; it’s a simple evolution to replace film with a CCD and a memory card. The first digital SLRs were superficially identical to the film SLRs they replaced.

Nikon D70 Digital SLR

Nikon D70 Digital SLR

Nikon F70 SLR

Nikon F70 SLR

But I was wrong. The first thing I found with a Digital SLR was that the tedious and lengthy feedback loop between taking a photograph and working out why it looked better or worse than other shots had disappeared. Now I could take a shot, look at the results, make adjustments and re-shoot on the spot … I probably learned more about taking photographs in three months with my D-SLR than I did in 5 years of owning an SLR.

This was no doubt helped by a complete inversion of the economic model. My original SLR was fairly cheap to buy but the recurring costs (for film and film processing mainly) were high and directly proportional to the activity of taking photographs. The D-SLR was more expensive to buy but I could take as many photographs as I liked without worrying about how much it was going to cost me to see the results.

And the differences in process and economics were really just the start. Showing photographs to people is no longer something that has to be done one-to-one, handing over physical prints. The transition from camera to online is smooth, simple and fast. I could put my old film-photographs online but that required a long and hard slog involving a flat-bed scanner, some very ropey editing software and a lot of patience. Flickr, twitpic and the like have moved the game on from people simply showing their photographs to sharing them with whoever might be interested.

And so on … in short, ‘going digital’ was a revolution for photography, not an evolution.

I feel the same about cloud computing. My initial reaction was “that’s kind of nice” but I was immersed in the world of building large-scale on-premise enterprise software and failed to see beyond the superficial similarities: the systems I was building lived in data centres and were accessed through a browser so what really was new?

data-centre

On-premise data centre ... Or is it a cloud computing data centre?

However, after spending the past six months building systems for the cloud in the cloud I see the same kind of fundamental shifts in enterprise software that ‘going digital’ brought to photography.

The process of delivering systems has changed. As someone who worries a lot about the non-functional characteristics of a system (availability, scalability, performance, security, manageability, maintainability and so on) I now worry a lot less about how to build these into the system and a lot more about understanding what the platform I’m building on gives me. With a ‘raw’ cloud environment like Amazon EC2 some of these still need quite a bit of work, with a Platform-as-a-Service environment like Force.com, its all there for me.

As someone who likes to build systems using weekly iterations, the flexibility of cloud environments is a godsend. Before we used to set up a number of different environments for production, staging, QA, development and so on and have strict processes for governing what was released into each environment (and making all this work on a weekly cycle was hard). In cloud environments we still need to look after production but any other environment needed for whatever purpose is extremely simple to create, populate and then decommission when we’re done.

The economics of delivering systems has changed. On-premise solutions need to have sufficient capacity to deal with the sharpest peak in demand. Adding further capacity can be a lengthy and very expensive processes regardless of whether you get the benefit of that capacity or not and reducing capacity can often be so expensive that its cheaper not to bother. There are all sorts of regulations that (quite rightly) protect the integrity of the enterprise IT infrastructure against the vagaries of the system you’re introducing to it and these can be extremely expensive to adhere to or get an exception from.

Cloud environments turn most of this on its head. Now you pay for what you need and, if you need to increase or reduce capacity that’s a very simple and quick operation with a directly proportional increase or reduction in what you pay. And many of the regulations needed to protect the corporate IT infrastructure simply don’t apply because the system isn’t in your corporate IT infrastructure. Of course that doesn’t mean that governance isn’t required, especially around the data you move into the cloud, but many of the regulations that are aimed at limiting access to shared resource, for example, become irrelevant.

Last week I integrated Amazon S3 storage with the Force.com platform to give me a way of providing secure, well-managed access to an almost unlimited amount of document storage through a rich, browser-based interface. Suppose I wanted to use this to allow a team of, say, 30 users to manage a content repository of 1TB of information. At a rough estimate this would cost ~$2000 per year. How much would it cost to build and deploy an on-premise solution to do the same kind of thing?

As with digital photography, once you’ve got past the differences in process and economics, a whole set of new possibilities emerge that simply wouldn’t work in the ‘old’ way of doing things. It’s still relatively early days and I think the really exciting new opportunities that cloud computing brings have yet to be seen, but here’s one big new possibility to start with. Suppose I wanted to sell my ‘unlimited capacity managed document repository’ solution (and other companies have already produced identical products so I probably wont). In the ‘old’ way of doing things I’d need to buy a huge amount of storage capacity, set up a number of servers to serve the management interface, write a load of software to do user management and security, and so on. The cost of just getting started would be massive and, even then, who would trust a small company with the secure storage of their important documents? This is a business that could only work with a serious amount of VC money behind it. In the world of cloud-computing however my cost of start-up is simply the cost of writing the integration between S3 and Force.com and that is all I’m asking customers to trust. The secure storage is provided by S3 and the management interface by Salesforce.com: both billion-dollar companies who invest extremely heavily in security, availability and so on.

Evolution is a process of gradual progressive change, revolution is a radical and pervasive change. To me, cloud computing feels like a revolution, not evolution.

Remote Pairing in the Cloud

I had my first experience of remote pairing in 2002. Remote pairing has all the usual conventions of pair programming (two people working simultaneously on a single task with frequent switches of ‘driver’ and ‘navigator’) except that, rather than the two developers being sat side-by-side at the desk working with one monitor, one keyboard and one mouse, they work in two physically separate locations, often from home.

Back in 2002 the technology limitations made a lot of our choices for us. We used:

  • Microsoft Net Meeting for desktop sharing
  • Each developer had the same development environment separately maintained on their local machine (Eclipse IDE, JVM, infrastructure products, etc.)
  • Speaker phone for voice
  • 512/1MBps ADSL internet connections

This worked but there were a number of ‘hassles’ ranging from slow swapping of driver and navigator (latency on Net Meeting was such that the driver had to be using their local machine with the navigator observing remotely and making the odd click if necessary), to dealing with firewall issues, to keeping two development environments perfectly in sync and ensuring that all tests pass on both machines. John Daniels and I presented on remote pairing as part of a session on dispersed development at OT2004 and I found that the slides from that session are still available online.

Recently I found myself remote pairing again and was surprised to find that many individual aspects of the set-up have improved without things really getting any better:

  • Broadband download speeds are way up but upload speeds (crucial in peer-to-peer desktop sharing) are unchanged
  • There are many more technologies for desktop sharing – including Skype, iChat (I now use Macs rather than Wintel), Adobe Acrobat  Connect, GoToMeeting, and so on – but they all have varying approaches to viewing vs. controlling with the ones that give the best viewing experience invariably not supporting taking control, meaning we still have to swap ‘host’ every time we want to swap driver.
  • Using Skype for voice is far better quality and, more importantly, far cheaper than using a landline but contributes to connection saturation
  • Developing Cloud-based solutions for Force.com removes some, but not all, of the local environment problems but the fact that each file save and each test run uses the Internet connection also contributes to connection saturation

Seven years on the whole experience was actually worse than in 2002. Not only were the bandwidth limitations of two fast, urban ASDL connections causing poor refresh rates on the shared desktop but the times to save a file, access a web page and run our tests were soaring: unacceptable for development.

What we really needed was an environment where we weren’t limited by upload speeds, where the Skype and desktop sharing connections didn’t contribute to the save, browse and test times in building the application and where we had one environment to set up and maintain. And the answer was actually pretty obvious: develop for the cloud in the cloud.

Currently our setup is:

  • A 64-bit CentOS installation running as an image in Amazon’s EC2. Into this we’ve installed the Force.com development environment, our testing tools, a browser and a freenx server – the only things we really need. This has been serialised onto Amazon’s S3 storage.
  • NoMachine NX clients on local machines to access the remote desktop (using ‘shadowing’ to create a shared session). This is crucial as NX is the first technology I’ve seen that makes a remote desktop session feel like it is running on the local machine. It’s not quite there but the differences are pretty subtle and for most of what you do when pairing – file editing and testing as opposed to graphic image manipulation or fast context switching between lots of windows – its better than adequate.
  • Skype connection for voice (your bog-standard peer-to-peer, non-cloud variety)

Yesterday was the first full day of development in this environment and I have to say it went better than expected (and certainly felt a few years on from my first experiences of remote pairing). We got the benefits we expected – desktop sharing latency is now determined by 4MBps+ download speed rather than 256KBps upload speed with Skype not having a noticeably detrimental effect – and a few we didn’t. The fact that the development environment is physically located in the same country as the Force.com data centre means our saving/browsing/testing times are lower than they are when working locally in the UK. The nature of development means we don’t need to worry about re-serialising the EC2 image at the end of every day, we simply place any non-Force.com assets under version control and then terminate the image meaning we start with a fresh, clean environment every morning. And the nature of EC2 means that, when we need to get another pair working, we simply run up two instances of our dev image rather than one!

The next step is to provision a Windows environment under EC2 or one of the dedicated Windows cloud providers so we can run multi-browser testing; once we have that we’ll have a complete, cloud based version of our local development environments for remote pairing. The step after that is probably to ditch the local environments altogether.

Large and Small Scale Refactoring

Reading Kent Beck’s post about Ordinary and Extraordinary Design reminded me of a long-running discussion on a long-running project about what refactoring is for and who decides how much effort should be expended in refactoring. Over time we came to recognise two different types of refactoring – small and large scale – that are, perhaps tangentially, related to Kent’s ordinary and extraordinary design.

Small scale refactoring – reifying, removing duplication, renaming, and anything that removes the nasty, smelly, cruddy bits of code that make coders feel bad – is the inalienable right of the XP developer. Refactoring is the process by which the developer makes the environment they work in (the code) a pleasant place to be. The customer or the management team have no right to ask the developer not to spend time refactoring and they trust that the team will organise themselves such that the time is spent well (not too much time spent making pedantic changes or going backwards and forwards between different designs in a refactoring war). The importance of making the code a pleasant place (read: well designed) shouldn’t be underestimated: it has a direct impact on productivity, ease of innovation, ease of adoption (bringing new people onto the team or transferring ownership to a new team), estimate reliability and so on.

Large scale refactoring – rengineering some part of the system to a new approach, upgrading to a new version of the infrastructure, or whatever – is something that I believe has to be scoped, agreed and prioritised with the customer. There are two main reasons for this: the first is that this level of refactoring is likely have an impact on the ‘visible productivity’ for the iteration, i.e. significant effort needs to be spent on work that appears to have no effect from the user’s perspective. So the user needs to be comfortable with how the refactoring will affect their schedule. This is different to small scale refactoring where that effort is amortised across lots of different tasks that result in user-visible changes because the effort is in addition to rather than part of ‘normal work’.

The second reason is even more important but perhaps more controversial. Personally I believe that any work to, say, move from a point-to-point communication mechanism to a message bus, that can’t be explained in terms of benefits to the end users and customers, cannot be justified. Such a piece of work is (or should be) motivated by very different concerns to making the code a nice place to work in. Perhaps we’re worried about performance or scalability, perhaps we’re worried that it will be increasingly difficult to add new types of event consumers, perhaps we’re worried that our home-grown code isn’t robust or secure enough and want to replace it with a suitable off-the-shelf product. All of these types of concerns can be expressed to the customer in ways that allow them to make value and priority judgements in the same way they do for more feature-oriented changes.

[Of course all this presupposes that you have a customer who will work with you to understand the value of such non-functional work. And it requires you to be good at explaining that value in terms they can appreciate. I’ve had customers who believe better scalability or security is ‘down to the techies doing their job’ and then get upset when the technical team overrules their priorities to do some large-scale refactoring. Equally I’ve seen techies use fear, uncertainty and doubt to ‘con’ the customer into allowing them to make large changes that probably weren’t justified in the context of business prorities. No surprise: XP requires trust and effective collaboration to work.]

As Kent asks in his article ‘so what’? Well I think its important to understand the different motivations, actions and responsibilities in the two types of work and, especially, where the responsibility for decision making lies. In small scale refactoring the motivations, actions and responsibilities are all with the developers. In large scale refactoring the actions will still be the developers, the motivations need to be shared with the customer, and the responsibility for giving the go-ahead and prioritising needs to lie with the customer.

Is force.com the new Smalltalk?

Possibly a question that you never thought would (or should?) be asked and one to which the one-word answer has to be “no”. But its “no” with some interesting caveats.

I’m an engineer by background, not a computer scientist. I have a passing interest in language design but I’m much more interested in what a language allows you to deliver and how: does it make delivery quicker, is it easy to maintain, how easy is it to hire people with these skills, and so on? I’ve developed seriously in assembly language, C, Smalltalk and Java and have dabbled with Fortran, Javascript, C# and Ruby. Of these Smalltalk was the first I really felt at home in: I could quickly and easily build powerful, performant, scalable systems and, at the time, its was still accepted that Smalltalk was a viable choice for enterprise systems so there was a good community of people with real experience to talk to and learn from. In many ways, moving to Java was a step back initially but as the Eclipse IDE got better, Java gained the ability to remote debug, and the library and component support got richer, I began to feel at home with it too.

Dabbling with force.com reminded me of my experiences with Smalltalk. The most striking thing about it is the thing I really loved about Smalltalk: you develop in the same environment the user uses. This is an incredibly powerful concept that allows programmer and customer to literally work side by side in developing a solution (Dave Thomas called this a ‘super pairing’ in a conversation a couple of years ago). 

The next most interesting thing is how quick and easy it is to do what you want. In Smalltalk/GemStone, adding a new field to the database was a simple as adding a member to a class. No SQL to generate and run and no object-relational mapping layer to define. In DST (the Smalltalk CORBA product if you remember CORBA), making a method available remotely was a simple as including it in the IDL; no stubs and skeletons to generate and tailor. In force.com you add a new field to an object and there it is available in your forms, reports, via the REST API, and so on. Ruby/Rails may be a step forward from J2EE but its still not as easy as this.

These two combined means its very easy to work with your user to thrash out ambiguity, explore difficult concepts and making small change without having to resort to mock-ups or smoke-and-mirrors ‘rapid prototypes’. It might not be the way you want to do everything but its great for many of those features that are really important to the user.

Like Smalltalk, everything in force.com – including, tabs, object definitions, classes, pages and workflow tasks – is an object, a degree of simplicity that Java can never hope to achieve regardless of how much autoboxing and annotation you put in it. Everything the user uses in force.com has state, relationships and behaviour that are easily accessible by the developer in a single technology. Simple and powerful.

There are a number of rough edges, the such as atrocious support for debugging (back to the days of printf(“You are here”) again!) and the Apex language is, shall we say, pragmatic rather than elegant (as I said, I do have a passing interest in language design) but I can see those being smoothed off quite quickly as the developer community grows and the force.com developers have to start supporting this community.

Clearly force.com is a product delivered as a service run by a for-profit company where as Smalltalk is a general purpose language supported by a community of enthusiasts and commercial organisations so there is no direct comparison. But some of the old ‘Smalltalkness’ that Java never really gained despite trying very hard is very much present.