Tuesday 26 November 2013

Random idea: get rid of the need to specify a variable's scope

G'day:
This idea popped into my head the other day when looking at some of my colleague's C# code, and noticing at how nicely uncluttered it is. A good part of this was the fact they don't need to deal with scopes, so they don't need to mention them. But this got me thinking... why do we need to mention them either?

Currently if I want to use an application-scoped variable (or session-, request- etc), I need to do this:

<cfset application.mainDatasource = "mainDB">

<!--- more code etc --->

<cfquery name="stuff" datasource="#application.mainDatasource#">
    <!--- etc --->
</cfquery>

It's fair enough that when creating the variable I need to specify which scope it goes in (basically its persistence/longevity strategy), but I don't think we should have to re-tell ColdFusion where the variable is every time we use it. I should be able to do this:

<cfset application mainDatasource = "mainDB">

<!--- more code etc --->

<cfquery name="stuff" datasource="#mainDatasource#">
    <!--- etc --->
</cfquery>

Or to make it more explicit (I am not suggesting this syntax, it's just to clarify how I'm decoupling the variable reference from its scope):

<cfset scope="application" name="mainDatasource" value="mainDB">

Because, really, the variable should only be a reference to the underlying value, and that reference can just as easily point to something in the application scope implementation as it could anything else. We can already do this:

<!--- outputAppVariableViaReference.cfm --->
<cfset refToAppVar = application.testVariable>
<cfoutput>#refToAppVar#</cfoutput>

In this case refToAppVar is a reference to something in the application scope... but we don't need to explicitly say so.

What we want to know about our mainDatasource variable is there in its name: that it points to the mainDatasource. We don't give a shit that its in the application scope. And on those rare occasions we do give a shit, we can just look it up, eg: mainDatasource.getScope(), or getScope(mainDatasource) or something.

Note: superficially this might look like I'm advocating an extension to the god-awful practice ColdFusion has of doing a scope-look-up on unscoped variables. This is different from that: it's not looking up a bunch of scopes, it's just the simple reference name points to memory that is "in" the application scope.

There will be the odd occasion in which one might want or need to have same-named variables in different scopes. So in that situation, one would need to specify which one one was talking about, by namespacing the variable reference, eg:

application.someVarWithAmbiguousName    = "this is the application-scoped one";
variables.someVarWithAmbiguousName        = "this is the variables-scoped one";

writeOutput("The application-scoped one is: #application.someVarWithAmbiguousName#");

As I hint at there, I think these situations will mostly arise from poor variable naming, but - still - it's something that needs to be considered.

However unqualified references should still be around, and an unqualified reference should point to the "nearest" variable of that name.

This would help declutter CFML code, I think.

What do you think?

--
Adam