5

In JavaScript, is there any mechanism that would make it possible to set a function return value without using the keyword "return"?

6
  • 7
    Yes, It is. By using global variable. Commented Dec 27, 2013 at 7:00
  • 1
    @hicurin Since var result = myFunc(); won't work, this is not a return value. Commented Dec 27, 2013 at 7:08
  • @IngoBürk if myFunc(); return a value, it will assign to result. If not, this is just like you call myFunc(); Commented Dec 27, 2013 at 7:27
  • It will broken purpose of using functions Commented Dec 27, 2013 at 8:22
  • @SeyedMortezaMousavi It will broken purpose of functions? What are you trying to convey? I can't understand most of the comments on this thread. Commented Dec 27, 2013 at 8:28

6 Answers 6

7

Of course you can. All the other answers talk about:

  1. Assigning a value to a variable in a parent scope.
  2. Assigning a value to a property of an object in a parent scope.

There is however a third method and this method is very powerful: CONTINUATIONS.

For a moment let's assume that return is a function. For example:

function add(a, b) {
    return(a + b);
}

Now what if you didn't want to use return? We could do something like this:

function add(a, b, ret) {
    ret(a);
}

To put it simply a continuation is a function which is used in place of a return statement. More formally:

A continuation is a function which is called by another function. The last thing the other function does is call the continuation. It doesn't do anything else after that.

Hence a continuation is like the functional equivalent of the return statement.

Continuations have a lot of advantages:

  1. You can pass multiple return values to the continuation.
  2. You can write functions recursively instead of iteratively.
  3. You can choose not to call the continuation (in which case you're changing the control flow).
  4. You can choose to call one of multiple continuations (like a throw continuation).

However continuations have two main disadvantages:

  1. If you write programs in continuation passing style then you'll end up with a lot of nested functions.
  2. JavaScript doesn't have tail call elimination. Hence recursive functions increase the stack size.

For example:

function fib(n, k) {
    switch (n) {
    case 0:  k(0); break;
    case 1:  k(1); break;
    default:
        fib(n - 1, function (x) {
            fib(n - 2, function (y) {
                k(x + y);
            });
        });
    }
}

fib(20, console.log); // maximum recursion depth exceeded

You can use setTimeout to eliminate tail call recursion:

Function.prototype.async = function () {
    return setTimeout.bind(null, this, 0).apply(null, arguments);
};

function fib(n, k) {
    switch (n) {
    case 0:  k(0); break;
    case 1:  k(1); break;
    default:
        fib.async(n - 1, function (x) {
            fib.async(n - 2, function (y) {
                k(x + y);
            });
        });
    }
}

fib(20, console.log); // 6765

You can use backcalls from LiveScript to make your code look better:

Function::async = -> setTimeout.bind(null, @, 0) ...

fib = (n, k) -->
    | n == 0    => k 0
    | n == 1    => k 1
    | otherwise =>
        x <- fib.async n - 1
        y <- fib.async n - 2
        k x + y

fib 20, alert # 6765

You can try it out for yourself on the http://livescript.net/ site. Just use a value smaller than 20. Preferably 10.

Sign up to request clarification or add additional context in comments.

1 Comment

That is a clever answer. So, instead of x = func (); do_y (x), you suggest x = func(do_y). Not exactly the same as simply setting the return value without using "return" -- which I guess isn't currently possible in Javascript (wanted to make sure of that), but it is a decent answer... The nested function disadvantage is really a big one, though. Sometimes, your return value is used multiple times (like if I wanted to return some big object thing that's used many times... it would be less maintainable to use multiple continuations in that case)
2

There is no other way to return a value, that's what return is for. But since we have side effects, you can edit a variable in a wider scope like this:

var a = 5;
function setA(x)
{
    a = x;
}
setA(6);

Alternatively you can pass an object to the function and by using pass by reference change variables in that object. This page details how that works.

As mentioned above, this is not the same as a result value, as the following will fail:

var newA = setA(a); // undefined instead of 5

Comments

1

My understanding is that you don't want to use return because you don't want to stop your function. So you can use promises to get a value from a function without stopping it:

const run = () => new Promise((resolve)=>{
  const a = 1 + 1;
  resolve(a);
  console.log('next');
})

async function test(){
  const neededResults = await run();
  console.log(neededResults);
}
test()

1 Comment

Technically there is a return.... Hope the person got their answer 9 years ago :)
0

using some global varible or if you want OOP concept then some class variable will be use and updates without return statement

var num1 = 5;
alert(num1);
function sum(a,b) {
    num1 = a+b; // Function Without return statement
}
//Calling Function
sum(3,4);
alert(num1);

7 Comments

That won't set a return value.
@Agamemnus What do you mean by "that won't set a return value"? It's setting a variable which you can use later. The only disadvantage is that the function must be defined in the scope in which the return variable is declared. Hence the path of least resistance is to make the return variable a global.
It sets a variable that can be considered the output variable, but it won't actually set the return value of "sum(a, b)".
@Agamemnus Obviously not. The only way to "return" a value from a function is by using return and I don't see how that's a problem. Why do you want to "return" a value from a function without using return? What are you trying to do?
Actually that's not entirely true. Having a defined "this" value will create an implicit return value. Being able to set the return value (kind of like "this" does) before returning would make my code clearer, in the case where the function is fairly big and composed mostly of defining properties -- in that case, one has to return the object right at the end. The code then becomes fragmented into three parts: an initial part, a section defining properties, and then a final "return" statement. Being able to set the return value will reduce that to just two parts.
|
0

The best (most readable/testable) way to create your functions is to have them receive what they need, and return what they should. However if you need to avoid returning for some reason there are several ways to do this:

Set a variable in scope

You could create a variable in a closure, then set the value in a function.

(function() {
  var a = 12;
  var fnc = function() {
    a = 13;
  }
  fnc();
  // value of a is now 13 as a is in scope for fnc
})();

Create a global object

You could create a global object and set an attribute on it:

window.app = window.app || {};
app.a = 12;

var b = function() {
  app.a = 13;
}
b();
// the value of app.a is now 13 as app is in scope for fnc

2 Comments

Thanks... these are fine ways to set intended result values, but I was asking whether one could set a return value (i.e.: the return value of the function) without using the keyword "return".
I suspect it to be impossible, because that would preclude all kinds of compiler optimisation. I would love to be proved wrong on that though, it would be a cool language feature.
0

You can also note that ES6 arrow functions allow to return a value for a simple expression without any keyword nor brackets :

const double = n => n*2;
console.log(double(2));

const sum = (a,b) => a+b;
console.log(sum(1,2));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.