Function composition

From Rosetta Code
Revision as of 21:11, 18 April 2009 by rosettacode>Kevin Reid (add E example)
Task
Function composition
You are encouraged to solve this task according to the task description, using any language you may know.

Create a function, compose, whose two arguments f and g, are both functions with one argument. The result of compose is to be a function of one argument, (lets call the argument x), which works like applying function f to the result of applying function g to x.

I.e:

 compose(f, g)(x) == f( g(x) )

Reference: Function composition

Hint: Implementing compose correctly requires creating a closure. If your language does not support closures directly, you will need to implement it yourself.

Ada

The interface of a generic functions package. The package can be instantiated with any type that has value semantics. Functions are composed using the operation '*'. The same operation applied to an argument evaluates it there: f * x. Functions can be composed with pointers to Ada functions. (In Ada functions are not first-class): <lang ada> generic

  type Argument is private;      

package Functions is

  type Primitive_Operation is not null
     access function (Value : Argument) return Argument;
  type Func (<>) is private;
  function "*" (Left : Func; Right : Argument) return Argument;
  function "*" (Left : Func; Right : Primitive_Operation) return Func;
  function "*" (Left, Right : Primitive_Operation) return Func;
  function "*" (Left, Right : Func) return Func;

private

  type Func is array (Positive range <>) of Primitive_Operation;

end Functions; </lang> Here is an implementation; <lang ada> package body Functions is

  function "*" (Left : Func; Right : Argument) return Argument is
  Result : Argument := Right;
  begin
     for I in reverse Left'Range loop
        Result := Left (I) (Result);
     end loop;
     return Result;
  end "*";
  function "*" (Left, Right : Func) return Func is
  begin
     return Left & Right;
  end "*";
  function "*" (Left : Func; Right : Primitive_Operation) return Func is
  begin
     return Left & (1 => Right);
  end "*";
  
  function "*" (Left, Right : Primitive_Operation) return Func is
  begin
     return (Left, Right);
  end "*";

end Functions; </lang> The following is an example of use: <lang ada> with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions; with Ada.Text_IO; use Ada.Text_IO; with Functions;

procedure Test_Compose is

  package Float_Functions is new Functions (Float);
  use Float_Functions;
  Sin_Arcsin : Func := Sin'Access * Arcsin'Access;

begin

  Put_Line (Float'Image (Sin_Arcsin * 0.5));

end Test_Compose; </lang> Sample output:

 5.00000E-01

ALGOL 68

Translation of: Python
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386

Note: Returning PROC (REAL x)REAL: f1(f2(x)) from a function apparently violates standard ALGOL 68's scoping rules. ALGOL 68G warns about this during parsing, and then rejects during runtime. <lang algol>MODE F = PROC(REAL)REAL; # ALGOL 68 is strong typed #

  1. As a procedure for real to real functions #

PROC compose = (F f, g)F: (REAL x)REAL: f(g(x));

OP (F,F)F O = compose; # or an OPerator that can be overloaded #

  1. Example use: #

F sin arc sin = compose(sin, arc sin); print((sin arc sin(0.5), (sin O arc sin)(0.5), new line))</lang> Output:

+.500000000000000e +0 +.500000000000000e +0

ALGOL 68 is a stack based language, and the following apparently does not violate it's scoping rules.

Works with: ALGOL 68 version Standard - Jan 1975 Boston SC allowed Partial Parametrization.
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386

<lang algol>MODE F = PROC(REAL)REAL; # ALGOL 68 is strong typed #

  1. As a procedure for real to real functions #

PROC compose = (F f, g)F: ((F f2, g2, REAL x)REAL: f2(g2(x)))(f, g, ); # Curry #

PRIO O = 7; OP (F,F)F O = compose; # or an OPerator that can be overloaded #

  1. Example use: #

F sin arc sin = compose(sin, arc sin); print((sin arc sin(0.5), (sin O arc sin)(0.5), new line))</lang>

C

Only works for functions taking a double and returning a double: <lang c>#include <stdlib.h>

/* generic interface for functors from double to double */ typedef struct double_to_double {

 double (*fn)(struct double_to_double *, double);

} double_to_double;

  1. define CALL(f, x) f->fn(f, x)


/* functor returned by compose */ typedef struct compose_functor {

 double (*fn)(struct compose_functor *, double);
 double_to_double *f;
 double_to_double *g;

} compose_functor; /* function to be used in "fn" in preceding functor */ double compose_call(compose_functor *this, double x) {

 return CALL(this->f, CALL(this->g, x));

} /* returns functor that is the composition of functors

  f & g. caller is responsible for deallocating memory */

double_to_double *compose(double_to_double *f,

                         double_to_double *g) {
 compose_functor *result = malloc(sizeof(compose_functor));
 result->fn = &compose_call;
 result->f = f;
 result->g = g;
 return (double_to_double *)result;

}


  1. include <math.h>

/* we can make functors for sin and asin by using

  the following as "fn" in a functor */

double sin_call(double_to_double *this, double x) {

 return sin(x);

} double asin_call(double_to_double *this, double x) {

 return asin(x);

}


  1. include <stdio.h>

int main() {

 double_to_double *my_sin = malloc(sizeof(double_to_double));
 my_sin->fn = &sin_call;
 double_to_double *my_asin = malloc(sizeof(double_to_double));
 my_asin->fn = &asin_call;
 double_to_double *sin_asin = compose(my_sin, my_asin);
 printf("%f\n", CALL(sin_asin, 0.5)); /* prints "0.500000" */
 free(sin_asin);
 free(my_sin);
 free(my_asin);
 return 0;

}</lang>

C++

Note: this is already implemented as __gnu_cxx::compose1() <lang cpp>#include <functional>

  1. include <cmath>
  2. include <iostream>

// functor class to be returned by compose function template <class Fun1, class Fun2> class compose_functor :

 public std::unary_function<typename Fun2::argument_type,
                            typename Fun1::result_type>

{ protected:

 Fun1 f;
 Fun2 g;

public:

 compose_functor(const Fun1& _f, const Fun2& _g)
   : f(_f), g(_g) { }
 typename Fun1::result_type
 operator()(const typename Fun2::argument_type& x) const
 { return f(g(x)); }

};

// we wrap it in a function so the compiler infers the template arguments // whereas if we used the class directly we would have to specify them explicitly template <class Fun1, class Fun2> inline compose_functor<Fun1, Fun2> compose(const Fun1& f, const Fun2& g) { return compose_functor<Fun1,Fun2>(f, g); }

int main() {

 std::cout << compose(std::ptr_fun(::sin), std::ptr_fun(::asin))(0.5) << std::endl;
 return 0;

}</lang>

Common Lisp

<lang lisp>(defun compose (f g) (lambda (x) (funcall f (funcall g x))))</lang> Example use: <lang lisp>>(defun compose (f g) (lambda (x) (funcall f (funcall g x)))) COMPOSE >(let ((sin-asin (compose #'sin #'asin))))

  (funcall sin-asin 0.5))

0.5</lang>

D

D 2.0 version of compose function (template). <lang D>

   import std.stdio;
   import std.math;
   T delegate(S) compose(T, U, S)(T delegate(U) f, U delegate(S) g) {
       return (S s) { return f(g(s)); };
   }

</lang>

Compose working both in D 1.0 and 2.0: <lang D>

   T delegate(S) compose(T, U, S)(T delegate(U) f, U delegate(S) g) {
       struct Wrapper {
           typeof(f) fcp;
           typeof(g) gcp;
           T foobar(S s) { return fcp(gcp(s)); }
       }
       Wrapper* hold = new Wrapper;
       hold.fcp = f;
       hold.gcp = g;
       return &hold.foobar;
   }

</lang>

E

def compose(f, g) {
  return fn x { return f(g(x)) }
}

Forth

<lang forth>

compose ( xt1 xt2 -- xt3 )
 >r >r :noname
    r> compile,
    r> compile,
    postpone ;

' 2* ' 1+ compose ( xt ) 3 swap execute . \ 7 </lang>

Haskell

This is already defined as the . (dot) operator in Haskell. <lang haskell>compose f g x = f (g x)</lang> Example use: <lang haskell>Prelude> let compose f g x = f (g x) Prelude> let sin_asin = compose sin asin Prelude> sin_asin 0.5 0.5</lang>

Java

<lang java>public class Compose {

   // Java doesn't have function type so we define an interface
   // of function objects instead
   public interface Fun<A,B> {
       B call(A x);
   }
   public static <A,B,C> Fun<A,C> compose(final Fun<B,C> f, final Fun<A,B> g) {
       return new Fun<A,C>() {
           public C call(A x) {
               return f.call(g.call(x));
           }
       };
   }
   public static void main(String[] args) {
       Fun<Double,Double> sin = new Fun<Double,Double>() {
           public Double call(Double x) {
               return Math.sin(x);
           }
       };
       Fun<Double,Double> asin = new Fun<Double,Double>() {
           public Double call(Double x) {
               return Math.asin(x);
           }
       };
       Fun<Double,Double> sin_asin = compose(sin, asin);
       System.out.println(sin_asin.call(0.5)); // prints "0.5"
   }

}</lang>

JavaScript

<lang javascript>

function compose(f, g) {
  return function(x) { return f(g(x)) }
}
var id = compose(Math.sin, Math.asin)
print id(0.5)   //  0.5

</lang>

Joy

Composition is the default operation in Joy. The composition of two functions is the concatenation of those functions, in the order in which they are to be applied. <lang joy>

g f

</lang>

Objective-C

The FunctionComposer is able to compose any object that conforms to the protocol FunctionCapsule (a selector/method accepting any object as argument and returning another object, i.e. computing a "function" of an object). A FunctionCaps class thought to encapsulate a function returning a double and with a double as argument is shown; anyway, as said, any object conforming to FunctionCapsule protocol can be composed with another object conforming to the same protocol. Argument passed and returned can be of any object type.

<lang objc>#include <Foundation/Foundation.h>

// the protocol of objects that can behave "like function" @protocol FunctionCapsule -(id)computeWith: (id)x; @end


// a commodity for "encapsulating" double f(double) typedef double (*func_t)(double); @interface FunctionCaps : NSObject <FunctionCapsule> {

 func_t function;

} +(id)capsuleFor: (func_t)f; -(id)initWithFunc: (func_t)f; @end

@implementation FunctionCaps -(id)initWithFunc: (func_t)f {

 self = [self init];
 function = f;
 return self;

} +(id)capsuleFor: (func_t)f {

 return [[[self alloc] initWithFunc: f] autorelease];

} -(id)computeWith: (id)x {

 return [NSNumber numberWithDouble: function([x doubleValue])];

} @end


// the "functions" composer @interface FunctionComposer : NSObject <FunctionCapsule> {

 id funcA;
 id funcB;

} +(id) createCompositeFunctionWith: (id)A and: (id)B; -(id) initComposing: (id)A with: (id)B; -(id) init; -(id) dealloc; @end

@implementation FunctionComposer +(id) createCompositeFunctionWith: (id)A and: (id)B {

 return [[[self alloc] initComposing: A with: B] autorelease];

}

-(id) init {

 NSLog(@"FunctionComposer: init with initComposing!");
 funcA = nil; funcB = nil;
 return self;

}

-(id) initComposing: (id)A with: (id)B {

 self = [super init];
 if ( ([A conformsToProtocol: @protocol(FunctionCapsule)] == YES) &&
      ([B conformsToProtocol: @protocol(FunctionCapsule)] == YES) ) {
   [A retain]; [B retain];
   funcA = A; funcB = B;
   return self;
 }
 NSLog(@"FunctionComposer: cannot compose functions not responding to protocol FunctionCapsule!");
 return nil;

}

-(id)computeWith: (id)x {

 return [funcA computeWith: [funcB computeWith: x]];

} @end

-(void) dealloc {

 [funcA release];
 [funcB release];
 [super dealloc];

}


// functions outside... double my_f(double x) {

 return x+1.0;

}

double my_g(double x) {

 return x*x;

}


int main() {

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 id funcf = [FunctionCaps capsuleFor: my_f];
 id funcg = [FunctionCaps capsuleFor: my_g];
 id composed = [FunctionComposer 

createCompositeFunctionWith: funcf and: funcg];

 printf("g(2.0) = %lf\n", [[funcg computeWith: [NSNumber numberWithDouble: 2.0]] doubleValue]);
 printf("f(2.0) = %lf\n", [[funcf computeWith: [NSNumber numberWithDouble: 2.0]] doubleValue]);
 printf("f(g(2.0)) = %lf\n", [[composed computeWith: [NSNumber numberWithDouble: 2.0]] doubleValue]);
 [pool release];
 return 0;

}</lang>

OCaml

<lang ocaml>let compose f g x = f (g x)</lang> Example use: <lang ocaml># let compose f g x = f (g x);; val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>

  1. let sin_asin = compose sin asin;;

val sin_asin : float -> float = <fun>

  1. sin_asin 0.5;;

- : float = 0.5</lang>

Octave

<lang octave>function r = compose(f, g)

 r = @(x) f(g(x));

endfunction

r = compose(@exp, @sin); r(pi/3)</lang>

Perl

<lang perl>sub compose

  {my ($f, $g) = @_;
   return sub {$f->($g->(@_))};}

use Math::Trig; print compose(sub {sin $_[0]}, \&asin)->(0.5), "\n";</lang>

Python

<lang python>compose = lambda f, g: lambda x: f( g(x) )</lang> Example use: <lang python>>>> compose = lambda f, g: lambda x: f( g(x) ) >>> from math import sin, asin >>> sin_asin = compose(sin, asin) >>> sin_asin(0.5) 0.5 >>> </lang>

Scheme

<lang scheme>(define (compose f g) (lambda (x) (f (g x))))</lang> Example use: <lang scheme>> (define (compose f g) (lambda (x) (f (g x)))) > (define sin_asin (compose sin asin)) > (sin_asin 0.5) 0.5</lang>

Smalltalk

<lang smalltalk>| composer fg | composer := [ :f :g | [ :x | f value: (g value: x) ] ]. fg := composer value: [ :x | x + 1 ]

              value: [ :x | x * x ].

(fg value:3) displayNl.</lang>

Standard ML

This is already defined as the o operator in Standard ML. <lang sml>fun compose (f, g) x = f (g x)</lang> Example use: <lang sml>- fun compose (f, g) x = f (g x); val compose = fn : ('a -> 'b) * ('c -> 'a) -> 'c -> 'b - val sin_asin = compose (Math.sin, Math.asin); val sin_asin = fn : real -> real - sin_asin 0.5; val it = 0.5 : real</lang>

Tcl

Works with: Tcl version 8.5

Create a compose procedure that returns an anonymous function. Then use the apply command to apply the function to the argument x <lang tcl>package require Tcl 8.5 namespace path {::tcl::mathfunc}

proc compose {f g} {

   return [list x [subst -nocommands {$f [$g [set x]]}]]

}

set sin_asin [compose sin asin] apply $sin_asin 0.5 ;# ==> 0.5 apply [compose abs int] -3.14 ;# ==> 3</lang>