My post yesterday on dynamic methods invocation in Delphi has raised a few doubts about the rationale behind sch an "unnatural" way of writing Delphi code. I should have posted the rationale behind dynamic method invocation before starting showing code... but at least I'm doing it before delving into the actual tech details, a post I originally wanted to do today, but I'm delaying.

So do you want to invoke a method that doesn't exists at compile-time? There isn't a single answer, but I have used similar coding in real projects and have seen trends (mostly in other languages) going in this direction. So here is a short list of reasons:

  • It is trendy. I know, this is not a technical reason. But with people who keep complaining Delphi is always behind every other language, I think it is worth pointing out Delphi has features that other popular languages (Java, C#) are thinking of adding now. And why are they adding this features? Mostly because they are trendy, and they have become trendy because Ruby on Rails is heavily based on them. Again, does it make any sense for Delphi to clone Ruby features? Certainly not, but claiming "hey we can do it as well" is certainly legitimate.
  • Dynamic invocation is a common features of dynamic languages, from Ruby to JavaScript, which are not compiled in a strict sense. As Delphi developers you probably share with me some aversion for slow, late-bound, non compile-checked language features. I won't certainly use them as a standard coding practice. However there are situations in which we end up doing the same, in an even worse way. have you even accessed a property by name with RTTI? Have you ever passed a database field name (the string, I mean) as parameter? Every time you use a string to "parameterize" the meaning of a function call you are delaying the resolution of a symbol at runtime. With dynamic invocation you are doing exactly the same, only you are using the language base syntax rather than a convoluted string based one. How comes is setting a dynamic property with a variant is much worse than calling SetPropValue? The former can be more readable.
  • Although I'm a string supporter of strongly typing and related features, I appreciate a lot when flexibility is build into a program in a way I don't have to recompile it when I could only reconfigure it. From DFM files to configuration files, to applications that change depending on database metadata, there are many cases in which you want flexibility into your programs.
  • I've used this technique while toying with Domain Specific Languages. An internal DSL is like a sub-language hosted by your language and written according to its syntax, but meant almost for non programmers, easy to read and understand, not too bound to the language syntax. This is the situation in which calling date.am7 could be better that data.at (7, 'am'), the former is easier to write and read, especially for a non-programmer. You might not like the entire DSL movement, but I find it quite interesting.
  • Coding against partially undefined (at compile time) or flexible data structures is quite neat. Won't it be nice to say table1.usename when the latter is a field of the table rather than writing table1.fieldbyname('username')? Sure, Delphi can generate the field definitions for you with the fields editor, but when you hit a table with a slightly different structure you are stuck. I ended using a similar solution to the one outlined here for XML DOM navigation. In my code (well, I wrote it with others) you could write data.user.name to get the name node under the user node of the document. Of course, the document needed to have those specific nodes or you'd have a runtime error. But the XML document could have different formats provided those nodes where present, something you don't get if you import the data structure at compile time and let Delphi define interfaces for you.

I might not have convinced you, I know, but here are some reasons I find interesting for using dynamic method invocation when it is needed. I will never give up strong type-checking as a general compiler rule, but I appreciate exceptions. The trouble, though, is that writing this code in Delphi is much more difficult than I'd like... but that something for another post (which might take a few day, due to Easter holidays. For now, if you have other reasons for using (or not using) dynamic methods invocation feel free to comment here (or in yuor blog, posting a link here, as you prefer).

To summarize, Delphi is more powerful and flexible than most of its user think. Let's use that power when needed...