Tuesday 14 July 2015

CFML: should "Parameter validation error for the [functionanme] function" be a compile time error?

I encountered this whilst trying to guess how a CFML function worked. When one passes the incorrect number of arguments to a built-in function, one gets a compile error, not a runtime exception. I'm wondering if this should be the case?

Here's a pared-back repro:

// bif.cfm
try {
    result = val("42", "bogus arg");
writeOutput("The result is: [#result#]");
} catch (any e){
    writeOutput("#e.type#: #e.message#");

When I run this I get a compile error:

If - on the other hand - I call a UDF with too many arguments:

// udf.cfm
function value(string){
    return val(string);
try {
    result = value("42", "bogus arg");
writeOutput("The result is: [#result#]");
} catch (any e){
    writeOutput("#e.type#: #e.message#");

Then ColdFusion simply ignores the extra arguments and gets on with it:

The result is: [42]

There's two considerations here:

  1. I can't error-trap the invalid call to the built-in function. This is, admittedly, a fairly "niche" situation to be in, but I was writing a unit test for said function (and I have no documentation for it to hand, so was guessing as to the syntax), and I'd really rather compilation didn't simply break if it gets the wrong args.
  2. What does it matter if I pass it too many args? As long as I pass the correct types for the ones it's expecting, who cares about any other cruft? It'd actually be nice to be able to pass a struct or array as an argument collection here, and it just grabs the ones it's interested in and leaves the rest alone.

I guess it's nice to do stuff once at compile time, rather than every time the code is executed, but it does reduce flexibility. It also represents an inconsistency in the language in that I can pass extraneous arguments to my own code, but I cannot pass them to CFML's own functions.

Lucee, btw, behaves the same way.

Now I'm not suggesting this is a bug - I see why it's been done this way - but shouldn't the language behave uniformly? I'm not sure.

I wonder what the overhead of changing the argument-check to be at run-time instead of compile time? I do think in a dynamic language, as much as practical should be pushed to runtime, to add this sort of flexibility. Maybe.

TBH I'm not advocating any change here, I just found myself wondering about this, and can't form a strong opinion on it. So figured I'd ask you lot.