Question

Is there a way to extract a variable that is closed over by a function?

In the (JavaScript-like) R language values that are closed-over can be accessed by looking up the function's scope directly. For example, the constant combinator takes a value and returns a function that always yields said value.

K = function (self) {
    function () {
        self
    }
}

TenFunction = K(10)
TenFunction()
10

In R the value bound to "self" can be looked up directly.

environment(TenFunction)[[ "self" ]]
10

In R this is a perfectly normal and acceptable thing to want to do. Is there a similar mechanism in JavaScript?

My motivation is that I'm working with functions that I create with an enclosed value called "self". I'd like to be able to extract that data back out of the function. A mock example loosely related to my problem is.

var Velocity = function (self) {
    return function (time) {
        return self.vx0 + self.ax * time
    }
}

var f = Velocity({vx0: 10, ax: 100})

I'd really like to extract the values of self.vx0 and self.ax as they are difficult to recover by other means. Is there a function "someFun" that does this?

someFun(f).self

{vx0: 10, ax: 100}

Any help or insights would be appreciated. If any clarification is needed leave a comment below and I'll edit my question.

Was it helpful?

Solution

Not as you have described, no. Function objects support very few reflective methods, most of which are deprecated or obsolete. There is a good reason for this: while closures are a common way to implement lexically scoped functions, they are not the only way, and in some cases they may not be the fastest. Javascript probably avoids exposing such details to allow implementations more flexibility to improve performance.

That said, you can get around this in various ways. One approach is to add an argument to the inner function telling it that it should return the value of a certain variable rather than doing what it usually does. Alternatively, you can store the variable alongside the function.

For an example of an alternative implementation technique, look up "lambda lifting". Some implementations may use different approaches in different situations.

Edit

An even better reason not to allow that sort of reflection is that it breaks the function abstraction rather horribly, and in doing so exposes hairy details of how the function was produced. If you want that sort of access, you really want an object, not a function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top