insteadof operator

# Bucaran (9 years ago)

Sometimes you have a function that receives a parameter shadowing an existing function or variable in the parent scope.

In some cases I would like to use the same variable name to avoid having to come up with new names. Contrived example ahead:

import path from "path"

function doSomething (_path) {
	if (path.dirname(_path) === "/" ) {
	// ...
 	} else {
	}
}

It would be nice if there was a special construct like typeof or instanceof that would take a name and evaluate to whatever variable / function of the same name existing in the parent scope (or undefined otherwise).

import path from "path"

function doSomething (path) {
	if ((insteadof path).dirname(path) === "/" ) {
	// ...
 	} else {
	}
}

In this case the expression above using the made-up inteadof operator would evaluate to the imported path variable instead of the path variable name.

# Jordan Harband (9 years ago)

What would happen if this operator was used in the global scope?

# Edwin Reynoso (9 years ago)

I'm highly doubting something like this will be made just because of wanting to use the same variable name. What's the real use, besides more code than using a different variable name.

# Bucaran (9 years ago)

The default behavior is best most of the time, but for those times when you need the object in the parent scope I thought it’d nice :)

What would happen if this operator was used in the global scope?

It should throw an runtime error.

# Bergi (9 years ago)

Bucaran schrieb:

It would be nice if there was a special construct like typeof or instanceof that would take a name and evaluate to whatever variable / function of the same name existing in the parent scope (or undefined otherwise).

Sorry, no. Please not. This would be a horrible feature, making name collisions (which are already confusing as hell at times) even more confusing. Scoping is already complicated, no need to introduce an edge case that all tooling (including human brains) would need to get learned.

There already does exist a simple, familiar, and working solution (well, multiple ones actually), it's not worth the trouble of introducing a new operator.

Bergi

# joe (9 years ago)

[sorry forgot to reply to all] ---------- Forwarded message ---------- From: "joe" <joeedh at gmail.com>

Date: Jun 25, 2015 5:34 PM Subject: Re: insteadof operator To: "Bergi" <a.d.bergi at web.de>

Cc:

Would there be any security issues? Also, runtime or lexical scope?

I've actually wanted this feature for a while now, but always assumed it had no chance of happening due to security issues. Of course, I know nothing about security so I could be wrong.

# Salvador de la Puente González (9 years ago)

If the outer name collides with your inner name its because the meaning of the outer name inside the new context has changed. So, find a better name.

For the path example, what is wrong is the name of the package. You can replace with pathtools for instance.

And remember you always can use the explicit global object to avoid collisions. El 25/6/2015 17:37, "joe" <joeedh at gmail.com> escribió:

# Bergi (9 years ago)

joe wrote:

Would there be any security issues? Also, runtime or lexical scope?

I've actually wanted this feature for a while now, but always assumed it had no chance of happening due to security issues. Of course, I know nothing about security so I could be wrong.

Actually, now that you mention it, yes there might be. Iirc, some sandboxing techniques rely on executing unknown scripts in an own scope where globals (and other stuff that could be used to escape) are shadowed by local variables that contain the "secured" counterparts. By introducing an operator to undo shadowing, you could break out of that.

Bergi

# monolithed (9 years ago)

There's an an equivalent in C++:

#include <iostream>

static int foo = 1;

int bar (const int &foo) {
::foo = 2;

return foo;
}

int main () {
std::cout << foo << ',' << bar(1) << std::endl; // 2,1
 return 0;
}

:: is more reasonable for me

# Bucaran (9 years ago)

On Jun 26, 2015, at 9:42 AM, Salvador de la Puente González <salva at unoyunodiez.com> wrote:

And remember you always can use the explicit global object to avoid collisions.

Indeed. Thanks for mentioning that.

# Rick Waldron (9 years ago)

It's not immediately clear which path binding insteadof will resolve to here:

import path from "path";

function dirOp(path) { with (path) { if ((insteadof path).dirname(path) === "/") { // ... } } }

dirOp({ path: "" });

Or even...

import path from "path";

function dirOp(path) { try { // ... } catch (path) { if ((insteadof path).dirname(path) === "/") { // ... } } }

dirOp({ path: "" });

If that's not compelling enough, then this might be:

import { dirname } from "path";

function dirOp(path) { if (dirname(path) === "/") { // ... } }

dirOp({ path: "" });

# Bucaran (9 years ago)

Allow try…catch blocks to return a value.

Sometimes I wrap a try…catch in a function and return a value based in whether there was an error or not.

It would be useful if you could use return inside a try…catch block to accomplish the same.

  let stuff = try {
    return ...
  } catch (e) { return … ? … : ... }
# Nick Krempel (9 years ago)

On 11 July 2015 at 14:40, monolithed <monolithed at gmail.com> wrote:

#include <iostream>

static int foo = 1;

int bar (const int &foo) {
::foo = 2;

return foo;
}

int main () {
std::cout << foo << ',' << bar(1) << std::endl; // 2,1

(This looks like undefined behavior as the evaluation of "foo" and the function call "bar(1)" are indeterminately sequenced.)

return 0;