Coldfusion has a long history and you can see that in the syntax.
Cfoutput query is a perfect example, the first version of coldfusion was
only about reading data from a datasource, so it had only a couple of tags,
including cfquery and cfoutput*.
At that time the syntax has made sense, but then cfloop was indroduced, at
that time they should define that cfoutput no longer makes loop, only
cfloop should, but they didn’t for backward compatibility…
That cfoutput does makes loop makes no sense at all, we have cfloop for
that and what is even worse, cfloop and cfoutput works not exact the same
way (see group attrs).
So cfoutput like it works today only makes sense if you know the history.
An other example is that arrays in acf are “passed by value”, that is
absolutely useless, the reason for this is*, in the beginning arrays was
stored as string list (see all the list functions cf still has) and strings
are handled by value. Even the technology behind it has completely changed,
it still simulates that old behavior, only to be backward compatible. That
is maybe also the reason arrays are starting with index 1.
This are 2 examples of many for stupidity to be backward compatible, but
ther are also samples where cf acts strange for no reason.
CFM based custom tags are a good example for this, with CFM based custom
tags allaire indroduced the possibility to have a local scope. So the
variables scope inside a custom tag is local and to access the callers
variables scope you call “caller.whatever”, so the variables scope acts
like a stack. Then with cf5 macromedia indroduced script functions and at
least I was expecting that they use of course the same concept for
functions, but sadly this was not the case, they indroduced “var” and a
complete different concept to handle local scopes, a hidden scope you can’t
touch directly and you can only set new variables before any working code
and of course no stack of parent scopes. But of course Adobe then decided
to make it even more complicated and add the “local” scope, my personal
hell, I have written testcases for this scope and believe me that scope is
completely strange. They did backward compatibility with that scope that
the scope ended with no logic at all. Things like this:
var local=structNew();
local.whatever=1;
This does not produce the key local in the local scope, no this line is
simply IGNORED!
Problem here is nobody was ever thinking about the bigger picture, there
was no language design behind all this decision for sure, to be honest I
think that the guys added script functions at macromedia was not even aware
of the scope concept in custom tags.
When paramount does a new Star Trek movie they always have fans involved in
the making, because they see logial failures in the story paramount people
do not, macromedia and Adobe clearly didn’t that. That is why community
involvement is very important in cases like this.
So what should a .lucee
do better in all this cases:
- ditch cfoutput-query, it is useless
- lucee is already passing arrays by ref, so no need to change here
- ditch cfm based custom tags, we have support for component based custom
tags
- ditch “var” ( I know people love var, I do it as well, but it makes now
sense, the “local” scope is the one following the logic of the language)
- ditch all the bullshit the local scope does for backward compatibility.
- if we already on this topic, ditch the argument scope, we only need one
local scope for functions.
- ditch the variables scope in components and make the this scope private
by default.
- ditch application.cfm of course.
- ditch dot notation upper case
- scope cascading to strict
- … And lot more
What we should keep
I know may say ditch query objects and tags in general, but I disagree on
this, they are still handy in some situations.
Micha
P.s. All this popped into my mind while writing, so please don’t see that
this is curved into to stone…
pss. forgive me when this is not a 100% accurate, this is not first hand, I
never used cf1.