Thursday, 18 December 2008

Delphi Prism – Class Contracts

One of the new features of Delphi Prism, which you may not have heard about is native support for Class Contracts. Class Contracts are Delphi Prism’s implementation of design by contract.

The whole premise of Design by Contract is that components of a software system interact with each other on the basis of mutual obligations (a contract). Therefore a method of any class may :

  • Insist that any client calling the method must adhere to a certain pre-condition.
  • Guarantee a certain post-condition on exit.
  • or will commit to maintain a certain property (Invariants).

Pre-Conditions

A pre-condition frees the method from having to maintain any checking code as it can be certain that the pre-condition will be met. Delphi Prism implements pre-conditions using the require keyword.

method MyClass.ToString(const aIndex : Integer) : string;
require
aIndex >= 0;
begin
result := fStrings[aIndex];
end;


Pre-Conditions are evaluated before the method is executed.


Post-Conditions

A post-condition ensures that the client knows what to expect from the method after it has executed. Delphi Prism implements post-conditions using the keyword ensure.


method MyClass.ToString(const aIndex : Integer) : string;
require
aIndex >= 0;
begin
result := fStrings[aIndex];
ensure
result.Length > 0;
end;


The old scope prefix can be used in the ensure section for local variables and parameters,  and refers to the values as they were before the method executed.


method MyClass.Add(aValue : string);
require
aValue <> ‘’;
begin
fStrings.Add(aValue);
ensure
Count = old Count+1;
end;

The old construct is only supported for integers and value types of both parameters and local variables. The compiler saves the value before execution of the method.


Class Invariants

Class invariants ensure that certain properties or fields of an object comply with a fixed state. Class invariants may be either private or public. We need to be careful here, as the way these work may initially seem counter intuitive. Public invariants, are checked after every public method only. (Actually, after the ensure clause, if it exists), while private invariants, are checked after both public and private methods. Another point to make is that both public and private invariants have access to all fields of the class. The public and private scope modifiers only indicate on which methods the invariants will apply.



  TestClass = public class
private
fValue : Integer;
private invariants
fValue > 0;
public invariants
fValue > 35;
public
//public methods
end;

Since public fields can be accessed from outside the class, they cannot be used in invariants as there is no way to restrict what goes on outside of the class. Having said that, public fields are never advisable anyway, so it’s not that much of a restriction

If any of the contracts above are not upheld, an assertion is raised. Assertions are by default enabled for the debug configuration, and disabled for the release configuration.


The Future

So what could be added in future to make class contracts even more useful than they already are?


  • Pre and Post conditions for interfaces

ITest = interface
method Test(const aValue : Integer) : string; requires aValue >= 0 ensures result <> '';
end;

With this syntax, we not only specify what the implementation must look like, but we also specify how it must behave.


  • Exceptional Post-Conditions

The ability to specify what exceptions a method can/should raise.


method Test; raises System.OverflowException;

  • Frame Conditions

Frame conditions restricts what a method can modify. Sample syntax could look like

  method Test; modifies fValue; 

Conclusion

Class constructs are not one of those features that you cannot live without. You could happily go on writing code and never use them once. However, by adding class contracts to your code, you make it clearer what the class does, and how it does it. Class contracts remove some of the ambiguity and a lot of the guessing. Up until now, we have used method signatures to indicate how class users can go about using our classes. We have also had to document a lot of other information so the user knows what is expected of him/her, and what he/she can expect from the class. With class contracts, a lot of that documentation is now part of the class, and can be checked at run-time to ensure the application is doing what we intended it to do in the first place.

Saturday, 13 December 2008

Do all great programmers start young?

I was recently hearing one of the Stackoverflow podcasts, where Jeff and Joel were interviewing Steve Yegge from Google. Jeff mentioned how he started programming at the age of around 13, and how the developers he has the most affinity with are also those who started at around 13, and were largely self-taught. Steve agreed with him (being one of those who started young), and insisted that the best developers are those who start young and are self-taught. And I have to agree! Well I would, since I started at 13 too.

I remember my parents bought us a Texas Instruments TI 99/4A, when we couldn’t find any Sinclair Spectrums (I think they were called Timex in the US) in stock anywhere. It was Christmas 1981, and I was 12 going on 13. The first thing I did when we got the computer home, was to type out one of those game listings you’d find in video game magazines. I’d actually bought the magazine before the computer. After spending a few hours typing it in (my typing skills were non existent then!), I typed in run, and waited. It kind of worked, but the score at the top right hand corner of the screen was not working. Disaster! I must have typed something in wrong. So I roped in my little brother to read me line by line, while I checked for any typos. After another few hours, we finally concluded, that we had typed it in correctly. I don’t know what drove me, but I had to fix it. It was a graphical score, with each digit independent of the others. So with every increase in score, you’d increment the units column, until it were at 9, in which case, you’d set it back to 0, and increment the tens column, and so on and so forth. Seems trivial now, but it took me a few days to figure out TI-BASIC, and fix it. But boy what elation when I ran it, and it finally worked. The subsequent month’s magazine printed the bug-fix, but I had fixed it on my own. I was officially a programmer. Luckily due to a hardware quirk, while my friends played fast machine code games on their Commodore 64s and Spectrums, the TI99/4A had some drab Basic and Extended Basic games available or wildly expensive (well to a 12 year old they were)cartridges. So if you had a TI99/4A, you either learnt to program, or you made friends with the neighbours and their Commodore! I started writing games, and even advertised and sold a few tapes. (storage was on plain old audio tapes) …and so began the love affair with computers.

So when did you start programming?

Friday, 12 December 2008

WPF like effects in your Win32 forms

Are you still developing native applications? Would you like to do some cool tricks with your forms? How about making your windows fade in and out?

The Win32 API to the rescue! The function AnimateWindow can be used to blend in and out the form. To the FormShow event handler, add the following code :

AnimateWindow(Self.Handle, 1000, AW_ACTIVATE or AW_BLEND);

To reverse the effect, add the following code to the FormClose event :

AnimateWindow(Self.Handle, 1000, AW_HIDE or AW_BLEND);


You can also get the form to slide in, rather than blend, by changing the flags to AW_SLIDE or AW_HOR_POSITIVE to get the slide to come in from the left for example.



The same approach can be used in Delphi Prism, when using WinForms. While Delphi Win32 imports the AnimateWindow method for you, in windows.pas, in Delphi Prism you have to do it yourself using P/Invoke. (As you would with C# or VB.NET may I add). So in your WinForm, add the following code to the private declaration :



private
const AW_HIDE = $10000;
const AW_ACTIVATE = $20000;
const AW_HOR_POSITIVE = $1;
const AW_HOR_NEGATIVE = $2;
const AW_SLIDE = $40000;
const AW_BLEND = $80000;
[DllImport("user32.dll", CharSet := CharSet.Auto)]
class method AnimateWindow(hwand : IntPtr; dwTime : Integer; dwFlags : Integer) : Integer;external;


Remember to add System.Runtime.InteropServices to the uses clause of your form. Now, you can add the same code as before (it's all object pascal, so the same syntax), to the Load and FormClosing events of your form.



  method MainForm.MainForm_Load(sender: System.Object; e: System.EventArgs);
begin
AnimateWindow(Self.Handle, 1000, AW_ACTIVATE or AW_BLEND);
end;

method MainForm.MainForm_FormClosing(sender: System.Object; e: System.Windows.Forms.FormClosingEventArgs);
begin
AnimateWindow(Self.Handle, 1000, AW_HIDE or AW_BLEND);
end;

So there you have it, forms that fade in and out.

Tuesday, 9 December 2008

Virtual Conferences

A few weeks back, I attended quite a few sessions of Emarcadero/Codegear’s Coderage III virtual conference. I’ve been to a few live conferences before, and have always found them very useful. This was my first virtual conference, and I must say I found it was almost as good as the real thing. There were a few audio issues, but nothing too distracting. As with all conferences, be they live or virtual, some of the sessions were great, others not so great, but I suppose that depends on what interests you. On the whole the sessions I attended were well presented, and hit the mark. I’m going to make a few observations though, so that perhaps Coderage IV might be even better.

  • Time Zones. There were a lot of sessions I’d have liked to attend, but at 4 in the morning, I also like to sleep. Now I know however you play this, there’s always going to be someone who’ll complain that 4 in the morning is time they should be in bed, but since the sessions were recorded, why not repeat them twice, even three times so that anyone in any time zone can find a decent timeslot? I know that you can get the replays after the event, but not the same thing..
  • I felt the sessions were slightly too short. Or perhaps the subjects that were covered were just too vast for the time allotted. I’m sure there’ll be someone who says the sessions were too long though.
  • Attendance was a little disappointing. Does that reflect a decline in the popularity of Delphi, or just the fact that a lot of people don;t like virtual conferences? Has anyone ever attended other virtual conferences? If so, how was the attendance there?

Another thing I noticed during this conference. From a technical point of view, being a trainer is much easier than being a day to day developer. I’m not saying the presenters at Coderage did not know their stuff. I’m sure that they do. It’s just that when giving a session of 45 minutes, you are forced to basically present glorified Hello World applications. You just scratch the surface.

I’m just trying to say that the technical side of things, while important (you can’t do a 45 minute session about something you know nothing about), is only a small part of what you need, to be a successful presenter. In my opinion, one of the best presenters I’ve ever had the pleasure of listening to, was Lino Tadros. His sessions, while having the requisite technical knowledge, had that X factor, that made them interesting, whatever the subject covered. The sign of a good teacher.

Does he still do Delphi, or has he completely gone over to the dark side? If so, he’s sorely missed!