First-class functions/Use numbers analogously

From Rosetta Code
Task
First-class functions/Use numbers analogously
You are encouraged to solve this task according to the task description, using any language you may know.

In First-class functions, a language is showing how its manipulation of functions is similar to its manipulation of other types.

This tasks aim is to compare and contrast a languages implementation of First class functions, with its normal handling of numbers.


Write a program to create an ordered collection of a mixture of literally typed and expressions producing a real number, together with another ordered collection of their multiplicative inverses. Try and use the following pseudo-code to generate the numbers for the ordered collections:

  x  = 2.0
  xi = 0.5
  y  = 4.0
  yi = 0.25
  z  = x + y
  zi = 1.0 / ( x + y )

Create a function multiplier, that given two numbers as arguments returns a function that when called with one argument, returns the result of multiplying the two arguments to the call to multiplier that created it and the argument in the call:

 new_function = multiplier(n1,n2)
 # where new_function(m) returns the result of n1 * n2 * m

Applying the multiplier of a number and its inverse from the two ordered collections of numbers in pairs, show that the result in each case is one.
Compare and contrast the resultant program with the corresponding entry in First-class functions. They should be close.

To paraphrase the task description: Do what was done before, but with numbers rather than functions

Common Lisp

<lang lisp>(defun multiplier (f g)

 #'(lambda (x) (* f g x)))

(let* ((x 2.0)

      (xi 0.5)
      (y 4.0)
      (yi 0.25)
      (z (+ x y))
      (zi (/ 1.0 (+ x y)))
      (numbers (list x y z))
      (inverses (list xi yi zi)))
 (loop with value = 0.5
       for number in numbers
       for inverse in inverses
       for multiplier = (multiplier number inverse)
       do (format t "~&(~A * ~A)(~A) = ~A~%"
                  number
                  inverse
                  value
                  (funcall multiplier value))))</lang>

Output:

(2.0 * 0.5)(0.5) = 0.5
(4.0 * 0.25)(0.5) = 0.5
(6.0 * 0.16666667)(0.5) = 0.5

The code from First-class functions, for comparison:

<lang lisp>(defun compose (f g) (lambda (x) (funcall f (funcall g x)))) (defun cube (x) (expt x 3)) (defun cube-root (x) (expt x (/ 3)))

(loop with value = 0.5

     for function in (list #'sin  #'cos  #'cube     )
     for inverse  in (list #'asin #'acos #'cube-root)
     for composed = (compose inverse function)
     do (format t "~&(~A ∘ ~A)(~A) = ~A~%"
                inverse
                function
                value 
                (funcall composed value)))</lang>

Output:

(#<FUNCTION ASIN> ∘ #<FUNCTION SIN>)(0.5) = 0.5
(#<FUNCTION ACOS> ∘ #<FUNCTION COS>)(0.5) = 0.5
(#<FUNCTION CUBE-ROOT> ∘ #<FUNCTION CUBE>)(0.5) = 0.5

E

This is written to have identical structure to First-class functions#E, though the variable names are different.

<lang e>def x := 2.0 def xi := 0.5 def y := 4.0 def yi := 0.25 def z := x + y def zi := 1.0 / (x + y) def forward := [x, y, z ] def reverse := [xi, yi, zi]

def multiplier(a, b) {

   return fn x { a * b * x }

}

def s := 0.5 for i => a in forward {

   def b := reverse[i]
   println(`s = $s, a = $a, b = $b, multiplier($a, $b)($s) = ${multiplier(a, b)(s)}`)

}</lang>

Output:

s = 0.5, a = 2.0, b = 0.5, multiplier(2.0, 0.5)(0.5) = 0.5
s = 0.5, a = 4.0, b = 0.25, multiplier(4.0, 0.25)(0.5) = 0.5
s = 0.5, a = 6.0, b = 0.16666666666666666, multiplier(6.0, 0.16666666666666666)(0.5) = 0.5

Note: def g := reverse[i] is needed here because E as yet has no defined protocol for iterating over collections in parallel. Page for this issue.

Haskell

<lang haskell>module Main

 where

import Text.Printf

-- Pseudo code happens to be valid Haskell x = 2.0 xi = 0.5 y = 4.0 yi = 0.25 z = x + y zi = 1.0 / ( x + y )

-- Multiplier function multiplier :: Double -> Double -> Double -> Double multiplier a b = \m -> a * b * m

main :: IO () main = do

 let
   numbers = [x, y, z]
   inverses = [xi, yi, zi]
   pairs = zip numbers inverses
   print_pair (number, inverse) =
     let new_function = multiplier number inverse
     in printf "%f * %f * 0.5 = %f\n" number inverse (new_function 0.5)
 mapM_ print_pair pairs

</lang>

This is very close to the first-class functions example, but given as a full Haskell program rather than an interactive session.

J

This seems to satisfy the current problem statement:

<lang j> multiplier=: conjunction def 'm * n * ]'</lang>

<lang j> 2 multiplier 0.5 (4) 4

  0.5 multiplier 4 (0.25)

0.5

  4 multiplier 0.25 (2+4)

6

  0.25 multiplier (2+4) (1%2+4)

0.25

  (2+4) multiplier (1%2+4) 2

2</lang>

J uses the concept of conjunctions to enable the composition of new verbs (functions). Conjunctions can link two verbs as in the First-class functions problem, analogous to the and in the phrase "cube and cuberoot". The First-class functions solution used the primitive conjunction @ to link two verbs to create a new verb. The solution here uses a user-defined conjunction multiplier that links two nouns (numbers in this case) to create a new verb - something like "multiply m and n by y" where m and n are the nouns immediately to the left and right of the conjunction.

OCaml

<lang ocaml># let x, xi, y, yi = 2.0, 0.5, 4.0, 0.25 ;;

  1. let z = x +. y
 and zi = 1.0 /. (x +. y) ;;
  1. let multiplier n1 n2 = (fun m -> n1 *. n2 *. m) ;;
  1. let numlist = [x; y; z]
 and numlisti = [xi; yi; zi] ;;
  1. List.map2 (fun n inv -> (multiplier n inv) 0.5) numlist numlisti ;;

- : float list = [0.5; 0.5; 0.5]</lang>

<lang ocaml># let cube = function x -> x *. x ;;

  1. let croot = function x -> x ** (1. /. 3.0) ;;
  1. let compose = fun f1 f2 -> (fun x -> f1(f2 x)) ;;
  1. let funclist = [sin; cos; cube]
 and funclisti = [asin; acos; croot] ;;
  1. List.map2 (fun inversef f -> (compose inversef f) 0.5) funclist funclisti ;;

- : float list = [0.5; 0.499999999999999889; 0.629960524947436706]</lang>

Python

This new task: <lang python>IDLE 2.6.1 >>> # Number literals >>> x,xi, y,yi = 2.0,0.5, 4.0,0.25 >>> # Numbers from calculation >>> z = x + y >>> zi = 1.0 / (x + y) >>> # The multiplier function is similar to 'compose' but with numbers >>> multiplier = lambda n1, n2: (lambda m: n1 * n2 * m) >>> # Numbers as members of collections >>> numlist = [x, y, z] >>> numlisti = [xi, yi, zi] >>> # Apply numbers from list >>> [multiplier(inversen, n)(.5) for n, inversen in zip(numlist, numlisti)] [0.5, 0.5, 0.5] >>></lang>

The Python solution to First-class functions for comparison: <lang python>>>> # Some built in functions and their inverses >>> from math import sin, cos, acos, asin >>> # Add a user defined function and its inverse >>> cube = lambda x: x * x * x >>> croot = lambda x: x ** (1/3.0) >>> # First class functions allow run-time creation of functions from functions >>> # return function compose(f,g)(x) == f(g(x)) >>> compose = lambda f1, f2: ( lambda x: f1(f2(x)) ) >>> # first class functions should be able to be members of collection types >>> funclist = [sin, cos, cube] >>> funclisti = [asin, acos, croot] >>> # Apply functions from lists as easily as integers >>> [compose(inversef, f)(.5) for f, inversef in zip(funclist, funclisti)] [0.5, 0.4999999999999999, 0.5] >>></lang> As can be see, the treatment of functions is very close to the treatment of numbers. there are no extra wrappers, or function pointer syntax added, for example.

Ruby

<lang ruby>multiplier = proc {|n1, n2| proc {|m| n1 * n2 * m}} numlist = [x=2, y=4, x+y] numlisti = [0.5, 0.25, 1.0/(x+y)] p numlist.zip(numlisti).map {|n,ni| multiplier.call(n,ni).call(0.5)}

  1. => [0.5, 0.5, 0.5]</lang>

This structure is identical to the treatment of Ruby's first class functions -- create a Proc object that returns a Proc object (a closure). We show that a number (or function) multiplied by its inverse (applied to its inverse function) multiplied by some number (passed some number as an argument) results in that number.

Scala

<lang scala>scala> val x = 2.0 x: Double = 2.0

scala> val xi = 0.5 xi: Double = 0.5

scala> val y = 4.0 y: Double = 4.0

scala> val yi = 0.25 yi: Double = 0.25

scala> val z = x + y z: Double = 6.0

scala> val zi = 1.0 / ( x + y ) zi: Double = 0.16666666666666666

scala> def multiplier(n1: Double, n2: Double) = (m: Double) => n1 * n2 * m multiplier: (n1: Double,n2: Double)(Double) => Double

scala> for {

    |   (number, inverse) <- numbers zip inverses
    |   new_function = multiplier(number, inverse)
    | } println("(%f * %f)(%f) = %f" format (number, inverse, 0.5, new_function(0.5)))

(2,000000 * 0,500000)(0,500000) = 0,500000 (4,000000 * 0,250000)(0,500000) = 0,500000 (6,000000 * 0,166667)(0,500000) = 0,500000</lang>

Scheme

This implementation closely follows the Scheme implementation of the First-class functions problem. <lang scheme>(define x 2.0) (define xi 0.5) (define y 4.0) (define yi 0.25) (define z (+ x y)) (define zi (/ (+ x y)))

(define number (list x y z)) (define inverse (list xi yi zi))

(define (multiplier n1 n2) (lambda (m) (* n1 n2 m)))

(define m 0.5) (define (go n1 n2)

 (if (not (or (null? n1)
              (null? n2)))
     (begin (display ((multiplier (car n1) (car n2)) m))
            (newline)
            (go (cdr n1) (cdr n2)))))

(go number inverse)</lang> Output:

0.5
0.5
0.5

Slate

<lang slate>define: #multiplier -> [| :n1 :n2 | [| :m | n1 * n2 * m]]. define: #x -> 2. define: #y -> 4. define: #numlist -> {x. y. x + y}. define: #numlisti -> (numlist collect: [| :x | 1.0 / x]).

numlist with: numlisti collect: [| :n1 :n2 | (multiplier applyTo: {n1. n2}) applyWith: 0.5].</lang>

Tcl

Works with: Tcl version 8.5

<lang tcl>package require Tcl 8.5 proc multiplier {a b} {

   list apply {{ab m} {expr {$ab*$m}}} [expr {$a*$b}]

}</lang> Note that, as with Tcl's solution for First-class functions, the resulting term must be expanded on application. For example, study this interactive session: <lang tcl>% set mult23 [multiplier 2 3] apply {{ab m} {expr {$ab*$m}}} 6 % {*}$mult23 5 30</lang> Formally, for the task: <lang tcl>set x 2.0 set xi 0.5 set y 4.0 set yi 0.25 set z [expr {$x + $y}] set zi [expr {1.0 / ( $x + $y )}] set numlist [list $x $y $z] set numlisti [list $xi $yi $zi] foreach a $numlist b $numlisti {

   puts [format "%g * %g * 0.5 = %g" $a $b [{*}[multiplier $a $b] 0.5]]

}</lang> Which produces this output:

2 * 0.5 * 0.5 = 0.5
4 * 0.25 * 0.5 = 0.5
6 * 0.166667 * 0.5 = 0.5

Ursala

The form is very similar to the first class functions task solution in Ursala, except that the multiplier function takes the place of the composition operator (+), and is named in compliance with the task specification. <lang Ursala>#import std

  1. import flo

numbers = <2.,4.,plus(2.,4.)> inverses = <0.5,0.25,div(1.,plus(2.,4.))>

multiplier = //times+ times

  1. cast %eL

main = (gang multiplier*p\numbers inverses) 0.5</lang> The multiplier could have been written in pattern matching form like this. <lang Ursala>multiplier("a","b") "c" = times(times("a","b"),"c")</lang> The main program might also have been written with an anonymous function like this. <lang Ursala>main = (gang (//times+ times)*p\numbers inverses) 0.5</lang> output:

<5.000000e-01,5.000000e-01,5.000000e-01>