Generic swap

From Rosetta Code
Jump to: navigation, search
Task
Generic swap
You are encouraged to solve this task according to the task description, using any language you may know.

The task is to write a generic swap function or operator which exchanges the values of two variables (or, more generally, any two storage places that can be assigned), regardless of their types. If your solution language is statically typed please describe the way your language provides genericity.

If variables are typed in the given language, it is permissible that the two variables be constrained to having a mutually compatible type, such that each is permitted to hold the value previously stored in the other without a type violation. That is to say, solutions do not have to be capable of exchanging, say, a string and integer value, if the underlying storage locations are not attributed with types that permit such an exchange.

Generic swap is a task which brings together a few separate issues in programming language semantics.

Dynamically typed languages deal with values in a generic way quite readily, but do not necessarily make it easy to write a function to destructively swap two variables, because this requires indirection upon storage places or upon the syntax designating storage places.

Functional languages, whether static or dynamic, do not necessarily allow a destructive operation such as swapping two variables regardless of their generic capabilities.

Some static languages have difficulties with generic programming due to a lack of support for (Parametric Polymorphism).

Do your best!

Contents

[edit] ACL2

(defun swap (pair)
(cons (cdr pair)
(car pair)))
 
(let ((p (cons 1 2)))
(cw "Before: ~x0~%After: ~x1~%" p (swap p)))

[edit] 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 specification. The second code snippet is the procedure body.

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;

[edit] usage

To use the generic swap procedure, you need to instantiate the procedure for each type that you intend to use.

 
with Generic_Swap;
...
type T is ...
package T_Swap is new Generic_Swap(Swap_Type => T);
A,B:T;
...
T_Swap(A,B);
 

[edit] ALGOL 68

A generic swap operator =:= was proposed in ALGOL Bulletin for standard ALGOL 68 so that the compiler could optimise the operation. However such an operator was not adopted and needs to be manually defined for each mode required.

Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8-8d
MODE GENMODE = STRING;
 
GENMODE v1:="Francis Gary Powers", v2:="Vilyam Fisher";
 
PRIO =:= = 1;
 
OP =:= = (REF GENMODE v1, v2)VOID: (
GENMODE tmp:=v1; v1:=v2; v2:=tmp
);
 
v1 =:= v2;
 
print(("v1: ",v1, ", v2: ", v2, new line))

Output:

v1: Vilyam Fisher, v2: Francis Gary Powers

[edit] 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.

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

[edit] AppleScript

AppleScript has built-in support for swapping. This is generic and works for all combinations of data types.

set {x,y} to {y,x}

[edit] AutoHotkey

Swap(ByRef Left, ByRef Right)
{
temp := Left
Left := Right
Right := temp
}

[edit] AWK

 
# syntax: GAWK -f GENERIC_SWAP.AWK
BEGIN {
printf("%s version %s\n",ARGV[0],PROCINFO["version"])
foo = 1
bar = "a"
printf("\n%s %s\n",foo,bar)
rc = swap("foo","bar") # ok
printf("%s %s %s\n",foo,bar,rc?"ok":"ng")
printf("\n%s %s\n",foo,bar)
rc = swap("FOO","BAR") # ng
printf("%s %s %s\n",foo,bar,rc?"ok":"ng")
exit(0)
}
function swap(a1,a2, tmp) { # strings or numbers only; no arrays
if (a1 in SYMTAB && a2 in SYMTAB) {
if (isarray(SYMTAB[a1]) || isarray(SYMTAB[a2])) {
return(0)
}
tmp = SYMTAB[a1]
SYMTAB[a1] = SYMTAB[a2]
SYMTAB[a2] = tmp
return(1)
}
return(0)
}
 

output:

gawk version 4.1.0

1 a
a 1 ok

a 1
a 1 ng

[edit] Batch File

Swap using pass-by-name

@echo off
setlocal enabledelayedexpansion
set a=1
set b=woof
echo %a%
echo %b%
call :swap a b
echo %a%
echo %b%
goto :eof
 
:swap
set temp1=!%1!
set temp2=!%2!
set %1=%temp2%
set %2=%temp1%
goto :eof

[edit] BBC BASIC

[edit] Built-in function

      a = 1.23 : b = 4.56
SWAP a,b
PRINT a,b
 
a$ = "Hello " : b$ = "world!"
SWAP a$,b$
PRINT a$,b$

[edit] Custom function

      a = 1.23 : b = 4.56
PROCswap(^a,^b, 5)
PRINT a,b
 
a$ = "Hello " : b$ = "world!"
PROCswap(^a$,^b$, 6)
PRINT a$,b$
END
 
DEF PROCswap(a%, b%, s%)
LOCAL i%
FOR i% = 0 TO s%-1
SWAP a%?i%,b%?i%
NEXT
ENDPROC

Output:

      4.56      1.23
world!    Hello

[edit] Bracmat

(!a.!b):(?b.?a)

[edit] Burlesque

 
\/
 

Stack-based swap.

[edit] C

This has a restriction that a and b must be the same size.

void swap(void *va, void *vb, size_t s)
{
char t, *a = (char*)va, *b = (char*)vb;
while(--s)
t = a[s], a[s] = b[s], b[s] = t;
}

[edit]
Works with: gcc

If you have gcc, you can write a preprocessor macro with __typeof__.

  • Caution: __typeof__ is a gcc extension, not part of standard C. __typeof__ does not conflict with C89 because the standard allows compilers to add keywords with underscores like __typeof__.
#define Swap(X,Y)  do{ __typeof__ (X) _T = X; X = Y; Y = _T; }while(0)

Usage examples are:

#include <stdio.h>
 
#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);
}

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

[edit] 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:

template<typename T> void swap(T& left, T& right)
{
T tmp(left);
left = right;
right = tmp;
}

Note that this function requires that the type T has an accessible copy constructor and assignment operator.


The standard utility 'swap' can be used to swap two values:

std::swap(x,y);

It will work with any types.

[edit] 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.

static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}

[edit] Chapel

Chapel supports swapping directly via tuples and destructuring:

(a, b) = (b, a)

Both variables must be of the same type. The Fibonnacci implementation contains an example.

[edit] Clojure

 
(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
 

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

[edit] CMake

CMake has only one data type: the string.

function(swap var1 var2)
set(_SWAP_TEMPORARY "${${var1}}")
set(${var1} "${${var2}}" PARENT_SCOPE)
set(${var2} "${_SWAP_TEMPORARY}" PARENT_SCOPE)
endfunction(swap)
set(x 42)
set(y "string")
swap(x y)
message(STATUS ${x}) # -- string
message(STATUS ${y}) # -- 42

Because of limitations in CMake, there are a few specific situations where swap() will fail to swap the variables.

  1. When _SWAP_TEMPORARY is the name of the second variable:
    set(x 42)
    set(_SWAP_TEMPORARY "string")
    swap(x _SWAP_TEMPORARY)
    message(STATUS ${x}) # -- 42
    message(STATUS ${_SWAP_TEMPORARY}) # -- 42
    Inside swap(), its local variable _SWAP_TEMPORARY shadows the original _SWAP_TEMPORARY from the parent scope, preventing access to the original value.
  2. When value of either variable is "CACHE" or "PARENT_SCOPE":
    string(TOUPPER CACHE x)
    set(y "string")
    swap(x y) # CMake Error... set given invalid arguments for CACHE mode.
    swap() can never set a variable to "CACHE" or "PARENT_SCOPE", because these are keywords of set() command.

[edit] Common Lisp

(rotatef a b)
 
(psetq a b b a)

[edit] ColdFusion

This is another standard swap.

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

[edit] D

import std.algorithm: swap; // from Phobos standard library
 
// The D solution uses templates and it's similar to the C++ one:
void mySwap(T)(ref T left, ref T right) {
auto temp = left;
left = right;
right = temp;
}
 
void main() {
import std.stdio;
 
int[] a = [10, 20];
writeln(a);
 
// The std.algorithm standard library module
// contains a generic swap:
swap(a[0], a[1]);
writeln(a);
 
// Using mySwap:
mySwap(a[0], a[1]);
writeln(a);
}
Output:
[10, 20]
[20, 10]
[10, 20]

[edit] dc

We use two registers to swap in POSIX dc.

1 2 SaSbLaLb f
=2 1

Reverse (r) is a built-in stack command available as a GNU extension for dc.

1 2 r f
=2 1

[edit] Déjà Vu

To swap the two top-most items on the stack:

swap

To swap two variables without needing a third name, using the stack for temporary storage:

set :a set :b @a @b

[edit] Delphi

Delphi does not have generics as such. The following code must be copied for each type that a swap is required. T should be changed to the required type.

 
procedure Swap_T(var a, b: T);
var
temp: T;
begin
temp := a;
a := b;
b := temp;
end;
 

Generics were introduced with Delphi 2009

 
program GenericSwap;
 
type
TSwap = class
class procedure Swap<T>(var left, right: T);
end;
 
class procedure TSwap.Swap<T>(var left, right: T);
var
temp : T;
begin
temp := left;
left := right;
right := temp;
end;
 
var
a, b : integer;
 
begin
a := 5;
b := 3;
writeln('Before swap: a=', a, ' b=', b);
TSwap.Swap<integer>(a, b);
writeln('After swap: a=', a, ' b=', b);
end.
 

[edit] E

(slots)

def swap(&left, &right) {
def t := left
left := right
right := t
}

(functional)

def swap([left, right]) {
return [right, left]
}

[edit] Erlang

Erlang variables are single assignment and Erlang is dynamically typed, so this task doesn't really apply.

The closest thing would be to swap the items in a list (shown in the shell).

 
1> L = [a, 2].
[a,2]
2> lists:reverse(L).
[2,a]
 

Or swap the items in a tuple (also shown in the shell).

 
1> T = {2,a}.
{2,a}
2> list_to_tuple(lists:reverse(tuple_to_list(T))).
{a,2}
 

[edit] F#

let swap (a,b) = (b,a)

[edit] Factor

Depending on how you look at it: this task doesn't apply, or it's trivial:

swap

[edit] Falcon

 
a = 1
b = 2
a,b = arr = b,a
 

Reading right to left: Assign b & a into an array variable called arr, then assign into a & b

[edit] Fortran

Works with: Fortran version 90 and later
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

[edit] Forth

swap

[edit] Frink

The following example will work on all Frink data types:

 
[b,a] = [a,b]
 

[edit] Gecho

 
1 !0 2 !1
 

Now tape[0] and tape[1] are set to 1 and 2, respectively.

 
&0 &1 !0 pop !1
 

This pushes the value of tape[0] to the stack, tape[1] to the stack, sets tape[0] to the top element, and then pops it, then tape[1] to the top element.

[edit] Go

[edit] Built in

Not a valid solution, since the task requires writing a function or operator, but it is worth mentioning that Go's built in assignment operator does generic swap. The following swaps the values of a and b as long as they are of identical type.

a, b = b, a

[edit] Pass interfaces

A generic swap function can easily be written however, if you require the caller to use variables of the empty interface type. The empty interface can hold a value of any type.

package main
 
import "fmt"
 
func swap(a, b *interface{}) {
*a, *b = *b, *a
}
 
func main() {
var a, b interface{} = 3, "four"
fmt.Println(a, b)
swap(&a, &b)
fmt.Println(a, b)
}

Output:

3 four
four 3

[edit] Pass pointers

Somewhat less restrictive, this version allows pointers of any type to be passed, as long as they are the same type.

package main
 
import (
"fmt"
"reflect"
)
 
func swap(a, b interface{}) error {
ta := reflect.TypeOf(a)
tb := reflect.TypeOf(b)
if ta != tb {
return fmt.Errorf("swap args are different types: %v and %v", ta, tb)
}
if ta.Kind() != reflect.Ptr {
return fmt.Errorf("swap args must be pointers")
}
ea := reflect.ValueOf(a).Elem()
eb := reflect.ValueOf(b).Elem()
temp := reflect.New(ea.Type()).Elem()
temp.Set(ea)
ea.Set(eb)
eb.Set(temp)
return nil
}
 
func main() {
a, b := 3, "cats"
fmt.Println("a b:", a, b)
err := swap(a, b)
fmt.Println(err, "\n")
 
c, d := 3, 4
fmt.Println("c d:", c, d)
err = swap(c, d)
fmt.Println(err, "\n")
 
e, f := 3, 4
fmt.Println("e f:", e, f)
swap(&e, &f)
fmt.Println("e f:", e, f, "\n")
 
type mult struct {
int
string
}
 
g, h := mult{3, "cats"}, mult{4, "dogs"}
fmt.Println("g h:", g, h)
swap(&g, &h)
fmt.Println("g h:", g, h)
}

Output:

a b: 3 cats
swap args are different types: int and string 

c d: 3 4
swap args must be pointers 

e f: 3 4
e f: 4 3 

g h: {3 cats} {4 dogs}
g h: {4 dogs} {3 cats}

[edit] Groovy

Groovy has support for swapping built in:

(a, b) = [b, a]

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

def swap(a, b) {
[b, a]
}

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:

def (x, y) = swap(1, 3)
assert x == 3
assert y == 1

Some examples here show an in-place swap of indexed elements in an array or collection, so for completeness here is an in-place swap of arbitrary indexed elements in a list:

def listSwap = { a, i, j ->
assert (0..<(a.size())).containsAll([i,j]);
a[[j,i]] = a[[i,j]]
}
 
def list = [2,4,6,8]
listSwap(list, 1, 3)
assert list == [2,8,6,4]

[edit] 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.

swap :: (a, b) -> (b, a)
swap (x, y) = (y, x)

This swap function is available in the Data.Tuple standard library module in GHC 7.0+

[edit] Icon and Unicon

Icon provides a :=: operator for this. Additionally, there is a reversible exchange operator <-> that reverses the exchange if resumed.

procedure main()
x := 1
y := 2
x :=: y
write(x," ",y)
# swap that will reverse if surrounding expression fails
if x <-> y & x < y then write(x, " ", y)
end
 

[edit] IDL

IDL is dynamically typed and array-centric, so swapping is quite easy for any data type. The TEMPORARY function sets its argument to "undefined", and allows us to swap without any large copying.

pro swap, a, b
c = temporary(a)
a = temporary(b)
b = temporary(c)
end

[edit] 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):

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

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

   |.2 3
3 2
|.&.;:'one two'
two one

A generic destructive swap of named values would instead require reference to the locations being destroyed. Here's an implementation of that:

destructiveSwap=:4 :0
t=. do y
(y)=: do x
(x)=: t
i.0 0 NB. result is meaningless
)

Example use:

   V1=: 'cat'
V2=: 7
'V1' destructiveSwap 'V2'
V1
7
V2
cat

[edit] Java

Works with: Java version 1.5+

Java uses references, so it can't swap the values of two variables that don't belong to a class.

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

[edit] 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.

function swap(arr) {
var tmp = arr[0];
arr[0] = arr[1];
arr[1] = tmp;
}

Also there is metaprogramming solution. It uses code generation and eval. To avoid naming conflicts(user can pass 'tmp', which causes var tmp = tmp) it uses buildin, per activation context (thats why it is enclosed into self executing lambda), var arguments for temp storage.

function swap(aName, bName) {
return ('(function(){ arguments[0] = aName; aName = bName; bName = arguments[0] })()'
.replace(/aName/g, aName)
.replace(/bName/g, bName)
)
}
var x = 1
var y = 2
eval(swap('x', 'y'))
 

[edit] Joy

Provided that the stack contains at least two elements and/or aggregates:

swap

changes the order of those elements and/or aggregates.

[edit] Julia

Similar to Python, Julia has built-in support for swapping:

a, b = b, a

[edit] Lang5

swap        # stack
reverse # array


[edit] Lasso

define swap(a, b) => (: #b, #a)
 
local(a) = 'foo'
local(b) = 42
 
local(a,b) = swap(#a, #b)
stdoutnl(#a)
stdoutnl(#b)
Output:
42
foo

[edit] Using Decompositional Assignment

local(a)   = 'hair'
local(b) = 'moose'
local(a,b) = (: #b, #a)
stdoutnl(#a)
stdoutnl(#b)
Output:
moose
hair

[edit] Lisaac

(a, b) := (b, a);

[edit]

 
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]
 

[edit] Lhogho

Lhogho is very similar except that it does not have a localmake opcode.

 
to swap :s1 :s2
local "t
make "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]
 

[edit] Logtalk

:- object(paws).
 
:- public(swap/4).
swap(First, Second, Second, First).
 
:- end_object.

Usage examples:

| ?- paws::swap(apples, oranges, X, Y).
X = oranges
Y = apples
yes
 
| ?- paws::swap(3.14, ext(lgt), X, Y).
X = ext(lgt)
Y = 3.14

yes

[edit] LOLCODE

LOLCODE's dynamic typing makes generic swapping trivial. In addition, the special IT variable‒which contains the most recently evaluated expression‒permits doing so without explicitly creating a temporary variable.

HAI 1.3
 
I HAS A foo ITZ "kittehz"
I HAS A bar ITZ 42
 
foo, foo R bar, bar R IT
 
VISIBLE foo BTW, 42
VISIBLE bar BTW, kittehz
 
KTHXBYE

[edit] Lua

Lua evaluates the values on the right-hand side before assigning them to the variables on the left-hand side. This behaviour allows the following notation to be used to swap two values:

 
x, y = y, x -- swap the values inside x and y
t[1], t[2] = t[2], t[1] -- swap the first and second values inside table t
 

Usage example:

 
x, y = 3, 4
print(x, y) --> 3 4
x, y = y, x -- swap
print(x, y) --> 4 3
 

[edit] 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

Output:

x y

y x

[edit] Maple

The assignment operator in Maple can swap values, since the right hand side is evaluated before the assignment occurs.

 
> a, b := 2, "foo":
> a;
2
 
> b;
"foo"
 
> a, b := b, a: # SWAP
> a;
"foo"
 
> b;
2
 

[edit] Mathematica

Mathematica functions are generic by default; however, it has to be told not to evaluate the arguments before executing the function.

swap[a_, b_] := {a, b} = {b, a}
SetAttributes[swap, HoldAll]

[edit] MATLAB / Octave

It is unnecessary to define a "swap" function in MATLAB because swaps are trivial operations. In fact, they are so natural to the language that multiple swaps can be performed simultaneously.

Example:

>> a = [30 40 50 60 70]
 
a =
 
30 40 50 60 70
 
>> a([1 3]) = a([3 1]) %Single swap
 
a =
 
50 40 30 60 70
 
>> a([1 2 4 3]) = a([2 3 1 4]) %Multiple swap, a.k.a permutation.
 
a =
 
40 30 60 50 70

[edit] Maxima

a: 10$
b: 20$
 
/* A simple way to swap values */
[a, b]: [b, a]$
 
a; /* 20 */
b; /* 10 */
 
/* A macro to hide this */
swap(x, y) ::= buildq([x, y], ([x, y]: [y, x], 'done))$
 
swap(a, b)$
 
a; /* 10 */
b; /* 20 */

[edit] MAXScript

swap a b

[edit] 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)

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;

Examples:

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;

[edit] Modula-3

GENERIC INTERFACE GenericSwap(Elem);
 
PROCEDURE Swap(VAR left: Elem.T; VAR right: Elem.T);
 
END GenericSwap.
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.

Here is an example usage for integers:

INTERFACE IntSwap = GenericSwap(Integer) END IntSwap.
MODULE IntSwap = GenericSwap(Integer) END IntSwap.
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.

Output:

Left = 10
Left = 20

[edit] Nemerle

For pairs, namespace Nemerle.Utility.Pair contains Swap():

def coords    = (1, -1);
def invcoords = Swap(coords);
Or to swap two mutable variables of the same type:
a <-> b;

But, enough about built in functionality, let's demonstrate using generics:

Swap[T, U] (a : T, b : U) : U * T
{
(b, a)
}

[edit] NetRexx

Values stored in the default Rexx data type are treated as typeless data; context is based on the contents. Swapping the contents of variables stored in Rexx object can be achieved via the PARSE instruction.

/* NetRexx */
options replace format comments java crossref symbols nobinary
 
-- Simple values with no spaces can be swapped without the use of a parse template
lval = 27
rval = 5
say 'Before - <lval>'lval'</lval> <rval>'rval'</rval>'
parse (lval rval) rval lval
say 'After - <lval>'lval'</lval> <rval>'rval'</rval>'
say
 
-- More complex data needs to use some form of parsing template
lval = 'This value started on the left'
rval = 'This value started on the right'
dlm = 12x80facebead01 -- some delimiting value that is unlikely to occur in the LVAL to be swapped
say 'Before - <lval>'lval'</lval> <rval>'rval'</rval>'
parse (lval || dlm || rval) rval (dlm) lval
say 'After - <lval>'lval'</lval> <rval>'rval'</rval>'
say
 
return
 
Output:
Before - <lval>27</lval> <rval>5</rval>
After  - <lval>5</lval> <rval>27</rval>

Before - <lval>This value started on the left</lval> <rval>This value started on the right</rval>
After  - <lval>This value started on the right</lval> <rval>This value started on the left </rval>

[edit] Nial

Like J

|reverse 1 2
=2 1

[edit] Nimrod

Builtin procedure swap. Example usage:

swap(a, b)

[edit] 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.

let swap (x, y) = (y, x)

If the arguments are constrained to be reference values, a swap function is simple:

let swapref x y =
let temp = !x in
x := !y;
y := temp

[edit] 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.

  proc {SwapCells A B}
Tmp = @A
in
A := @B
B := Tmp
end

Or shorter, if we exploit the fact that the assignment operator := returns the old value of the cells:

  proc {SwapCells A B}
B := A := @B
end

A functional swap, operating on pairs:

  fun {SwapPair A#B}
B#A
end

[edit] PARI/GP

Pari is near-typeless—everything is a GEN.

my(tmp=a);
a=b;
b=tmp;
Works with: PARI/GP version 2.6.0 and above
[a,b]=[b,a]

[edit] Pascal

Works with: Free_Pascal version 2.6.0

Standard Pascal does not have generics, but FreePascal has a start:

program generictest;
 
{$mode objfpc}
 
type
generic TSwap<T> = procedure (var a, b: T);
 
procedure Proc1(var a, b: integer);
var
temp: integer;
begin
temp := a;
a := b;
b := temp;
end;
 
var
S, T: integer;
SwapInt: specialize TSwap<integer>;
 
begin
S := 4;
T := 3;
SwapInt := @Proc1;
writeln(S, T:2);
SwapInt(S, T);
writeln(S, T:2);
end.

Output:

4 3
3 4

[edit] Perl

Perl has support for swapping built-in

($y, $x) = ($x, $y);

Here's a generic swap routine:

sub swap {@_[0, 1] = @_[1, 0]}

[edit] 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.

Alternatively, you can write it like this:

($x, $y) .= reverse;

[edit] PHP

function swap(&$a, &$b) {
list($a, $b) = array($b, $a);
}

[edit] PicoLisp

xchg works with any data type

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

Output:

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

[edit] PL/I

[edit] Using the preprocessor

%swap: procedure (a, b);
declare (a, b) character;
return ( 't=' || a || ';' || a || '=' || b || ';' || b '=t;' );
%end swap;
%activate swap;
 
The statement:-
swap (p, q);
 
is replaced, at compile time, by the three statements:
t = p; p = q; q = t;

[edit] Using generic procedures

declare swap generic (
swapf when (float, float),
swapc when (char, char));
 
swapf: proc (a, b);
declare (a, b, t) float;
t = a; a = b; b = t;
end swapf;
swapc: proc (a, b);
declare (a, b) character(*);
declare t character (length(b));
t = a; a = b; b = t;
end swapc;
 
declare (r, s) character (5);
call swap (r, s);

Both of the above are not completely generic, but depend on either the presence of

  • a temporary variable with the same attributes of the variables to be swapped, OR
  • data-attribute specific procedures for the swap

The following code is completely generic, but, in line with the usual safety offered by PL/I, swaps only the contents up to the storage occupied by the smallest of the two variables: Prino 01:24, 11 February 2011 (UTC)

[edit] Completely generic code using the pre-processor

%swap: proc(x,y);
dcl (x, y) char;
 
x = trim(x); /* Just for neatness sake */
y = trim(y);
 
ans('begin; ') skip;
ans(' dcl c char (1); ') skip;
ans(' dcl sx char (1) based(px); ') skip;
ans(' dcl sy char (1) based(py); ') skip;
ans(' dcl i fixed bin (31); ') skip;
ans(' dcl px ptr init (addr(' || x || ')); ') skip;
ans(' dcl py ptr init (addr(' || y || ')); ') skip;
ans(' do i = 1 to min(stg(' || x || '), stg(' || y || '));') skip;
ans(' c = sx; ') skip;
ans(' sx = sy; ') skip;
ans(' sy = c; ') skip;
ans(' px = px + 1; ') skip;
ans(' py = py + 1; ') skip;
ans(' end; ') skip;
ans('end; ') skip;
%end swap;
%act swap;
 
dcl c1 char (10) init ('1234567890');
dcl c2 char (10) init ('ABCDEFGHIJ');
dcl f1 fixed bin (31) init (12345);
dcl f2 fixed bin (31) init (98765);
 
put data(c1, c2, f1, f2);
swap(c1, c2);
swap(f1, f2);
put data(c1, c2, f1, f2);
f1 = -656877352; /* '5a5a5a5a'x, aka 'QQQQ' */
swapper(c1, f1);
put data(c1,f1);

The code generated by 'swap(c1, c2);' looks like

 
begin;
dcl c char (1);
dcl sx char (1) based(px);
dcl sy char (1) based(py);
dcl i fixed bin (31);
dcl px ptr init (addr(C1));
dcl py ptr init (addr(C2));
do i = 1 to min(stg(C1), stg(C2));
c = sx;
sx = sy;
sy = c;
px = px + 1;
py = py + 1;
end;
end;

and, because declarations in PL/I begin blocks are local to that block, generating several blocks with the same variables will not cause any problems.

The result of compiling, linking and executing the above code:

C1='1234567890'
C2='ABCDEFGHIJ'
F1=         12345
F2=         98765;
C1='ABCDEFGHIJ'
C2='1234567890'
F1=         98765
F2=         12345;
C1='QQQQEFGHIJ'
F1=   -1044200508;

[edit] Pop11

Swap is easily done via multiple assignment:

(a, b) -> (b, a);

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

[edit] PostScript

Works with anything you can put on the operand stack:
exch

[edit] PowerShell

PowerShell allows swapping directly, through tuple assignment:

$b, $a = $a, $b

But one can also define a function which swaps the values of two references:

function swap ([ref] $a, [ref] $b) {
$a.Value, $b.Value = $b.Value, $a.Value
}

When using this function the arguments have to be explicitly given as references:

swap ([ref] $a) ([ref] $b)


[edit] Prolog

 
swap(A,B,B,A).
 
?- swap(1,2,X,Y).
X = 2,
Y = 1.
 

[edit] PureBasic

Built in function:

Swap a, b

[edit] Python

Python has support for swapping built in:

a, b = b, a

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

def swap(a, b):
return b, a

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.

[edit] R

R function arguments are passed by value, not by reference. You can work around this, however, by using their names and environment:

swap <- function(name1, name2, envir = parent.env(environment()))
{
temp <- get(name1, pos = envir)
assign(name1, get(name2, pos = envir), pos = envir)
assign(name2, temp, pos = envir)
}

Usage:

> x <- 1
> y <- 2
> swap('x', 'y')
> cat(x, y)
2 1

[edit] Racket

A swap operation can be easily written as a macro in Racket. The macro will even work as expected in Typed Racket.

 
#lang racket/load
 
(module swap racket
(provide swap)
 
 ;; a simple macro to swap two variables
(define-syntax-rule (swap a b)
(let ([tmp a])
(set! a b)
(set! b tmp))))
 
;; works fine in a statically typed setting
(module typed typed/racket
(require 'swap)
 
(: x Integer)
(define x 3)
 
(: y Integer)
(define y 4)
 
(swap x y)
(printf "x is ~a~n" x)
(printf "y is ~a~n" y))
 

[edit] REBOL

rebol [
Title: "Generic Swap"
Author: oofoe
Date: 2009-12-06
URL: http://rosettacode.org/wiki/Generic_swap
Reference: [http://reboltutorial.com/blog/rebol-words/]

]
 
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 "."]

Output:

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

[edit] Retro

swap

[edit] REXX

REXX has no primitive for swapping, but it can easily be performed using a temporary variable.
(This is the slowest of the three versions.)

[edit] using temp

a = 'I see you.'
b = -6
 
_temp_ = a /*swap ··· */
a = b /* A ··· */
b = _temp_ /* and B */

[edit] using VALUE

This version will work with any values.

a = "bull feathers"
b = 10
 
a=value('b', a) /*swap A and B */

[edit] using PARSE

If it's known that there are

  • no blanks
  • no null values
  • (maybe) no whitespace (such as tabs)

in the values, the following method can be used:
(This is the fastest of the three versions.)

a = -199e-12
b = 12.
 
parse value a b with b a /*swap A and B */

Note that some REXX interpreters handle whitespace differently, some honor whitespace,
others don't   (particularly the older versions).

[edit] RLaB

RLaB does not have a built-in function for swapping the content of two variables. However, there is a workaround which comes from the fact that the global variable space $$ contains all the variables var1, var2 and so forth as $$.var1, ...

Let we want to swap the content of two variables, which names are a and b, then the following function would do the trick

 
swap = function(x,y)
{
if (!exist($$.[x]))
{ return 0; }
if (!exist($$.[y]))
{ return 0; }
local (t);
t = $$.[x];
$$.[x] = $$.[y];
$$.[y] = t;
return 1;
};
 
>> a=1
1
>> b = "fish"
fish
>> swap( "a" , "b" );
>> a
fish
>> b
1
 

[edit] Ruby

As of Ruby 2.00 (and probably earlier), this works for Ruby scripts, but not for Ruby code entered directly into the Ruby REPL, "irb".

Ruby has support for swapping built in:

a, b = b, a

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

def swap(a, b)
return b, a
end

This method does not swap the original variables, because Ruby passes parameters by value. Instead, this method returns simply a new array with the order of the elements switched. The caller may assign the original variables with the return value:

x = 42
y = "string"
x, y = swap x, y
puts x # prints string
puts y # prints 42

[edit] Run BASIC

Run BASIC does not have support for swapping built in:

a = 1
b = 2
'----- swap ----
tmp = a
a = b
b = tmp
end

[edit] Sather

A possible way that needs the type of the objects to be specified:

class SWAP{T} is
swap(inout a, inout b:T) is
t ::= a;
a := b;
b := t;
end;
end;
class MAIN is
main is
x ::= 10;
y ::= 20;
SWAP{INT}::swap(inout x, inout y);
#OUT + x + ", " + y + "\n";
end;
end;

[edit] 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 need not be declared in the example below, but 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 receives two values, and returns a tuple with the values inverted.

def swap[A,B](a: A, b: B): (B, A) = (b, a)

[edit] Scheme

; swap elements of a vector
; vector-swap! is not part of r5rs, so we define it
(define (vector-swap! v i j)
(let ((a (vector-ref v i)) (b (vector-ref v j)))
(vector-set! v i b)
(vector-set! v j a)))
 
(let ((vec (vector 1 2 3 4 5)))
(vector-swap! vec 0 4)
vec)
; #(5 2 3 4 1)
 
 
; we can swap also in lists
(define (list-swap! v i j)
(let* ((x (list-tail v i))
(y (list-tail v j))
(a (car x))
(b (car y)))
(set-car! x b)
(set-car! y a)))
 
(let ((lis (list 1 2 3 4 5)))
(list-swap! lis 0 4)
lis)
; (5 2 3 4 1)
 
 
; using macros (will work on variables, not on vectors or lists)
(define-syntax swap!
(syntax-rules ()
((_ a b)
(let ((tmp a))
(set! a b)
(set! b tmp)))))
 
; try it
(let ((a 1) (b 2)) (swap! a b) (list a b))
; (2 1)

[edit] Seed7

A generic template to generate swap functions is defined with:

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;

An instance of a swap function can be generated with:

generate_swap(integer);
generate_swap(string);

A swap function can be called with:

swap(a, b);

[edit] Slate

This must be done with a macro method in Slate, but is in the standard library:

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."
[
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
].

Usage:

a `swapWith: b

[edit] Smalltalk

Works with: GNU Smalltalk

An OrderedCollection can collect any kind of objects; so this swap implementend extending the OrderedCollection class is really generic.

OrderedCollection extend [
swap: a and: b [
|t|
t := self at: a.
self at: a put: (self at: b).
self at: b put: t
]
]

[edit] SNOBOL4

The "canonical" version from M. Emmers tutorial:

* 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

[edit] 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.

fun swap (x, y) = (y, x)

If the arguments are constrained to be reference values, a swap function is simple:

fun swapref (x, y) =
let temp = !x in x := !y; y := temp end

[edit] Tcl

Works with: Tcl
proc swap {aName bName} {
upvar 1 $aName a $bName b
lassign [list $a $b] b a
}
Works with: Tcl
proc swap {aName bName} {
upvar 1 $aName a $bName b
foreach {b a} [list $a $b] break
}

alternatively:

proc swap {aName bName} {
upvar 1 $aName a $bName b
set a $b[set b $a; list]
}
set a 1
set b 2
puts "before\ta=$a\tb=$b"
swap a b
puts "after\ta=$a\tb=$b"

Outputs:

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

[edit] ThinBASIC

Generic function, swap the content of two variables.

Swap Var1, Var2

[edit] TI-89 BASIC

TI-89 BASIC is dynamically typed, so the genericity is implicit. It has no pass by reference, so we must pass the variable names as strings. It is dynamically scoped, so we must choose hopefully distinct names for the variables.

Define swap(swapvar1, swapvar2) = Prgm
Local swaptmp
#swapvar1 → swaptmp
#swapvar2 → #swapvar1
swaptmp → #swapvar2
EndPrgm
 
1 → x
2 → y
swap("x", "y")
x
2
y
1

[edit] Trith

As with other stack-based languages (e.g. Factor and Joy), the solution to this task is a trivial matter of swapping the top two operands on the stack:

swap

[edit] 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.

pmgs("x","y") = ("y","x")    # the pattern matching way
 
ugs = ~&rlX # the idiosyncratic Ursala way
 
#cast %sWL
 
test = <pmgs ('a','b'),ugs ('x','y')>

output:

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

[edit] V

Using the view to shuffle the stack.

[swap [a b : b a] view].
 
1 2 swap
= 2 1
'hello' 'hi' swap
='hi' 'hello'

[edit] VBScript

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

sub swap( byref x, byref y )
dim temp
temp = x
x = y
y = temp
end sub

Usage:

dim a 
a = "woof"
dim b
b = now()
swap a,b
wscript.echo a
wscript.echo b

Output:

5/02/2010 2:35:36 PM
woof

[edit] Visual Basic

Visual Basic can use the VBScript example above, with the caveat that it won't work if any DEFtype (except DefVar) has been used. (The default data type is Variant, which can be used as a stand-in for any variable type.)

Also, the sub will fail if one arg is a string containing non-numeric data and the other arg is numeric.

[edit] Wart

There's a primitive for modifying bindings.

(swap! x y)

New bindings can be created in parallel.

let (x y) (list y x)
...

[edit] XPL0

The name Swap is normally used to call an intrinsic routine that swaps bytes in an integer. Thus Exch is used here instead. A and B must both be the same size.

include c:\cxpl\codes;
 
proc Exch(A, B, S);
char A, B, S;
int I, T;
for I:= 0 to S-1 do
[T:= A(I); A(I):= B(I); B(I):= T];
 
 
real X, Y;
[X:= 3.0; Y:= 4.0;
Exch(addr X, addr Y, 8);
RlOut(0, X); RlOut(0, Y); CrLf(0);
]

Output:

    4.00000    3.00000

[edit] Yorick

Yorick has a built-in function swap for exchanging the contents of two variables without requiring a temporary copy. Example of use:

> a = 1
> b = "foo"
> swap, a, b
> a
"foo"
> b
1

Swapping elements in an array can be accomplished using index lists. Arbitrary permutations of swaps are also straightforward. Example:

> foo = [10,20,30,40,50]
> foo([1,2]) = foo([2,1])
> foo
[20,10,30,40,50]
> foo([3,4,5]) = foo([4,5,3])
> foo
[20,10,40,50,30]

[edit] zkl

As a general case, no. Here a fake around for two known classes (which are the same for ease of example):

class C{var v; fcn init(n){v=n}}
var c1=C(1), c2=C(2);
println(c1.v," : ",c2.v);
fcn swap(ca,cb,name){
tmp:=ca.resove(name);
ca.setVar(name,cb.resolve(name)); cb.setVar(name,tmp)
}
swap(c1,c2,"v");
println(c1.v," : ",c2.v);
Output:
1 : 2
2 : 1
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox