In a higher-order language, computation can produce not just scalar values, but also values with behavior. In other words, computations can compute computations. It’s a powerful idea, and higher-order programming languages are everywhere, but what do they look like? Here’s a classic example of a higher-order function, the derivative function, written in a bunch of different languages. In each example, I use the derivative function to compute a cosine function from a sine function.
(I know that even modern versions of Fortran have support for object and closures. If you speak Fortran and can translate the example, please let me know.)
Python:
from math import sin
e = 0.0001
# (ℝ → ℝ) → (ℝ → ℝ)
def deriv(f):
def fp(x):
return ((f(x+e) - f(x-e)) / (2*e));
return fp
print deriv(sin)(4)
JavaScript:
var ε = 0.0001;
// (ℝ → ℝ) → (ℝ → ℝ)
function deriv(f) {
return function (x) {
return (f(x+ε) - f(x-ε)) / (2*ε);
};
}
deriv(Math.sin)(4);
Ruby:
# -*- coding: utf-8 -*-
class Calculus
def e
0.0001
end
# (ℝ → ℝ) → (ℝ → ℝ)
def deriv(f)
fp = lambda { |x|
(f.call(x+e) - f.call(x-e)) / (2*e)
}
return fp
end
end
puts Calculus.new.deriv(lambda { |x| Math.sin(x) }).call(4)
Scala:
def ε = 0.0001
// (ℝ → ℝ) → (ℝ → ℝ)
def deriv(f: Double => Double) = {
def fp(x: Double) =
(f(x+ε) - f(x-ε)) / (2*ε)
fp _
}
object Main {
def main(args: Array[String]) {
println(deriv(math.sin)(4))
}
}
C#:
using System;
public class Calculus {
static double ε = 0.0001;
// (ℝ → ℝ) → (ℝ → ℝ)
static Func<double, double>
deriv(Func<double, double> f) {
return (x)
=> (f(x+ε) - f(x-ε)) / (2*ε);
}
static public void Main() {
Console.WriteLine(deriv(Math.Sin)(4));
}
}
Java:
interface Func<X,Y> {
Y apply(X x);
}
class Calculus {
Double ε = 0.0001;
// (ℝ → ℝ) → (ℝ → ℝ)
public Func<Double, Double>
deriv(final Func<Double, Double> f) {
return new Func<Double,Double>() {
public Double apply(Double x) {
return ((f.apply(x+ε) - f.apply(x-ε)) / (2*ε));
}
};
}
}
class Sin implements Func<Double, Double> {
public Double apply(Double x) {
return Math.sin(x);
}
}
class Main {
public static void main(String[] args) {
System.out.println(
new Calculus().deriv(new Sin()).apply(4d));
}
}
X10:
class Calculus {
val ε = 0.0001;
// (ℝ → ℝ) → (ℝ → ℝ)
def deriv(f: (Double) => Double) {
val fp = (x: Double) =>
(f(x+ε) - f(x-ε)) / (2*ε);
return fp;
}
}
public class Deriv {
public static def main(args: Array[String](1)) {
val cos = new Calculus().deriv((x: Double) => Math.sin(x));
x10.io.Console.OUT.println(cos(4.0));
}
}
Racket (thanks to Robby Findler):
#lang racket
(define ε 0.0001)
;; (ℝ → ℝ) → (ℝ → ℝ)
(define ((deriv f) x)
(/ (- (f (+ x ε))
(f (- x ε)))
(* 2 ε)))
((deriv sin) 4)
Post a Comment