So this has been bugging me. For example, takes a string input and draws its function. So I am wondering how it takes a basic string and returns a function that can be run. Not desmos.com specifically they're just a good example.
How would one return a working function from a string?
Every way I look at it if you return function()... it will try and run the function and return it right then.
Eg:
var string = "x^2";
//return
function f = (x) => {
return x * x;
}
Edit: expanding to try and explain better, it is a bit difficult to explain.
function generate_f = (string) => {
return f(x);
}
f = generate_f("x^2");
returns: a function that can be called, eg to draw the function to a canvas.
function f = (x) => { return Math.pow(x, 2); }
f = generate_f("x^3 + 4");
function f = (x) => { return Math.pow(x, 3) + 4; }
Imagine I ran the string through a parser, I tokenize "x^3 + 4" into an array ["x", "^", 3, "+", 4] I loop through I see x, check next value see ^ and then 3 I then add Math.pow(x, 3) to a thing, as it checks for a power value, then I add to that thing +4, now if I did this it would break at Math.pow(x, 3) as there is no x value so how would you return a working function.
3 Answers 3
I believe you'd have to do some parsing of the string to get the full functionality you're looking for.
A decent library you can play with is http://mathjs.org/docs/expressions/parsing.html
Comments
Use JavaScript's Function Constructor.
For example:
var square = Function("x", "return Math.pow(x,2)");
square(2); // 4
Generating a dynamic function
You have the right idea for your generate_f function. You will just have to use the Function constructor to turn the string input into a function that may be called.
function generate_f(expression){
// use Function constructor
// to build a new function
// from the 'expression' string argument
var customFunction = Function("x", "return " + expression);
return customFunction;
}
var myFunction = generate_f("Math.pow(x,3) + 4;");
myFunction(2); // 12
Arguments
You will notice that in the above examples the Function constructor is used to create functions with a single argument, x. If you want to build a function that accepts more arguments, you may use a comma-delimited list or one string per argument.
Example:
// function arguments defined using a comma-delimited list
var sum = Function("x, y, z", " return x + y + z; ");
// function arguments defined using one string per argument
var add = Function("a", "b", " return a + b; ");
var i = sum(1, 2, 3); // 6
add(i, 1); // 7
If you are generating a function that does not accept any arguments, just provide the function body expression.
var functionBody = " return 'This function has no arguments.'; ";
var noArgs = Function(functionBody);
noArgs(); // This function has no arguments.
Notes
Any leading arguments to the Function constructor are parameters to your generated function. The last argument to the Function constructor is always the function body.
When using the Function constructor remember to always type capital letter F:
// function constructor (returns a new function)
var myFunction = Function(functionArgument, functionBody);
// function declaration (declares a function)
myFunction = function(){ /* expression */ };
- The
generate_ffunction could be rewritten as such:
function generate_f(){
var args = Array.prototype.slice.call(arguments);
var nArguments = args.length;
var functionBody;
if(nArguments == 1){ // build function with no arguments (function body only)
functionBody = args[0];
return Function(functionBody);
}else if(nArguments > 1){ // build function that accepts arguments
functionBody = args.pop(); // remove last argument (the function body)
// form a comma-delimited list
// from the remaining arguments (the leading arguments)
var functionParameters = args.join(',');
return Function(functionParameters, functionBody);
}
return false;
}
Then you could use generate_f to build the functions from each example:
var square = generate_f("x", " return Math.pow(x,2); ");
var myFunction = generate_f("x", " return Math.pow(x,3) + 4; ");
var sum = generate_f("x, y, z", " return x + y + z; ");
var add = generate_f("a", "b", " return a + b; ");
var noArgs = generate_f(" return 'This function has no arguments.'; ");
Comments
This is called string parsing. In fact, it is exactly how a web browser takes your JavaScript code and makes the computer do something. You only need to convert the mathematical expression into some form that can be evaluated. You do not need to convert it into JavaScript. You can do the parsing by hand or user a library to help you. I suggest you do further research on string parsing.
eval?