Its a computing tradition to have your first program in a new programming language output ‘Hello World’, best not to go against tradition:
puts 'hello world'
This has uncovered an issue with the WYSIWYG editor built into WordPress which is stripping out the name part of the pre tags that is used by the google syntax highlighter. I have found a work around though which you can find out about here.
I’ve really needed to get round to learning a powerful object oriented scripted or interpreted programming language to replace windows batch files (which I currently use) for a while now. As Microsoft seems determined to gut their functionality with each new Windows release and I find myself wanting more functionality and power than batch scripts can provide. So I have been looking for a high level scripted or interpreted language for platform independent scripting, rapid application prototype and generally messing about with at home. Ideally the language is scripted or interpreted (so no compilation required), has a unit test harness available, ideally some form of IDE/debugger, some decent solid libraries (e.g, database, visualisation/graphing etc) and is object oriented.
I know I don’t want to use the following languages mostly for reasons of personal taste:
- Perl as I can never remember it’s syntax and I can’t seem to read any script I’ve written in Perl after a week or so.
- php as I already use it for web development (and like it a lot) but it does not really seam suitable for scripting or quick application development that is not running on a web server.
- Java I’ve never gotten on with, but that was probably more to do with falling out with my Java lecturer at university. Although I should probably revisit Java at some point as it seems very popular at the enterprise level.
- I also want something not Microsoft specific, as much as I love C# I want something I can use easily on my Mac or Linux boxes at home without compiling.
So far I’ve narrowed it down to either Python or Ruby. Originally I was going to learn Python as I like its use of white space for scoping, its wide range of libraries and maturity as a language. However there seems to be a lot of buzz about Ruby these days, especially its Rails framework and all the buzz has piqued my interest. Further investigation into Ruby has me now leaning towards learning it mostly for the trivial reason (as the languages are equally matched in my mind) that Ruby has the similar concept and syntax of public, protected and private for methods which is familiar to me as a C++ and C# programmer.
In fact I am more then leaning towards Ruby as I bought a copy of ‘The Ruby Programming Language‘ at lunchtime, mostly as it was getting good reviews online and because the original developer of Ruby was a co-author. I always enjoyed Bjarne Stroustrup‘s ‘The C++ Programming Language‘ book, getting the language creators view on their creation is always fascinating and provides valuable insights.
So expect to see more posts about Ruby as I work my way through the book and experiement. I can even post code snippets with syntax highlighting thanks to the Google Syntax Highlighter in the form of a handy plug-in for WordPress!
There are many different programing languages in existence today (I’m going to write about the languages I am familiar with) and I like to visualise their relationships as layers of a cake. There are two main ways to categorise programming languages: as having high or low levels of abstraction and as either compiled or interpreted languages.
The bottom half of the cake consists of the languages with low levels of abstraction, with microcode at the bottom and C++ at the top, all of these languages are compiled languages which means their source code is interpreted and compiled into a lower level language e.g, C++ is compiled into assembler. I categorise C++as a lower level language for the purposes of this diagram as its memory management is still a manual process unlike the languages in the layers above it, which makes it less trivial to use.
Microcode is the lowest level of abstraction available and it is the programming language used to create assembly language instructions. Assembly Language is the language used by computer processors (CPUs) and is specific to each CPU family and is also the lowest level at which software can typically interact with the CPU. Next is the common low level languages C and C++ which I’ve bundled into the same layer as C++ can compile C code so they are not really completely distinct. Although C++ is a higher level language than C as it supports object oriented programming which is typically considered a feature of high level languages.
The top half of the cake can be roughly split in to two groups of programming languages: those languages that are compiled (blue box) into a lower level language before execution by a compiler and those that are interpreted (green box) at run time by an specific interpreter program. The bottom half of the green and blue boxes represent the respective compilers and interpreters for the languages. It is worth noting that although the .net programming languages (C#, CLR C++ and VB.net) and the Java family of languages are all compiled, they are compiled into byte code executables before they can be executed (run) by a virtual machine (usually written in C/C++). The interpreted languages Ruby, php and Python are not compiled before execution but are interpreted at run time by an interpreter program (again usually written in C/C++). Interestingly interpreters do exist to process Ruby (JRuby & IronRuby) and Python (JPython & IronPython) source code into byte code for the Java virtual machine or .net CLI, allowing ruby or python to be run on any Java or .net CLI virtual machine.
Compiled languages like Java or .net must be recompiled before they can run on a different virtual machine however this is usually not a serious issue as .net and Java virtual machines exist for most opereating systems in some form or another. Recompilation is not a requirement for interperated lanagues which only require a functioning intererator on the target operating system to be able to be run, which makes them easier to use across multiple operating systems and leds to them being considered more portable than the compiled languages.
Knowing what is required to complete a programming task can be a black art, unless some thought is used. This can be observed by how frequently engineers complete 90% of a task to only then spend a further significant period of time finishing the last elusive 10% of the task. In the worst cases that final 10% can account for 90% of the duration of the task, which takes the task duration way over the initial estimate.
I think a lot of this underestimation of task length comes down to engineers not having an idea of what being done looks like for the task they are attempting. Here is some guidelines I use, note that implementation does not take up a lot of space: the list is mostly focused on what is required before and after implementation. These guidelines are not perfect and I sometimes forget or skip some points depending on the scale of the task:
- Is the User Story (or requirements) accurate?
- Has a brief design been created in some form e.g. notebook, whiteboard or electronically with at least:
- The User story (or requirements), a sentence or two.
- Solution summary, a paragraph or two.
- A sketch of the solution.
- Technical notes, if required.
- Has the design been peer reviewed, remember its cheapest to fix bugs at the requirements and design phase.
- Initial task estimation.
- Break the task down into sub-tasks (if required).
- Estimate duration for each sub-task.
- Have all the sub tasks or features been completed.
- Has any duplication that has been generated been refactored?
- Have unit tests been added or updated for the new feature.
- Has the executing program code been walked through in a debugger?
- Has the end user reviewed the finished feature?
- Has every file that is about to be checked in been compared to its previous version with a difference tool to confirm the changes to the file are the changes that are required.
- Has the code been code reviewed by a peer.
- Has the code been analysed with:
- Check in
- Remove any unchanged files from the change list.
- Remove any temporary hacks from the change list e.g, for configuration or testing purposes.
- Check that all files that need to be added/removed from source control are included.
- If possible confirm the code builds on a separate test computer before checking in, to make sure no files are missing.
I’m still pondering ‘What done looks like’ so I’ll probably revisit and revise this list at some point in the future, as I’d really like to develop a simple check list I can use to educate more junior engineers.
It would seem that as a profession Software Engineers when left to their own devices will attempt to make a perfect solution to a problem, rather than accepting a working solution. This may sound innocent enough as being 75% perfect (with a working solution) is usually not too painful in time and effort to achieve, however the last 25% is typically brutal to achieve (if it is even possible to begin with).
This trend towards perfection is probably due to the medium with which we work: programming languages and mathematics. Both mathematics and programming languages are completely unlike the physical elements most conventional non-software related engineering disciplines have to work with. Our elements are much closer to pure thought stuff than the physical elements, limited only by our imagination and creativity as to how we can manipulate and combine these components to achieve a solution. This is computing’s greatest strength, as in many ways we are limited only by our conceptual abilities.
This is also perhaps one of our greatest weaknesses, as it makes accepting a non-ideal solution harder than it should be, as our natural inclination is towards the perfect solution. I think this manifests most visibly in the industry wide ‘not invented here‘ syndrome. Where engineers will resist taking components or systems developed else where and using them in their own systems and programs. Instead preferring to design and implement their own ‘better’ solution, usually this resistance will take the form of pointing out the flaws in the component and they could make it better.
This misses one of the key points of reusing components: reusing components saves time and effort that can then be better used to assemble our pre-built components in more creative and powerful solutions to the problem at hand. To insist on building our 100% perfect sub components every time means that you are spending time and effort on making sub components slightly more perfect than existing sub components. This time and effort could otherwise be better used in our higher level solution composition than spent perfecting low level components that have already been made, usually in several different ways by several different groups and tested thoroughly over several generations of software.
Think of what would happen if another engineering discipline like automobile manufacturers where to use such a methodology: rediscovering and design something as basic as a wheel, internal combustion or making steel every time they designed and built a new model of vehicle, the pace of automotive development and inovation would slow to a crawl.
The six phases in the average game development cycle are illustrated below:
The initial phase of a project is ‘Pre Production’ where the main game concepts and features are brainstormed, designed, prototyped and signed off on. The end goal of this phase is to prove (usually via a demo) the core game play experience and produce a feature brief, technical designs and a development schedule. The project team is usually lightly staffed until ‘Production’ begins. Next comes the main development phase ‘Production’, this is usually the longest phase in a project and is where the games features and content are created and put together. The ‘Production’ phase is usually broken into several parts separated by milestones with pre-set deliverables according to the development schedule.
After production comes the main bug fixing portions of the cycle, although ideally bug fixing should be a continuous activity during the whole cycle. ‘Alpha’ is usually defined as the phase when all game features have been implemented but the game still contains major bugs like crash bugs and the game play still needs tweaking. Next is ‘Beta’ usually defined as features complete with no major or crash bugs, ‘Beta’ is usually restricted to minor tweaking of the game.
Post ‘Beta’ all that is left to do is ship the product, traditionally this meant sending a disc (usually gold coloured CD-R) of the title to the publisher for duplication for retail. This is where the term ‘going Gold’ comes from. During the ‘Gold’ phase of development any changes are forbidden except bug fixes requested by the publisher.
The final phase of a project is post production, during this phase the whole development team is not usually present as people take holidays or are assigned to other projects. The main focus during ‘Post Production’ is that of clean up and refactoring of the code base, pipelines and game systems. This includes analysing the development cycle, usually in the form of ‘Post-mortem’ style reviews and brainstorm sessions with the focus to improve future development efforts based on recent experience.