First-class functions/Use numbers analogously: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added Nemerle)
Line 852: Line 852:
{{omit from|PureBasic}}
{{omit from|PureBasic}}
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}} <!-- Cannot do function composition. Function definitions are dynamic, but functions cannot be passed as values. -->
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}} <!-- Cannot do function composition. Function definitions are dynamic, but functions cannot be passed as values. -->

[[Category:Functions and subroutines]]

Revision as of 19:41, 15 July 2011

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

ALGOL 68

This example is incorrect. Please fix the code and remove this message.

Details: Compare and contrast the resultant program with the corresponding entry in First-class functions.

Translation of: python
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8-8d

Note: Standard ALGOL 68's scoping rules forbids exporting a proc[edure] (or format) out of it's scope (closure). Hence this specimen will run on ELLA ALGOL 68, but is non-standard. For a discussion of first-class functions in ALGOL 68 consult "The Making of Algol 68" - C.H.A. Koster (1993). <lang algol68>REAL

 x  := 2,
 xi := 0.5,
 y  := 4,
 yi := 0.25,
 z  := x + y,
 zi := 1 / ( x + y );

MODE F = PROC(REAL)REAL;

PROC multiplier = (REAL n1, n2)F: ((REAL m)REAL: n1 * n2 * m);

  1. Numbers as members of collections #

[]REAL num list = (x, y, z),

      inv num list = (xi, yi, zi);
  1. Apply numbers from list #

FOR key TO UPB num list DO

 REAL n = num list[key],
      inv n = inv num list[key];
 print ((multiplier(inv n, n)(.5), new line))

OD</lang> Output:

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

C#

Works with: C# version 4.0

The structure here is exactly the same as the C# entry in First-class functions. The "var" keyword allows us to use the same initialization code for an array of doubles as an array of functions. Note that variable names have been changed to correspond with the new functionality. <lang csharp>using System; using System.Linq;

class Program {

   static void Main(string[] args)
   {
       double x, xi, y, yi, z, zi;
       x = 2.0;
       xi = 0.5;
       y = 4.0;
       yi = 0.25;
       z = x + y;
       zi = 1.0 / (x + y);
       var numlist = new[] { x, y, z };
       var numlisti = new[] { xi, yi, zi };
       var multiplied = numlist.Zip(numlisti, (n1, n2) =>
                      {
                          Func<double, double> multiplier = m => n1 * n2 * m;
                          return multiplier;
                      });
       foreach (var multiplier in multiplied)
           Console.WriteLine(multiplier(0.5));
   }

} </lang>

Clojure

<lang clojure>(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 numbers [x y z]) (def invers [xi yi zi])

(defn multiplier [a b]

     (fn [m] (* a b m)))

> (for [[n i] (zipmap numbers invers)]

      ((multiplier n i) 0.5))

(0.5 0.5 0.5)</lang> For comparison: <lang clojure> (use 'clojure.contrib.math) (let [fns [#(Math/sin %) #(Math/cos %) (fn [x] (* x x x))]

     inv [#(Math/asin %) #(Math/acos %) #(expt % 1/3)]]
 (map #(% 0.5) (map #(comp %1 %2) fns inv)))

</lang> Output:

(0.5 0.4999999999999999 0.5000000000000001)

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

D

This example is incorrect. Please fix the code and remove this message.

Details: Compare and contrast the resultant program with the corresponding entry in First-class functions.

<lang d>import std.stdio: writefln;

void main() {

   auto x = 2.0;
   auto xi = 0.5;
   auto y = 4.0;
   auto yi = 0.25;
   auto z = x + y;
   auto zi = 1.0 / (x + y);
   auto multiplier = (double a, double b) {
       return (double m){ return a * b * m; };
   };
   auto forward = [x,  y,  z];
   auto reverse = [xi, yi, zi];
   foreach (i, a; forward) {
       auto b = reverse[i];
       writefln("%f * %f * 0.5 = %f", a, b, multiplier(a, b)(0.5));
   }

}</lang> Output:

2.000000 * 0.500000 * 0.5 = 0.500000
4.000000 * 0.250000 * 0.5 = 0.500000
6.000000 * 0.166667 * 0.5 = 0.500000

Alternative implementation (same output): <lang d>import std.stdio, std.range;

void main() {

 auto x = 2.0;
 auto xi = 0.5;
 auto y = 4.0;
 auto yi = 0.25;
 auto z = x + y;
 auto zi = 1.0 / (x + y);
 auto multiplier = (double a, double b) {
   return (double m){ return a * b * m; };
 };
 auto forward = [x,  y,  z];
 auto reverse = [xi, yi, zi];
 foreach (f; zip(forward, reverse))
   writefln("%f * %f * 0.5 = %f", f.at!0, f.at!1,
            multiplier(f.at!0, f.at!1)(.5));

}</lang>

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.

Factor

This example is incorrect. Please fix the code and remove this message.

Details: Compare and contrast the resultant program with the corresponding entry in First-class functions.

<lang factor> USING: arrays fry kernel math prettyprint sequences ; IN: hof CONSTANT: x 2.0 CONSTANT: xi 0.5 CONSTANT: y 4.0 CONSTANT: yi .25

z ( -- z )
   << x y + suffix! >> ; inline
zi ( -- zi )
   << 1 x y + / suffix! >> ; inline
numbers ( -- numbers )
   << x y z 3array suffix! >> ; inline
inverses ( -- inverses )
   << xi yi zi 3array suffix! >> ; inline

CONSTANT: m 0.5

multiplyer ( n1 n2 -- q )
   '[ _ _ * * ] ; inline
go ( n1 n2 -- )
   2dup [ empty? ] bi@ or not ! either empty
   [
       [ [ first ] bi@ multiplyer m swap call . ]
       [ [ rest-slice ] bi@ go ] 2bi
   ] [ 2drop ] if ;

</lang>

Fantom

<lang fantom> class Main {

 static |Float -> Float| combine (Float n1, Float n2)
 {
   return |Float m -> Float| { n1 * n2 * m }
 }
 public static Void main ()
 {
   Float x := 2f
   Float xi := 0.5f
   Float y := 4f
   Float yi := 0.25f
   Float z := x + y
   Float zi := 1 / (x + y)
   echo (combine(x, xi)(0.5f))
   echo (combine(y, yi)(0.5f))
   echo (combine(z, zi)(0.5f))
 }

} </lang>

The combine function is very similar to the compose function in 'First-class functions'. In both cases a new function is returned:

<lang fantom>

 static |Obj -> Obj| compose (|Obj -> Obj| fn1, |Obj -> Obj| fn2)
 {
   return |Obj x -> Obj| { fn2 (fn1 (x)) }
 }

</lang>

Go

"Number means value"

Task interpretation 1: "Number" means a numeric value, not any sort of reference. This is the most natural interpretation in Go.

At point A, the six variables have been assigned values, 64 bit floating point numbers, and not references to anything that is evaluated later. Again, at point B, these values have been copied into the array elements. (The arrays being "ordered collections.") The original six variables could be changed at this point and the array values would stay the same.

Multiplier multiplies pairs of values and binds the result to the returned closure. This might be considered a difference from the First-class functions task. In that task, the functions were composed into a new function but not evaluated at the time of composition. They could have been, but that is not the usual meaning of function composition.

This task however, works with numbers, which are not reference types. Specifically, the closure here could could have closed on n1 an n2 individually and delayed multiplication until closure evaluation, but that might seem inconsistent with the task interpretation of working with numbers as values. Also, one would expect that a function named "multiplier" does actually multiply.

Multiplier of this task and compose of the First-class function task are similar in that they both return first class function objects, which are closed on free variables. The free variables in compose held the two (unevaluated) functions being composed. The free variable in multiplier holds the result of multiplication.

At point C, numbers and their inverses have been multiplied and bound to first class functions. The ordered collection arrays could be modified at this point and the function objects would be unaffected.

<lang go>package main

import "fmt"

func main() {

   x := 2.
   xi := .5
   y := 4.
   yi := .25
   z := x + y
   zi := 1 / (x + y)
   // point A
   numbers := []float64{x, y, z}
   inverses := []float64{xi, yi, zi}
   // point B
   mfs := make([]func(float64) float64, len(numbers))
   for i := range mfs {
       mfs[i] = multiplier(numbers[i], inverses[i])
   }
   // point C
   for _, mf := range mfs {
       fmt.Println(mf(1))
   }

}

func multiplier(n1, n2 float64) func(float64) float64 {

   // compute product of n's, store in a new variable
   n1n2 := n1 * n2
   // close on variable containing product
   return func(m float64) float64 {
       return n1n2 * m
   }

}</lang> Output:

1
1
1

"Number means reference"

Task interpretation 2: "Number" means something abstract, evaluation of which is delayed as long as possible. This interpretation is suggested by the task wording that this program and and the corresponding First-class functions program "should be close" and "do what was done before...."

To implement this behavior, reference types are used for "numbers" and a polymorphic array is used for the ordered collection, allowing both static and computed objects to stored.

At point A, the variables z and zi are assigned function literals, first class function objects closed on x and y. Changing the values of x or y at this point will cause z and zi to return different results. The x and y in these function literals reference the same storage as the x and y assigned values 2 and 4. This is more like the the First-class functions task in that we now have functions which we can compose.

At point B, we have filled the polymorphic arrays with all reference types. References to numeric typed variables x, xi, y, and yi were created with the & operator. z and zi can already be considered reference types in that they reference x and y. Changes to any of x, xi, y, or yi at this point would still affect later results.

Multiplier, in this interpretation of the task, simply composes multiplication of three reference objects, which may be variables or functions. It does not actually multiply and does not even evaluate the three objects. This is very much like the compose function of the First-class functions task.

Pursuant to the task description, this version of multiplier "returns the result of n1 * n2 * m" in the sense that it sets up evaluation of n1, n2, and m to be done at the same time, even if that time is not quite yet.

At point C, changes to x, xi, y, and yi will still propagate through and affect the results returned by the mfs objects. This can be seen as like the First-class functions task in that nothing (nothing numberic anyway) is evaluated until the final composed objects are evaluated. <lang go>package main

import "fmt"

func main() {

   x := 2.
   xi := .5
   y := 4.
   yi := .25
   z := func() float64 { return x + y }
   zi := func() float64 { return 1 / (x + y) }
   // point A
   numbers := []interface{}{&x, &y, z}
   inverses := []interface{}{&xi, &yi, zi}
   // point B
   mfs := make([]func(n interface{}) float64, len(numbers))
   for i := range mfs {
       mfs[i] = multiplier(numbers[i], inverses[i])
   }
   // pointC
   for _, mf := range mfs {
       fmt.Println(mf(1.))
   }

}

func multiplier(n1, n2 interface{}) func(interface{}) float64 {

   return func(m interface{}) float64 {
       // close on interface objects n1, n2, and m
       return eval(n1) * eval(n2) * eval(m)
   }

}

// utility function for evaluating multiplier interface objects func eval(n interface{}) float64 {

   switch n.(type) {
   case float64:
       return n.(float64)
   case *float64:
       return *n.(*float64)
   case func() float64:
       return n.(func() float64)()
   }
   panic("unsupported multiplier type")
   return 0 // never reached

}</lang>

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 new problem statement:

<lang j> x =: 2.0

  xi         =:  0.5
  y          =:  4.0
  yi         =:  0.25
  z          =:  x + y
  zi         =:  1.0 % (x + y)  NB. / is spelled % in J
  fwd        =:  x ,y ,z
  rev        =:  xi,yi,zi
  multiplier =:  2 : 'm * n * ]'</lang>

Example use:

<lang> fwd multiplier rev 0.5 0.5 0.5 0.5</lang>

For contrast, here are the final results from First-class functions#J:

<lang> BA unqcol 0.5 0.5 0.5 0.5 0.5</lang>

Mathematica

This example is incorrect. Please fix the code and remove this message.

Details: Compare and contrast the resultant program with the corresponding entry in First-class functions.

<lang Mathematica>f[x_, y_] := x*y*# & f[a, b] x = 2; xi = 0.5; y = 4; yi = 0.25; z = x + y; zi = 1/(x + y); f[x, xi][0.5] f[y, yi][0.5] f[z, zi][0.5]</lang>

For example:

a b #1 &

0.5

0.5

0.5

Nemerle

Translation of: Python

<lang Nemerle>using System; using System.Console; using Nemerle.Collections.NCollectionsExtensions;

module FirstClassNums {

   Main() : void
   {
       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 multiplier = fun (a, b) {fun (c) {a * b * c}};
       def nums = [x, y, z];
       def inums = [xi, yi, zi];
       WriteLine($[multiplier(n, m) (0.5)|(n, m) in ZipLazy(nums, inums)]);
   }

}</lang>

OCaml

<lang ocaml># let x = 2.0;;

  1. let y = 4.0;;
  1. let z = x +. y;;
  1. let coll = [ x; y; z];;
  1. let inv_coll = List.map (fun x -> 1.0 /. x) coll;;
  1. let multiplier n1 n2 = (fun t -> n1 *. n2 *. t);;

(* create a list of new functions *)

  1. let func_list = List.map2 (fun n inv -> (multiplier n inv)) coll inv_coll;;
  1. List.map (fun f -> f 0.5) func_list;;

- : float list = [0.5; 0.5; 0.5]

(* or just apply the generated function immediately... *)

  1. List.map2 (fun n inv -> (multiplier n inv) 0.5) coll inv_coll;;

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

Oz

<lang oz>declare

 [X Y Z] = [2.0  4.0  Z=X+Y]
 [XI YI ZI] = [0.5  0.25  1.0/(X+Y)]
 fun {Multiplier A B}
    fun {$ M}
       A * B * M
    end
 end

in

 for
    N in [X  Y  Z]
    I in [XI YI ZI]
 do
    {Show {{Multiplier N I} 0.5}}
 end</lang>

"Multiplier" is like "Compose", but with multiplication instead of function application. Otherwise the code is identical except for the argument types (numbers instead of functions).

PARI/GP

Works with: PARI/GP version 2.4.2 and above

<lang parigp>multiplier(n1,n2)={

 x -> n1 * n2 * x

};

test()={

 my(x = 2.0, xi = 0.5, y = 4.0, yi = 0.25, z = x + y, zi = 1.0 / ( x + y ));
 print(multiplier(x,xi)(0.5));
 print(multiplier(y,yi)(0.5));
 print(multiplier(z,zi)(0.5));

};</lang> The two are very similar, though as requested the test numbers are in 6 variables instead of two vectors.

Perl 6

Works with: Rakudo version 2011.06

<lang perl6>sub multiplied ($g, $f) { return { $g * $f * $^x } }

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

my @numbers = $x, $y, $z; my @inverses = $xi, $yi, $zi;

for @numbers Z @inverses { say multiplied($^g, $^f)(.5) }</lang> Output:

0.5
0.5
0.5

The structure of this is identical to first-class function task.

PicoLisp

<lang PicoLisp>(load "@lib/math.l")

(de multiplier (N1 N2)

  (curry (N1 N2) (X)
     (*/ N1 N2 X `(* 1.0 1.0)) ) )

(let (X 2.0 Xi 0.5 Y 4.0 Yi 0.25 Z (+ X Y) Zi (*/ 1.0 1.0 Z))

  (mapc
     '((Num Inv)
        (prinl (format ((multiplier Inv Num) 0.5) *Scl)) )
     (list X Y Z)
     (list Xi Yi Zi) ) )</lang>

Output:

0.500000
0.500000
0.500001

This follows the same structure as First-class functions#PicoLisp, just that the function 'multiplier' above accepts two numbers, while 'compose' below accepts two functions: <lang PicoLisp>(load "@lib/math.l")

(de compose (F G)

  (curry (F G) (X)
     (F (G X)) ) )

(de cube (X)

  (pow X 3.0) )

(de cubeRoot (X)

  (pow X 0.3333333) )

(mapc

  '((Fun Inv)
     (prinl (format ((compose Inv Fun) 0.5) *Scl)) )
  '(sin  cos  cube)
  '(asin acos cubeRoot) )</lang>

With a similar output:

0.500001
0.499999
0.500000

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.

R

<lang R>multiplier <- function(n1,n2) { (function(m){n1*n2*m}) } x = 2.0 xi = 0.5 y = 4.0 yi = 0.25 z = x + y zi = 1.0 / ( x + y ) num = c(x,y,z) inv = c(xi,yi,zi)

multiplier(num,inv)(0.5)

Output [1] 0.5 0.5 0.5 </lang>

Compared to original first class functions <lang R>sapply(mapply(compose,f1,f2),do.call,list(.5)) [1] 0.5 0.5 0.5</lang>

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> val numbers = List(x, y, z) numbers: List[Double] = List(2.0, 4.0, 6.0)

scala> val inverses = List(xi, yi, zi) inverses: List[Double] = List(0.5, 0.25, 0.16666666666666666)

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

scala> def comp = numbers zip inverses map multiplier.tupled comp: List[(Double) => Double]

scala> comp.foreach(f=>println(f(0.5))) 0.5 0.5 0.5</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)

 (for-each (lambda (n1 n2)
             (display ((multiplier n1 n2) m))
             (newline))
           n1 n2))

(go number inverse)</lang> Output:

0.5
0.5
0.5

Slate

This example is incorrect. Please fix the code and remove this message.

Details: Compare and contrast the resultant program with the corresponding entry in First-class functions.

<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>