“Clean Code” in AS3
In 2008, Uncle Bob (Robert C. Martin) proposed to the Agile Community that the Agile Manifesto should have a fifth tenet: “Craftsmanship over Execution”.
It is often held as obviously true that functionality is the most important element of code, since without functionality code is useless. So long as code works, readability and execution speed are valuable. Broadly, Martin argued that this is wrong: craftsmanship is more important than functionality; the professionalism with which we produce our code is the most valuable aspect of our work.
Most software development teams execute, but they don’t take care. We value execution, but we value craftsmanship more. Uncle Bob
It is clear to see why this is a difficult sell! At the moment I work at an agency, where in many cases the typical ‘agency mentality’ prevails: work is to be done as quickly as possible. However, all experienced coders know the consequences of trying to do too much too quickly: quick work leads to bugs, bugs lead to more work, dissatisfied clients, frustrated bosses, and – too intangibly to explain to most bosses – more work on future projects because of less code-reuse. Perhaps you know and accept all this, but it is worth repeating. And repeating, and repeating.
That said, too many of the Flash community seem not to know these truths. The Flash community is in great need of learning from the Agile elder statesmen. Most third party libraries value functionality above all and show little care for craftsmanship.
The history of Flash coding has been to strive for speed; to squeeze functionality out of the Flash Player like no-one had squeezed before. Many people have also created third-party libraries to help fellow coders shortcut to functionality and avoid reinventing a particular wheel. Unfortunately those libraries tend to be poorly written, buggy and unreadable. Even classes in the AS3 Core Library, which is run by some significant Flash notables, seem to have been rushed, no effort taken to clean them up for future developers to learn from or extend.
A Practical Example – The Delaunay Algorithm
Recently I wanted to do some work by creating a Delaunay Triangulation Diagram. I knew what it is, and roughly how the algorithm worked, but as would most people, I Googled it in the hope that someone had already created the algorithm in AS3 that I could use. I found this post on indiemaps.com. It’s a lovely post if you want to understand what the Delaunay Triangulation is or what it does, but the accompanying code is utterly horrible. I defy anyone to be able to read through this algorithm and understand how it works. Here’s a snippet:
public static function triangulate(pxyz:Array):Array {
var v:Array=new Array();
var nv = pxyz.length;
for (i=0; i < (nv*3); i++) {
v[i]=new ITriangle();
}
// the points must be sorted on the x dimension for the rest to work
pxyz.sortOn("x", Array.NUMERIC);
var complete:Array = null;
var edges:Array = null;
var nedge = 0;
var trimax, emax = 200;
var status = 0;
var inside:Boolean;
var xp, yp, x1, y1, x2, y2, x3, y3, xc, yc, r;
var xmin, xmax, ymin, ymax, xmid, ymid;
var dx, dy, dmax;
var ntri = 0;
/* Allocate memory for the completeness list, flag for each triangle */
trimax = 4*nv;
complete = new Array();
for (var ic=0; ic<trimax; ic++) complete[ic] = false;
/* Allocate memory for the edge list */
edges = new Array();
for (var ie=0; ie<emax; ie++) edges[ie] = new IEdge();
/*
Find the maximum and minimum vertex bounds.
This is to allow calculation of the bounding triangle
*/
xmin = pxyz[0].x;
ymin = pxyz[0].y;
xmax = xmin;
ymax = ymin;
for (var i=1;i<nv;i++)
{
if (pxyz[i].x < xmin) xmin = pxyz[i].x;
if (pxyz[i].x > xmax) xmax = pxyz[i].x;
if (pxyz[i].y < ymin) ymin = pxyz[i].y;
if (pxyz[i].y > ymax) ymax = pxyz[i].y;
}
dx = xmax - xmin;
dy = ymax - ymin;
dmax = (dx > dy) ? dx : dy;
xmid = (xmax + xmin) / 2.0;
ymid = (ymax + ymin) / 2.0;
The problem with this class is plain: it was ported. Clearly it was also ported from a functional language that had no pretence towards OOP. Such ports rely on a line-by-line transposition from one language to another and a bit of testing to check they work. Porting normally means that the porter doesn’t understand what is being ported. It is translation but rarely transliteration.
In the case of the Delaunay Algorithm, perhaps this is not much of a problem; there aren’t really many ways to extend this algoritm. In the case of a framework however, it ought to be unforgivable. If people can’t read the code they can’t improve it, amend it, extend it, adjust it. It makes them consumers and prevents community interaction. The code, the users and the original developer all suffer because of it over the long term.
Faced with this code, I decided to write an implementation of Delaunay’s algorithm myself. I have had this reaction to nearly every piece of library code I’ve read recently! Out of frustration, I have started writing unit testing frameworks, bulk loaders, tween engines, architectural frameworks, 3D engines, and game engines before realising that I don’t have enough time to all these libraries’ functionalities, and will have to live precariously by accepting that the library is closed to me because of its practical complexity and unreadability.
I must point out that I greatly admire and respect the coders who have successfully created the versions of these frameworks that I use (and would admire a great many others if only I knew your work better!), but I can’t help be frustrated at the effort I have to expend in order to read what they have done, particularly if I find a bug! It is the wasted effort that frustrates me: someone understood what they were doing when they wrote this the first time, so why didn’t they write it in such a way that I could understand too?
My own version of the Delaunay Algorithm is in Google Code as the first iteration of the as3voronoi library. It is a work in progress and by no means perfect. Uncle Bob would chastise many of my naming choices, ridiculous comments, and probably some of the design choices that I have made. However, I think that you can at least read this implementation, starting with the math.delaunay.Delaunay class and working out into the other classes as necessary. Here is a method:
public function addPoint(point:Point):void
{
if (!listOfPoints.add(point))
return;
if (listOfPoints.count == 3)
addInitialTriangle();
else
addPointToTriangulation(point);
listOfEdges.clearUnusedEdges();
}
This is not a direct comparision between two functionally equivalent pieces of code, but merely try to give the flavour of the approach.
Please Write More Beautiful Code
If you can’t explain it simply, you don’t understand it well enough. Albert Einstein
If you are a serious AS3 coder, writing serious code that you hope people will take on and use for serious projects, then please write beautiful code, not just functional code. Write code that explains itself, that reads like English, that uses both sides of peoples’ brains.
Please don’t dazzle the community with archane cleverness, complex methods, and huge classes.
Please don’t let your code rot, by adding functional change on functional change without reflecting on the general structure of your code and refactoring where practical.
If you come from an artistic background and aren’t steady on your coding feet, innovate and explore and hack around, but then sit down with a friendly developer and pair program your innovation into something clean, readable, and reusable.
And please fight when your bosses or fellow coders contend that it’s not worth it. If it isn’t worth it on that day (and it probably will be), it certainly will be in three months time.
Agile Software Development Resources
These two books from Uncle Bob are excellent resources for learning about writing more elegant code:



Nice post.
I agree that a lot of AS3 code – either due to poor coding abilities or strange heritage (ports, AS2) – is pretty miserable, and that a lot of libraries could be much better written.
Of course, when you are doing small projects on tight deadlines, it’s hard to spend a lot of time on craftsmanship. :-/
As AS3 projects grow up, the code quality will get better and better simply out of self defense. Flex is a good example – it has pretty decent quality, comments, tests, etc.
Ben Garney
26 Aug 09 at 2:01 am
I could not agree more. Please, we need clean code in Actionscript and we need to understand what clean code is.
My co-workers write an applaing amount of comments, the code has smells and even as we often get into heated debates where they tell me the ‘necessity’ of comments, they themselves comment inconsistantly. If you are going to force me to write comments, then make sure we do it consistnatly – otherwise what is the point.
I find that coders get the illusion that their code is organized and clean by adding comments, but it’s only that, just an illusion. Also, I find that comments are made because many developers do not work in a robust IDE – so they compenstate that with comments.
Preach on my borhter…preach on.
Alan
26 Aug 09 at 2:04 am
First, thanks for the AS3 Voronoi classes. First chance I get, I plan on implementing these in my AS3 isolining classes, for which I originally ported (fairly directly, in about 20 minutes) Florian Jenett’s Java classes to AS3. The resultant AS3 classes you describe as “utterly horrible”.
Though it’s hard to disagree with your central point, which is oddly but simply enough that we should all just write better code, I do disagree with the implication that anything less than beautiful is worthless and unreleasable.
In May 2008 I was interested in isolines in Flash. They hadn’t been created dynamically in a Flash app before, so far as I knew. Many solutions existed, I thought, but one required Delaunay triangulation, for which no AS3 code existed. To move on to my own isolining ideas, I quickly ported Jenett’s code, which was itself a port of some C code. This allowed me to quickly release some triangulated irregular network-based isoline interpolation code, about a week after porting the triangulation code.
Should I not have released the isolining code and requisite Delaunay port?– especially considering the many warnings provided in my code and associated post about the port’s non-AS3 provenance? Given my (and everyone’s) limited schedule, this would have meant waiting 15 months for your beautiful classes.
Zachary Forest Johnson
26 Aug 09 at 4:02 am
Zachary, oh dear, I must apologise. It is extremely unfair to pick on your class, which I chose only because it was the most recent example of code I couldn’t follow. You are right of course; when you want to build upon others’ work you have to use what is already there. I don’t blame you, if I wasn’t on my high horse this month I may have done the same.
That said the real problem was that you had to port a pretty horrible bit of code in the first place. His was an algorithm written until it worked, then left. Once my algorithm is mature, I would be flattered if you move across to use it.
Thanks for your comment, and apologies again for the unreasonable use of your class to make my point.
alec
26 Aug 09 at 7:54 am
[...] I have just posted an update for the as3voronoi library, which I started writing for a pet project of mine, after I became annoyed by the lack of a good open-source library!. [...]
Voronoi Diagrams – as3voronoi v.0.2 at AlecMcE.com
27 Aug 09 at 11:12 pm
WRONG! (ok, partly right…)
“I Googled it in the hope that someone had already created the algorithm in AS3 that I could use”
How many times have you found an example/experiment on a flash blog, where the author writes, “I want to clean up the code before releasing it” and never actually ever got around to it?
While no-one will disagree that clean code is better than dirty, I feel it’s frustrating that due to peer pressure, or plain programming elitism that developers/artists get scared to release their source code in case someone pokes fun at their naive syntax.
For me the ideas/principles behind the code are far more valuable, and code that proves itself worthy of re-use can always be re-written and restructured for that purpose.
Your example just proves that point. Rather have some code that works, than no code at all, right?
So I say, publish your dirt and let others worry about cutting and polishing it into a diamond.
Even if you ARE trying to build a re-usable library, there could be others in the community more qualified to help mould your efforts into a well structured library, leaving you to concentrate on the more creative, imaginative side of things.
Peter Strømberg
28 Aug 09 at 10:21 am
Here’s an example from the top of your very own blogroll…
http://blog.andre-michelle.com/2005/as3-perspective-texturemapping/
(search for the word “clean” on the page)
(Good old André did go on to release the cleaned up version at a much later date, but anyone who reads his blog would have settled for the dirty version that day!)
Peter Strømberg
28 Aug 09 at 10:30 am
@Peter
I’ve heard this often, and disagree. Hopefully I can disagree without resorting to shouty headlines?
ActionScripters tend to have a different perspective because their projects tend to be small scale and disposable. If you worked on a major project over many years, I think you’d have a different perspective. Changing requirements and coders over the life of a project means that there is a professional responsibility to maintain the highest level of readability possible. This is what R.C. Martin (Uncle Bob) calls being a ‘Craftsman’.
For me the problem is a premise to the sentence “I want to clean up the code before releasing it”. Why on earth would you write something dirty in the first place, if you are capable of something clean?
If a carpenter wanted to craft a cabinet, they wouldn’t just ‘knock one up’ then ‘sand it down’. They’d take care over every joist, every angle and every cut. When it was finished they would release it to the world, and it would be rightly admired.
Perhaps you want to write code quickly to prove a concept? If so, then to me it depends who you want to prove it to. If you want to prove to yourself something is possible, write code how you wish and don’t publish it. If you want to prove it to the world, how do I know the published code produces the result of the published SWF? Only if the general community can read the code, understand it and accept it does a ‘proof’ get close to the meaning of the word.
I’m not sure what to make of the reference to André Michelle. He’s obviously an absurdly talented developer, and I love to keep up with what he’s working on, but I can’t say I know any of his code. It may be the world’s ugliest code for all I know, in which case while I admire it, I couldn’t use it in any of my professional projects in case there were hidden errors I could do nothing about.
alec
28 Aug 09 at 11:35 am
Fair enough, each to his own. I don’t think I’ve ever experienced “hidden errors I could do nothing about” when I’ve got the source code. I just wanted to stress that many of us would rather have a crudely/hurriedly written example than no working code to look at whatsoever.
I’ve worked on a framework (hyperGIS) in flash for 7 years, and in that time re-written virtually from scratch a couple of times, from AS1 to AS2 and then to AS3. Though longevity is good, an overhaul every few years can also be good, rather than clinging on to libraries that you have invested so much sweat in, you can’t let them go.
Admitedly I’m just representing the flip side of the argument, not to be provocative, but because I would hate this article to stop people publishing what they think is cool, if not beautiful.
Peter Strømberg
31 Aug 09 at 9:38 am
On another post, @mikestead pointed out this link, which is well worth a look. Though not exactly on the ‘clean code’ theme, it shares much in common with the sentiment:
InfoQ: Effective API Design
alec
1 Sep 09 at 10:30 am
RT @AS3hash: RT @alecmce: My thoughts on Clean Code in #as3 http://bit.ly/PwnE2. #FlashDev
This comment was originally posted on Twitter
retrogamer4ever
21 Nov 09 at 10:08 am