I just discovered something (I think is) interesti...
# cfml-general
t
I just discovered something (I think is) interesting. the local scope contains the arguments scope in ACF (but not in Lucee). https://trycf.com/gist/6050f996d30b9dff8f7094ab79d15ff2/acf2021?theme=monokai
šŸ˜€ 1
b
That is correct.
Adobe sort of "piggy backs" the two scopes together
In Lucee, they are true proper separate scopes
z
We have been contemplating doing this for lucee
b
Which is ironic since I can remember a time when the Lucee engineers sort of mocked Adobe for not using a real scope šŸ˜‰
It turns out tho, when you really lean into function programming, you can have thousands of closure invocations on a single request, and when every single one of those closure invocations has to create and destroy two scopes, it adds up (and churns memory)
z
So should localmode write to arguments?
b
But heck, it doesn't even take closures-- just a framework with a lot of method calls too. Really any UDF calls
localMode is orthogonal to this IMO
āœ… 1
• localmode -- where unscoped variables live by default • what we're talking about -- how the CF engine implements the storage of local and arguments scopes (which have the same lifespan) behind the scenes
w
this behavior always bugged me about the local/arguments sharing in acf: https://trycf.com/gist/4bf5395cdda944cfe152d76f1d0fc49f/acf2021?theme=monokai
comment out line 11 and it works fine. lucee doesn't care and imo behaves correctly
b
I've never thought that error in ACF was a results of a technical limitation due to their design (especially since the
arguments
are basically namespaced inside the
local
struct anyway) I always just assumed they were trying to "save us from ourselves" so we wouldn't write bad code.
And here's the crazy thing.. change your code to this and it works on Adobe!
Copy code
local.var1 = "three";
It's only with the
var
keyword that it complains!
w
this behavior goes pretty far back in acf, at least to cf10, so it definitely had nothing to do with closures/needing to cleanup two scopes, etc
b
No, no- I never meant to intend that Adobe ever did anything because of that. It was just an observation of performance overhead I've seen in Lucee over the years.
w
fair enough. and the disconnect with var and local and it working/not working, var predated local scoping actually being allowed iirc?
b
I think if having the scopes joined in Adobe offers any performance benefit, it was likely dumb luck
I always chalked that decision up to pure laziness, lol
w
that is, using local.var1
b
I don't recall off the top of my head TBH
w
yes, can't foresee that being a design decision
too many other dumb decisions that didn't work out to give them a pass on that
yeah, cf8 had var, and you had to
<cfset var local = structnew()>
to be able to local.somevar a variable. if you didn't var local, then you ended up actually creating a
variables.local
struct. it was corrected/finetuned in cf9
šŸ‘ 1
not that it matters terribly to the discussion, but the last couple of responses here echo this: https://stackoverflow.com/questions/25335713/cf8-vs-cf10-local-scope-declared-in-parent-not-visible-in-child-functions
a
Not being able to
var
a variable of the same name as a declared parameter predates the arguments and local scopes even existing. In CF5 one gets this error:
Copy code
Local variable names cannot be declared more than once, nor can they conflict with parameter names.
Code:
Copy code
function f(x) {
    var x = 1;
    return x;
}
Reason being: there were no explicit local and arguments scopes in those days, so no way to distinguish between the parameter value and the local value, so CFML disallowed it. This makes sense. There's insufficient visibility in CF5 to check how each data structure is implemented, and the contents thereof; so dunno whether there's a reference to the arguments data structure in the local-variables data structure or not. Well: if there's a way of looking I dunno what it is. Certainly the scopes didn't exist in CF5. However this is a different thing to the rule that a function can't have a local variable with the same name as a named parameter.