Wednesday, 14 October 2015

CFML: operator overloading

A while back I posted my "What I'd like to see in ColdFusion 12 (redux, as is happens)" article, and I provided links to most of the tickets I raised for features to facilitate discussion and input from you lot.

One feature I mentioned in passing but forgot to add the link to was operator overloading. I did actually create the ticket, but I forgot to link to it. The ticket is 4013841.

Now I know a full-fledged operator overloading system would be quite an undertaking, and there's also been some industry push-back on the validity of having too comprehensive a system as it would compromise code clarity. EG: we know what 2 * 3 means, but what does Apple * Banana mean? Even if the object types of the operands could meaningfully be multiplied, it doesn't make for clear code.

However this does not mean there aren't really good situations in which this sort of control might be useful.

Here's some examples I provided with the ticket:

// Person.cfc
component {
    property dateOfBirth;

    function compare(p1, p2){

Would allow:

adam = new Person(createDate(1970,2,17));
zachary = new Person(createDate(2011,3,24));
if (adam > zachary){
    writeOutput("Yay! Dad finally wins at something. Being old. Grumble.");

Or another example is best demonstrated by PHP's ArrayAccess interface, which allows the definition of a few methods (offsetExists(), offsetSet(), offsetGet(), offsetUnset()) which then allows one to treat an object like an array, by overloading the behaviour of the [] syntax (not a true operator in this case). C# also allows for this sort of thing too (then again, C# allows for almost full operator overloading, as far as I recollect).

Or not even really operator overloading, but just extending built-in CFML processing by permitting a class to implement a toString() method which is then used whenever an object reference is used where a String is expected, eg:

// Person.cfc
component {
    property dateOfBirth

    function toString(){
        return dateOfBirth.dateFormat("yyyy-mm-dd");

writeOutput(zachary); // 2011-03-24

This is all useful, clear stuff. However Adobe have just fed-back with a fairly unthinking response:

Operatore overloading is known to have its own issues because of which it is not supported in many languages.

This is pretty much the boilerplate response when a naesayer encounters a discussion about operator overloading. It kinda suggests to me that not a great deal of thought went into the reaction, but rather "he said operator overloading: use that stock response".

I did go on to point this out:

Well: out of the top ten programming languages (

  • Java - no
  • C - no
  • C++ - yes
  • Python - yes
  • C# - yes
  • R - could not determine
  • PHP - limited
  • JavaScript - very limited
  • Ruby - yes
  • Matlab - yes

So more than 50% offer at least some operator overloading.

Another situation relevant language that supports this is Groovy (which is like what CFML could have become had it been stewarded properly).

[After some more investigation of languages that popped into my mind...] Rust does; Go doesn't. Swift does. Scala does. Erlang doesn't seem to (but could not find a definitive source), F# does. Clojure seems to allow it. Haskell seems to. Even blimin' Perl does!

[note: those are all the languages I checked. I did not cherry-pick which ones to check to fortify my position]

I think your observation is based on the position that Java took when it decided not to do operator overloading, which is rather out of date now. Things have moved on.

There are caveats to be considered when providing for operator overloading, but I don't think you are correct in writing them off as "known issues", and I think the knowledge you are basing this on is perhaps out of date, or just mired in "how Java decided to do things". CFML is a more dynamic and forward-thinking language than Java, so you should not let your Java background hold us back.
I think Adobe needs to spend some time thinking about what they can do to make the CFML language better - especially as they've spent so much time holding it back whilst other languages have passed it by. Using a stock answer of "operator overloading bad" it a bit leaden, IMO.

But maybe I should not have used the term "operator overloading" as this was only a part of what I was thinking of at the time. And, TBH, I kinda knew it would be a risky suggestion and likely to be dismissed in exactly the way it was.

What do you think? Ought I have taken a more piecemeal approach and suggested individual pieces of functionality which draw from this concept? I thought of that, but was slightly wary that the whole concept needs some thought, rather than just blting bits and pieces on. Dilemma.