Intermediate Algorithm Scripting: Arguments Optional - instructions unclear

Hello,

A few questions -

  1. The instructions open with the following sentences:

“Create a function that sums two arguments together. If only one argument is provided, then return a function that expects one argument and returns the sum.”

My first question: returns the sum of what? i.e., if the function is to sum two arguments, but only one argument is provided, what would be the sum of the single argument, which I presume would be a single number? are we simply providing the value of the single argument as the sum? If not, what would we be summing together?

Further down in the instructions, I do see the following:
“Calling this returned function with a single argument will then return the sum:
var sumTwoAnd = addTogether(2);
sumTwoAnd(3) returns 5 .”

However I am not clear if this is the sum to which they are referring above.

  1. Also, when I try to call the following “functions”:

addTogether(2)(3)
and
addTogether(2)([3])

I get a TypeError: addTogether(…) is not a function which I guess would make sense since there are two sets of parentheses, so to my novice eyes they don’t look like the JS functions I’m used to seeing.

My second question: how do you call a function that is not a function, in order to test these cases?

  1. The final sentence of the instructions state,

“If either argument isn’t a valid number, return undefined.”

My third question: what is considered a valid number? An integer? a non-negative number? typeof is number? not NaN?

Thanks in advance for taking a look at this, and for your willingness to help.

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36.

Challenge: Arguments Optional

Link to the challenge:

  1. You need to make a function that takes one or two arguments.
    a) If you are given two numbers (num1 and num2), you return the sum of those two numbers.
    b) If you are given one number, (numFromNow), you return a function that takes one argument (numFromFuture) and returns the sum of the new number and the original numFromNow + numFromFuture.
  2. You need to use the sample syntax they gave to call this function. The new function will be the return value. You can’t call it with the syntax you were trying.
  3. A valid input is a number. An invalid input is anything that is not a number.

Sample syntax:

// Adding two numbers
console.log("Adding two numbers")
let mySum = addTogether(5, 6); // Returns 11
console.log(mySum);

// Creating a function that adds
console.log("Make new adding function")
let add5And = addTogether(5); // Returns function
console.log(add5And);

// Use adding function from above
console.log("Use new adding function")
mySum = add5And(6); // Should still be 7
console.log(mySum);

@JeremyLT, thanks for the reply.

  1. I do understand from the instructions that I need to make a function that takes one or two arguments. However, I don’t understand your explanation in 1b) regarding numFromNow and numFromFuture. Where are these numbers coming from?

  2. Where are you getting the sample syntax from?

How do I incorporate the following into the function:
addTogether(2)(3) should return 5.
and
addTogether(2)([3]) should return undefined.

The above are the test cases that are given in the exercise when I click the box for “run the tests” - the implication is that we would call the function as in these test cases, in order to get the output indicated (respectively, 5 or undefined).

  1. I understand that a valid input is a number, but the instructions state “If either argument isn’t a valid number, return undefined.” So what is meant by a valid number? How do we test if a number is valid or not? isNan will give a different result than typeof, right?

for example, typeof("3") is string but isNaN("3") is false meaning that “3” is a number, right?

  1. I just picked two variable names. If you prefer,
console.log(addTogether(num1, num2))

and

let addFunc = addTogether(num1);
console.log(addFunc(num2));

should do the same thing.

  1. Sample syntax given in challenge description:

var sumTwoAnd = addTogether(2);
sumTwoAnd(3) returns 5 .

I am surprised that addTogether(2)(3) works, but I see it on the test suite now. I think that the quoted syntax from the problem description is a bit easier to wrap your mind around, personally.

  1. Any number is valid. Anything that is not a number is invalid. Since number is valid, you only need to check if the inputs are numbers. (i.e. isNaN isn’t what you want)

you use the parenthesis to call the function, right?
so if addTogether(2) returns a function, you can also call that returned function in the same as any function, or you can store it in a variable and call it later. If you want to call it soon after it is returned you can do that by putting other round parenthesis soon after: addTogether(2)(3)

if addTogether doesn’t return a function, you get this error when calling addTogether(2)(3)

you will stop getting it once you manage the returning a function thing

2 Likes

Since functions are values in JavaScript, just as you can return a number or string or other types of values from a function, you can also return another function.

function makeNameLogger(name) {
  return function() {
    console.log(name);
  }
}

const logBill = makeNameLogger("Bill");
const logBob = makeNameLogger("Bob");

logBill(); // logs "Bill" to the console
logBob(); // logs "Bob" to the console

// You can also immediately call the returned function:
makeNameLogger("Stacy")(); // logs "Stacy" to the console

In the above example the makeNameLogger function takes one argument, name, and returns a new function that will log the name to the console when called.

Even though the return function from makeNameLogger doesn’t take any arguments, the function remembers the value of name from when it was created.

We can take this one step further, and define the return function with some arguments. Then in the return function we can use both the sets of arguments.

function makeStringRepeater(string) {
  return function(times) {
    return string.repeat(times);
  }
}

const repeatA = makeStringRepeater("A");
console.log(repeatA(5)); // logs "AAAAA" to the console

To solve this problem, you’ll need to do something similar, except instead of string and times, you’ll have two numbers. The return value of the inner function should be the sum of those two numbers.

1 Like

@ilenia, thanks for the explanation, I think I understand what you mean.

1 Like

Ok thanks @colinthornton, that’s helpful.

1 Like

@colinthornton, @JeremyLT and @ilenia,

I’m still having trouble understanding the second sentence in the instructions:

“If only one argument is provided, then return a function that expects one argument and returns the sum.”

What is the sum? The sum of what? The sum of the single argument? I don’t understand how you can have a sum of just one number, unless it is the number itself? Are we to write a function that simply returns the value of the argument?

I’m also not understanding the following:

var sumTwoAnd = addTogether(2);

What is the value of addTogether(2)? It would be the sum referenced above, since there is only one argument…which leads me back to the question of:
What is the sum?

If you only have one argument you return a function.

// myFunc is a function
var myFunc = addTogether(num1);

When you call this function, it adds its argument to num1:

// result will equal num1 + num2
var result = myFunc(num2)

@JeremyLT, I’m afraid I still am not getting it.

Here is my code so far, maybe this will help.

function addTogether() {
  var arr = [arguments[0], arguments[1]];
  var sum;
  if (typeof(arguments[0]) !== "number" || typeof(arguments[1]) !== "number") {
    //console.log(undefined);
    return undefined;
  }

  if (arguments.length === 1) {
    var one = function() {
        addTogether(num);
    }
    one();
  }

  if (arguments.length === 2) {
    arr.reduce(function(acc,curr) {
        sum = acc + curr;
    });
    //console.log(sum);
    return sum;
  }
  
}

This is another way to write the requirements that’s pretty close to your current code:

function addTogether() {
  if (/* invalid argument(s) */)
    return undefined;

  if (/* one valid argument */)
    return /* function that adds */

  if (/* two valid arguments */)
    return /* sum of both arguments */
}

Your condition

  if (typeof(arguments[0]) !== "number" || typeof(arguments[1]) !== "number") {

is too strict, because arguments[1] is allowed to be undefined.

Your function is a bit off:

  if (arguments.length === 1) {
    var one = function() {
        addTogether(num);
    }
    one();
  }

You make a function called one but it’s contents are not quite right. You need this function to take one argument and add that argument to the current arguments[0]. You then need to return this function.

@JeremyLT,

I’m not understanding your explanation above, since it seems that both arguments have to be a valid number as per the instructions:
“If either argument isn’t a valid number, return undefined.”

You can have 1 or 2 arguments. If you have only 1 argument, then by default arguments[1] = undefinded. arguments[1] being undefined is valid.

@JeremyLT,

I’ve occasionally encountered misleading, incomprehensible or vague instructions on FCC. Just to be clear, are you saying that the instructions are incorrect? I think my main issue is that I am not understanding the instructions.

The instructions and I agree, though I am perhaps saying it clearer.

If you have one argument, it must be valid. If you have one argument, then by default, the second argument is undefined.

If you have two arguments, they must both be valid.

@JeremyLT,

Sorry, but I don’t see complete agreement between your explanations and the instructions. I have faith that your explanations are correct, but the explanation provided in the exercise is still quite incomprehensible to me.

My explanation is the challenge description + some internal descriptions of how JavaScript works that I just learned myself over the last few days : )

1 Like

@JeremyLT, @ilenia, @colinthornton,

It looks a bit garbled but I finally got it to work with this code (and I finally understand how it works, just not exactly sure why). Your examples helped, and I tried ignoring the instructions. Thanks!

function addTogether() {
  if (arguments.length === 1) {
    if (typeof(arguments[0]) !== "number") {
      return undefined;
    }
    var num1 = arguments[0];
    return function(num2) {
      return addTogether(num1, num2);
    }    
  }
  if (arguments.length === 2) {
     if (typeof(arguments[0]) !== "number" || typeof(arguments[1]) !== "number") {
    return undefined;
  }
    var arr = [arguments[0], arguments[1]];
    var sum;
    arr.reduce(function(acc,curr) {
        sum = acc + curr;
    });
    return sum;
  }
  
}
1 Like

Congratulations! I think the trickiest part of this is returning a function sometimes and a number others.