Return multiple values: Difference between revisions

From Rosetta Code
Content added Content deleted
(added haskell, ocaml, sml)
(added scheme)
Line 298: Line 298:
puts "33 + 12 = #{sum}"
puts "33 + 12 = #{sum}"
puts "33 - 12 = #{difference}"</lang>
puts "33 - 12 = #{difference}"</lang>

=={{header|Scheme}}==
Scheme can return multiple values using the <code>values</code> function, which uses continuations:
<lang scheme>(define (addsub x y)
(values (+ x y) (- x y)))</lang>

You can use the multiple values using the <code>call-with-values</code> function:
<lang scheme>(call-with-values
(lambda () (addsub 33 12))
(lambda (sum difference)
(display "33 + 12 = ") (display sum) (newline)
(display "33 - 12 = ") (display difference) (newline)))</lang>

The syntax is kinda awkward. SRFI 8 introduces a <code>receive</code> construct to make this simpler:
<lang scheme>(receive (sum difference) (addsub 33 12)
; in this scope you can use sum and difference
(display "33 + 12 = ") (display sum) (newline)
(display "33 - 12 = ") (display difference) (newline))</lang>

SRFI 11 introduces a <code>let-values</code> construct to make this simpler:
<lang scheme>(let-values (((sum difference) (addsub 33 12)))
; in this scope you can use sum and difference
(display "33 + 12 = ") (display sum) (newline)
(display "33 - 12 = ") (display difference) (newline))</lang>


=={{header|Standard ML}}==
=={{header|Standard ML}}==

Revision as of 06:47, 21 October 2011

Return multiple values is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Show how to return more than one value from a function.

C++

The new 2011 C++ standard includes tuples, which allow a number of different values of even different types to be passed around. <lang cpp>#include <algorithm>

  1. include <iostream>
  2. include <tr1/tuple>

std::tr1::tuple<const int , const int> minmax ( const int * numbers , const int num ) {

  const int *maximum = std::max_element ( numbers , numbers + num ) ;
  const int *minimum = std::min_element ( numbers , numbers + num ) ;
  std::tr1::tuple<const int , const int> result( *maximum , *minimum ) ;
  return result ;

}

int main( ) {

  const int numbers[ ] = { 17 , 88 , 9 , 33 , 4 , 987 , -10 , 2 } ;
  int numbersize = sizeof( numbers ) / sizeof ( int ) ;
  std::tr1::tuple<const int , const int> result = minmax( numbers , numbersize ) ;
  std::cout << "The greatest number is " << std::tr1::get<0>( result ) 
     << " , the smallest " << std::tr1::get<1>( result ) << " !\n" ;
  return 0 ;

}</lang> Output:

The greatest number is 987 , the smallest -10 !

Common Lisp

Besides the obvious method of passing around a list, Common Lisp also allows a function to return multiple values. When citing the return values, if no interest is shown for multiple values, only the first (the primary return value) is used. Multiple values are not a data structure such as a tuple, list or array. They are a true mechanism for returning multiple values.

Returning a single value is accomplished by evaluating an expression (which itself yields a single value) at the end of a body of forms.

<lang lisp>(defun return-three ()

 3)</lang>

The next possibility is that of returning no values at all. For this, the values function is used, with no arguments:

<lang lisp>(defun return-nothing ()

 (values))</lang>

To combine the values of multiple expressions into a multi-value return, values is used with arguments. The following is from an interactive CLISP session. CLISP's listener shows multiple values separated by a semicolon:

<lang lisp>[1]> (defun add-sub (x y) (values-list (list (+ x y) (- x y)))) ADD-SUB [2]> (add-sub 4 2)  ; 6 (primary) and 2 6 ; 2 [3]> (add-sub 3 1)  ; 4 (primary) and 2 4 ; 2 [4]> (+ (add-sub 4 2) (add-sub 3 1))  ; 6 + 4 10 [5]> (multiple-value-call #'+ (add-sub 4 2) (add-sub 3 1)) ; 6+2+4+2 14</lang>

What happens if something tries to use the value of a form which returned (values)? In this case the behavior defaults to taking the value nil:

<lang lisp>(car (values)) ;; no error: same as (car nil)</lang>

What if the values function is applied to some expressions which also yield multiple values, or which do not yield any values? The answer is that only the primary value is taken from each expression, or the value nil for any expression which did not yield a value:

<lang lisp>(values (values 1 2 3) (values) 'a)</lang>

yields three values:

-> 1; NIL; A

This also means that values can be used to reduce a multiple value to a single value:

<lang lisp>;; return exactly one value, no matter how many expr returns,

nil if expr returns no values

(values expr)</lang>

Multiple values are extracted in several ways.

1. Binding to variables:

<lang lisp>(multiple-value-bind (dividend remainder) (truncate 16 3)

 ;; in this scope dividend is 5; remainder is 1
 )</lang>

2. Conversion to a list:

<lang lisp>(multiple-value-list (truncate 16 3)) ;; yields (5 1)</lang>

3. Reification of multiple values as arguments to another function:

<lang lisp>;; pass arguments 5 1 to +, resulting in 6: (multiple-value-call #'+ (truncate 16 3))</lang>

4. Assignment to variables: <lang lisp>;; assign 5 to dividend, 1 to remainder: (multiple-value-setq (dividend remainder) (truncate 16 1))</lang> (values ...) syntax is treated as a multiple value place by setf and other operators, allowing the above to be expressed this way: <lang lisp>(setf (values dividend remainder) (truncate 16 1))</lang>

D

<lang d>import std.stdio, std.typecons;

auto addSub(T)(T x, T y) {

   return tuple(x + y, x - y);

}

void main() {

   auto r = addSub(33, 12);
   writefln("33 + 12 = %d\n33 - 12 = %d", r.tupleof);

}</lang> Output:

33 + 12 = 45
33 - 12 = 21

This pull request:

https://github.com/D-Programming-Language/dmd/pull/341

if accepted will allow nice tuple destructuring code like: <lang d>(auto m1, m2) = addSub(33, 12);</lang>

Factor

With stack-oriented languages like Factor, a function returns multiple values by pushing them on the data stack. For example, this word */ pushes both x*y and x/y.

<lang factor>USING: io kernel math prettyprint ; IN: script

*/ ( x y -- x*y x/y )
   [ * ] [ / ] 2bi ;

15 3 */

[ "15 * 3 = " write . ] [ "15 / 3 = " write . ] bi*</lang>

Its stack effect declares that */ always returns 2 values. To return a variable number of values, a word must bundle those values into a sequence (perhaps an array or vector). For example, factors (defined in math.primes.factors and demonstrated at Prime decomposition#Factor) returns a sequence of prime factors.

Go

Functions can return multiple values in Go:

<lang go>func addsub(x, y int) (int, int) {

 return x + y, x - y

}</lang>

Or equivalently using named return style:

<lang go>func addsub(x, y int) (sum, difference int) {

 sum = x + y
 difference = x - y
 return

}</lang>

When a function returns multiple values, you must assign to a comma-separated list of targets:

<lang go>sum, difference := addsub(33, 12) fmt.Printf("33 + 12 = %d\n", sum) fmt.Printf("33 - 12 = %d\n", difference)</lang>

Haskell

Every function returns one value. The conventional way to return multiple values is to return a tuple.

<lang haskell>addsub x y =

 (x + y, x - y)</lang>

You can use pattern matching to extract the components:

<lang haskell>main = do

 let sum, difference = addsub 33 12
 putStrLn $ "33 + 12 = " ++ show sum
 putStrLn $ "33 - 12 = " ++ show difference</lang>

Icon and Unicon

Icon and Unicon values range from simple atomic values like integers and strings to structures like lists, tables, sets, records. The contents of structures are heterogeneous and any of them could be used to return multiple values all at once. Additionally, generators are supported that return multiple results one at a time as needed.

The following examples return 1, 2, 3 in different ways:

<lang Icon>procedure retList() # returns as ordered list return [1,2,3] end

procedure retSet() # returns as un-ordered list insert(S := set(),3,1,2) return S end

procedure retLazy() # return as a generator suspend 1|2|3 end

procedure retTable() # return as a table T := table() T["A"] := 1 T["B"] := 2 T["C"] := 3 return T end

record retdata(a,b,c)

procedure retRecord() # return as a record, least general method return retdata(1,2,3) end</lang>

J

To return multiple values in J, you return an array which contains multiple values. Since the only data type in J is array, this is sort of like asking how to return only one value in another language.

<lang j> 1 2+3 4 4 6</lang>

OCaml

Every function returns one value. The conventional way to return multiple values is to return a tuple.

<lang ocaml>let addsub x y =

 x + y, x - y</lang>

(Note that parentheses are not necessary for a tuple literal in OCaml.)

You can use pattern matching to extract the components:

<lang ocaml>let sum, difference = addsub 33 12 in

 Printf.printf "33 + 12 = %d\n" sum;
 Printf.printf "33 - 12 = %d\n" difference</lang>

PARI/GP

The usual way to return multiple values is to put them in a vector: <lang parigp>foo(x)={

 [x^2, x^3]

};</lang>

PHP

Every function returns one value. The conventional way to return multiple values is to bundle them into an array.

<lang php>function addsub($x, $y) {

 return array($x + $y, $x - $y);

}</lang>

You can use the list() construct to assign to multiple variables:

<lang php>list($sum, $difference) = addsub(33, 12); echo "33 + 12 = $sum\n"; echo "33 - 12 = $difference\n";</lang>

PicoLisp

A PicoLisp function returns a single value. For multiple return values, a cons pair or a list may be used. <lang PicoLisp>(de addsub (X Y)

  (list (+ X Y) (- X Y)) )</lang>

Test: <lang PicoLisp>: (addsub 4 2) -> (6 2)

(addsub 3 1)

-> (4 2)

(+ (car (addsub 4 2)) (car (addsub 3 1)))

-> 10

(sum + (addsub 4 2) (addsub 3 1))

-> 14</lang>

Pike

multiple values are returned through an array. an array can be assigned to separate variables. <lang Pike>array(int) addsub(int x, int y) {

   return ({ x+y, x-y });

}

[int z, int w] = addsub(5,4);</lang>

Python

Every function returns one value. The conventional way to return multiple values is to bundle them into a tuple.

<lang python>def addsub(x, y):

 return x + y, x - y</lang>

(Note that parentheses are not necessary for a tuple literal in Python.)

You can assign to a comma-separated list of targets:

<lang python>sum, difference = addsub(33, 12) print "33 + 12 = %s" % sum print "33 - 12 = %s" % difference</lang>

Ruby

Every function returns one value. The conventional way to return multiple values is to bundle them into an Array.

Use an array literal:

<lang ruby>def addsub(x, y)

 [x + y, x - y]

end</lang>

Or use return with 2 or more values:

<lang ruby>def addsub(x, y)

 return x + y, x - y

end</lang>

(With at least 2 values, return makes a new Array. With 1 value, return passes the value, without making any Array. With 0 values, return passes nil.)

Assignment can split the Array into separate variables.

<lang ruby>sum, difference = addsub(33, 12) puts "33 + 12 = #{sum}" puts "33 - 12 = #{difference}"</lang>

Scheme

Scheme can return multiple values using the values function, which uses continuations: <lang scheme>(define (addsub x y)

 (values (+ x y) (- x y)))</lang>

You can use the multiple values using the call-with-values function: <lang scheme>(call-with-values

 (lambda () (addsub 33 12))
 (lambda (sum difference)
   (display "33 + 12 = ") (display sum) (newline)
   (display "33 - 12 = ") (display difference) (newline)))</lang>

The syntax is kinda awkward. SRFI 8 introduces a receive construct to make this simpler: <lang scheme>(receive (sum difference) (addsub 33 12)

 ; in this scope you can use sum and difference
 (display "33 + 12 = ") (display sum) (newline)
 (display "33 - 12 = ") (display difference) (newline))</lang>

SRFI 11 introduces a let-values construct to make this simpler: <lang scheme>(let-values (((sum difference) (addsub 33 12)))

 ; in this scope you can use sum and difference
 (display "33 + 12 = ") (display sum) (newline)
 (display "33 - 12 = ") (display difference) (newline))</lang>

Standard ML

Every function returns one value. The conventional way to return multiple values is to return a tuple.

<lang sml>fun addsub (x, y) =

 (x + y, x - y)</lang>

You can use pattern matching to extract the components:

<lang sml>let

 val (sum, difference) = addsub (33, 12)

in

 print ("33 + 12 = " ^ Int.toString sum ^ "\n");
 print ("33 - 12 = " ^ Int.toString difference ^ "\n")

end</lang>

Tcl

Tcl commands all return a single value, but this value can be a compound value such as a list or dictionary. The result value of a procedure is either the value given to the return command or the result of the final command in the body in the procedure. (Commands that return “no” value actually return the empty string.) <lang tcl>proc addsub {x y} {

   list [expr {$x+$y}] [expr {$x-$y}]

}</lang> This can be then assigned to a single variable with set or to multiple variables with lassign. <lang tcl>lassign [addsub 33 12] sum difference puts "33 + 12 = $sum, 33 - 12 = $difference"</lang>