isClosure() is flawed in two ways?

Adobe docs description for isClosure():

Determines whether a value or expression references a function defined via a function expression, as opposed to a function statement.

So why wasn’t the function named isFunctionExpression() and have a separate isClosure() which returns what one would expect that to return?

Moreover, function expressions are NOT automatically closures, yet isClosure() returns true even when the function expression is NOT a closure.

[Click for Gist Example]

Lucee docs description for isClosure():

Checks if given Object is a closure or not.

In reality what it actually returns is mostly the same as Adobe CF i.e. whether the function is an expression. BUT it also returns false for all arrow functions, even when they are actual closures.

[Click for Gist Example]

Should Lucee’s implementation diverge from Adobe’s?

Personally I think it should actually return the boolean of whether the function is a closure AND there should also be a new isFunctionExpression().

Pie in the sky dreams perhaps, and another low priority (like … how useful is isClosure() anyways? LOL) but I figured I’d be the … first to document it?

I did find LDEV-250 from 2015, but I’m pretty sure what I’m talking about is a different issue, not whether lambdas are closures, but what the return values of isClosure() should be.

(Although I’ll additionally debate that a lambda is NOT a closure if it does not capture variables from its surrounding lexical scope.)

Is my analysis correct or no?

I bet @AdamCameron has a few choice words to say about this. :stuck_out_tongue:

1 Like

Upon further deliberation I’ve come to realize that apparently neither Adobe nor Lucee docs actually define what a closure is, and I’ve been able to gather how there are two conflicting definitions:

The formalist definition (used by language specs and some documentation like MDN) defines a closure as any function with a reference to its lexical environment, even if it never uses it. For example, even a plain old function that does absolutely nothing still has access to its lexical scope e.g. global scope, Request, Application, etc. That’s technically accurate, but it conflicts with practical intuition. The end result is that … every function is a closure? I mean … just … WHUT THE?

In practical, real-world usage, developers usually mean:

A closure is when a nested function retains access to variables from a parent function after that parent function has exited.

That’s when closures are actually interesting and powerful because they:

  • Preserve state across invocations
  • Avoid polluting global scope
  • Create private variables

So, now another question is … which definition is isClosure() supposed to be using as the basis for its return value? I just can’t imagine what’s the practical use of the function if the formalist definition is used. :roll_eyes:

And either way, Lucee’s implementation doesn’t match Adobe’s, so the other question remains, whether it should (or should not) match Adobe’s.

can you elaborate?

code examples also really help illustrate the problem!

@Zackster I did already provide two Gist examples. See above.