0

I'm trying to build a function in JS that has a return composed of different nested functions based on a parameter passed by the user.

function addA(otherFunction)
{
//gets the result from some base function and modifies it
//e.g. +1
}

function addB(otherFunction)
{
//does the same thing as addA, except different values. Consider it a variation of addA.
//eg. -1
}

function constr(input)
{
//based on the chars in input, we will recursively select a new function to be applied.
//the value of this function should be a function
if (...) return addA(constr(shorterInput))
if (*last char) return addA
if (*last char) return addB
if (...) return addB(constr(shorterInput))
}

So far, my script is recognizing addA and and addB as functions. But when it strings two functions together, for example

addB(addA)

The type becomes undefined. Can anybody let me know why it does not register as a function and/or the proper way to return nested functions. Thanks!

Edit: Here is the real code:

function cons(a,b)
{
  return function (selector) {
    return selector(a,b);
  };
}

function a(list)
{
  function aHelper(a,b)
  {
    return a
  }
  return list(aHelper);
}

function d(list)
{
  function dHelper(a,b)
  {
    return b
  }
  return list(dHelper);
}

function abc(input)
{
  if (input.length==0 || input==null) return null;
  var x=input.charAt(input.length-1);
  if (x==='a') 
  {
    if (input.length>1) 
    {
      var z=a(abc(input.substr(0,input.length-1)));
      return z;
    }
      return a;
  }
  if (x==='d')
  {
    if (input.length>1) 
    {
      var z=d(abc(input.substr(0,input.length-1)));
      return z;
    }
    return d;
  }
}
function show(list) {
  var sval;
  if (list == null) return '()';
  else if (typeof list!='string')
  {
    sval = '(' + show(a(list)) + ' ' + show(d(list)) + ')';
  }
  else 
  {
    sval=list;
  }
  return sval;
}

var func=abc('ad');
var func2=abc('a');
var list=cons('a',cons('b','c'));
console.log(typeof func);
console.log(typeof func2);
console.log(typeof list);
console.log(typeof func2(list));
console.log(typeof func(list));

12
  • 1
    It would help a lot if you could post the real code you actually have problems with, not only some pseudo code. Commented Sep 17, 2016 at 19:34
  • 1
    The otherFunction parameter seems to be supposed to contain a function that can be called with a value and returns a value, right? The addA function you are passing is no such function, it is one that takes and returns other functions. Commented Sep 17, 2016 at 19:37
  • 1
    Thanks for the code. Where did you get this list representation from? It's horrible. Commented Sep 17, 2016 at 19:47
  • 1
    I can see where your problem lies, but I can't tell you how to solve it as I am unsure what you want abc to do. What is the task you're trying to accomplish? And what type do you think should abc have? Commented Sep 17, 2016 at 19:49
  • 1
    I'm pretty sure you should be using var list=cons('a',cons('b', cons('c', null)));, right? Commented Sep 17, 2016 at 20:16

1 Answer 1

2

Your function abc is supposed to return a function that can process lists, like a or d. However, you match that signature only in 2 out of 7 cases:

  • return a, return d are fine
  • return null - that's not a callable value
  • z = d(…); return z does return a list
  • z = a(…); return a does return an element of the list (of whatever type)
  • d(abc(…)) and a(abc(…)) use abc as if it would return a list

A correct implementation would look like this:

function abc(directions) {
    if (directions.length == 0) {
       return function id(list) { return list; }; // a function that does nothing
    }
    var f = directions[0] == 'a' ? car : cdr; // ignoring other values, you might also throw an error
    var processRest = abc(input.slice(1));

    return function(list) { // make a function to process a list
        var z = f(list); // do the current operation
        return processRest(z); // do the rest of operations
    };
}

Or even better/shorter with the help of higher-order function composition:

function id(x) { return x; }
function compose(f, g) {
    if (f == id) return g;
    if (g == id) return f;
    return function(x) { return f(g(x)); };
}
function abc(dirs) {
    return !dirs.length ? id : compose(abc(dirs.slice(1)), dirs[0]=='a'?car:cdr);
}
Sign up to request clarification or add additional context in comments.

8 Comments

Try to fix it with these hints. I'm going to uncomment my solution if you've got something
The problem I have is that even if replace z=d(abc)... with return a(d), it still considers a(d) as undefined`
You have to pass a list to a. Not a function like d or abc(…)
No, it's not impossible. Right, in the context that abc operates in, there are only functions (like a, d, or the result of the recursive call). But inside these functions, there is a list, and you need to use that. Did you learn about closures yet? Use one.
@YinanWang Yes, that's what my answer states: abc needs to return a function (that then does the work). Have you used closures before?
|

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.