Sunday, July 6, 2008

Some observations on Delphi and CodeGear RAD

To whatever random Delphi people that might read this blog and think that my criticisms stem from me not using CodeGear RAD for any length of time, please understand that the project I'm working on is relatively complex. I'm converting 30 or so forms from VB to Delphi, doing bug fixes all along the way. I use it all, xml, datasets, all kinds of widgets, straight file manipulation, everything. If there's anything at all that I can discover about Delphi or CodeGear RAD to help me work on this project, I use it. It especially frustrates me when I KNOW there's a way to do something in .NET, but there's no counterpart in the Delphi API's. I usually end up having to manually code more in Delphi than I did in C#/.NET.
  • Delphi has no foreach control statement.
  • Delphi arrays are primitive datatypes (like C, or you can call it a pointer with offsets, just like C, whatever floats your boat). So if you want to search an array, you have to write the code to do it yourself. There's no array object types, so there's no myArray.Find(value). I imagine there's redundant array searching code in pretty much every Delphi app out there (unless you rolled your own API into a .dll and bring it with you to different projects).
  • If I pass a dynamic array into a function, Delphi assumes that it is a static array when in the function.
  • Why doesn't ShowMessage automatically convert numerics to strings with an overloaded "+" operator? Oh it can, you say.... if I overload "+" myself... great.
  • CodeGear RAD does not understand nested block comments. It takes the first end block comment, and applies that to the first start block comment. Nested block comments should function like nested parenthesis.
  • Delphi has no automatic set/get declarations for accessing data inside a class. Not a big deal, but I thought it was nifty when C# added special syntax just for this.

15 comments:

  1. "bring your api to a dll".. hehe
    Comparing Delphi (or object pascal) language with C# is silly. Delphi language born many years before C#. Read the newspapers please! :P

    You are so much VB guy. Thats the reason you dont get comfortable with Delphi and dont get how to work with VCL.

    BTW, why you do the switch? Why dont stay with VB? If you dont have the energy or the time or the motivation to know deep something before using, why start using knowing nothing about it?

    Have no sense. get a few books of marco cantu, read this, and then, just then start working with delphi.

    Is not as supposedto be? If buy and read 5 books of .NET, because i plan to switch some day. I suggest you read more.

    Best regards.

    ReplyDelete
  2. ForEach is called "For x IN somearray/list/etc." in Delphi. Check the help.

    CodeGear has had it as a design goal that your Delphi code should be able to compile in both Win32 and .NET.
    This puts some limitations on what can be done with basic stuff like arrays etc.
    Some like that feature, others do not. But sometimes you can't have the cake and eat it too.

    As to your dynamic/static issue I think that depends on how you pass the array.

    I think that you will find that most Delphi users are quite happy you cannot overload operators such as + and that basic types are not automatically converted to other types. Thats one of the main reasons I use Delphi myself. ShowMessage(IntToStr(SomeVar1 + SomeVar2)) leaves no room for misreading when the next guy has to change the code.

    I agree with the nested comments but have learned to live with it.

    If we are lucky we will get the same smart set/get stuff for properties in the next version. If not there is always:
    property x: integer read Fx write Fx;
    followed by Ctrl-Alt-C to get the variable.

    Happy coding :-)

    ReplyDelete
  3. Lars:
    Ahhhhh, thanks for the tip on the for loop =).

    As far as my problems with arrays, I was thinking it might have to do with pass by value as opposed to pass by reference, but I didn't have time to to research the difference between the two in Delphi.

    I see your point on not overloading operators, and upon further thought, I agree with you in principle. I just got spoiled by other languages that automatically overloaded + for string concatenation.

    As far as the get/set routines, I write them on my own for each of the properties in my classes. I'll look more into "property x: integer read Fx write Fx;".

    In any case, thanks for reading, and thanks for commenting!

    ReplyDelete
  4. Donald Shimoda: I'm trying to cut you some slack, cause it sounds like english isn't your first language. If you read my posts more carefully, it is very clear that my favorite language is C#.

    ReplyDelete
  5. Lars:

    I've been doing some reading, and I've found some conflicting info that suggests Delphi in fact does allow operator overloading.

    http://www.aspfree.com/c/a/.NET/The-Delphi-Language-Part-2/10/

    But I still agree that it is a bad idea in general.

    ReplyDelete
  6. Upon further thought, Delphi allowing operator overloading was probably put in so that the language could be compatible with .NET (same reason why Delphi now has nested types).

    ReplyDelete
  7. If I remember correctly, operator overloading was introduced together with COM variant support - way before .NET.

    ReplyDelete
  8. I still think you should learn a bit more before blogging...
    - for in
    - TList.IndexOf
    - operator overloading for records (and class helpers, that C# still lacks), since D2006 in Win32
    - properties are so much better
    - nested comments with different styles (yes, this could be improved) // { /*

    ReplyDelete
  9. Marco: I respect your opinion, and I am grateful for those of you who take the time to write to me and try to educate me. Usually how I come up with my posts, is as I code, I take notes. To post entries here, I compile my notes for the day. It just seems that my notes for CodeGear RAD tend to be more negative.

    I don't have the time to sit for weeks on end to learn the special ins and outs of a language and/or IDE. So far this year, I've worked with C#, Java, Delphi, Mumps, Bash scripting, Cobol, Windows, Linux, Eclipse, Vim, Visual Studio, CodeGear RAD, XML, RDBMS, and non-relational databases. For the most part I can do it all rather seamlessly. I get annoyed with CodeGear RAD because I expect more from CodeGear RAD. It's so close to Visual Studio that I get annoyed when things don't function as well as VS.

    ReplyDelete
  10. Branden,

    Yes english is not my first language. And?

    Your comments:

    "I don't have the time to sit for weeks on end to learn the special ins and outs of a language and/or IDE. So far this year, I've worked with C#, Java, Delphi, Mumps, Bash scripting, Cobol, Windows, Linux, Eclipse, Vim, Visual Studio,"

    Thats the reason because you are not good enough in nothing. You will never exploit Delphi if you dont take the needed time to learn it. Period. Same happens to everyhting. You cannot manage all the stuff you mentioned. For that reason you are not a expert in nothing, and cannot accmplish even the simplest task you try to do with VCl and Delphi.

    So, stop blaming something you dont know, either at a 2% level. Is silly, ignorant and pedantic.

    Read and learm then talk about something. Simple rules for your life.

    Best regards.

    ReplyDelete
  11. Donald:

    The way of the future is knowing how to apply any kind of technology to a given field. My speciality is the medical field. I don't care what the programming language is, I can write code in all of them. My interests lie in how enterprise applications can improve patient care. I will use whatever programming language or tool is the best to solve the problem at hand.

    And as far as english not being your first language, when I said "I'm trying to cut you some slack", I meant that I was trying to be NICE to you because I understand that english isn't your first language.

    Do you actually read my posts, or do you decide to just troll because you're bored? Are you actually able to answer any of the technical issues that I've had? So far, I haven't seen any good content from you that shows you know Delphi or RAD Studio either. If you are only good at one language or platform, YOU are the one that is being left behind.

    ReplyDelete
  12. "I've worked with C#, Java, Delphi, Mumps, Bash scripting, Cobol, Windows, Linux, Eclipse, Vim, Visual Studio,"

    Until you don't understand that Delphi (through TurboPascal) predates most of those languages/IDE (but COBOL) and thereby developed its own standards without being influenced too much by later languages (and being Pascal, little influenced by C either), you won't be able to use it proficiently. Don't expect it behaves like Java or C# - it was not designed so. Delphi is not a pure OO language. It has non OO datatypes (like C++...).

    1) "Foreach" is called "for ... in", a clever way to avoid to introduce a new keyword that could have made older code incompatible - they used two keywords already in use.

    2) No, there are no array object types, there are lists. There are functions to search within arrays, though. Delphi arrays are like C arrays. For..in works with array, though.

    3) Don't mistake "dynamic arrays" and "open array parameters":

    type
    TMyArray: array of Integer; // dynamic array

    procedure P(A: array of Integer); // open array parameter

    The syntax is similar, but they have different meanings. An open array parameter takes *any* array, including but not limited to dynamic arrays. If you need a dynamic array parameter, declare it and use it the the parameter definition:

    procedure P(A: TMyArray);

    the parameter is then a dynamic array and it is not static within the procedure.

    4) Implicit conversions are for BASIC developers :) Use Format() and format specifiers to build messages:

    ShowMessage(Format('Error %s at line %d', [ErrorMsg, Line]));

    Much clearer to read.

    5) Delphi does not support nested comments - but supports nested functions :-P Never feel a real need for nested comments, though. Use ctrl+/ to comment a whole block of code.

    6) Delphi can use get/set methods or can access a field directly. That's why it's up to the developer to choose what to use:

    // property access a field directly
    property Bar: string read FBar write FBar;
    // property reads from field and write through method
    property Bar: string read FBar write SetBar;
    // read and write through methods
    property Bar: string read GetBar write SetBar;

    Code completion will help you to fill the blanks...

    ReplyDelete
  13. LDS: Thanks for the tips, especially on Format. You can see though, how a beginner to Delphi would get confused on passing a "dynamic array" vs "open array parameters". If you were learning how to pass by value in Delphi, then attempted to apply the same style to pass by reference, you would end up with "open array parameters", which is not pass by reference.

    And yes, any language can use get/set methods, I usually write my own in whatever language I happen to be writing in. Thanks for the tip on properties though.

    ReplyDelete
  14. And as far as languages go, while I prefer working in C#, I'm actually best at Mumps.

    ReplyDelete
  15. I did not understand your issues with by value/by reference and arrays:

    // open array, by value (copy on stack)
    procedure P(A: array of Integer);
    // open array, by reference (no copy)
    procedure P(var A: array of Integer);

    with dynamic arrays, things are different. A dynamic array variable is an implicit pointer to a structure that defines the array (ref counter, boundaries, data), like strings - but unlike strings they do not use copy-on-write semantic - if the reference count is > 1 and the array is changed, no copy is made and the original array is changed. Thereby:

    procedure P(A: TDynIntegerArray);

    passes a copy of the implicit pointer, but A[0] := 1 will change the same array.

    procedure P(var A: TDynIntegerArray);

    will pass a reference to the original implicit pointer (useful mostly if you have to act on the implicit pointer itself and not the array contents).

    I agree that this are intricacies that can deceive a beginner, unluckily a 25 years old language can develop some (see C/C++...), especially when new features are added while trying to mantain compatibility and without using lots of new reserved words. IMHO is better than throwing languages away and creating new incompatible ones.

    One thing to blame in RAD 2007 is the lack of the "Language Guide" that was in every box until Delphi 7. It explained in a terse form everything you needed to know about the language. But because people no longer read printed manual it was removed.

    I understand if you have to code in several languages at once you may have not time for a systematic reading, but then communities around languages can help - just approach them in a different way next time, please.

    Anyway "chapeau" for admitting your own mistakes - it can be not easy. Thank you.

    ReplyDelete