Home
Archives
About us...
Advertising
Contacts
Site Map
 

ruby in steel

 

Chrome 1.5
Eur 199, Eur 149 Competitive upgrade (from Delphi), Eur 49 student licence
http://www.chromesville.com/
review
 

Chrome 1.5 - Pascal reborn

RemObjects' Chrome is an innovative implementation of Object Pascal for Microsoft's Visual Studio .NET. Huw Collingbourne wonders if this could this really be the rebirth of the Pascal language?

See also: The Bitwise interview with Chrome chief architect, marc hoffman.

These days, C-like languages seem to have swept through the developer world like the Mongol Hordes, crushing all other languages that should dare to cross their path. From the baroquely complex C++ to the simplified syntax of Java and its .NET cousin, J#, curly braces and plus-plus operators have become almost inescapable. When Microsoft created a new language, C#, specifically for the .NET platform, it really looked as though other syntaxes might as well admit defeat. Not even that old warhorse, Visual Basic, was entirely welcome in the brave new world of .NET. So what hope for Pascal…?

Chrome 1.5 integrates with Visual Studio 2003 or 2005 (some features are only available in VS 2005) and supports application development using .NET 1.1, .NET 2.0, the .NET Compact framework and Mono.
The Chrome IDE

There is nothing surprising about the Chrome development environment. Hosted by Visual Studio, it has all the form design and coding features that you would expect

You have access to the Visual Studio debugger so that you can easily set breakpoints, watch variables and step through Chrome code

In the editor, you can complete code statements (here in a sample project illustrating Chrome’s Generics) by selecting items from drop-down lists

In modern times, one company alone has really championed Pascal. In spite of flirtations with languages ranging from Prolog to C++ (and a long term relationship with Java), Borland is, perhaps, pre-eminently The Pascal Company. In the early days Borland built its reputation on its Turbo Pascal compiler for MS DOS. Over the last decade or so, its fine Delphi product has put an object orientated version of Pascal at the core of a suite of visual design and coding tools for Windows.

With the advent of .NET, many vendors chose to integrate their languages into Microsoft’s Visual Studio. Borland, however, decided to host Delphi within its own multi-language programming product called The Borland Developer Studio (see the Bitwise Review). This meant that Visual Studio users were left without a full, professional Pascal implementation. That is, until RemObjects launched a Chrome – a version of the Object Pascal language for Visual Studio. Launched for Visual Studio 2003 last year, Chrome is now on version 1.5 which also supports Visual Studio 2005. In this review, I’ve been trying to find out what sets Chrome apart from other .NET languages.

Life After Delphi?

As you might expect, a long-time Delphi programmer (like me) will quickly feel at home when coding in Chrome. To take a simple example, let’s suppose you create a new Windows application that displays ‘Hello world’ in textBox1 when button1 is clicked. You begin the process by selecting the Chrome Windows Application template. This loads up a blank form into the Visual Studio workspace. Onto this you drop a button and a Textbox and double-click the button to go into the editor and add some code.

Your cursor is now placed inside this event-handling method:

method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
begin
end;

Now, between the begin and end keywords, you insert this simple Object Pascal assignment:

textBox1.Text := 'Hello world';

And that’s it. A ‘Hello world’ program in one line of code. If you glance at the code which Chrome has automatically created for this project, you will see much in common with Delphi. There’s the interface section for declarations at the top of the unit and the implementation section for executable code beneath it. The form definition block is similar to Delphi’s with its type declaration and private, protected and public methods.

Chrome is far from being a slavish Delphi ‘clone’ however. Already one difference is obvious. The button1_Click() method is declared using the keyword method rather than the keyword procedure as in Delphi. In Chrome, a procedure or a function can be declared as a method though the keywords procedure and function are also available as alternatives. In the above code, for example, if you replace the method keyword with the procedure keyword the code will still compile.

It Takes Two…

When installed into Visual Studio 2005, Chrome supports a number of features specific to version 2 of the .NET Framework such as generics to allow you to code type-safe list processing routines which can be used with lists of varying data types. This lets you write (say) one sorting or reversing routine for use with lists of strings, integers or user-defined objects. Without generics you would either have to write multiple routines or do a great deal of type checking and casting. A generic routine is initialised to a specific object type when it is used to ensure reliable type checking. You can create your own for each loops to enumerate through generic lists.

There are also nullable types which allow you to assign a nil value to types for which nil has hitherto not been available. So you can, for example, set an integer or a Boolean to nil (indicating that it is unknown or undefined) rather than merely to something like -1 or false to indicate a precise and fixed value.

As with Microsoft’s languages for .NET 2.0, Chrome 1.5 lets you use ‘nested’ classes in which one class is restricted for use ‘inside’ another class. Chrome also provides this feature for .NET 1.1, if you happen to be using VS 2003. Let’s see how this works. Let’s suppose you have a Room class and a Treasure class. This is how you might define your Room:

Room = public class
   private
     t : Treasure;
     _name : string;
   public
     property name: string read _name write _name;
     property treasurename: string read t.name write t.name;
     constructor( aName, aTreasureName : String );
end;

Rooms can exist anywhere but Treasure objects can only exist in Rooms. You don’t want them to be accessible by Troll and Dragon classes, for instance. To make this so, you declare the Treasure class to be nested in the Room class like this:

Treasure nested in Room  = public class
   private
     _name : string;
   public
     property name: string read _name write _name;
     constructor( aName : String );
end;

Now, if you try to create  Treasure object outside of a Room, the compiler will complain that Treasure is an unknown type. Inside a Room object, however, Treasure is a valid type; if you need to access the class from outside a Room you can use dot notation like this:

var
  aTreasure : Room.Treasure;

Another new feature in Chrome 1.5 is ‘variable type inference’. This means that it is possible, in some circumstances, to omit type declarations of variables. By tradition Pascal, being a strongly typed language, requires variable names and types to be specified in a var block before used in code, like this:

var
  x : Integer;
begin
  x := 2;
  textBox1.Text := x.ToString();
end;

Chrome lets you use this shortcut type-free variable definition:

begin
  var x := 2;
  textBox1.Text := x.ToString();
end;

I must say that I can’t honestly see much point in this. I have always thought that distinct, unambiguously typed variable declaration blocks were a strength rather than a weakness of Pascal. However, other people will doubtless disagree with me.

You can also declare inline variables within for loops as here:

for i: integer := 1 to 10 do
    x := x + 1;

There are too many syntactical differences from standard Pascal or Delphi to enumerate fully here. A few things which have struck me include case statements in which the selector can be a string; case type of in which a selection is made by matching the specific type of a variable rather than its value; and with statements in which inline variables are used and objects may be created, like this:

with r: Room := new Room() do begin
     r.name := 'Bright cave';
     r.treasurename := 'Torch (on)';
end;

Other notable language features of Chrome include full namespace support – the scope of a single namespace may extend across several code ‘units’; asynchronous methods for multi-threading; partial classes allowing a single class definition to span multiple files; and operating overloading A full list of Chrome’s principal language features can be found here: http://www.chromesville.com/language/.

The Compact Framework?

On the Chrome web site, you will read that Chrome can be used to write “fully managed native .NET applications for the Microsoft .NET Framework, the Compact Framework or the Mono and Portable.NET platforms”.

Well yes, it can. Up to a point. I should say that I have only been using Chrome for the .NET platform so I have to take on trust that it works well with Mono and Portable .NET. However, I remain unpersuaded that Chrome would be my language of choice for Compact Framework development. I was expecting to be able to start a Chrome ‘Smart Device’ Wizard, as I can with C# and Visual Basic; in those languages, this gives me access to a full suite of visual design and debugging tools including a set of on-screen ‘emulators’ for testing applications on my PC prior to downloading them into a hand-held device. Chrome has no such wizards. Instead, you are supposed to develop applications in Visual Studio and link against Compact Framework assemblies subsequently, in the same way that you might link to Mono or Portable .NET. While the Chrome web site optimistically describes this procedure as “almost too easy”, the Chrome help system does (if you search hard) admit to significant deficiencies in its support for CF design and deployment:

“At this time, Chrome does not support automatic deployment to CF. You will need to copy file(s) across using ActiveSync and run the applications manually on the device. There is no current support for the Form Designer or Debugger - these are under investigation for a future release.”

In short, while you can design CF applications with Chrome, I cannot imagine why anyone should choose to do so given the hugely superior tools provided by C# and VB.NET.

Contractual Obligations

The Chrome language also includes a rather unusual feature called ‘Class Contracts’. This is similar to the ‘Design By Contract’ features of the Eiffel language; RemObjects claims that Chrome is the first mainstream .NET language to provide native support for this.

Class Contracts aim to provide a mechanism for enforcing requirements upon a class and its methods rather than merely stating those requirements in the specification or comments. This is how RemObjects describes the problem:

“In classical programming, even for today's object oriented programming, such requirements are usually specified in documentation somewhere (if documentation is written at all), or might even just exist in the mind of the developer. Sooner or later, the code will outgrow the specification and requirements will be broken.”

To avoid the possibility that documented requirements may be ignored, the requirement itself is entered into the code itself like this:

method MainForm.test_contract(aValue : Integer) : Integer;
require
  aValue >=0;
begin
  // Here some code does clever maths which will
  // produce erroneous results with minus values

end;

In the above example, while it is possible to send a minus value as the aValue argument, the code that follows will, in such a case, produce an invalid result. The require statement tests the value and, if it is less than zero, an error condition (which is called an ‘assertion’ but, to all intents and purposes, resembles an exception) is raised. You can also add an ensure condition at the end of a method to test the value of some variable when the method exits, like this:

method MainForm.test_contract(aValue : Integer) : Integer;
begin
  // some clever maths here
ensure
  aValue > 0;
end;

Class contracts also let you define required values (invariants) for properties. Don’t get the idea, however, that class contracts somehow ‘fix’ potential errors. They don’t. The require and ensure parts are debugging aids. When their requirements are not met, an error occurs and it is up to the programmer to fix it.

Let’s look at another example. Suppose our Room object has multiple constructors, each of which take varying numbers of arguments to initialise internal data. One constructor initialises only the Room itself but not the Treasure object, a_treasure, which it contains. It is quite possible that a certain Room will not contain an initialised Treasure object. So what happens if such a Room is passed to this method?

method MainForm.ShowRoom( aRoom : Room );
begin
   Messagebox.Show('Room: ' + aRoom.name + ' contains: ' +
                    aRoom.treasurename);
end;

In fact, this is what happens:

Error message

You get a pretty uninformative error message and you now have to squirrel away through your code in order to try to track down the source of the problem. Now let’s try this again with this rewritten method:

method MainForm.ShowRoom( aRoom : Room );
require
   aRoom.a_treasure <> nil;
begin
   Messagebox.Show('Room: ' + aRoom.name + ' contains: ' +
                    aRoom.treasurename);
end;

This time, this is what happens;

OK, so it’s still an error message. But at least it’s an informative one. The screenshot above is too small to read all the text - and the error message box is too big to fit comfortably onto this web page, so here’s a close-up of just a part of the text:

As you can see this gives you some useful information – not least of which being the method name and the precondition which failed. My feeling is that, while class contracts are a handy way to document and debug your code, they are no more than that. Careful programmers would, in any case, test values before executing code or use exception handling for trapping unpredictable errors. That said, the more debugging the better so they are to be welcomed.

The Development Tools

Chrome’s programming environment is Visual Studio so, if you are already familiar with this, there is no much more to be said. It has the same form designer and coder with code-colouring, collapsing, IntelliSense and all the rest. Other editing features include easy navigation between a class declaration and implementation and class-completion which adds implementation code to match the class definition.


Chrome can take advantage of Visual Studio tools such as the improved form designer available in VS 2005 with its visual alignment guides to help you fine-tune the position of controls

Some editing capabilities are supplied by a free third-part tool called DXCore from Developer Express . One of the more obvious of these capabilities is synchronised renaming. When your cursor is in the name of an identifier such as a method or class type it causes the identifier to be highlighted and any change you make to its name causes the same change to be made to all other occurrences of the name in your source code. At first sight this looks like a good idea. In fact, I find it to be more of a hindrance than a help.


Here I am changing the name of the class Room. When I edit it in one place the changes instantly propagate to all other occurences of the class name.

Let’s suppose you have a class called Room and you want to change its name to MyRoom. To do this you simply edit any occurrence of the name Room and all other occurrences are kept in sync. But now let’s suppose you have a nested class, Treasure, which is inside Room. Now you edit the constructor name, Room.Treasure(). As soon as your cursor lands upon the name Room, it is automatically highlighted. Now when you add .Treasure all other occurrences of Room have .Treasure appended to them – not at all what you want to happen! Similar problems arise if you specifically want to edit just one occurrence of the identifier, Room. While you may not see it happening, all the other references to Room scattered through your code will also be altered.

To be fair, I should say that you can ‘break the link’ to prevent synchronised renaming by pressing the Enter key when an identifier is highlighted. If (like me) you often forget to that that, however, you can accidentally mess up your code big time. As far as I can work out, there is no way to disable Sync Editing without uninstalling DevExpress itself – something I plan to do soon.

While the editing features, on the whole, are comparable with those offered by other Visual Studio languages, I did notice one or two rough edges. The code alignment, for example, is a bit eccentric. When you press the Enter key after a begin keyword, the next line is indented, even if it happens to be the end keyword. The end part of a begin block has to be aligned manually. Moreover, the alignment process is a bit slow (you can see it happening on screen). This contrasts with Microsoft’s C#, which correctly and quickly auto-aligns begin and end braces and indents any enclosed code. RemObjects tells us that improvements to code alignment are planned for a future release.

Mono and Portable .NET

In addition to .NET programming, Chrome also can be used for creating Mono and Portable .NET programs. Mono is the name of an open source project aimed at providing software for developing and running .NET applications on Linux, Solaris, Mac OS X, Windows and Unix. It is sponsored by Novell. At the time of writing, Mono is at version 1.1.13. RemObjects says that “In general, applications compiled with the normal .NET framework will deploy just fine for Mono.”

Portable .NET is the name given to an open source implementation of tools and libraries compatible with the .NET CLI (Common Language Infrastructure). Developed by the DotGNU Project, it aims to operate on multiple platforms including Windows, Linux, Mac OS X and others. Portable .NET is still in development but has not yet reached a version 1.0 release. Chrome 1.5 claims “tentative support” for Portable.NET. RemObjects says “our testing under pnet has been limited, so it is not considered an officially supported platform at this time.”

To develop Mono and Portable .NET applications you can create .NET Chrome projects within Visual Studio and then link them against other CLR assemblies (e.g. Mono or Portable .NET) for deployment. This is explained in more detail on the Chrome web site.

Summary

For anyone used to Pascal, particularly Delphi, the Chrome language has the obvious attraction of familiarity. Since (unlike Delphi) it is hosted by Visual Studio, new releases are rapidly able to make use of innovations in .NET itself. This explains why Chrome 1.5 already works with .NET 2.0 whereas the current release of Delphi is still restricted to .NET 1.1. Moreover, if your company is already using Visual Studio .NET you may encounter less resistance to the idea of evaluating a fairly low cost language plug-in for Visual Studio than to the idea of investing thousands of dollars on the Borland Developer Studio.

That said, the question has to be asked: what is Chrome for? In the past, the distinctions between various language and development tools was pretty clear cut. If you wanted to do efficient, low-level programming, C or C++ was likely to be your first choice. For ‘safer’ programming with good visual design tools, Visual Basic would have been preferred. And then, of course, there were those farsighted developers who demanded the best of both worlds – real programming power plus excellent visual design tools – and that’s where Delphi came into the picture.

These days, the choices are not so clear cut. This is particularly so once you enter the world of .NET – in which the same class library, visual design tools and runtime system are shared by a multitude of languages. As a consequence, when choosing a .NET language, I suppose the first question that many people will ask may be: why should we use anything other than C#?

Microsoft created C# from the ground up specifically for .NET. Just to rub salt into Pascal programmers’ wounds, the chief architect of the language was none other than the creator of Delphi, Anders Hejlsberg. Now, while Pascal programmers may have some aesthetic objections to the syntax of C# (I myself am far from being seduced by the curly braces, case sensitivity and peculiar for loops), fundamentally it is a perfectly good language – in essence, it is the ‘standard’ .NET language; and, anyhow, if you have a full copy of Visual Studio, you already have C#.

So why would you want to use any other language? In my opinion this is a question to which even Microsoft itself has found no good answer. Its attempts to convince people of the merits of Visual Basic .NET are unconvincing. Previous versions of VB had distinct advantages over C++. The present version of VB.NET has no significant advantages over C#.

In spite of some interesting language extensions in Chrome, I can find no truly compelling reason to use Chrome in preference to C#. By ‘compelling reason’ I mean something which you could tell your boss in order to convince him or her that Chrome was a definitively better .NET language than C#.

Delphi at least can offer such a reason: its ability to span the Win32 and .NET platforms provides developers with a unique way of migrating existing applications to .NET or embarking upon simultaneous development of ‘cross platform’ (Win32 and .NET). It is, of course, possible, that Chrome’s ‘cross platform’ support for Mono and Portable .NET may have a similar appeal for some developers. For an example of a project utilising Chrome for cross-platform development, see the Chrome:Portal Content Management System site. It is too early to predict how well Chrome will succeed for this kind of development.

Delphi developers who have moved to .NET may be tempted by Chrome mainly due to the close similarity of its Object Pascal syntax to that of Delphi’s Object Pascal. Moreover, if you are already using Visual Studio, you can add in Chrome for around $240 whereas even the ‘entry level’ edition of Delphi will cost you in excess of $1,000. Don’t think that you will simply be able to import old Delphi projects, however. You may be able to cut and paste a good chunk of Delphi code but Chrome does not offer full Delphi compatibility so it’s not just a case of ‘load and run’.

For most people, the main reason for choosing Chrome, it seems to me, is likely to be personal preference. I can understand why you might favour the Pascal syntax and why you might, moreover, wish to program Pascal from within Visual Studio. This is essentially the argument given by RemObjects themselves:

“Most of those who move from Delphi to .NET choose to use Visual Studio, and within it the choice of languages is, in most cases, between C# and VB.NET. While both these languages would be acceptable choices, many developers would still prefer to use Object Pascal and not have to learn a completely new language. So why not give them Object Pascal inside Visual Studio?”

If you are in the fortunate position to act purely on your personal preferences, Chrome may be a good choice. I suspect, however, that rather few professional developers are likely to have quite so much freedom…

 

February 2006

 


Home | Archives | Contacts

Copyright © 2006 Dark Neon Ltd. :: not to be reproduced without permission