Recently I've been learning Lua and I love how easy it is to write a function that returns a function. I know it's fairly easy in Perl as well, but I don't think I can do it in C without some heartache. How do you write a function generator in your favorite language?
So that it's easier to compare one language to another, please write a function that generates a quadratic formula:
f(x) = ax^2 + bx + c
Your function should take three values (a
, b
, and c
) and returns f
. To test the function, show how to generate the quadratic formula:
f(x) = x^2 - 79x + 1601
Then show how to calculate f(42)
. I'll post my Lua result as an answer for an example.
Some additional requirements that came up:
All of a
, b
, c
, x
, and f(x)
should be floating point numbers.
The function generator should be reentrant [1]. That means it should be possible to generate:
g(x) = x^2 + x + 41
And then use both f(x)
and g(x)
in the same scope.
Most of the answers already meet those requirements. If you see an answer that doesn't, feel free to either fix it or note the problem in a comment.
function quadratic(a, b, c)
{
return function(x)
{
return a*(x*x) + b*x +c;
}
}
var f = quadratic(1, -79, 1601);
alert(f(42));
quadratic a b c = \x -> a*x*x + b*x + c
or, I think more neatly:
quadratic a b c x = a*x*x + b*x + c
(if you call it with only three parameters, you get back a function ready for the fourth)
To use:
let f = quadratic 1 -79 1601 in f 42
Generalizing it to arbitrary-order polynomials (as the OCaml [1] answer does) is even nicer in Haskell:
polynomial coeff = sum . zipWith (*) coeff . flip iterate 1 . (*)
f = polynomial [1601, -79, 1]
main = print $ f 42
Treating functions as if they were numbers:
{-# LANGUAGE FlexibleInstances #-}
instance Eq (a -> a) where (==) = const . const False
instance Show (a -> a) where show = const "->"
instance (Num a) => Num (a -> a) where
(f + g) x = f x + g x; (f * g) x = f x * g x
negate f = negate . f; abs f = abs . f; signum f = signum . f
fromInteger = const . fromInteger
instance (Fractional a) => Fractional (a -> a) where
(f / g) x = f x / g x
fromRational = const . fromRational
quadratic a b c = a*x^2 + b*x + c
where x = id :: (Fractional t) => t -> t
f = quadratic 1 (-79) 1601
main = print $ f 42
...although if 1 (-79) 1601
weren't numeric literals, this would require some additional application of const
.
def quadratic(a, b, c):
return lambda x: a*x**2 + b*x + c
print quadratic(1, -79, 1601)(42)
# Outputs 47
Without using lambda (functions can be passed around in Python like any variable, class etc):
def quadratic(a, b, c):
def returned_function(x):
return a*x**2 + b*x + c
return returned_function
print quadratic(1, -79, 1601)(42)
# Outputs 47
Equivalent using a class rather than returning a function:
class quadratic:
def __init__(self, a, b, c):
self.a, self.b, self.c = a, b, c
def __call__(self, x):
return self.a*x**2 + self.b*x + self.c
print quadratic(1, -79, 1601)(42)
# Outputs 47
quadratic = lambda a, b, c: lambda x: a*x**2 + b*x + c
also works. Wouldn't recommend it though. - Beni Cherniavsky-Paskin
Func<double, double, double, Func<double, double>> curry =
(a, b, c) => (x) => (a * (x * x) + b * x + c);
Func<double, double> quad = curry(1, -79, 1601);
function quadratic($a, $b, $c)
{
return function($x) use($a, $b, $c)
{
return $a*($x*$x) + $b*$x + $c;
};
}
$f = quadratic(1, -79, 1601);
echo $f(42);
I don't see one using boost::lambda [1] yet...
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <iostream>
using namespace std;
using namespace boost;
using namespace boost::lambda;
function<float(float)> g(float a,float b,float c)
{
return a*_1*_1 + b*_1 + c;
}
int main(int,char**)
{
const function<float(float)> f=g(1.0,-79.0,1601.0);
cout << f(42.0) << endl;
return 0;
}
(works with whichever gcc and boost are current on Debian/Lenny).
[1] http://www.boost.org/doc/libs/1%5F38%5F0/doc/html/lambda.htmlNot pretty, and not very well generalized, but...
typedef struct tagQuadraticFunctor QuadraticFunctor, *PQuadraticFunctor;
typedef double (*ExecQuadratic)(PQuadraticFunctor f, double x);
struct tagQuadraticFunctor{
double a;
double b;
double c;
ExecQuadratic exec;
};
double ExecQuadraticImpl(PQuadraticFunctor f, double x){
return f->a * x * x + f->b * x + f->c;
}
QuadraticFunctor Quadratic(double a, double b, double c){
QuadraticFunctor rtn;
rtn.a = a;
rtn.b = b;
rtn.c = c;
rtn.exec = &ExecQuadraticImpl;
return rtn;
}
int main(){
QuadraticFunctor f = Quadratic(1, -79, 1601);
double ans = f.exec(&f, 42);
printf("%g\n", ans);
}
#include <stdarg.h>
typedef struct tagFunctor Functor, *PFunctor;
typedef void (*Exec)(PFunctor f, void *rtn, int count, ...);
struct tagFunctor{
void *data;
Exec exec;
};
void ExecQuadratic(PFunctor f, void *rtn, int count, ...){
if(count != 1)
return;
va_list vl;
va_start(vl, count);
double x = va_arg(vl, double);
va_end(vl);
double *args = (double*)f->data;
*(double*)rtn = args[0] * x * x + args[1] * x + args[2];
}
Functor Quadratic(double a, double b, double c){
Functor rtn;
rtn.data = malloc(sizeof(double) * 3);
double *args = (double*)rtn.data;
args[0] = a;
args[1] = b;
args[2] = c;
rtn.exec = &ExecQuadratic;
return rtn;
}
int main(){
Functor f = Quadratic(1, -79, 1601);
double ans;
f.exec(&f, &ans, 1, 42.0); // note that it's very important
// to make sure the last argument
// here is of the correct type!
printf("%g\n", ans);
free(f.data);
}
&f
argument to f.exec
, which just doesn't feel like a normal function to me... - ephemient
(defn quadratic [a b c] #(+ (* a % %) (* b %) c)) ((quadratic 1 -79 1601) 42) ; => 47
Arbitrary-order polynomials:
(use 'clojure.contrib.seq-utils 'clojure.contrib.math) (defn polynomial [& cs] #(apply + (map (fn [[pow c]] (* c (expt % pow))) (indexed cs)))) ((polynomial 1601 -79 1) 42) ; => 47
Featuring parameter list destructuring goodness and some handy libs from clojure.contrib.
(define (quadratic a b c)
(lambda (x)
(+ (* a x x) (* b x) c)) )
(display ((quadratic 1 -79 1601) 42))
def foo (a,b,c)
lambda {|x| a*x**2 + b*x + c}
end
bar = foo(1, -79, 1601)
puts bar[42]
gives
47
Here's a nice one line example in F#:
let quadratic a b c x = a*x*x + b*x + c
let f = quadratic 1 -79 1601 // Use function currying.
printfn "%i" (f 42)
And for arbitrary-order:
let polynomial coeffs x =
coeffs |> List.mapi (fun i c -> c * (pown x i)) |> List.sum
let f = polynomial [1601; -79; 1]
f 42
And to generalize over numerics:
let inline polynomial coeffs x =
coeffs |> List.rev |> List.mapi (fun i c -> c * (pown x i)) |> List.sum
> let f = polynomial [1601.; -79.; 1.];;
val f : (float -> float)
> let g = polynomial [1601m; -79m; 1m];;
val g : (decimal -> decimal)
(untested)
First, we need a Function interface:
public interface Function {
public double f(double x);
}
And a method somewhere to create our quadratic function. Here we're returning an anonymous implementation of our Function interface. This is how Java does "closures". Yeah, it's ugly. Our parameters need to be final for this to compile (which is good).
public Function quadratic(final double a, final double b, final double c) {
return new Function() {
public double f(double x) {
return a*x*x + b*x + c;
}
};
}
From here on out, it's reasonably clean. We get our quadratic function:
Function ourQuadratic = quadratic(1, -79, 1601);
and use it to get our answer:
double answer = ourQuadratic.f(42);
You don't.
And here's why:
// OneArgFunction.java
// Generic interface for reusability!
public interface OneArgFunction<P,R> {
public R evaluate(P param);
}
// Somewhere in your code
public OneArgFunction<Double, Double> quadratic(final double a, final double b, final double c) {
return new OneArgFunction<Double, Double>() {
public Double evaluate(Double param) {
return param*param*a + param*b + c;
}
};
}
// And...
OneArgFunction<Double, Double> quadratic = quadratic(1, -79, 1601);
System.out.println(quadratic.evaluate(42));
final
, but Haskell wears that same limitation with pride! - Daniel Earwicker
(defun make-quad (a b c) #'(lambda (x) (+ (* a x x) (* b x) c))) (funcall (make-quad 1 -78 1601) 42)
x86_32 Assembly (I am very new to it, it may not be the best way to do it, comments welcome):
#define ENTER_FN \
pushl %ebp; \
movl %esp, %ebp
#define EXIT_FN \
movl %ebp, %esp; \
popl %ebp; \
ret
.global main
calculate_fabcx: #c b a x
ENTER_FN
# %eax= a*x*x
movl 20(%ebp), %eax
imull %eax, %eax
imull 16(%ebp), %eax
# %ebx=b*x
movl 12(%ebp), %ebx
imull 20(%ebp), %ebx
# %eax = f(x)
addl %ebx, %eax
addl 8(%ebp), %eax
EXIT_FN
calculate_f: #x
ENTER_FN
pushl 8(%ebp) # push x
movl $0xFFFFFFFF, %eax # replace by a
pushl %eax
movl $0xEEEEEEEE, %eax # replace by b
pushl %eax
movl $0xDDDDDDDD, %eax # replace by c
pushl %eax
movl $calculate_fabcx, %eax
call *%eax
popl %ecx
popl %ecx
popl %ecx
popl %ecx
EXIT_FN
.set calculate_f_len, . - calculate_f
generate_f: #a b c
ENTER_FN
#allocate memory
pushl $calculate_f_len
call malloc
popl %ecx
pushl $calculate_f_len
pushl $calculate_f
pushl %eax
call copy_bytes
popl %eax
popl %ecx
popl %ecx
movl %eax, %ecx
addl $7, %ecx
movl 8(%ebp), %edx
movl %edx, (%ecx)
addl $6, %ecx
movl 12(%ebp), %edx
movl %edx, (%ecx)
addl $6, %ecx
movl 16(%ebp), %edx
movl %edx, (%ecx)
EXIT_FN
format:
.ascii "%d\n\0"
main:
ENTER_FN
pushl $1601
pushl $-79
pushl $1
call generate_f
popl %ecx
popl %ecx
popl %ecx
pushl $42
call *%eax
popl %ecx
pushl %eax
pushl $format
call printf
popl %ecx
popl %ecx
movl $0, %eax
EXIT_FN
copy_bytes: #dest source length
ENTER_FN
subl $24, %esp
movl 8(%ebp), %ecx # dest
movl %ecx, -4(%ebp)
movl 12(%ebp), %ebx # source
movl %ebx, -8(%ebp)
movl 16(%ebp), %eax # length
movl %eax, -12(%ebp)
addl %eax, %ecx # last dest-byte
movl %ecx, -16(%ebp)
addl %eax, %edx # last source-byte
movl %ecx, -20(%ebp)
movl -4(%ebp), %eax
movl -8(%ebp), %ebx
movl -16(%ebp), %ecx
copy_bytes_2:
movb (%ebx), %dl
movb %dl, (%eax)
incl %eax
incl %ebx
cmp %eax, %ecx
jne copy_bytes_2
EXIT_FN
By coincidence, this thread fits perfectly to whan I am doing at the moment, namely, collecting implementations of Church Numerals in several languages (which is a similar problem, but slightly more complicated). I have already posted some (javascript, java, c++, haskell, etc.) on my Blog, for example here [1] and in older posts, just if somebody is interested in this (or has an additional implementation for me ^^).
[1] http://uxul.wordpress.com/2009/03/13/generating-church-numbers-with-tcl-sparc-assembly-and-x86-assembly/function quadratic (a, b, c)
return function (x)
return a*(x*x) + b*x + c
end
end
local f = quadratic (1, -79, 1601)
print (f(42))
The result:
47
Several other answers have further generalized the problem to cover all polynomials. Lua handles this case as well:
function polynomial (...)
local constants = {...}
return function (x)
local result = 0
for i,v in ipairs(constants) do
result = result + v*math.pow(x, #constants-i)
end
return result
end
end
#include <iostream>
class Quadratic
{
int a_,b_,c_;
public:
Quadratic(int a, int b, int c)
{
a_ = a;
b_ = b;
c_ = c;
}
int operator()(int x)
{
return a_*x*x + b_*x + c_;
}
}
int main()
{
Quadratic f(1,-79,1601);
std::cout << f(42);
return 0;
}
I don't actually have a compiler that supports this, so it could be (probably is) wrong.
auto quadratic = [](double a, double b, double c) {
return [=] (double x) { return a*x*x + b*x + c; };
};
auto f = quadratic(1, -79, 1601);
std::cout << f(42) << std::endl;
sub quadratic {
my ($a, $b, $c) = @_;
return sub {
my ($x) = @_;
return $a*($x*$x) + $b*$x + $c;
}
}
my $f = quadratic (1, -79, 1601);
print $f->(42);
function quadratic($a, $b, $c) {
return create_function('$x',
'return ' . $a . ' * ($x * $x) + ' . $b . ' * $x + ' . $c . ';'
);
}
$f = quadratic(1, -79, 1601);
echo $f(42) . "\n";
The result:
47
public Func<double, double> F(double a, double b, double c){
Func<double, double> ret = x => a * x * x + b * x + c;
return ret;
}
public void F2(){
var f1 = F(1, -79, 1601);
Console.WriteLine(f1(42));
}
In Python using only lambdas:
curry = lambda a, b, c: lambda x: a*x**2 + b*x + c
quad = curry(1, -79, 1601)
test :-
create_quadratic([1, -79, 1601], Quadratic),
evaluate(Quadratic, 42, Result),
writeln(Result).
create_quadratic([A, B, C], f(X, A * X**2 + B * X + C)).
evaluate(f(X, Expression), X, Result) :-
Result is Expression.
Testing:
?- test.
47
true.
let quadratic a b c = fun x -> a*x*x + b*x + c
but really, thanks to currying, the following is equivalent:
let quadratic a b c x = a*x*x + b*x + c
For compilation reasons, the first is actually better because the compiler wont need to call caml_applyX and caml_curryX. Read more here [1]
How about general polynomials (with floats)?
let polynomial coeff =
(fun x ->
snd (List.fold_right
(fun co (i,sum) ->
((i+.1.0), sum +. co *. (x ** i))) coeff (0.0,0.0))
)
[1] http://ocaml.janestreet.com/?q=node/30With the FFCALL [1] library installed,
#include <trampoline.h>
static struct quadratic_saved_args {
double a;
double b;
double c;
} *quadratic_saved_args;
static double quadratic_helper(double x) {
double a, b, c;
a = quadratic_saved_args->a;
b = quadratic_saved_args->b;
c = quadratic_saved_args->c;
return a*x*x + b*x + c;
}
double (*quadratic(double a, double b, double c))(double) {
struct quadratic_saved_args *args;
args = malloc(sizeof(*args));
args->a = a;
args->b = b;
args->c = c;
return alloc_trampoline(quadratic_helper, &quadratic_saved_args, args);
}
int main() {
double (*f)(double);
f = quadratic(1, -79, 1601);
printf("%g\n", f(42));
free(trampoline_data(f));
free_trampoline(f);
return 0;
}
[1] http://www.haible.de/bruno/packages-ffcall-README.htmlf
is a function pointer to some code that was dynamically allocated and generated by FFCALL. - ephemient
quadratic
is a function which returns a function pointer. - ephemient
(*quadratic(double a, double b, double c))(double)
- u0b34a0f6ae
def makeQuadratic(a: Int, b: Int, c: Int) = (x: Int) => a * x * x + b * x + c
val f = makeQuadratic(1, -79, 1601)
println(f(42))
Edit: Apparently, the above solution uses integer values instead of floating point values. To comply with the new requirements, makeQuadratic must be changed to:
def makeQuadratic(a: Float, b: Float, c: Float) =
(x: Float) => a * x * x + b * x + c
Smalltalk
A simple solution using a code block:
| quadratic f | quadratic := [:a :b :c | [:x | (a * x squared) + (b * x) + c]].
And to generate the function and call it:
f := quadratic value: 1 value: -79 value: 1601. f value: 42.
clang (LLVM's C compiler) has support for what they call blocks [1] (closures in C):
double (^quadratic(double a, double b, double c))(double) {
return _Block_copy(^double(double x) {return a*x*x + b*x + c;});
}
int main() {
double (^f)(double);
f = quadratic(1, -79, 1601);
printf("%g\n", (^f)(42));
_Block_release(f);
return 0;
}
At least, that's how it should work. I haven't tried it out myself.
[1] http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.htmlsub quadratic($a, $b, $c) { -> $x { $a*$x*$x + $b*$x + $c } }
my &f := quadratic(1, -79, 1601);
say f(42);
function quadratic(a,b,c) {
return function(x) {
return a*(x*x) + b*x + c;
}
}
var f = quadratic (1, -79, 1601);
f(42);
Using functional languages is just way too easy.
fun quadratic (a, b, c) = fn x => a*x*x + b*x + c : real;
val f = quadratic (1.0, ~79.0, 1601.0);
f 42.0;
[1] http://www.smlnj.org/PowerShell has a notion of ScriptBlock, which is like an anonymous method;
$quadratic = { process { $args[0]*($_*$_) + $args[1]*$_ + $args[2]; } }
42 | &$quadratic 1 (-79) 1601
47
[1] http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspxFor sheer perversity, using boost::mpl [1] to do it all at compile time...
(Floats aren't allowed as template arguments, so this is integers only.)
#include <boost/mpl/arithmetic.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/comparison.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/lambda.hpp>
#include <iostream>
using namespace boost::mpl;
// g returns a quadratic function f(x)=a*x^2+b*x+c
template <typename a,typename b,typename c> struct g
:lambda<
plus<
multiplies<a,multiplies<_1,_1> >,
plus<multiplies<b,_1>,c>
>
>{};
// f is the quadratic function with the coefficients specified
typedef g<int_<1>,int_<-79>,int_<1601> >::type f;
// Compute the required result
typedef f::apply<int_<42> >::type result;
// Check the result is as expected
// Change the int_<47> here and you'll get a compiler (not runtime!) error
struct check47 {
BOOST_MPL_ASSERT((equal_to<result,int_<47> >));
};
// Well if you really must see the result...
int main(int,char**) {
std::cout << result::value << std::endl;
}
(Works on Debian/Lenny's gcc+boost)
I'm not sure whether there's some way of getting the compiler to log out that the result is int_<47>
without triggering a compiler error message.
Just to emphasise the compile-time aspect: if you inspect the assembler you'll see
movl $47, 4(%esp)
movl std::cout, (%esp)
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
and you can plug result::value
into anywhere that needs a compile-time constant e.g 'C'-array dimensions, integer template arguments, explicit enum values...
Practical applications ? Hmmm...
[1] http://www.boost.org/doc/libs/1%5F38%5F0/libs/mpl/doc/index.htmlauto quadratic(float a, float b, float c) {
return delegate(float x) { return a * x * x + b * x + c; };
} // ^ optional
auto f = quadratic(1, -79, 1601);
writeln( f(42) );
Using an anonymous function
function f=quadratic(a,b,c)
% FUNCTION quadratic. returns an inline polynomial with coefficients a,b,c
f = @(x)a*x^2+b*x+c;
or using inline which is not as clean/concise
function f=quadratic2(a,b,c)
% FUNCTION quadratic. returns an inline polynomial with coefficients a,b,c
f = inline(['(',num2str(a),'*x^2)+(',num2str(b),'*x)+(',num2str(c),')'],'x');
Usage
>> ff = quadratic(1,-79,1601);
>> ff(42)
ans =
47
(Simpler version than ephemient's answer)
fun quadratic (a, b, c) x = a*x*x + b*x + c : real;
val f = quadratic (1.0, ~79.0, 1601.0);
f 42.0;
or
fun quadratic a b c x = a*x*x + b*x + c : real;
val f = quadratic 1.0 ~79.0 1601.0;
f 42.0;
(but I think the first version more closely matches what was requested)
This is a variant of what Azim [1] posted, which will allow you to create functions that do computations which are too complex to encompass in an anonymous function:
function f = quadratic(a,b,c)
f = @nested_fcn;
function value = nested_fcn(x)
value = a*x^2+b*x+c;
end
end
Usage:
fcn = quadratic(1,-79,1601);
fcn(42)
[1] http://stackoverflow.com/questions/644246/how-do-you-create-a-function-that-returns-a-function-in-your-language-of-choice/644280#644280quadratic[a_, b_, c_] := a #^2 + b # + c &
f = quadratic[1,-79,1601];
Print[f[42]];
47
Using a form of currying:
quad[a_, b_, c_][x_] := a x^2 + b x + c
f = quad[1, -79, 1601];
f[42]
47
Using pure functions:
f = Function[x, # x^2 + #2 x + #3] &;
g = f[1, -79, 1601];
g[42]
47
Generalization to arbitrary polynomials:
poly[a__]:= With[{n=Length@{a}},Evaluate[Table[#,{n}]^Reverse@Range[0,n-1].{a}]&]
poly[1,-79,1601][42]
47
C# 2.0
Create a delegate named QuadraticFormula with the following return type and parameter
delegate float QuadraticFormula(float x);
create static method named CreateFormula to return delegate QuadraticFormula
class Program
{
static void Main(string[] args)
{
QuadraticFormula formula = CreateFormula(1, 2, 1);
Console.WriteLine(formula(-1));
}
static QuadraticFormula CreateFormula(float a, float b, float c)
{
return delegate(float x)
{
return a * x * x + b * x + c;
};
}
}
CoffeeScript
quadratic = (a, b, c) -> (x) -> a * x * x + b * x + c
This is possible in Visual Basic .NET too.
Dim quadratic = Function (a As Double,b As Double,c As Double) _
Function(x As Double) (a * x * x) + (b * x) + c
Dim f = quadratic(1.0, -79.0, 1601.0)
f(42.0)
Alternate version:
sub fn {
my ( $aa, $bb, $cc ) = @_;
sub { $x = shift; $x = $x ** 2 * $aa + $x * $bb + $cc }
}
print fn( 1, -79, 1601 )->( 42 );
One could also actually store the generated function:
$f = fn( 1, -79, 1601 );
print $f->( 42 );
proc quadratic { a b c } {
set name "quadratic_${a}_${b}_${c}"
proc $name {x} "return \[expr ($a)*(\$x)*(\$x)+($b)*(\$x)+($c)\]"
return $name
}
Usage:
set f [quadratic 1 -79 1601]
$f 123
Notes:
{}
's, but to get variable substitution to work correctly, without going to a lot of trouble elsewhere, It's set here using "
's and abundant \
'sRHSeeger suggests a way to make the function construction a little easier, using [string map]
:
proc quadratic { a b c } {
set name "quadratic_${a}_${b}_${c}"
proc $name {x} [string map [list %A $a %B $b %C $c] {
return [expr {(%A * $x * $x) + (%B * $x) + %C}]
}]
return $name
}
Of course this can be used in the very same way. Tcl8.5 also has a way to apply a function to arguments without creating a named proc, by using the [apply]
command. It looks similar, again using the [string map]
method.
proc quadratic_lambda { a b c } {
return [list {x} [string map [list %A $a %B $b %C $c] {
return [expr {(%A * $x * $x) + (%B * $x) + %C}]
}]]
}
set f [quadratic_lambda 1 -79 1601]
apply $f 123
I've given this version a different name to emphasize that it works a little differently. Notice that it returns a list that looks similar to the arguments to a proc. Using [apply]
on this value is exactly equivalent to invoking a proc with args and body matching the first argument of the apply command with the rest of the apply command. The upside of this is that you don't polute any namespaces for one-off type procs. the downside is that it makes it just a little more tricky to use a proc that actually does exist.
ActionScript 2
function quadratic(a:Number, b:Number, c:Number):Function {
function r(x) {
var ret = a*(x*x)+b*x+c;
return ret;
}
return r;
}
var f = quadratic(1, -79, 1601);
trace(f(42));
Actionscript 2 or 3:
function findQuadradic( a:Number, b:number, c:Number ):Function
{
var func:Function = function( x:Number ){
return
a * Math.pow( x, 2 ) +
b * Math.pow( x, 1 ) + // TECHNICALLY more correct than * x.
c * Math.pow( x, 0 ); // TECHNICALLY more correct than * 1.
}
var quadFunc:Function = findQuadratic( 1, -79, 1601 );
trace( quadFunc( 42 ) );
More interestingly, you could do it another way:
function findExponential( ...a:Array ):Function{
// in AS2, replace this with findExponential():Function{
var args:Array = arguments.concat() // clone the arguments array.
var retFunc:Function = function( x:Number ):Number{
{
var retNum:Number = 0;
for( var i:Number = 0; i < args.length; i++ )
{
retNum += arg[ i ] * Math.pow( x, args.length - 1 - i );
}
return retNum
}
}
Now you could do:
var quad:Function = findExponential( 1, -79, 1601 );
return quad( 42 );
Or
var line:Function = findExponential( 1, -79 );
return line( 42 );
Here's a generalized version using Functional Java [1]. First import these:
import fj.F;
import fj.pre.Monoid;
import fj.data.Stream;
import static fj.data.Stream.iterate;
import static fj.data.Stream.zipWith;
import static fj.Function.compose;
And here's a generalized polynomials module:
public class Polynomials<A> {
private final Monoid<A> sum;
private final Monoid<A> mul;
private static <A> F<F<A, A>, Stream<A>> iterate(final A a) {
return new F<F<A, A>, Stream<A>>() {
public Stream<A> f(final F<A, A> f) {
return iterate(f, a);
}
}
}
private static <A> F<Stream<A>, A> zipWith(final F<A, F<A, A>> f,
final Stream<A> xs) {
return new F<Stream<A>, A>() {
public A f(final Stream<A> ys) {
return xs.zipWith(f, ys);
}
}
}
public Polynomials(final Monoid<A> sum, final Monoid<A> mul) {
this.sum = sum;
this.mul = mul;
}
public F<A, A> polynomial(final Stream<A> coeff) {
return new F<A, A>() {
public A f(final A x) {
return compose(sum.sumLeft(),
compose(zipWith(mul.sum(), coeff),
compose(iterate(1), mul)));
}
}
}
}
Example usage with integers:
import static fj.pre.Monoid.intAdditionMonoid;
import static fj.pre.Monoid.intMultiplicationMonoid;
import static fj.data.List.list;
...
Polynomials<Integer> p = new Polynomials<Integer>(intAdditionMonoid,
intMultiplicationMonoid);
F<Integer, Integer> f = p.polynomial(list(1601, -79, 1).toStream());
System.out.println(f.f(42));
[1] http://functionaljava.orgNasal [1] ( LGPL'ed scripting language for extension/embedded use [2])
var quadratic = func(a,b,c) {
func(x) {a* (x*x) +b*x +c} # implicitly returned to caller
}
var result=quadratic(1,-79,1601) (42);
print(result~"\n");
[1] http://www.plausible.org/nasalquadratic(){
eval "${quadratic:=f}(){ let r=${a:=1}*\$x*\$x+${b:=1}*\$x+${c:=1} ; echo \$r ; }"
}
To use it, you need to set a
, b
, and c
:
a=1; b=-79; c=1601; quadratic=f; quadratic
a=1; b=1; c=41; quadratic=g; quadratic
(The quadratic
function defaults to setting the constants to 1, but it's best not to rely on that.) Here's how to get the results:
$ x=42;f;g
47
1847
Tested with ksh
and bash
.
Note: fails the floating-point requirement. You could use bc
or some such in the body of the quadratic
function to implement it, but I don't think it would be worth the effort.
declare
fun {Quadratic A B C}
fun {$ X}
A*X*X + B*X + C
end
end
F = {Quadratic 1.0 ~79.0 1601.0}
in
{Show {F 42.0}}
I think it's interesting that Oz does not have special syntax for unnamed functions. Instead, it has a more general concept: The "nesting marker", which marks the return value of an expression by its position.
[1] http://www.mozart-oz.orgClojure
The first call creates a polynomial function by grouping multiplications, in the example (a x^2 + b x + c) => (((a) x + b) x + c) The second created the poly and evaluates it.
(defn polynomial [& a] #(reduce (fn[r ai] (+ (* r %) ai)) a))
((polynomial 1, -79, 1601 ) 42) ; => 47
function quadratic(a, b, c)
function(x)
a*(x*x) + b*x +c
quadratic <- function(a, b, c) {
function(x) a*x*x + b*x + c
}
f <- quadratic(1, -79, 1601)
g <- quadratic(1, 1, 41)
f(42)
g(42)
[1] http://www.r-project.org/With no named local variables (though you could use them if you want... :p).
/quadratic {[4 1 roll {3 index dup mul 4 3 roll mul add 3 1 roll mul add}
aload pop] cvx} def
/f 1 -79 1601 quadratic def
/g 1 1 41 quadratic def
42 f =
42 g =
Returns
47
1847
Of course, you don't need to name these functions either. Here's a completely anonymous version:
42 dup {[4 1 roll {3 index dup mul 4 3 roll mul add 3 1 roll mul add}
aload pop] cvx} exch 1 -79 1601 4 index exec exec = 1 1 41 4 3 roll exec exec =
Not perfect, but...
/* file "quad.c" */
static double _a, _b, _c;
typedef double(*fnptr)(double);
double quad_get(double x)
{
return _a * x * x + _b * x + _c;
}
fnptr quadratic(double a, double b, double c)
{
_a = a;
_b = b;
_c = c;
return &quad_get();
}
/* file "quad.h" */
typedef double(*fnptr)(double);
extern fnptr quadratic(double a, double b, double c);
/* file "main.c" */
#include <stdio.h>
#include "quad.h"
int main(void)
{
fnptr f = quadratic(1, -79, 1601);
printf("%lf\n", f(42));
return 0;
}