Delphi Prism and the Cirrus Framework

The May 2009 Release of Delphi Prism introduced the Cirrus layer that provides Delphi Prism developers access to a library for Aspect Oriented Programming natively for the first time. The AOP Wikipedia article has a much more detailed explaination than I could provide but for those who don’t want to read the full article AOP represents a new programming paradigm which claims to allow a cleaner separation of concerns. The general idea is that you can write your code as an Aspect which can then be injected into your target class, allowing the Aspect code to replace, wrap or alter the target code. There are a few 3rd party frameworks for Delphi Win32 such as MeAOP but I’m not sure if their support is anything like as extensive as Cirrus.

Why would you need  to use AOP?

Many people don’t really understand why they would need to use AOP in any way. It’s true that nearly all programming paradigms support some form of separation and modularity but to see where this can quickly fall down, you simply have to look at the classic logging example which has been the staple diet of coverage of the Cirrus framework. Logging is a good example because it is likely that if your application implements logging features, then you probably have logging code mixed up in your beautifully designed business objects at various places tainting the implementation of your once clean object.

A Simple Example

For the purposes of those people who weren’t convinced on it’s usefulness from the example given. Imagine we have a very important Business object of a Type called TCustomer. We’ve been told that we need to log everything done to our Customer objects for audit purposes (and you wouldn’t want to get on the wrong side of the Internal Audit team..).  We could easily add our logging calls into every function of TCustomer but this going to require a lot of CTRL+C, CTRL+V and is a lot of identical code-repetition and shouldn’t we be striving to avoid code repetition? This might also get your local overly-sensitive Anti Copy-Paste mafia up in arms. There is another problem with simply inserting our code into each method: What happens if later on, another programmer adds another method for updating, deleting or even just saving a copy of our Customer. Internal Audit are not going to be happy. Of course, you could blame it on your inexperienced colleague but that’s not going to make much difference, it’s a team failure after all.

Had we used AOP we could have used something as simple as the Cirrus Introduction LogToMethod code, tagged our TCustomer class with a single attribute and been saved from this potential oversight:

?View Code DELPHI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// For the full code for this example, please see the original introductory tutorial at:
// http://prismwiki.codegear.com/en/Cirrus_Introduction
namespace MyLogToMethodAspect;
 
interface
uses
  RemObjects.Oxygene.Cirrus;
 
type
  [AttributeUsage(AttributeTargets.Class or AttributeTargets.Struct)]
  LogToMethodAttribute = public class(System.Attribute, IMethodImplementationDecorator)
  public
    [Aspect:AutoInjectIntoTarget]
    class method LogMessage(aEnter: Boolean; aName: String; Args: Array of object);
 
    method HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
  end;
 
implementation
 
class method LogToMethodAttribute.LogMessage(aEnter: Boolean; aName: String;
  Args: Array of object);
begin
  if aEnter then
    Console.WriteLine('Entering ' + aName)
  else
    Console.WriteLine('Exiting ' + aName);
end;
 
method LogToMethodAttribute.HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
begin
  if String.Equals(aMethod.Name, 'LogMessage',
    StringComparison.OrdinalIgnoreCase) then exit;
  if String.Equals(aMethod.Name, '.ctor',
    StringComparison.OrdinalIgnoreCase) then exit;
 
  // Cool use of anonymous methods here....
  aMethod.SetBody(Services,
    method begin
      LogMessage(true, Aspects.MethodName, Aspects.GetParameters);
      try
        Aspects.OriginalBody;
      finally
        LogMessage(false, Aspects.MethodName, Aspects.GetParameters);
      end;
    end);
end;
 
end.

Of course, you don’t need Aspect Oriented Programming in the same way as you don’t need Object Oriented Programming, we could just revert to procedural programming but as programmers we strive to separate various concerns cleanly and this is another step towards that.

What’s the catch?

The problem with separating our code in such a way is that potentially, it could be hard for a programmer unfamiliar with AOP to understand the code as the only clue of any logging activity for our target class might be a single attribute in our interface section. Our Aspect might also rely upon the underlying method in which case we could run into problems if we restructure or  move our methods around causing unintended consequences. There is also a concern that a serious bug in our Aspect code could lead to a more widespread failure in the program (as it has the potential to be applied to large swathes of code easily).

However, with careful testing and implementation these potential drawbacks can be mitigated.

Apart from Logging, what else can I use it for?

Typical uses include logging, authentication, caching and dependency injection. John Moshakis has been blogging some elegant real-life uses of the Cirrus framework such as Implementing Dependency Injection, allowing him to switch seamlessly between test and production services in an app.

My Own Journey to AOP

After the Cirrus Framework was released I wanted to try to build my own Aspect which wasn’t the logging sample provided. I had a service that retrieved a string of XML from a REST Web Service at frequent intervals which I felt could be improved with caching functionality. The Code for the Web Service and for the Cache were just test classes for the purpose of this experiment but I would imagine that you could extend this to use the The Caching Application Block from the Microsoft Enterprise Library if you wished. Normally, I could add caching to each method by modifying it like so:

?View Code DELPHI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
method TFlickr.GetUserInformation(username: String): String;
begin
  // Do we have this information in our cache?
  if (MyCache.HasData('UserInfo_' + username)) then
  begin
    // We do, use the cache'd data.
    Result := MyCache.GetData('UserInfo_' + username);
  end
  else
  begin
    // No cache'd version, retrieve a new set of data.
    { Open our TCP Socket, call the webservice with the
      correct parameters and return the result.     }
    // Add our newly retrieved data to the cache.
    MyCache.SetData('UserInfo_' + username, Result);
  end;
end;

This method of implementation would lead to me having to put this code into each method and would lead to code repetition and possibly bugs being introduced (for example, if I forgot to update the cache key string on one method). I wondered if I could have a CacheString attribute that would allow me to automaticaly add my generic “do we have cache’d data? if so use it else carry on”  code to each method.

First of all, I tried essentially moving this code into a Method Aspect and adding a generic key function which takes the method name and method arguements and turns it into a consistent string using the Aspects.MethodName and Aspects.GetParameters methods:

WARNING! BROKEN CODE:

?View Code DELPHI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class method MyCache.getKeyFromMethod(aName: String; Args: Array of object): String;
begin
  var argConcat: String;
 
  argConcat := aName;
  for argTemp: String in Args do
  begin
    argConcat := argConcat + argTemp;
  end;
 
  Result := argConcat;
end;
 
method MyCacheAttribute.HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
begin
  aMethod.SetBody(Services,
    method begin
	  var cacheKey := MyCache.getKeyFromMethod(Aspects.MethodName, Aspects.GetParameters);
	  // Do we have this information in our cache?
	  if (MyCache.HasData(cacheKey)) then
	  begin
		// We do, use the cache'd data.
		Result := MyCache.GetData(cacheKey);
	  end
	  else
	  begin
        Aspects.OriginalBody;
 
        // Send the result of the Original Method to the Cache for next time.
        MyCache.setData(cacheKey, Result);
      end;
    end);
end;

Unfortunately it is not quite as simple as just placing your code into the AMethod.SetBody Anonymous method. Luckily it turned out that the Cirrus documentation on the Wiki had recently been updated and I discovered the Cirrus Statements and Cirrus Values namespaces after a bit of helpful guidance from John Moshakis on StackOverflow and Twitter (thank-you for that John!). I discovered that what you are required to do in most cases is to construct your code in an almost compiler like fashion using the Statement and Values namespaces.

Eventually after playing around with the Cirrus API, I eventually ended up with the following code:

?View Code DELPHI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
method MemCacheAttribute.HandleImplementation(Services: IServices; aMethod: IMethodDefinition);
begin
  // Get a Reference to our Result Value
  var newResult := new ResultValue();
 
  // Get our MemCache Object
  var cacheType := Services.FindType('AOPCacheLibrary.MyCache');
  // Setup our static methods.
  var getDataProc := new ProcValue(new TypeValue(cacheType), 'getData', [new NamedLocalValue('cacheKey')]);
 
  // Assign the result of our cache request to a local variable.
  var getDataAssignment := new AssignmentStatement(new NamedLocalValue('strData'), getDataProc);
 
  // CACHE DATA USED: To assign our Cache'd data to the Method Result
  var useCacheData := new AssignmentStatement(newResult, new NamedLocalValue('strData'));
  // CACHE DATA NOT USED: To assign the result of our OriginalBody to the Method Result.
  var useOriginalMethodResult := new AssignmentStatement(new NamedLocalValue('resultOriginal'), newResult);
 
  aMethod.SetBody(Services,
    method begin
      var strData: String;
      // Get our Cache Key Name
      var cacheKey := MyCache.getKeyFromMethod(Aspects.MethodName, Aspects.GetParameters);
 
      try
        // See if we have anything in the cache for this key.
        unquote(getDataAssignment);
        // Replace this
        unquote(useCacheData);
      except
        on E: Exception do
        begin
          var resultOriginal: String;
          // No cache data found, execute the original method body.
          Aspects.OriginalBody;
 
          // Assign the result of the Original Method to a new variable.
          unquote(useOriginalMethodResult);
          // Send the result of the Original Method to the Cache for next time.
          MyCache.setData(cacheKey, resultOriginal);
        end;
      end;
    end);
end;

According to the Red Gate .NET Reflector and Disassembler, this produces the following code:

?View Code DELPHI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    function TFlickr.GetUserInformation(username: String): String;
    var
        Result: string;
    begin
        cacheKey := MyCache.getKeyFromMethod('GetUserInformation', New(array[1] of TObject, ( ( userid ) )));
        try
            Result := MyCache.getData(cacheKey)
        except
            on E: Exception do
            begin
                // This is where we do our _ORIGINAL_ function
                resultOriginal := Result;
                MyCache.setData(cacheKey, resultOriginal)
            end
        end;
        begin
            Result := Result;
            exit
        end
    end;

This means that I can now add caching to any of my string returning web service methods in my class by simply tagging the methods that I want cached with a code attribute:

?View Code DELPHI
1
2
3
4
5
6
7
8
  TFlickr = public class
  private
	{code}
  public
    {more code etc, etc}
    [Aspect:MyStringCache]
    method TFlickr.GetUserInformation(username: String): String;
  end;

This works perfectly but there are a few problems with this code:

  • As you can see: constructing statements using the Cirrus API (in the statements before the aMethod.setBody) doesn’t exactly make for readable code. You may wish to consider outlining each statement with psuedocode so that it is clearer at a glance what the API calls produce.
  • I should be using the Cirrus Procedure Value calls for all three calls to the Static “MyCache” class but am not because I couldn’t quite get this working. Please be aware that John informs me that the method I use in the first and third instance is not the correct way to go about this.
  • This exact method only currently works for System.String returning methods. There must be a way of abstracting this function to apply it to almost a method returning almost any type (if anyone has any suggestions about how this might be accomplished then, by all means post a link in the comments).

Please note that the code above is NOT intended to be a reference implementation for AOP or Application Caching but is merely intended to show you my own learning path with Cirrus and AOP. The Cirrus API is quite difficult to work with at first and can give you frustrating compiler errors but it’s worth keeping an eye on the documentation pages and as more examples appear online it will become easier to work with. You should have the Red Gate .NET Reflector on hand with its disassemble function to confirm exactly what the resulting code in your Output assemblies looks like.

If you have any constructive suggestions for my code above then please let me know. Additionally, if you think it would be useful for me to post the downloadable Delphi Prism project then please also let me know in the comments below.

Starting your own journey to Cirrus/AOP

Posted in Delphi, Delphi Prism, Development | Tagged , , , | Leave a comment

Turbo Delphi: A Hidden gem in DelphiLive?

I enjoyed the Twitter live-coverage and exciting revelations of DelphiLive! particularly from JimMcKeeth and marcocantu but also many others. Despite the surprise revelations of Project X etc a particular slide caught my eye amongst the many others:

Delphi Targets

Did you see it? ..ISVs, VARs, Consultants and Hobbyists.. I jumped at the phrase and asked Jim whether any of the Product Roadmaps he’d seen at DelphiLive had revealed any plans for a renewed focus on Turbo or Hobbyist editions of Delphi however it seems that they did not specifically mention anything. Luckily Jim had noticed the significance of this typo phrase too and was kind enough to pose my question to the new Delphi Product Manager, Michael Rozlog:

Hope

I should make it entirely clear that this should not be read as a statement of intent from Michael or Embarcadero but merely an indication of Michael’s personal thoughts on Turbo or Personal Delphi editions. This is encouraging news though, as many of you will know I wrote a long Open letter to Codegear on the subject of the sadly neglected Turbos and received a lot of feedback indicating that many of you felt the same way.

So what now?

Personally I’m thrilled that there seems to be at least some internal support for a renewed Turbo or Personal Delphi Edition but as usual, the devil is in the detail, How can we get a great home/hobbyist product (as opposed to a crippled and essentially useless product) without costing Codegear precious sales/revenue?

There are several different facets to this problem:

  • What type of audience is the product is actually targetting? (Home users, Small ISVs, commercial vs strictly hobbyists?)
  • How should product be limited for that audience without damaging it’s viability or sales of the full product (As Delphi’s fate is intertwined with that of Codegear – not something we want).

There are three different potential products in my mind:

  1. A Purchasable Commercial Product which is essentially a step down from Delphi Professional SKU in both price and features made for smaller software shops and developers that don’t need the features of the full versions.
  2. A Non-commercially licensed product equivalent to the educational edition (which If I remember correctly is the Professional SKU?) where the price is a token amount to cover the cost of the bandwidth and packaging cost of the product.
  3. A Commercially licensed but absolutely free product which is crippled in its functionality and features even more than the current Turbo Explorer Editions.

As you might have guessed from my use of mildly emotive language in the 3rd point above and in my Open Letter to Codegear regarding the Turbos I consider the 3rd Option to be a non-offering. Sadly, previous statements from the former Delphi Product Manager, Nick Hodges, hinted that this was also the way he felt it might go.

I would be interested to see how the previous editions of Delphi impacted Sales (there must be paperwork, come on?) as I felt that these were always an amazing offering for Hobbyists and Home users wanting to take up the language (I remember finding Delphi 6 Personal on a magazine cover disc – presumably thanks to the always excellent Tim Anderson).

I would ideally like to see something in between the 2nd and 3rd options option a reality, I am not qualified to make a factual assertion on this but I don’t think it would hurt sales if strictly limited to non-commercial use in the license. Massive Feature limiting such as removing the ability to use 3rd Party VCL components as the Turbo Editions persued removes some of the most well-known and advantageous reasons for using Delphi in my opinion and is therefore unsuitable for an ambassador product (which these editions would be). I won’t rehash my argument about why the product needs to be both free and well featured (see my Turbo Delphi Open Letter) but I will say this:

Whether it is fair or not, Microsoft and the Eclipse foundation have forced their hand – a reasonably useful free IDE for home and hobbyist users wanting to experiment with a language is now a minimum requirement for competitiveness in the programming language market.

It is worth noting that the Updated Personal or Turbo delphi is currently only number 8 on the list requests at the Delphi Uservoice page, we really need people to vote for it and also to discuss their thoughts on the potential product in the comments over there.

Michael suggested that he was looking for feedback, so I’m looking for feedback. Firstly: What would your Turbo or Personal Product look like and secondly: what would you do if you were the Delphi Product Manager? How do the results of these two views differ? Please think about it and then either put it in the comments below or on the Delphi Uservoice page.

Posted in Delphi, Development, apps-i-love, codegear | Tagged , , | 14 Comments

Diary of a C# to Delphi Prism conversion

I have in the past written up a few tips for converting a Delphi.NET project to Delphi Prism but this time I thought it might be useful for me to write up my experiences on converting this C# Project to Delphi Prism by initially using the C#ToPas Tool from RemObjects. Many of you who attended CodeRage III (in a virtual manner) might remember Jim McKeeth’s Revenge of Delphi Robot rage session. The aim of the session was to build a Unreal Tournament 3 Bot to fight it out against other competitor’s bots in an Unreal Tournament 3 arena using the (then) newly recently Delphi Prism tool. For those who didn’t attend, I’ll spoil the ending and just tell you that somehow my bot won. ;-)

Jim is planning another session for the DelphiLive conference (which I really wish I could go to, check it out if you haven’t already). However when running the last tournament we encountered a number of fatal bugs in the .NET UT3 Bot library which was originally put together by Andy Sterland & James Lissiak. As a result Jim and I had been discussing the idea of porting the original library to Delphi Prism so that we could fix a few of the more serious bugs, it would also allow potential Prism Developers who were not familiar with C# to dig into the library itself. This is a project conversion diary which will outline the approaches I tried, any hurdles I encountered and a few tips for trying to avoid them when converting your own project.

I started by running the C#ToOxygene Tool on all of the source files within the project, It’s a very simple and easy to use tool that as its name implies aims to convert C# source files to Delphi Prism files. I was able to run the tool without issue on every C# source file except for 3 where for some reason it exited producing the error:  ”Error during processing: Index was out of range” (Issue logged (rather clumsily) as #37).

Having started on the basics of the translation using the conversion tool to do the grunt work I then dived into the code with the Prism Wiki and MSDN C# documentation open to make a start on correcting the 600-odd errors that the resulting project produced upon an attempted Build.

At first glance I felt that the resultant code was a little bit visually “messy” in places and I felt it might be easier to prettify the code using a Code Formatter such as the JEDI Code Format tool to clean up the auto generated code and highlight any mismatched parenthesis or similar errors. However unfortunately the JEDI tool is not compatible with Prism and therefore refused to help me. If anyone knows of a Code Formatting tool which is compatible with Delphi Prism then please let me know in the comments below.

A few other issues which I encountered with the generated code or more generally are outlined below:

Internal Keyword

The C# internal (msdn doc) keyword was not correctly translated – for this I took a trip to the Prism Wiki and looked up the Class Member Visibility Levels page to find that the equivalent level assembly is listed there (Issue #42). Note that in Delphi Prism you can also have assembly or protected or assembly and protected depending upon whether you wish the class to be visible to descendants.

The C# “this” Keyword

The C# this. (msdn doc) keyword was not correctly translated to the Delphi Prism Self. equivalent that we’re all accustomed to. This isn’t hard to spot when going through the generated code and the issue had already been logged by Anton Kasyanov (Issue #39) and should be fixed shortly.

Float Types

One class made extensive use of the float type (msdn doc) which doesn’t exist as is a built-in type for Delphi Prism so you’ll need to convert it to one of the two Float types depending upon the precision you require.

Operator Overloading

Operator Overloading is not something that Delphi developers may be traditionally used to but Delphi Prism supports this nicely. However instead of using the sign operator that C# Developers use you’ll need to lookup the operator name and declaration on the Operator Overloading Wiki Page. eg. The Equals operator is declared as so:

?View Code DELPHI
1
class operator Equal(obj1, obj2: UTIdentifier): boolean;

Differences between return, Result and exit

This should be obvious to any C# Developer but it could be easy to forget about. Don’t forget that the return C# method (msdn doc) terminates execution of the method in which it is being executed and returns to the calling method and therefore be wary of using Result blindly in an identical manner, particularly with boolean statements that rely upon this fact. Eg. Consider the following C# Code:

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
public override bool Equals(object obj)
{
	if (obj is UTVector)
	{
		if (this._x == ((UTVector)obj)._x &&
			this._y == ((UTVector)obj)._y &&
			this._z == ((UTVector)obj)._z)
		{
			return true;
		}
	}
	return false;
}

Clearly, if you simply replace the return false; with Result := False; you will end up with a method that always returns False because the expression will always be executed no matter what Result is set to earlier in the method. In this case I simply moved the Result := false; to the top of the method. Delphi Prism also supports the Exit keyword which also allows you to Return a result parameter. This method is a lot closer to the C# return keyword and usage but the Exit page on the Prism Wiki warns against using too many exit keywords to avoid making the code harder to maintain.

Constructors are not named

This is a rare example of where the original C# code actually looks much closer to the end Delphi Prism code than a traditional Delphi programmer might think. In C# you might have a class and constructor that might look like this:

?View Code CSHARP
1
2
3
4
5
6
public class UTIdentifier
{
	internal UTIdentifier(string Id)
	{
	}
}

In Prism, we have nameless constructors which means that the equivalent Delphi Prism constructor implementation might look like this:

?View Code DELPHI
1
2
3
  constructor UTIdentifier(id: String);
  begin
  end;

It is important to note that in your class interface should adhere to this rule too. eg constructor(id: String);

This was something that the C#ToPas tool also generated incorrectly. (Issue #44)

Short-Circuit Boolean Expressions

I came across the C# || operator which performs a short-circuited OR boolean evaluation of the operands. I wasn’t sure that the Delphi Prism or operator produces the same behaviour but if I read the Expression Evaluation page correctly then I believe it does (In Delphi 2009, at least, this behaviour is set through the {$B+/-} compiler flag) .

Event Assignment

The Event Assignment routine for multicast delegate type events is slightly different in Delphi Prism from what we’re used to in Delphi Win32. Looking at the Event Assignment page in the wiki we can see that the actual method for assignment is much closer to the C# equivalent and uses the same C# += and -= operators. The C#ToPas tool converted this code a little too literally converted this C# code:

?View Code CSHARP
1
2
this._connection.OnDataReceived += new EventHandler(DataReceived);
this._connection.OnErrorOccurred += new EventHandler(ErrorOccurred);

to this:

?View Code DELPHI
1
2
Self._connection.OnDataReceived := Self._connection.OnDataReceived + new EventHandler(DataReceived);
Self._connection.OnErrorOccurred := Self._connection.OnErrorOccurred + new EventHandler(ErrorOccurred)

Which produces a compiler Error that Events in Delphi Prism don’t allow access to the underlying field. You should use the += operator instead as seen on the Wiki. (C#ToPas Issue logged as Issue #45).

UPDATE: I’ve just noticed (after logging my own issue) that the event assignment issue has already been reported and has been marked as Won’t Fix (Issue #27) so it looks like you’ll need to check _every_ event assignment in your project manually.

Switch and Case Statements

The C#ToPas tool did not appear to react well at all to use of the C# switch and case statements. I can’t give you any specific advice on how to fix these because each case statement was generated slightly differently in my converted code and therefore I can only advise that you check these manually or rewrite each of these methods by hand.

Reserved Keywords

Sadly this isn’t an issue that is related to the C#ToPas tool but more of an intrinsic difficulty when converting interoperable code between languages. I encountered at least one class that made use of a few reserved words in Delphi such as begin and end – I’m still not sure what to do with these for now.

Overall Impression

Despite a few early bugs the C#ToPas Tool is a good platform to begin converting your C# code to Delphi Prism although you may wish to ensure that you have some extensive Unit Tests for your code before the main code is converted so as to ensure that any bugs introduced can be picked up on quickly (which you have anyway right?). It is also worth noting that the Delphi Prism Wiki (which now authenticates via your CDN login) has excellent coverage and is an absolutely invaluable reference for anyone working with Delphi Prism.

By the time this entry is published I suspect that Carlo will be very close to fixing some or most of the above bugs in the C#ToPas tool.

The code is nowhere near complete yet and most of the files are still straight out of the Automatic conversion and therefore will not compile in any way but I’ve put what we have so far up on the rather smooth Github site at the PrismUT3RemoteBot project which anyone can fork and push changes back to. Git is a little strange to work with at first because it’s a different mindset to SubVersion/CVS but it’s worth checking out if you haven’t already.

Posted in C#, Delphi, Delphi Prism, Development, Podcast at Delphi | Tagged , , | Leave a comment

My Developer / Utility Toolbox

Most Developers will already have come accross many of these tools but just as every plumber has a favoured brand of wrench or electrician has a favoured model of multi-meter we all have a favourite set of productivity enhancing utilities. Here are a few of the tools which I find tremendously useful or find developing without particularly painful. Writing up a small list of these utilities also helps me more than it may help you because it’ll also serve as a todo list for any new workstation that I want to set myself up on in the future.

(Items marked with an Asterisk * are non-free)

Delphi Tools

GExperts – Every Delphi Developer should have GExperts, adding a fantastic selection of features to the Delphi IDE and Editor.

cnWizard IDE – Quite a few commenters suggested adding cnWizard IDE here, I’ve never actually tried it but did consider it against GExperts. What put me off was the relatively uninformative website (yes, shallow of me but I can’t help it!).

DelphiCodeToDoc Options

DelphiCodeToDoc Options

DelphiCodeToDoc – Generate documentation from your Delphi Source comments, including JavaDoc compatible comments. DelphiCodeToDoc is open source and can generate Windows Help Files or HTML Documentation (or both).

SmartInspect* - This is a commercial product which gives you amazing code logging features for Delphi, .NET and Java applications (and even PHP too now which I also find useful). No more inserting breakpoints, watches and spurious ShowMessages()’s just to track the variables in an application. Even allows Remote Logging when an executable is deployed on a different machine. Saved me from a particuarly frustrating problem in a remote app recently.

SmartInspect Console

SmartInspect Console

Innosetup – A Free installer which allows you to create fully customisable installers which support nearly every version of windows and even 64 bit architectures. I’ve also found it to be just as functional and much easier to use than some of it’s expensive competitors.  Did I mention it’s also free?

MemCheck – Not really an application per se. Not fully Delphi 2009 compatible yet but this is a useful little unit that means adding a single line to your project file and then creates a log file of the memory leaks in your application.

WAnt –  A Delphi specific Build Automation tool in the same fashion as the Java Ant tool. I looked into this tool recently because I wanted a way to automatically Checkout, Build and Test the Dwitterphi project that I’m working on so I know when the SVN Trunk has been broken.

Editors / IDEs

Programmers Notepad 2 – A General Purpose Notepad replacement which includes Syntax highlighting support, bookmarks, code folding, project and project group support and all the usual gubbins which you would expect from a lightweight notepad replacement.

Zend Studio* – My copy is a few years old, before they switched to Eclipse. I’m actually looking at replacing this with something newer and free.

Zend Development Environment (older version)

Zend Development Environment (older version)

Eclipse – Needs no real introduction. A Base for so many tools. I also use the RadRails package for Rails and Ruby Development.

Version Control / File Comparison

Beyond Compare 3* – An amazing File Comparison utility with 3 way merge capability, folder sync capabilities, specialised viewers for various file types and remote comparison tools. I’ve mentioned it many times before but this is an essential tool for developers.

Beyond Compare 3

Beyond Compare 3

Toroise SVN – Easy to use interface for Subversion which integrates beautifully with the Windows Shell. My only gripe with this particular tool is that it seems to bug you often to download the latest updates when they should by now have implemented an auto-update feature.

SVNMonitor – Only Recently suggested to me by @dmiliam via Twitter. I installed it and found it tremendously useful for keeping tabs on whats happening with a SVN Repository.

Internet

SmartFTP* – There are a million FTP Clients out there, some are free with comparable features to SmartFTP but none come close to the overall package and polish that SmartFTP represents including support for FTPS and SFTP and very smooth transfer queues and folder sync features.

FeedDemon – Developed in Delphi by Nick Bradbury. It’s considered very cool to use Google Reader nowadays but you can’t beat the stability and power of a Desktop Reader and FeedDemon has it all. Fast and efficient, especially good when combined with the NewsGator Online Sync Service that allows me to sync unread/read items to my Work PC or even my Blackberry with NewsGator Go! and catch up with news on the go. Sync with Google Reader is also on the way. FeedDemon FTW.

FeedDemon 3

FeedDemon 3

twhirl – I prefer twhirl as my Twitter client of choice as it isn’t as big and bulky as TweetDeck but all that will change when there is a great native win32 twitter client.

Browser

FireFox – No explaination neccessary really.

  • Web Developer Toolbar – Simply indispensable for those who spend a great deal of time crafting Browser content or applications.
  • YSlow – I’ll be honest: I’ve never had a site that is big enough to need the level of optimisation that Yahoo.com does but the advice this tool gives is sound and it will help you to identify bottlenecks in your sites performance.
  • FireBug - Edit, debug, and monitor HTML, CSS and JavaScript live in any web page.

Google Chrome – Used for Day to Day browsing because it’s an order of magnitude faster than almost any other browser out there in general browsing (Just my opinion).

SuperPreview – A fabulous tool from Microsoft unveiled at Mix09 which allows you to view web pages in Internet Explorer 6, 7 and 8 as well as your other browsers whilst allowing you to super-impose expected layouts on top of one another to see how the renderings differ. No more hefty VMs required for testing layouts.. great success!

Shell / Miscellaneous

Open Command Window Here shortcute

Open Command Window Here shortcute

Command Prompt Here - A hugely underrated and disarmingly simple shell extension which adds an “Open Command Prompt Here” sub-item to the context menu in Windows Explorer. No more cd “C:really really really long path name” for these users.

UltraMon* – This improves the Multi-Monitor support in Windows hugely, something that if you haven’t tried it, try it now! Monitor specific task bars, extra system buttons on each window, wallpaper and desktop icon management. Ultramon is so useful that I’m suprised it hasn’t already been acquired by Microsoft like the SysInternals team were.

ProcessExplorer from SysInternals

ProcessExplorer from SysInternals

SysInternals – From by Mark Russinovich and Bryce Cogswell, The best set of power user utilities available out there, Acquired by Microsoft a few years ago. My personal favourites are:

  • Process Explorer – Think of the windows task manager on steroids, double it and then add more.
  • Autoruns – Comprehensive lists of everything starting up when your computer does.
  • ps* Utils – Lightweight remote versions of your favourite windows commands.

VirtualBox – A Free and Open Source VM competitor to Microsoft VirtualPC and VMWare etc. Not as polished as VMWare in some parts of the user interface or networking features but very usable and getting much better with every release.

Window Clippings* – Recommended to me by marc hoffman (although how he knew about it – primarily being a mac user I’m not sure). A very easy Screenshot and Window Clipping tool. Great features, addons available and inexpensive. Everyone has their own preference for a Screenshot tool so whilst I would completely recommend this, I wouldn’t push for you to change over any other.

Power Toys – An amazing set of utilities that add to windows.

SyncToy 2 - A File and Folder Synchronisation tool that I use to keep files backed up to my home servers and which I will use to Sync important indispensable files (music!) to my NetBook when I finally purchase it!

This isn’t a completely comprehensive list (I’m not going to dump a list of everything from Windows Add/Remove Programs!) but I’d love to hear if you think I’m missing out on any spectacularly useful utilities for Delphi or Web Development. Hopefully you found at least one utility in this list that you’ve been putting off trying and have realised why I found it to be useful.

Posted in Delphi, Development, Miscellaneous, Web Development, apps-i-love | Tagged , , | 24 Comments

Design Decisions – A REST Library

Since Jim has posted Episode 24 of the Podcast at Delphi.org and explained that we’re making an open source Twitter client I thought I would write a quick post about some of the design decisions which we’re already facing. In Particular about the decisions around the internal class that will handle communication with the Twitter API.

Background

As a little background we’re aiming to create an open source Twitter client using Delphi, involving the wider community in as much as possible. We realise that there are several million existing clients for virtually every platform, language and environment ever built but we would like to do this because:

  • There aren’t currently any Libraries or Applications built with Delphi (afaik).
  • This will hopefully provide discussion and learning resources for the Podcast and for the community.
  • It will be fun for those involved!

The aim of the client isn’t to be the most fully functional or visual-effects laden available but to produce a solid, stable and lightweight native client. We simply won’t have the developer time or resources available to build the next Tweetdeck. Most of the most widely used desktop twitter applications such as my own personal favourite TWhirl are built on the Adobe Air which means they usually consume vast quantities of RAM, an issue which I clearly wanted to avoid as I’m fed up with a my Twitter client consuming 100Mb+ of RAM.

The Twitter API

The Twitter API is a simple API which attempts to adhere to the Representational State Transfer (REST) principles. At it’s most basic state, you can get the latest public timeline of tweets through an Http GET request to: http://twitter.com/statuses/public_timeline.xml

Library within a Project Design Decisions

As part of the overall Twitter Client design we wanted to have a Delphi Twitter API client library which a delphi developer could extract and potentially use on a different project if they so wished.

One of the other design considerations is that our library needed to be reserved about making API calls. This is because the Twitter API is rate limited and usually only allows 100 requests per 60 minute time period but this can dynamically change according to the load that Twitter is under (for example, Heavy traffic and infrastructure problems during WWDC 08 meant it was reduced to 60 requests). We must also not forget that many users have more than one application accessing the API so we can’t assume that all 100 requests are solely for our own use meaning that we must be as restrained with our API calls as we can.

When we began pulling together this library I initially felt that there were two different routes which we could take:

  • A One to One direct representation of the Twitter API Methods. i.e. For each call in the REST API Documentation, there should be an equivalently named function taking the same parameters with a minimally structured result object.
  • A Higher level and more object orientated “Delphi-ified” Abstraction of this. i.e. Break away from the naming of the API functions into higher level requests and objects that might potentially make several low level API calls for one of the high level functions.

The Second option is the authentic Delphi way of doing this and would lead to the creation of a library which would draw on the strengths of Delphi. The advantage of the One to One Direct Representation of the API it means that almost any developer who is familiar with the Twitter API can read the documentation and see exactly what he is calling and how he is calling it without having to learn the idiosyncrasies of a client library on top of understanding the API. The bare-bones API version however would need some higher level handling and objects building on top of it before it could be really useful to our Twitter client but would require careful data cache’ing to avoid utilising too many API requests.

This leaves a whole host of questions to be resolved:

  • How modular do you make the class before you begin to erode the flexibility of your library?
  • How much code are you prepared to add to make the class generic enough to be used in other projects but without compromising on the purpose for which it was built (this project)?

These questions are not unique to Twitter or REST API libraries in general; Most Delphi components abstract a specified resource in a similar way to this, some choose the minimal API reflection technique, others provide a full high level object orientated interface.

I suspect that the optimal solution to ours lies somewhere in the middle but I would love to get some opinions on how you would design it? Have any of you worked with similar REST clients and have guidance or tips to pass on? Are their any similar remote libraries which you have used which were so easy to use that you would recommend we learn from them?

Posted in Delphi, Development, Podcast at Delphi | Tagged , , | 10 Comments

Delphi3000 Malware Problems

Just a short post to warn Delphi community members that when I tried to visit long standing community code site  Delphi3000.com I received a warning from Google Chrome that the site apparently contains a significant load of Malware:

The Dialog Chrome gives me when I visit Delphi3000.com

The Dialog Chrome gives me when I visit Delphi3000.com

The more advanced description of what Google claims to have found can be viewed on their Advisory page but the short version is that it seems that the site could’ve been hacked 3 days ago (when Google first detected it) and a whole host of nasties implanted. Here’s what they say they found:

Malicious software includes 12 scripting exploit(s), 1 exploit(s). Successful infection resulted in an average of 5 new process(es) on the target machine.

Malicious software is hosted on 20 domain(s), including [redacted], [redacted] and [redacted].

Hopefully the guys at Delphi3000.com will notice this soon and will clear up their server (if anyone knows the maintainers then please let them know). In the meantime I would advise that anyone browsing avoid this particular site until it’s cleared, especially if you’re using earlier versions of Internet Explorer which might be more susceptible to exploitation.

On a separate note: I’ve been pretty busy of late and will be a guest on the next episode of the Podcast at Delphi.org with Jimmarc hoffman and Steve Kamradt which is due to appear on the site in the next 24 hours talking about a new project. I don’t think I said very much, mostly because we discovered my microphone has an uncanny habit of picking up background noise! oops. None-the-less, it was great fun to be on the podcast finally and I enjoyed taking part and contributing. I’ll be posting in greater detail about the subject of the podcast when it becomes available.

Posted in Delphi, Development, Much ado about Nothing | 10 Comments

Delphi can do MQTT too!

I have recently released my MQTT Client for Delphi, which can now be found and downloaded here . TMQTTClient is a non-visual Delphi Client Library for the IBM Websphere MQ Transport Telemetry protocol. It allows you to connect to a Message Broker that uses MQTT such as the Really Small Message Broker (RSMB) which is freely available for evaluation on IBM Alphaworks. Alternatively for it’s larger brother you can try the IBM Lotus Expeditor product.

I felt that I should explain a little bit about what RSMB is and why you might want to use either RSMB or another broker that supports MQTT for a project. RSMB is a small and ultra-lightweight Message Broker, it takes only 50KB of Code and can run in 150KB of Memory or less (obviously you might find this varies slightly for you). A resource consumption level which makes it ideal for situations where it is required to run on low power servers (such as the Viglen MPC-L which runs on just 10W) or in resource constricted environments.

The MQTT Protocol itself is equally compact but no less powerful and is perfect for running on Low Bandwidth or unreliable connection environments where you may have many sensors connected via different means. MQTT is a Publish / Subscribe model where a client can subscribe to a particular “topic” (verbose example /home/kitchen/temperature) and will then receive messages from Publishers on that topic (for example 18 degrees celsius). Potentially very powerful as I’m sure you’ll agree, you can understand why the Pervasive messaging group at IBM are particularly excited about this technology.

RSMB also has the very useful feature of being able to bridge with other Message Brokers which allows messages to be passed on between brokers.

 

What do you actually use this for?

I use RSMB and MQTT as the messaging transport for my Home Monitoring and Automation Network as a result of the great talks I heard from the great IBM pervasive messaging team that I met when I attended Homecamp last November. In order to demonstrate it’s usage, it is probably easiest to explain a scenario which is implemented on my home network. 

Example: I currently have my CurrentCost unit hooked up to my home server which publishes it’s electricity usage and temperature information to an MQTT Topic to my RSMB Server. This data is then published to subsribers such as an “ambient orb” which, I’m currently building based on the Arduino platform, that glows a different colour depending on how the current usage compares to the normal average for this particular time of day (Glowing Red, for example, if I’m consuming a lot more than normal).

This is a very similar setup to the one that powers Andy Standford-Clark’s Twittering house and to the Ambient orb setup that Nick O’Leary describes (with photos) in his own blog post here. The Key point is that having the lightweight messaging protocol MQTT as the backbone makes adding and removing devices easy. (no matter what shape or size they may be)

Nick O’Leary has written a very handy MQTT Client for the Arduino platform which allows my ambient orb to get the latest consumption data from the CurrentCost unit without them having to talk directly to each other.  There are also MQTT Client reference  implementations for Java, C and 3rd party implementations for Ruby and an unofficial Perl library. 

Why not use a more widely compatible transport such as one based on XML?

It’s true that in the example provided above the transport used could be a Web Service or a simple RSS feed but what makes MQTT particularly useful is that it uses a Publish/Subsribe model which lends itself more to real time data than either of the above. MQTT is also considerably more lightweight which allows you to fit a client into a device like the Arduino without the On-the-wire and library XML Parsing overhead. 

Ok, how can I get started?

Downloading and Setting up RSMB is very easy, you’ll need an IBM.com ID to download but then setup simply involves extracting the zip file and running the appropriate executable (Windows and Linux binaries are included). To use TMQTTClient you simply need to download the component and extract the two units in TMQTTClient. You will also need to make sure you have the excellent Synapse Communications components available on your search path somewhere.

After that you could publish messages to your broker telling you that you had a new email from your Delphi code in this sort of manner:

?View Code DELPHI
1
2
3
4
5
6
7
8
9
10
11
uses MQTT;
 
var
	MQTTClient: TMQTTClient;
begin
	MQTTClient := TMQTTClient.Create('localhost', 1883);
	MQTTClient.Connect;
	MQTTClient.Publish('/messaging/email/john', '1 New Message');
	MQTTClient.Disconnect;
	MQTTClient.Free;
end;

Subscribing to a topic is just as easy and you can create an event handler to handle incoming Publish messages on any particular topic:

?View Code DELPHI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
uses MQTT;
var
	MQTTClient: TMQTTClient;
 
procedure TmyForm.btnConnectClick(Sender: TObject);
begin
	MQTTClient := TMQTTClient.Create(eIP.Text, StrToInt(ePort.Text));
	MQTTClient.OnPublish := OnPublish;
	MQTTClient.Connect;
        MQTTClient.Subscribe('/messaging/email/john');
	MQTTClient.Publish('/messaging/email/john', '1 New Message');
end;
 
procedure TmyForm.OnPublish(Sender: TObject; topic, payload: string);
begin
	memoStatus.Lines.Add('Publish Received. Topic: '+ topic + ' Payload: ' + payload);
end;

Having written this, I can now focus on building out the rest of my home monitoring network (details to come another time) which will be super easy (I hope!) now that it is based on a MQTT/RSMB system.

Posted in Delphi, Development, Home Automation | Tagged , , , | 2 Comments

Quick Tip for handling IE Invalid XML Files

I encountered a strange bug with a Google Maps API application which loaded a set of points and other information from a static XML File.  The Application would work beautifully for every browser except for Internet Explorer 6 and 7 (Surprise! Surprise!) where it would simply fail to load any data.

After a bit of Googling I was tipped off to the idea that my XML File could contain non-visible invalid XML Characters. Trying to open the XML file in Internet Explorer confirmed this suspicion as it threw up a rather unhelpful and non-descriptive error. I tried opening the document up in a Hex editor but the document was large and my untrained eye could not locate the problematic character(s) amongst the valid ones. After taking a few excellent suggestions on Twitter I tried opening the file in Altova’s XML Spy didn’t help correct the document as it claimed the document to be “well-formed”. After a little bit of Googling for XML Document Inspection solutions I stumbled upon a newsgroup post mentioning using Dave Raggett’s excellent HTML Tidy Utility (which can, contrary to it’s name, be used for a lot more than HTML!).

By running the Tidy tool with the command line arguments:

tidy -mi my_broken_xmlfile.xml

This instructs tidy to indent and prettify the xml file (which I would always recommend for any XML File in development) and to modify the original file. In the process of Indenting and Prettifying it removes any invalid characters which make the document invalid. You could also write the Tidy’d XML file to a separate file using the -o output-file option instead. I then used Scooter Software’s fantastic Beyond Compare tool to view the difference(s) between the old and new versions in order to check what changes had been made.  

Incidentally, Beyond Compare is an invaluable tool for any developer allowing Both Local and Remote Comparisons, 3 way merging of documents and even folder comparisons (remote or local: very useful for websites).

Posted in Web Design, Web Development, apps-i-love | Tagged , , | Leave a comment

The Delphi Channel: Coding Delphi for Fun

I am a great fan of the Microsoft Coding 4 Fun blog and feel that there should be something similar for Delphi Progammers. I am trying to get something similar started as a way of boosting the relevance, appeal and attraction of Delphi to novice, hobbyist or student programmers. 

Why? 

The aim of it would be to encourage developers to dabble in a series of fun projects and technologies which they might not get the chance to use in their everyday work. It will also have the aim of trying to encourage more novice/student/hobbyist developers to take up Delphi by demonstrating that it can be used for more than Enterprise N-Tier Database Applications. This also ties in nicely with my Open Letter to CodeGear about the Turbo Delphi family last week (Short update on that article at the end of this one).

What sort of articles would it include?

It will publish articles in 4 very broad categories, but not be strictly limited to those categories, which may intersect each other at various points: 

  1. Hardware – Interacting with any kind of hardware gadget. Examples would include interacting with a USB Bluetooth Lock, WiiMotes or controlling your home.
  2. Software – Interacting with other software. Anything that solely interacts with other software such writing plugins for Windows Live Writer (ok – I was short of ideas on this one!).
  3. Web Services – Interacting with plenty of Web 2.0 APIs. Examples such as getting pictures from Flickr, Updating Twitter or Writing a Facebook Application.
  4. Gaming – Interacting with or Writing Games. Good Example: Revenge of the Robot Rage contest which Jim McKeeth held over on the Podcast at Delphi.org (which incidentally I did win :) ). Please note that this would not aim to replace the many excellent resources on writing games in Delphi.

I realise that there is a lot of overlap between those categories but I wanted to demonstrate the types of articles and example projects that I was thinking of. Many of these projects could simply be a simple translation of the C# or VB.NET version on Coding4Fun as even just having the code in Delphi would still add value.

This wouldn’t simply be an extension of my personal blog, I would ideally like to see articles being contributed by lots of Delphi Developers who may have played with projects like this in the past and wouldn’t mind putting their experiences into Article form. I have a domain and I have a draft site running but I consider this post a call for Delphi Developers to suggest, contribute or request articles that they would like to see.

Why not write all the articles yourself?

Whilst I have a few articles which I am in the process of writing I feel that as a resource it would be much better with Developers contributing on areas of their own interest and expertise. Many more developers than myself would be able to contribute much more adventurous tickerings. 

How can I get involved?

It is nothing urgent but please give it some thought: have you had any projects recently which other people might find fun? Have you bought any new gadgets recently that you’d like to try to tinker with in a Delphi environment? Is there something you would particularly like to see an article written about? 

If you have any thoughts then please contact me by email or through twitter (@jamiei).

 

Update on my Open Letter to CodeGear about the Turbo Product Family.

I had a lot of great (and supportive) feedback from my Open Letter to CodeGear last week but I saw the below information in my Google Analytics statistics for this blog and it made me laugh. It would seem that either the folks at CodeGear HQ (in Scotts Valley) are miraculously fast readers or they read just the title and immediately became bored enough to click away. 

Did they really consider it? The great people at CodeGear HQ must be very fast readers!

Did they really consider it? The great people at CodeGear HQ must be very fast readers!

Being able to read that quickly is something that I would love to learn to do, if anyone knows their secret, please let me know!

Posted in Delphi, Delphi Channel, Development, codegear | Tagged , , , | 6 Comments

The Turbo Delphi Product Family: An Open Letter.

To whom it may concern at Codegear,

A Recent posting over at The Doric Temple titled “how do I make the case for delphi (as a target business development environment)” has prompted me to wonder why Codegear has slightly neglected the Turbo family which to my knowledge hasn’t been updated since it’s initial release on the 5th September 2006.

I’ll be as clear as I can about this from the outset: I firmly believe that Codegear would benefit greatly from keeping their Turbo line up to date and built as an appealing overall package in order to attract hobbyist or student developers.

 

Why would Codegear give all this away for free or for a token sum?

I strongly suspect that the amount of users who pay for a full version of Delphi purely for Hobbyist or Student development is very slim. Who can honestly afford to pay £600 (Codegear Online Store - Delphi Professional 2009 – New User) for a tool which they don’t plan on recouping any of the cost of? With most Development in universities being done on Tools which are Free (such as eclipse), how can a University even justify spending on tools such as Delphi anymore? Therefore creating an appealing package for these users is getting your tool into the hands of Developers who wouldn’t otherwise have it (the current Turbos are arguably not appealing to new users compared to a tool like Visual Studio Express but more on that later). 

If Codegear are able to get Delphi into the hands of more developers then this will have an overall “morale” boosting effect on the community. Set aside the debate for now over what the knock-on effect to business development managers more potential new employees skilled in Delphi has. Lets look at this purely based on the effect of the increase in the number of Delphi Developers:

  • More Delphi Developers creating online and offline “noise”: articles, blog posts and posts on developer forums will have a positive branding and marketing effect for Codegear, something which they vitally need in order to remain relevant.
  • More Delphi Developers contributing community support, newsgroup posts and articles create a more appealing target development environment for potential business users.
  • More Delphi Developers create a bigger target market for component developers and will also create more components and code libraries themselves.

Codegear could turn Students and Hobbyists, a pitiful target market in turns of revenue potential, into a great contributor of Marketing and Product Support for their tools which will then be reflected in their revenue further up the chain at a relatively small opportunity cost.

There are Turbos available, why can’t everyone just use those?

Many of you will probably be wondering why the currently available Turbo family are not enough. The current Turbos are several years old and have not kept up with language, compiler and IDE developments made available in the “full” versions of Delphi. Now a more stable IDE and shiny new compiler and language features such as UTF-8 and Generics are not a big deal by themselves and certainly many developers won’t even use these features in every project. But for any prospective student who is beginning Delphi and has been doing their research they’re likely to find Articles, Community forum postings and Resources which do take advantage of these features, leaving them frustrated. In addition to this I’ll be frank:  there is an inherent satisfaction factor for any geek in using the latest technology, we’ve all experienced the desire to try out the new phone, a new gadget or the latest and greatest piece of technology. It’s an inherent part of being a geek, this is something that Microsoft understand and demonstrate with their Visual Studio Express line.

Additionally the Delphi.NET Turbo has been withdrawn because of the release of Delphi Prism and I’m hoping that this is a temporary withdrawel and a sign of a Turbo Prism in preparation. I would certainly like to see a Turbo version of Delphi Prism because, in my mind, a .NET offering has the greatest chance of drawing budding new developers away from C# and VB.NET because it allows them to interact with the Framework and concepts that they already know and to utilise the significant existing developer resources available for .NET Developers.  

The Turbo site also no longer seems to list the paid-for version of the Turbos which allowed you to install 3rd Party Components. The VCL and range of 3rd Party VCL components available is what sets Delphi apart as a language, how would you expect to sell someone the benefits of developing in Delphi whilst limiting the product to no 3rd party components? 

What exactly would you like to see then?

I would ideally like to see the following from Codegear:

  • Newer versions of the entire Turbo line - incorporating the fantastic IDE, compiler and language improvements released with RAD Studio 2009. Microsoft keep their Express editions rigidly up to date with the main Visual Studio lines.  
  • A Turbo version of Delphi Prism – A .NET offering with the power, flexibility and pace of new releases that Delphi Prism has would be a very appealing tool to try to lure existing C# and VB.NET developers into the Delphi community. 
  • A Getting Started documentation bundle - intended to get new users, students and hobbyists up and running on a couple of fun sample projects immediately, this could possibly be best served through Community authorship. See below. Heck – I’d even be prepared to put together a first pass of this myself! 
  • Allow the installation of 3rd Party VCL components – Consider what reasons you give when stating the advantages of using Delphi, limiting 3rd Party VCL components limits the appeal of the tool.
  • Allow the installation of more than one Turbo Product – In my mind it certainly makes sense to at least allow the installation of Delphi.NET (/Prism?) and Delphi for Win 32 on the same machine.
  • If it is necessary to cover costs: A low cost version of Delphi that would allow the ability to install more than Turbo product at a time and the ability to install 3rd Party components priced around the £50-£90 mark..

The Turbo Versions of Delphi were a very popular move by Codegear and I’m disappointed that they have let them fall behind but their intentions were in the correct place. I always felt that they could have made more of them if they had bundled more documentation with them. In my opinion they should include a “Getting Started” pack with a basic introduction to the language and a few fun tutorial projects to get started. This could even be a converted version of some pages from the Delphi Wiki, this way Codegear wouldn’t even have to author anything themselves. For the paid for version of the Turbos they could also look at rolling the cost of a PDF only version of one of the many excellent Delphi books currently available.

I would also happily see the license changed to non-commercial, educational and open source only development with the Turbo line if it meant that we could get a more powerful, more up to date version of Delphi for free or cheaply. 

Codegear is a Development Tools Business, they can’t give away Developer tools.

I know. The Codegear VPs and senior managers will probably have a long term strategic objective of increasing the viabilty of their tools as a development tool and as a development environment as a way of increasing demand for their product. I submit that this is simply another method of trying to acheive that aim. I don’t know how much the Turbos Line would cost to maintain but this could easily be offset as a form of marketing cost (which it would be), the returns of which could easily be tracked in the same way as other campaigns (# Google Mentions, # Newsgroup posts, New users, University teaching uptake).

 

Thank-you for taking the time to read this and consider the fate of the Turbo Family. I would love to hear support, comments or even criticism from anyone who has an opinion on this.

Posted in Delphi, Development, codegear | Tagged , , , | 17 Comments