Generic swap: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 573: Line 573:
===Built in function===
===Built in function===
<lang PureBasic>Swap a, b</lang>
<lang PureBasic>Swap a, b</lang>

===Generic function===
<lang PureBasic>
If OpenConsole()
Define temporary_var
a=1
b=2
Print("a="+Str(a)+", b="+Str(b)+#CRLF$)
temporary_var=a
a=b
b=temporary_var
Print("a="+Str(a)+", b="+Str(b)+#CRLF$)
CloseConsole()
EndIf</lang>


=={{header|Python}}==
=={{header|Python}}==

Revision as of 05:10, 27 February 2010

Task
Generic swap
You are encouraged to solve this task according to the task description, using any language you may know.

Many statically typed languages provide a generic programming capability. In C++ this capability is called templates. In Ada it is called generics. Such generic capabilities are simply the natural approach to programming for dynamically typed languages.

This task asks you to create a generic swap method that can be used for a wide variety of data types. If your solution language is statically typed please describe the way your language provides genericity. (This is actually a simple example of Parametric Polymorphism)

Ada

The generic parameters for an Ada generic procedure are defined in a procedure specification, while the algorithm is defined in a procedure body. The first code snippet is the procedure instantiation. The second code snippet is the procedure body.

<lang ada>generic

  type Swap_Type is private; -- Generic parameter

procedure Generic_Swap(Left : in out Swap_Type; Right : in out Swap_Type);

procedure Generic_Swap(Left : in out Swap_Type; Right : in out Swap_Type) is

  Temp : Swap_Type := Left;

begin

  Left := Right;
  Right := Temp;

end Generic_Swap;</lang>

AmigaE

The simpler way to write a swap is to use the Amiga E ability to return multiple values. All basic data type in Amiga E can be held by its LONG type, and complex data type (like lists) are indeed pointers (which fits into a LONG too); so, because of the fact that Amiga E is not strongly typed, this solution works for any type. <lang amigae>PROC swap(a,b) IS b,a

PROC main()

 DEF v1, v2, x
 v1 := 10
 v2 := 20
 v1, v2 := swap(v1,v2)
 WriteF('\d \d\n', v1,v2)           -> 20 10
 v1 := [ 10, 20, 30, 40 ]
 v2 := [ 50, 60, 70, 80 ]
 v1, v2 := swap(v1,v2)
 ForAll({x}, v1, `WriteF('\d ',x))  -> 50 60 70 80
 WriteF('\n')
 ForAll({x}, v2, `WriteF('\d ',x))  -> 10 20 30 40
 WriteF('\n')

ENDPROC</lang>

AppleScript

AppleScript has built-in support for swapping. This is generic and works for all combinations of data types. <lang AppleScript>set {x,y} to {y,x}</lang>

AutoHotkey

<lang autohotkey>Swap(ByRef Left, ByRef Right) {

   temp := Left
   Left := Right
   Right := temp

}</lang>

C

This has a restriction that a and b must be the same size. I think you could do better with preprocessor voodoo, but I am not enlightened enough to use it. I'm being cute here, so please don't hate me too much, and if a C guru could check it, I'd appreciate it (I tried it and it worked for me). It won't work for something like a linked list if you want all references to middle nodes to be translated, but it'll swap the heads just fine.

<lang c>void swap(void *a, void *b, size_t size) {

 char *ca, *cb;
 int i;
 ca = (char *)a;
 cb = (char *)b;
 for(i=0;i<size;*(ca+i)^=*(cb+i),*(cb+i)^=*(ca+i),*(ca+i)^=*(cb+i),++i);

}</lang>

You could also do it with a third buffer but then it wouldn't work for extremely large void pointers. It'd be faster to use a larger pointer than char *, but I wanted to keep it simple.

Another maybe better way is to use preprocessor macros and __typeof__ (supported by C89 at least)

<lang c>#define Swap(X,Y) do{ __typeof__ (X) _T = X; X = Y; Y = _T; }while(0)</lang>

Usage examples are:

<lang c>#include <stdio.h>

  1. define Swap(X,Y) do{ __typeof__ (X) _T = X; X = Y; Y = _T; }while(0)

struct test {

 int a, b, c;

};


int main() {

 struct test t = { 1, 2, 3 };
 struct test h = { 4, 5, 6 };
 double alfa = 0.45, omega = 9.98;
 
 struct test *pt = &t;
 struct test *th = &h;
 
 printf("%d %d %d\n", t.a, t.b, t.c );
 Swap(t, h);
 printf("%d %d %d\n", t.a, t.b, t.c );
 printf("%d %d %d\n", h.a, h.b, h.c );
 
 printf("%lf\n", alfa);
 Swap(alfa, omega);
 printf("%lf\n", alfa);
 
 printf("%d\n", pt->a);
 Swap(pt, th);
 printf("%d\n", pt->a);

}</lang>

This is tested with GCC with -std=c89 option.

C++

Generic programming in C++ is provided through templates. Templates in C++ are quite powerful: They form a Turing-complete compile-time sub-language. However, that power isn't needed for swap. Note that the C++ standard library already provides a swap function which contains optimized implementations for standard library types; thus it's advisable to use that instead of a self-written variant like the one below.

While the standard allows to separate declaration and definition of templates into different files using the export keyword, most compilers (including the most used ones) don't implement that. Therefore in practice, templates declared in header files also have to be defined there.

The implementation of the swap function template is straightforward:

<lang cpp>template<typename T> void swap(T& left, T& right) {

 T tmp(left);
 left = right;
 right = tmp;

}</lang> Note that this function requires that the type T has an accessible copy constructor and assignment operator.

C#

Works with: C# version 2.0+

C# 2.0 introduced the concept of generics to the language. Generics are outwardly similar to C++ templates, but are implemented quite differently: generics are maintained generically at runtime rather than being substitued with definite types by the compiler. Generics are intended to promote reusable, efficient, type-safe code, and are used widely throughout the .NET framework and 3rd party libraries, especially in collections. C# generics are less flexible than C++ templates, but are more strongly typed and arguably easier to deal with.

<lang csharp>static void Swap<T>(ref T a, ref T b) {

   T temp = a;
   a = b;
   b = temp;

}</lang>

Clojure

<lang lisp> (defn swap [pair] (reverse pair))  ; returns a list (defn swap a b '(b a))  ; returns a list (defn swap a b [b a])  ; returns a vector </lang>

The latter two implementations use destructured binding to define local names for the two elements.

ColdFusion

This is another standard swap.

<lang cfm><cfset temp = a /> <cfset a = b /> <cfset b = temp /></lang>

D

The solution for D is quite similar to that for C++:

<lang d>void swap(T)(ref T left, ref T right) {

 auto temp = left;
 left = right;
 right = temp;

}</lang>

dc

We use two registers to swap in POSIX dc. <lang dc>1 2 sa sb la lb f =2 1</lang> Reverse (r) is a built-in stack command available as a GNU extension for dc. <lang dc>1 2 r f =2 1</lang>

Common Lisp

<lang lisp>(rotatef a b)

(psetq a b b a)</lang>

E

(slots)

<lang e>def swap(&left, &right) {

 def t := left
 left := right
 right := t

}</lang>

(functional)

<lang e>def swap([left, right]) {

 return [right, left]

}</lang>

F#

<lang fsharp>let swap (a,b) = (b,a)</lang>

Falcon

<lang falcon> a = 1 b = 2 a,b = arr = b,a </lang> Reading right to left: Assign b & a into an array variable called arr, then assign into a & b

Fortran

Works with: Fortran version 90 and later

<lang fortran>MODULE Genericswap

 IMPLICIT NONE
 INTERFACE Swap
   MODULE PROCEDURE Swapint, Swapreal, Swapstring
 END INTERFACE

CONTAINS

 SUBROUTINE Swapint(a, b)
   INTEGER, INTENT(IN OUT) :: a, b
   INTEGER :: temp
   temp = a ; a = b ; b = temp
 END SUBROUTINE Swapint
 SUBROUTINE Swapreal(a, b)
   REAL, INTENT(IN OUT) :: a, b
   REAL :: temp
   temp = a ; a = b ; b = temp
 END SUBROUTINE Swapreal
 SUBROUTINE Swapstring(a, b)
   CHARACTER(*), INTENT(IN OUT) :: a, b
   CHARACTER(len(a)) :: temp
   temp = a ; a = b ; b = temp
 END SUBROUTINE Swapstring

END MODULE Genericswap

PROGRAM EXAMPLE

 USE Genericswap
 IMPLICIT NONE
 INTEGER :: i1 = 1, i2 = 2
 REAL :: r1 = 1.0, r2 = 2.0
 CHARACTER(3) :: s1="abc", s2="xyz"
 CALL Swap(i1, i2)
 CALL Swap(r1, r2)
 CALL Swap(s1, s2)
 WRITE(*,*) i1, i2   ! Prints 2 and 1
 WRITE(*,*) r1, r2   ! Prints 2.0 and 1.0
 WRITE(*,*) s1, s2   ! Prints xyz and abc

END PROGRAM EXAMPLE</lang>

Groovy

Groovy has support for swapping built in:

<lang groovy>(a, b) = [b, a]</lang>

But the task calls for a "generic swap method" to be written, so here it is:

<lang groovy>def swap(a, b) {

   [b, a]

}</lang> This function doesn't mutate anything, but simply returns a new list with the order of the elements switched. It can be used like shown below: <lang groovy>def (x, y) = swap(1, 3) assert x == 3 assert y == 1</lang>

Haskell

Like everything else in Haskell, tuples are immutable. This function doesn't mutate anything, but simply returns a new pair with the order of the elements switched.

The type signature, the first line, is optional; it may be inferred.

<lang haskell>swap :: (a, b) -> (b, a) swap (x, y) = (y, x)</lang>

Icon

Icon provides :=: operator for this.

<lang icon>procedure main()

  local x, y, v
  v := create(1 to 2)
  every (x | y) := @v
  write(x," ",y)
  x :=: y
  write(x," ",y)

end</lang>

J

J is dynamically typed and J's cycle primitive (C.) will swap elements of an arbitrary list. See also J's reference documentation on C.

Shown here are a list of prime numbers and the result of J's parser on some random text (inverting the parsing process on the swapped result):

<lang J> (<2 4) C. 2 3 5 7 11 13 17 19 2 3 11 7 5 13 17 19

  (<0 3)&C.&.;:'Roses are red. Violets are blue.'

Violets are red. Roses are blue.</lang>

Also, if the argument list can be guaranteed to be a pair, J's reverse primitive will swap the pair.

<lang J> |.2 3 3 2

  |.&.;:'one two'

two one</lang>

Java

Works with: Java version 1.5+

<lang java>class Pair<T> {

   T first;
   T second;

} public static <T> void swap(Pair<T> p) {

  T temp = p.first;
  p.first = p.second;
  p.second = temp;

}</lang>

JavaScript

JavaScript uses references, but if a function reassigns a parametric reference, the new object only has a local reference. However, if we wrap the variables to be switched in some other structure, like an object or an array, we can easily swap the values.

There's no actual "generics", since all variables are just that, variables of some kind.

The below function expects an array of length 2 (or longer), and switches the first two values in place, in the same array. This is closely related to how the Java solution works.

<lang javascript>function swap(arr) {

 var tmp = arr[0];
 arr[0] = arr[1];
 arr[1] = tmp;

}</lang>

Joy

Provided that the stack contains at least two elements and/or aggregates: <lang joy>swap</lang> changes the order of those elements and/or aggregates.

Lisaac

<lang Lisaac>(a, b) := (b, a);</lang>

<lang logo> to swap :s1 :s2

 localmake "t thing :s1
 make :s1 thing :s2
 make :s2 :t

end

make "a 4 make "b "dog swap "a "b  ; pass the names of the variables to swap show list :a :b  ; [dog 4] </lang>


Lua

References to the global table can be used to swap variables: <lang lua> function swap(v, u)

 local t = _G[u]
 _G[u] = _G[v]
 _G[v] = t

end

a, b = 3, 4 print(a, b) swap("a", "b") print(a, b) </lang>

M4

<lang m4>define(`def2', `define(`$1',`$2')define(`$3',`$4')')dnl define(`swap', `def2(`$1',defn(`$2'),`$2',defn(`$1'))')dnl dnl define(`a',`x')dnl define(`b',`y')dnl a b swap(`a',`b') a b</lang>

Output:

x y

y x

Mathematica

Mathematica functions are generic by default; however, it has to be told not to evaluate the arguments before executing the function. <lang mathematica>swap[a_, b_] := {a, b} = {b, a} SetAttributes[swap, HoldAll]</lang>

MAXScript

<lang maxscript>swap a b</lang>

Metafont

In Metafont, only numeric declarations can be omitted; any other type, must be explicitly given. So our swap, in order to declare and use a proper temporary variable(? in this code), must check the type of the variable passed (we check only for a; if b is of another kind, an error will occur)

<lang metafont>vardef swap(suffix a, b) =

 save ?; string s_;
 if boolean a: boolean ?
   elseif numeric a: numeric ? % this one could be omitted
   elseif pair a: pair ?
   elseif path a: path ?
   elseif pen a: pen ?
   elseif picture a: picture ?
   elseif string a: string ?
   elseif transform a: transform ? fi;
 ? := a; a := b; b := ?

enddef;</lang>

Examples:

<lang metafont>j := 10; i := 5; show j, i; swap(j,i); show j, i;

boolean truth[]; truth1 := true; truth2 := false; show truth1, truth2; swap(truth1,truth2); show truth1, truth2;</lang>

Modula-3

<lang modula3>GENERIC INTERFACE GenericSwap(Elem);

PROCEDURE Swap(VAR left: Elem.T; VAR right: Elem.T);

END GenericSwap.</lang> <lang modula3>GENERIC MODULE GenericSwap(Elem);

PROCEDURE Swap(VAR left: Elem.T; VAR right: Elem.T) =

 VAR temp: Elem.T := left;
 BEGIN
   left := right;
   right := temp;
 END Swap;

BEGIN END GenericSwap.</lang>

Here is an example usage for integers: <lang modula3>INTERFACE IntSwap = GenericSwap(Integer) END IntSwap.</lang> <lang modula3>MODULE IntSwap = GenericSwap(Integer) END IntSwap.</lang> <lang modula3>MODULE Main;

IMPORT IntSwap, IO, Fmt;

VAR left := 10;

   right := 20;

BEGIN

 IO.Put("Left = " & Fmt.Int(left) & "\n");
 IntSwap.Swap(left, right);
 IO.Put("Left = " & Fmt.Int(left) & "\n");

END Main.</lang>

Output:

Left = 10
Left = 20

Nial

Like J <lang nial>|reverse 1 2 =2 1</lang>

OCaml

Tuples are immutable in OCaml. This function doesn't mutate anything, but simply returns a new pair with the order of the elements switched. <lang ocaml>let swap (x, y) = (y, x)</lang> If the arguments are constrained to be reference values, a swap function is simple: <lang ocaml>let swapref x y =

 let temp = !x in
   x := !y;
   y := temp</lang>

Octave

GNU Octave has no way to pass a value by reference to a function; so to define a swap we must do as follow:

<lang octave>function [a, b] = swap(ia, ib)

 a = ib; b = ia;

endfunction

% testing va = 2; vb = 5; printf("%d %d\n", va, vb); [va, vb] = swap(va, vb); printf("%d %d\n", va, vb);</lang>

Oz

Oz variables are dataflow variables and cannot be changed once a value has been assigned. So a swap operation on dataflow variables does not make sense.

We can write a swap procedure for cells, though. Cells are mutable references. <lang oz> proc {SwapCells A B}

    Tmp = @A
 in
    A := @B
    B := Tmp
 end</lang>

Or shorter, if we exploit the fact that the assignment operator := returns the old value of the cells: <lang oz> proc {SwapCells A B}

    B := A := @B
 end</lang>

A functional swap, operating on pairs: <lang oz> fun {SwapPair A#B}

    B#A
 end</lang>

Perl

Perl has support for swapping built-in

<lang perl>($y, $x) = ($x, $y);</lang>

Here's a generic swap routine:

<lang perl>sub swap {@_[0, 1] = @_[1, 0]}</lang>

Perl 6

As Perl 5. Perl 6 supports type constraints for variables and subroutines, unlike Perl 5, but the default is still to permit all values.

PHP

<lang php>function swap(&$a, &$b) {

   list($a, $b) = array($b, $a);

}</lang>

PicoLisp

xchg works with any data type <lang PicoLisp>(let (A 1 B 2)

  (xchg 'A 'B)
  (println A B) )

(let (Lst1 '(a b c) Lst2 '(d e f))

  (xchg (cdr Lst1) (cdr Lst2))
  (println Lst1 Lst2) )</lang>

Output:

2 1
(a e c) (d b f)

Pop11

Swap is easily done via multiple assignment:

<lang pop11>(a, b) -> (b, a);</lang>

Pop11 is dynamically typed, so the code above is "generic".

PowerShell

PowerShell allows swapping directly, through tuple assignment: <lang powershell>$b, $a = $a, $b</lang> But one can also define a function which swaps the values of two references: <lang powershell>function swap ([ref] $a, [ref] $b) {

   $a.Value, $b.Value = $b.Value, $a.Value

}</lang> When using this function the arguments have to be explicitly given as references: <lang powershell>swap ([ref] $a) ([ref] $b)</lang>


Prolog

<lang prolog> swap(A,B,B,A).

?- swap(1,2,X,Y). X = 2, Y = 1. </lang>

PureBasic

Works with: PureBasic version 4.4.1

Built in function

<lang PureBasic>Swap a, b</lang>

Python

Python has support for swapping built in:

<lang python>a, b = b, a</lang>

But the task calls for a "generic swap method" to be written, so here it is:

<lang python>def swap(a, b):

   return b, a</lang>

Note that tuples are immutable in Python. This function doesn't mutate anything, but simply returns a new pair with the order of the elements switched.

REBOL

<lang REBOL>REBOL [ Title: "Generic Swap" Author: oofoe Date: 2009-12-06 URL: http://rosettacode.org/wiki/Generic_swap Reference: [1] ]

swap: func [ "Swap contents of variables." a [word!] b [word!] /local x ][ x: get a set a get b set b x ]

answer: 42 ship: "Heart of Gold" swap 'answer 'ship ; Note quoted variables. print rejoin ["The answer is " answer ", the ship is " ship "."]</lang>

Output:

The answer is Heart of Gold, the ship is 42.

Ruby

Ruby has support for swapping built in:

<lang ruby>a, b = b, a</lang>

But the task calls for a "generic swap method" to be written, so here it is:

<lang ruby>def swap(a, b)

   return b, a

end</lang> This function doesn't mutate anything, but simply returns a new array with the order of the elements switched.

Scala

Scala has type parameters and abstract types (not to be confused with abstract data types). The swap example is about as simple as such things can be, with no variance or high-order type parameters.

The return type needed not be declared in the example below. It is shown for clarity. However, as Scala does not pass parameters by reference, it cannot swap values in-place. To make up for that, it is receiving two values, and returning a tuple with the values inverted.

<lang scala>def swap[A,B](a: A, b: B): (B, A) = (b, a)</lang>

Scheme

This must be done with macros, since the parameters inside a procedure are copies of the actual parameters. <lang scheme>(define-syntax swap!

 (syntax-rules ()
   ((_ a b)
    (let ((tmp a))
      (set! a b)
      (set! b tmp)))))</lang>

Seed7

A generic template to generate swap functions is defined with: <lang seed7>const proc: generate_swap (in type: aType) is func

 begin
   const proc: swap (inout aType: left, inout aType: right) is func
     local
       var aType: temp is aType.value;
     begin
       temp := left;
       left := right;
       right := temp;
     end func;
 end func;</lang>

An instance of a swap function can be generated with: <lang seed7>generate_swap(integer); generate_swap(string);</lang> A swap function can be called with: <lang seed7>swap(a, b);</lang>

Slate

This must be done with a macro method in Slate, but is in the standard library: <lang slate>x@(Syntax LoadVariable traits) swapWith: y@(Syntax LoadVariable traits) &environment: env "A macro that expands into simple code swapping the values of two variables in the current scope." [| tmpVar |

 env ifNil: [error: 'Cannot swap variables outside of a method'].
 tmpVar: env addVariable.
 {tmpVar store: x variable load.
  x variable store: y variable load.
  y variable store: tmpVar load} parenthesize

].</lang>

Usage: <lang slate>a `swapWith: b</lang>

Smalltalk

Works with: GNU Smalltalk

An OrderedCollection can collect any kind of objects; so this swap implementend extending the OrderedCollection class is really generic. <lang smalltalk>OrderedCollection extend [

   swap: a and: b [

|t| t := self at: a. self at: a put: (self at: b). self at: b put: t

   ]

]</lang>

SNOBOL4

The "canonical" version from M. Emmers tutorial:

<lang snobol4>* SWAP(.V1, .V2) - Exchange the contents of two variables.

  • The variables must be prefixed with the name operator
  • when the function is called.
       DEFINE('SWAP(X,Y)TEMP')              :(SWAP_END)

SWAP TEMP = $X

       $X = $Y
       $Y = TEMP                            :(RETURN)

SWAP_END</lang>

Standard ML

Tuples are immutable in Standard ML. This function doesn't mutate anything, but simply returns a new pair with the order of the elements switched. <lang sml>fun swap (x, y) = (y, x)</lang> If the arguments are constrained to be reference values, a swap function is simple: <lang sml>fun swapref (x, y) =

   let temp = !x in x := !y; y := temp end</lang>

Tcl

Works with: Tcl version 8.5

<lang tcl>proc swap {aName bName} {

   upvar 1 $aName a $bName b
   lassign [list $a $b] b a

}</lang>

Works with: Tcl version 8.4

<lang tcl>proc swap {aName bName} {

   upvar 1 $aName a $bName b
   foreach {b a} [list $a $b] break

}</lang>

<lang tcl>set a 1 set b 2 puts "before\ta=$a\tb=$b" swap a b puts "after\ta=$a\tb=$b"</lang>

Outputs:

before	a=1	b=2
after	a=2	b=1

Ursala

Most functions are polymorphic without any special provision to that effect. Swapping a pair is a very inexpensive operation because no actual copying or overwriting is performed. <lang Ursala>pmgs("x","y") = ("y","x") # the pattern matching way

ugs = ~&rlX # the idiosyncratic Ursala way

  1. cast %sWL

test = <pmgs ('a','b'),ugs ('x','y')></lang>

output:

<('b','a'),('y','x')>

V

Using the view to shuffle the stack.

<lang v>[swap [a b : b a] view].

1 2 swap = 2 1 'hello' 'hi' swap</lang>

='hi' 'hello'

VBScript

This works for everything: strings, dates, booleans ... The fact is, with everything being a Variant, it's always generic.

<lang vb>sub swap( byref x, byref y ) dim temp temp = x x = y y = temp end sub</lang>

Usage: <lang vb> dim a a = "woof" dim b b = now() swap a,b wscript.echo a wscript.echo b</lang>

Output: <lang vb>5/02/2010 2:35:36 PM woof</lang>