Generic swap: Difference between revisions
Drkameleon (talk | contribs) (Added Arturo implementation) |
Drkameleon (talk | contribs) (added alternative implementation - for Arturo) |
||
Line 335: | Line 335: | ||
=={{header|Arturo}}== |
=={{header|Arturo}}== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
===Using multi-assignment=== |
|||
<lang rebol>swap: function [a,b]-> @[b,a] |
|||
c: 1 |
|||
d: 2 |
|||
print [c d] |
|||
[c,d]: swap c d |
|||
print [c d]</lang> |
|||
{{out}} |
|||
<pre>1 2 |
|||
2 1</pre> |
|||
===In-place modification=== |
|||
<lang rebol>swap: function [a,b]-> @[b,a] |
<lang rebol>swap: function [a,b]-> @[b,a] |
||
Revision as of 15:14, 12 May 2022
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
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!
11l
<lang 11l>F swap(&a, &b)
(a, b) = (b, a)</lang>
360 Assembly
Three consecutive exclusive OR's swap variable contents <lang 360 Assembly> SWAP CSECT , control section start
BAKR 14,0 stack caller's registers LR 12,15 entry point address to reg.12 USING SWAP,12 use as base MVC A,=C'5678____' init field A MVC B,=C'____1234' init field B LA 2,L address of length field in reg.2 WTO TEXT=(2) Write To Operator, results in:
- +5678________1234
XC A,B XOR A,B XC B,A XOR B,A XC A,B XOR A,B. A holds B, B holds A WTO TEXT=(2) Write To Operator, results in:
- +____12345678____
PR , return to caller LTORG , literals displacement
L DC H'16' halfword containg decimal 16 A DS CL8 field A, 8 bytes B DS CL8 field B, 8 bytes
END SWAP program end
</lang>
6502 Assembly
There are no atomic swap operations in 6502 Assembly but there are a few slower ways of doing it, using the stack. The 65c02 and 65816 revisions added a few commands which make swapping easier. The need for atomic swapping isn't really an issue since most 6502-based computers didn't use parallel processing; the biggest concern for registers or memory getting clobbered was from interrupts, which can be easily avoided by restricting the registers and/or memory they use, and using the stack to back up and restore their values at the beginning and end.
NMOS 6502
The original 6502 can't push X or Y onto the stack directly, and must do so through the accumulator. The most common way of swapping values is by pushing them onto the stack and popping them in the "wrong" order on purpose. <lang 6502asm>;swap X with Y pha ;push accumulator
txa pha ;push x tya pha ;push y pla tax ;pop y into x pla tay ;pop x into y
pla ;pop accumulator</lang>
Swapping A with X or Y is easiest with using zero page memory as a temporary store, or with self-modifying code.
<lang 6502asm> sta temp ;a label representing a zero page memory address txa pha ;push x
ldx temp
pla ;pop x into accumulator</lang>
Swapping memory locations is fairly straightforward on all versions of the 6502: <lang 6502asm> temp equ $00 temp2 equ $01 ;these values don't matter.
lda temp pha ;push temp lda temp2 pha ;push temp2
pla sta temp ;pop temp2 into temp pla sta temp2 ;pop temp into temp2</lang>
CMOS 65c02
This revision of the 6502 can push X and Y onto the stack directly. The above code can be condensed quite a bit. This is a different example that better illustrates how swapping can be done: <lang 6502asm>lda #$33 ldx #$44 ldy #$55
pha phx phy
pla ;a=#$55 ply ;y=#$44 plx ;x=#$33</lang>
8086 Assembly
The XCHG
command swaps two registers' values. It can also work with memory that is pointed to by an index register such as SI
, DI
,or BP
. Both registers must be the same size, which enforces type matching. You cannot XCHG AX,CL
for example since AX
is 16-bit and CL
is only 8-bit.
Here are some examples of the XCHG
command in action:
<lang asm>xchg ax,bx ;exchanges ax with bx
xchg ah,al ;swap the high and low bytes of ax
- XCHG a register with memory
mov dx,0FFFFh mov word ptr [ds:userRam],dx mov si,offset userRam mov ax,1234h xchg ax,[si] ;exchange ax with the value stored at userRam. Now, ax = 0FFFFh and the value stored at userRam = 1234h
- XCHG a register with a value on the stack.
mov ax,1234h mov bx,4567h push bx push bp mov bp,sp ;using [sp] as an operand for XCHG will not work. You need to use bp instead.
xchg ax,[2+bp] ;exchanges AX with the value that was pushed from BX onto the stack. Now, AX = 4567h,
;and the entry on the stack just underneath the top of the stack is 1234h.</lang>
8th
<lang forth> swap </lang> Or to swap between the stack and a var: <lang forth> dup @ -rot ! </lang>
ACL2
<lang Lisp>(defun swap (pair)
(cons (cdr pair) (car pair)))
(let ((p (cons 1 2)))
(cw "Before: ~x0~%After: ~x1~%" p (swap p)))</lang>
Action!
<lang Action!>INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
PROC Swap(BYTE POINTER ptr1,ptr2 INT size)
BYTE tmp INT i
FOR i=0 TO size-1 DO tmp=ptr1^ ptr1^=ptr2^ ptr2^=tmp ptr1==+1 ptr2==+1 OD
RETURN
PROC Main()
BYTE b1=[13],b2=[56] INT i1=[65234],i2=[534] REAL r1,r2 CHAR ARRAY s1="abcde",s2="XYZ"
Put(125) PutE() ;clear the screen ValR("32.5",r1) ValR("-0.63",r2)
Print("Swap bytes: ") PrintB(b1) Put(32) PrintB(b2) Print(" -> ") Swap(@b1,@b2,1) PrintB(b1) Put(32) PrintBE(b2)
Print("Swap integers: ") PrintI(i1) Put(32) PrintI(i2) Print(" -> ") Swap(@i1,@i2,2) PrintI(i1) Put(32) PrintIE(i2)
Print("Swap floats: ") PrintR(r1) Put(32) PrintR(r2) Print(" -> ") Swap(r1,r2,6) PrintR(r1) Put(32) PrintRE(r2)
Print("Swap strings: ") Print(s1) Put(32) Print(s2) Print(" -> ") Swap(@s1,@s2,2) Print(s1) Put(32) PrintE(s2)
RETURN</lang>
- Output:
Screenshot from Atari 8-bit computer
Swap bytes: 13 56 -> 56 13 Swap integers: -302 534 -> 534 -302 Swap floats: 32.5 -0.63 -> -0.63 32.5 Swap strings: abcde XYZ -> XYZ abcde
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.
<lang ada>generic
type Swap_Type is private; -- Generic parameter
procedure Generic_Swap (Left, Right : in out Swap_Type);
procedure Generic_Swap (Left, Right : in out Swap_Type) is
Temp : constant Swap_Type := Left;
begin
Left := Right; Right := Temp;
end Generic_Swap;</lang>
usage
To use the generic swap procedure, you need to instantiate the procedure for each type that you intend to use. <lang ada> with Generic_Swap; ... type T is ... procedure T_Swap is new Generic_Swap (Swap_Type => T); A, B : T; ... T_Swap (A, B); </lang>
Aime
Aime is statically typed. A generic swap utility may nonetheless be defined in terms of parameters of unspecified type and pass by reference. <lang aime>void __swap(&, &,,) {
set(0, $3); set(1, $2);
}
void swap(&, &) {
xcall(xcall, __swap);
}</lang>
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.
<lang algol68>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))</lang>
- Output:
v1: Vilyam Fisher, v2: Francis Gary Powers
Special option
The B6700 Algol compiler offered access to a special machine operation via a function called ReadLock(a,b) that could be invoked on a variety of operands. By using the ability to #define this = that; one could define Swap(a,b) to be a:=ReadLock(a,b) to attain the appearance of a Swap operation. This all relied on the working of magnetic core memory, specifically that to read a word, the word is made zero and in the process the memory hardware notes which bits were thereby flipped. Thus it passes on the value in the word and meanwhile, rewrites that content back to the word so as to preserve its value on reading. Similarly, to write a value to a word, the word is first zeroed.
ReadLock(a,b) functioned by reading a and writing its value to b, but also, recovering the value that was in b which it returns as the result of the function - which is written to a by the assignment, completing the swap. The ReadLock part is "atomic" or not interruptable, so it is used in semaphores and the like, but was available for other use. It swapped a single word, so could swap types such as integers or floating-point numbers (single precision) thus being somewhat generic.
Amazing Hopper
<lang Amazing Hopper>
- include <flow.h>
DEF-MAIN(argv,argc)
DIM(10) AS-INT-RAND( 10, random array ) SET( single var, 0.5768 ) PRNL( "SINGLE VAR: ", single var, "\nRANDOM ARRAY: ", random array ) single var <-> random array PRNL( "SINGLE VAR: ", single var, "\nRANDOM ARRAY: ", random array )
END </lang>
- Output:
$ hopper swap.flw SINGLE VAR: 0.5768 RANDOM ARRAY: 4,2,5,10,8,3,4,8,3,5 SINGLE VAR: 4,2,5,10,8,3,4,8,3,5 RANDOM ARRAY: 0.5768 $
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>
Arc
<lang Arc>(mac myswap (a b)
(w/uniq gx `(let ,gx a (= a b) (= b ,gx))))
(with (a 1
b 2) (myswap a b) (prn "a:" a #\Newline "b:" b))
</lang>
Arturo
Using multi-assignment
<lang rebol>swap: function [a,b]-> @[b,a]
c: 1 d: 2 print [c d]
[c,d]: swap c d print [c d]</lang>
- Output:
1 2 2 1
In-place modification
<lang rebol>swap: function [a,b]-> @[b,a]
c: 1 d: 2 print [c d]
[c,d]: swap c d print [c d]</lang>
- Output:
1 2 2 1
AutoHotkey
<lang autohotkey>Swap(ByRef Left, ByRef Right) {
temp := Left Left := Right Right := temp
}</lang>
AWK
<lang 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)
} </lang>
- Output:
gawk version 4.1.0 1 a a 1 ok a 1 a 1 ng
Applesoft BASIC
<lang Applesoft BASIC>A=43:B=47:H=A:A=B:B=H:?" A="A" B="B;</lang>
A=47 B=43
Axe
The Exch() command can swap data of any size at any two addresses. This example swaps two 2-byte variables. <lang axe>Exch(°A,°B,2)</lang>
Batch File
Swap using pass-by-name
<lang dos>@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</lang>
BaCon
<lang freebasic> x = 1 y$ = "hello"
SWAP x, y$ PRINT y$ </lang>
BBC BASIC
Built-in function
<lang bbcbasic> a = 1.23 : b = 4.56
SWAP a,b PRINT a,b a$ = "Hello " : b$ = "world!" SWAP a$,b$ PRINT a$,b$</lang>
Custom function
<lang bbcbasic> 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</lang>
- Output:
4.56 1.23 world! Hello
Beads
<lang beads>beads 1 program 'Generic swap'
var a = [1 2 "Beads" 3 4] b = [1 2 "Language" 4 5]
calc main_init swap a[4] <=> b[3]</lang>
- Output:
A = [1, 2, "Beads", 3, 4] B = [1, 2, "Language", 4, 5] ------------------------------------------------- A = [1, 2, "Beads", "Language", 4] B = [1, 2, 3, 4, 5]
BQN
Two variables can be exchanged with modified assignment:
<lang bqn>a‿b ⌽↩</lang>
With no right-hand side, this expands to a one-argument call a‿b ↩ ⌽ a‿b
. BQN doesn't make variable names or references first-class, so it wouldn't make sense to make this generic over variable names.
Bracmat
<lang bracmat>(!a.!b):(?b.?a)</lang>
Burlesque
<lang burlesque> \/ </lang>
Stack-based swap.
C
This has a restriction that a and b must be the same size.
<lang c>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;
}</lang>
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__.
<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>
- 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#
C#: Using a generic method
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 work with.
<lang csharp>static void Swap<T>(ref T a, ref T b) {
T temp = a; a = b; b = temp;
}</lang>
Usage:
<lang csharp>int a = 1; int b = 2; Swap(ref a, ref b); // Type parameter is inferred.</lang>
C#: Using tuple syntax
C# 7.0 introduced language support for tuples, which are implemented using the ValueTuple
family of structs. The example below creates a tuple with the values of b
and a
and uses deconstructing assignment to assign the members of the tuple back to the variables.
<lang csharp>int a = 1;
int b = 2;
(a, b) = (b, a);</lang>
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.
The standard utility 'swap' can be used to swap two values:
<lang cpp>std::swap(x,y);</lang>
It will work with any types.
C++11
C++11 adds move constructors which can be more efficient than copy constructors. <lang cpp>template<class T> void swap(T &lhs, T &rhs){
T tmp = std::move(lhs); lhs = std::move(rhs); rhs = std::move(tmp);
}</lang>
Chapel
Chapel includes a swap operator: <lang chapel>a <=> b</lang> and supports swapping directly via tuples and destructuring: <lang chapel>(a, b) = (b, a)</lang> Both variables must be of the same type. The Fibonnacci implementation contains an example.
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.
CMake
CMake has only one data type: the string.
<lang cmake>function(swap var1 var2)
set(_SWAP_TEMPORARY "${${var1}}") set(${var1} "${${var2}}" PARENT_SCOPE) set(${var2} "${_SWAP_TEMPORARY}" PARENT_SCOPE)
endfunction(swap)</lang>
<lang cmake>set(x 42) set(y "string") swap(x y) message(STATUS ${x}) # -- string message(STATUS ${y}) # -- 42</lang>
Because of limitations in CMake, there are a few specific situations where swap() will fail to swap the variables.
- When _SWAP_TEMPORARY is the name of the second variable: <lang cmake>set(x 42)
set(_SWAP_TEMPORARY "string") swap(x _SWAP_TEMPORARY) message(STATUS ${x}) # -- 42 message(STATUS ${_SWAP_TEMPORARY}) # -- 42</lang> Inside swap(), its local variable _SWAP_TEMPORARY shadows the original _SWAP_TEMPORARY from the parent scope, preventing access to the original value.
- When value of either variable is "CACHE" or "PARENT_SCOPE": <lang cmake>string(TOUPPER CACHE x)
set(y "string") swap(x y) # CMake Error... set given invalid arguments for CACHE mode.</lang> swap() can never set a variable to "CACHE" or "PARENT_SCOPE", because these are keywords of set() command.
COBOL
<lang COBOL>
PROGRAM-ID. SWAP-DEMO. AUTHOR. Bill Gunshannon. INSTALLATION. Home. DATE-WRITTEN. 16 December 2021. ************************************************************ ** Program Abstract: ** A simple program to demonstrate the SWAP subprogram. ** ************************************************************ DATA DIVISION. WORKING-STORAGE SECTION. 01 Val1 PIC X(72). 01 Val2 PIC X(72). PROCEDURE DIVISION. Main-Program.
DISPLAY 'Enter a Value: ' WITH NO ADVANCING. ACCEPT Val1. DISPLAY 'Enter another Value: ' WITH NO ADVANCING. ACCEPT Val2. DISPLAY ' ' . DISPLAY 'First value: ' FUNCTION TRIM(Val1) . DISPLAY 'Second value: ' FUNCTION TRIM(Val2) .
CALL "SWAP" USING BY REFERENCE Val1, BY REFERENCE Val2.
DISPLAY ' '. DISPLAY 'After SWAP '. DISPLAY ' '. DISPLAY 'First value: ' FUNCTION TRIM(Val1). DISPLAY 'Second value: ' FUNCTION TRIM(Val2).
STOP RUN. END PROGRAM SWAP-DEMO. IDENTIFICATION DIVISION. PROGRAM-ID. SWAP. AUTHOR. Bill Gunshannon. INSTALLATION. Home. DATE-WRITTEN. 16 December 2021. ************************************************************ ** Program Abstract: ** SWAP any Alphanumeric value. Only limit is 72 ** character size. But that can be adjusted for ** whatever use one needs. ************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TEMP PIC X(72).
LINKAGE SECTION.
01 Field1 PIC X(72). 01 Field2 PIC X(72).
PROCEDURE DIVISION USING BY REFERENCE Field1, BY REFERENCE Field2.
MOVE Field1 to TEMP. MOVE Field2 to Field1. MOVE TEMP to Field2.
GOBACK.
END PROGRAM SWAP.
</lang>
- Output:
Enter a Value: 33 Enter another Value: 77 First value: 33 Second value: 77 After SWAP First value: 77 Second value: 33 -------------------------------- Enter a Value: Hello World Enter another Value: Good Bye First value: Hello World Second value: Good Bye After SWAP First value: Good Bye Second value: Hello World
ColdFusion
This is another standard swap.
<lang cfm><cfset temp = a /> <cfset a = b /> <cfset b = temp /></lang>
Common Lisp
<lang lisp>(rotatef a b)
(psetq a b b a)</lang>
Crystal
Crystal directly supports swapping:
<lang ruby>a, b = b, a</lang>
D
<lang 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);
}</lang>
- Output:
[10, 20] [20, 10] [10, 20]
dc
We use two registers to swap in POSIX dc. <lang dc>1 2 SaSbLaLb 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>
DCL
symbols do not have to be declared, they can be integers or strings, they can change type on the fly <lang DCL>$ a1 = 123 $ a2 = "hello" $ show symbol a* $ gosub swap $ show symbol a* $ exit $ $ swap: $ t = a1 $ a1 = a2 $ a2 = t $ return</lang>
- Output:
$ @generic_swap A1 = 123 Hex = 0000007B Octal = 00000000173 A2 = "hello" A1 = "hello" A2 = 123 Hex = 0000007B Octal = 00000000173
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. <lang Delphi> procedure Swap_T(var a, b: T); var
temp: T;
begin
temp := a; a := b; b := temp;
end; </lang>
Generics were introduced with Delphi 2009 <lang Delphi> 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. </lang>
Déjà Vu
To swap the two top-most items on the stack: <lang dejavu>swap</lang> To swap two variables without needing a third name, using the stack for temporary storage: <lang dejavu>set :a set :b @a @b</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>
EchoLisp
<lang lisp>
- 1)
- a macro will do it, as shown in Racket (same syntax)
(define-syntax-rule (swap a b)
(let ([tmp a]) (set! a b) (set! b tmp)))
(define A 666) (define B "simon") (swap A B) A → "simon" B → 666
- 2)
- The list-swap! function allows to swap two items inside a list, regardless of their types
- This physically alters the list
(define L ' ( 1 2 3 4 🎩 )) (list-swap! L 1 ' 🎩 )
→ (🎩 2 3 4 1)
</lang>
Elena
ELENA 4.1 : <lang elena>import extensions;
swap(ref object v1, ref object v2) {
var tmp := v1;
v1 := v2; v2 := tmp
}
public program() {
var n := 2; var s := "abc"; console.printLine(n," ",s); swap(ref n, ref s); console.printLine(n," ",s)
}</lang>
2 abc abc 2
Elixir
Elixir provides a robust mechanism of pattern matching; the =
operator is actually the match operator. Using the match operator, values can be assigned and variables can be bound or unbound, but only on the left (=:
).
<lang Elixir>
x = 4
y = 5
{y,x} = {x,y} y # => 4 x # => 5
[x,y] = [y,x]
x # => 4
y # => 5
</lang>
Data structures can be used both for matching and for generally destructuring complex data. We can use anonymous functions to create a generic swap in iex. Note: using multiple value requires a data construct on which to match (as opposed to, say, Ruby's a,b = 1,2
), but we can use a list:
<lang Elixir> swap = fn x,y -> [y|x] end [x|y] = swap.(1,2) x # => 2 y # => 1 </lang>
Variables can be bound and rebound regardless of type <lang Elixir> swap_tuple = fn {x,y} -> {y,x} end {a,b} = swap_tuple.({1,:ok}) a # => :ok b # => 1
swap_list = fn [x,y] -> [y,x] end [a,b] = swap_list.([1,"2"]) a # => "2" b # => 1 </lang>
Emacs Lisp
<lang Lisp>(defun swap (a-sym b-sym)
"Swap values of the variables given by A-SYM and B-SYM." (let ((a-val (symbol-value a-sym))) (set a-sym (symbol-value b-sym)) (set b-sym a-val)))
(swap 'a 'b)</lang>
A macro can take variable names unquoted. Here prog1
eliminates the temporary variable above so as to avoid any chance of a name clash between the two variables and the temporary.
<lang Lisp>(defmacro swap (a b)
`(setq ,b (prog1 ,a (setq ,a ,b))))</lang>
A macro could use the cl-lib
psetf
which can store to various kinds of expressions as locations, for example list elements. psetf
evaluates all its values before storing (like the Common Lisp example).
<lang Lisp>(require 'cl-lib) (defmacro swap (a b)
`(cl-psetf ,a ,b ,b ,a))
(setq lst (list 123 456)) (swap (car lst) (cadr lst))
- now lst is '(456 123)</lang>
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).
<lang Erlang> 1> L = [a, 2]. [a,2] 2> lists:reverse(L). [2,a] </lang>
Or swap the items in a tuple (also shown in the shell).
<lang Erlang> 1> T = {2,a}. {2,a} 2> list_to_tuple(lists:reverse(tuple_to_list(T))). {a,2} </lang>
Euphoria
<lang Euphoria> include std/console.e -- for display
object x = 3.14159 object y = "Rosettacode"
{y,x} = {x,y}
display("x is now []",{x}) display("y is now []",{y}) </lang>
x is now Rosettacode y is now 3.14159
objects are generic, and can accept any type.
More strongly-typed variables can be swapped, if their types match or if the value is "acceptable" to the declared type.
In the above example, if we declared y as an integer, the swap would fail, pi is not an integer. If we declare y as an atom, it would succeed, as atoms can contain any valid number. If we declare y as a sequence or string, it would fail, because x is atomic.
F#
<lang fsharp>let swap (a,b) = (b,a)</lang>
Factor
Depending on how you look at it: this task doesn't apply, or it's trivial: <lang factor>swap</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
Fish
Swap the top two values on the stack: <lang fish>$</lang>
Forth
Since the Forth stack can contain pointers to any data type all we need is... <lang forth>swap</lang>
Fortran
<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>
Free Pascal
<lang pascal>{$ifdef fpc}{$mode delphi}{$H+}{$endif} { note this is compiled with delphi mode but will only compile in Free Pascal } { Delphi doesn't support this syntax } procedure swap<T>(var left,right:T); var
temp:T;
begin
temp:=left; left:=right; right:=temp;
end; var
a:string = 'Test'; b:string = 'me';
begin
writeln(a:6,b:6); swap<string>(a,b); writeln(a:6,b:6);
end.</lang>
Output: Test me me Test
FreeBASIC
FreeBASIC already has a built-in generic Swap procedure but a macro can be used to build another one: <lang freebasic>' FB 1.05.0
- Macro Declare_Swap(T)
Sub Swap_##T(ByRef t1 As T, ByRef t2 As T)
Dim temp As T = t2 t2 = t1 t1 = temp
End Sub
- EndMacro
Dim As Integer i, j i = 1 : j = 2
Declare_Swap(Integer) ' expands the macro Swap_Integer(i, j) Print i, j
Dim As String s, t s = "Hello" : t = "World"
Declare_Swap(String) Swap_String(s, t) Print s, t
Print Print "Press any key to exit" Sleep</lang>
- Output:
2 1 World Hello
Frink
The following example will work on all Frink data types:
<lang frink> [b,a] = [a,b] </lang>
FutureBasic
<lang futurebasic> include "ConsoleWindow"
dim as long i, j dim as double x, y dim as Str15 a, b
i = 1059 : j = 62 print i, j swap i, j print i, j print
x = 1.23 : y = 4.56 print x, y swap x, y print x, y print
a = "Hello" : b = "World!" print a, b swap a, b print a, b </lang>
Output:
1059 62 62 1059 1.23 4.56 4.56 1.23 Hello World! World! Hello
Fōrmulæ
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.
Programs in Fōrmulæ are created/edited online in its website, However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
In this page you can see the program(s) related to this task and their results.
Gambas
Click this link to run this code <lang gambas>Public Sub Main() Dim vA As Variant = " World" Dim vB As Variant = 1
Swap vA, vB
Print vA; vB
End</lang> Output:
1 World
Gecho
<lang gecho> 1 !0 2 !1 </lang> Now tape[0] and tape[1] are set to 1 and 2, respectively. <lang gecho> &0 &1 !0 pop !1 </lang> 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.
Go
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. <lang go>a, b = b, a</lang>
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. <lang go>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)
}</lang>
- Output:
3 four four 3
Pass pointers
Somewhat less restrictive, this version allows pointers of any type to be passed, as long as they are the same type. <lang go>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)
}</lang>
- 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}
Gri
Putting &
in a call makes the parameter "call by reference", giving a command the opportunity to modify a variable in the caller. So to swap variables,
<lang Gri>`Swap Vars &.a. &.b.' {
new .temp. .temp. = \.word2. \.word2. = \.word3. \.word3. = .temp. delete .temp.
}
.foo. = 123 .bar. = 456 Swap Vars &.foo. &.bar.
show .foo. " " .bar.
- prints "456 123"</lang>
Or similar to swap synonyms (strings),
<lang Gri>`Swap Syns &\a &\b' {
new \temp \temp = "\.word2." \.word2. = "\.word3." \.word3. = "\temp" delete \temp
}
\quux = "one" \xyzzy = "two" Swap Syns &\quux &\xyzzy
show "\quux \xyzzy"
- prints "two one"</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>
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: <lang groovy>def listSwap = { a, i, j ->
assert (0..<(a.size())).containsAll([i,j]); aj,i = ai,j
}
def list = [2,4,6,8] listSwap(list, 1, 3) assert list == [2,8,6,4]</lang>
Harbour
Harbour has no build-in swap function, however, implemention of a UDF is a fairly easy task. And since it's a dynamic typed lang, there won't be problem while swapping different value types.
Implementation: (We exploit "pass by reference" method on the parameters used) <lang visualfoxpro>PROCEDURE Swap( /*@*/v1, /*@*/v2 )
LOCAL xTmp xTmp := v1 v1 := v2 v2 := xTmp RETURN
</lang> Sample code: <lang visualfoxpro> FUNCTION Main()
LOCAL v1 := "World!", v2 := "Hello" ? v1, v2 // --> World! Hello Swap( @v1, @v2 ) ? v1, v2 // --> Hello World! RETURN 0
</lang>
Haskell
Pure swap
Usually Haskellers prefer to work with immutable data. The following 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>
This swap
function is available in the Data.Tuple
standard library module in GHC 7.0+
Swap mutable variables
The following function swaps the contents of two mutable references. Again the type signature is optional. <lang haskell>import Control.Monad.Ref swap :: MonadRef r m => r a -> r a -> m () swap xRef yRef = do
x<-readRef xRef y<-readRef yRef writeRef xRef y writeRef yRef x</lang>
Icon and Unicon
Icon provides a :=: operator for this. Additionally, there is a reversible exchange operator <-> that reverses the exchange if resumed. <lang icon>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 </lang>
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.
<lang IDL>pro swap, a, b
c = temporary(a) a = temporary(b) b = temporary(c)
end</lang>
IS-BASIC
<lang IS-BASIC>100 DEF SWAP(REF A,REF B) 110 LET T=A:LET A=B:LET B=T 120 END DEF 130 LET A=1:LET B=2 140 PRINT A,B 150 CALL SWAP(A,B) 160 PRINT A,B</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>
A generic destructive swap of named values would instead require reference to the locations being destroyed. Here's an implementation of that:
<lang J>destructiveSwap=:4 :0
t=. do y (y)=: do x (x)=: t i.0 0 NB. result is meaningless
)</lang>
Example use:
<lang J> V1=: 'cat'
V2=: 7 'V1' destructiveSwap 'V2' V1
7
V2
cat</lang>
Java
Java uses references, so it can't swap the values of two variables that don't belong to a class.
<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>
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. <lang javascript>function swap(aName, bName) {
eval('(function(){ arguments[0] = aName; aName = bName; bName = arguments[0] })()' .replace(/aName/g, aName) .replace(/bName/g, bName) )
} var x = 1 var y = 2 swap('x', 'y') </lang>
Solution without eval(), assuming that the code is running in the browser (window is the global object) <lang javascript>function swap(a, b) {
var tmp = window[a]; window[a] = window[b]; window[b] = tmp;
} var x = 1; var y = 2; swap('x', 'y'); </lang>
Another solution for swapping array items using destructing assignment: <lang javascript>const arr = [1, 2, 3, 4, 5]; [arr[0], arr[1]] = [arr[1], arr[0]] </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.
jq
jq is a functional language, so one is more likely to want to swap the two elements of an array than to swap the values of two variables, but jq does have variables and their values can be swapped, for example, using an intermediate variable, say $tmp, as illustrated here:<lang jq>jq -n '1 as $a | 2 as $b | $a as $tmp | $b as $a | $tmp as $b | [$a,$b]'</lang>
Here is a filter that will swap the elements of a two-element array: <lang jq>reverse</lang>
And here is a filter that, if presented with an array, will in effect copy it and then swap the i-th and j-th items, it being understood that if a is an array and k < 0 or k >= (a|length), then a[k] will evaluate to null: <lang jq>def swap(i;j): .[i] as $t | .[i] = .[j] | .[j] = $t;</lang>
Julia
Similar to Python, Julia has built-in support for swapping:
<lang julia>a, b = b, a</lang>
Kotlin
As Kotlin does not support passing parameters by reference and tuples cannot be destructured automatically to pre-existing variables, it's just as easy to swap variable values 'inline' rather than using a function. However, here's one of way of doing it generically using the latter: <lang scala>// version 1.1
fun <T> swap(t1: T, t2: T) = Pair(t2, t1)
fun main(args: Array<String>) {
var a = 3 var b = 4 val c = swap(a, b) // infers that swap<Int> be used a = c.first b = c.second println("a = $a") println("b = $b") var d = false var e = true val f = swap(d, e) // infers that swap<Boolean> be used d = f.first e = f.second println("d = $d") println("e = $e")
}</lang>
- Output:
a = 4 b = 3 d = true e = false
Lambdatalk
<lang scheme>
1) using an Immediately Invoked Function Expression: {{lambda {:x :y} :y :x} hello world} -> world hello
2) or user defined function {def swap {lambda {:x :y} :y :x}} -> swap
3) applied on words (which can be numbers) {swap hello world} -> world hello
{swap hello brave new world} -> brave new hello world
{swap {cons hello brave} {cons new world}} -> (new world) (hello brave) </lang>
Lang5
<lang Lang5>swap # stack reverse # array</lang>
langur
Langur does not have an option for using references (so far). The following is not directly applicable to the task, but values can be swapped using multi-variable assignment, including indexed values (for mutable variables).
<lang langur>var .abc = [1, 2, 3] var .def = [5, 6, 7]
.abc[3], .def[3] = .def[3], .abc[3]
writeln .abc writeln .def</lang>
Prior to 0.10, you would use parentheses as follows.
<lang langur>(.abc[3], .def[3]) = (.def[3], .abc[3])</lang>
- Output:
[1, 2, 7] [5, 6, 3]
Lasso
<lang lasso>define swap(a, b) => (: #b, #a)
local(a) = 'foo' local(b) = 42
local(a,b) = swap(#a, #b) stdoutnl(#a) stdoutnl(#b)</lang>
- Output:
42 foo
Using Decompositional Assignment
<lang lasso>local(a) = 'hair' local(b) = 'moose' local(a,b) = (: #b, #a) stdoutnl(#a) stdoutnl(#b)</lang>
- Output:
moose hair
Lhogho
Lhogho is very similar except that it does not have a localmake opcode.
<lang logo> 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] </lang>
Lingo
A generic swap function is not possible in Lingo, since scalar values are passed by value. But the following solution shows how such generic swapping still can be achieved by executing a single line of code: <lang lingo>on swap (x, y)
return "tmp="&x&RETURN&x&"="&y&RETURN&y&"=tmp"
end</lang> Usage: <lang lingo>x = 1 y = 2 do(swap("x","y")) put x, y -- 2 1</lang>
Lisaac
<lang Lisaac>(a, b) := (b, a);</lang>
LiveCode
<lang LiveCode>put "first" into a1 put "last" into b2 swap a1,b2 put a1 && b2
command swap @p1, @p2
put p2 into p3 put p1 into p2 put p3 into p1
end swap</lang>
Logo
<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>
Logtalk
<lang logtalk>:- object(paws).
:- public(swap/4). swap(First, Second, Second, First).
- - end_object.</lang>
Usage examples: <lang logtalk>| ?- 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</lang> yes
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.
<lang LOLCODE>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</lang>
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: <lang lua> 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 </lang>
Usage example: <lang lua> x, y = 3, 4 print(x, y) --> 3 4 x, y = y, x -- swap print(x, y) --> 4 3 </lang>
M2000 Interpreter
Swap is a statement in M2000 which get two identifiers, variables or array items. Variables and Array items are all internal type of Variant. Normally a numeric variable hold the first type we assign to it. Numeric types are: Double, Single, Decimal, Currency, Decimal, Long, Integer. Boolean is also a type but true and false are not boolean, they are double -1 and 0). When we use Swap internal only variant swap happen, without check of type of variant.
Here we make a local Swap and pass by reference, numbers and strings. References created without testing what type of variant we use. So calling swap we make a swap moving bytes, and for strings this means moving pointers to BSTR type of strings.
<lang M2000 Interpreter> \\ pgramming again Swap (for local use) Module Swap (&a, &b) {
\\ this call internal command - by default is by reference without using character & Swap a, b
} X=20 Y=100 Swap &x, &y Print X, Y, Type$(X)="Double",Type$(Y)="Double" A$="A$" B$="B$" Swap &A$, &B$ Print A$="B$", B$="A$" </lang>
Using Swap (internal command), for variables, groups (only for variables inside groups), pointers to groups, pointers to containers, etc. <lang M2000 Interpreter> a=1000 b=50 Swap a,b Print a, b A$="Hello" B$="There" Swap A$, B$ Print A$, B$ Dim A(4) A(0):=1,2,3,4 Swap A(3), A(2) Print A(3), A(2)
\\ Groups are Values Group alfa {
x=10, y=20
} Group Beta {
x=40, y=50
} \\ with List we show the public variables \\ so among other variables there are: \\ alfa[Group], alfa.x=10, alfa.y=20, beta[group], beta.x=40, beta.y=50 \\ So Alfa.x and Beta.x are simple variables, we can use swap Swap Alfa.x, Beta.x Print Alfa.x, Beta.x Swap Alfa.x, Beta.x List \\ We have to use a third variable to hold value For This {
\\ Local always make a new variable, and shadow any same local variable Local M=alfa alfa=beta beta=m
} \\ Now M erased (defined in For This block) Print Alfa.x=40, Alfa.y=50 Print Beta.x=10, Beta.y=20
\\ Using -> we make pointers to Alfa, and Beta \\ These pointers are valid until Alfa and Beta erased, or get Empty Group (->0) pA->Alfa pB->Beta Print pA=>x=40, pA=>y=50 Print pB=>x=10, pB=>y=20 Swap pA,pB Print pA=>x=10, pA=>y=20 ' pA point to beta Print pB=>x=40, pB=>y=50 'pB point to alfa Print type$(pA)="Group",Valid(pA=>X)=True pA->0 pB->0 Print type$(pA)="Group",Valid(pA=>X)=False \\ These pointers are valid until get Empty Group (->0), they point to a copy of Alfa and Beta \\ both are in heap as "closed groups" pA->(Alfa) pB->(Beta) Print pA=>x, pA=>y \\ swap need variables or arrays \\ pA=>x are closed to object so we have to open the object, and use the open one, where all public variables of group can be used For pA, pB {
Swap .x, .y
} Print pA=>x, pA=>y For pA, pB {
Swap .x, .y
} Print pA=>x, pA=>y Print pB=>x, pB=>y Swap pA,pB Print pA=>x, pA=>y Print pB=>x, pB=>y
L1=lambda x=1->{=x : x++} L2=lambda x=100->{=x : x--} Print L1()=1, L2()=100 Swap L1, L2 Print L1()=99, L2()=2 Swap L1, L2 Print L1()=3, L2()=98 \\ swap change pointers to containers (here pointers to arrays) A=(1,2,3,4,5) B=(6,7,8,9,10) Swap A, B Print A Print B \\ Arrays with () in names are values Dim A(10)=1, B(10)=2 For This {
Dim C() C()=A() A()=B() B()=C()
} Print A() Print 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
Maple
The assignment operator in Maple can swap values, since the right hand side is evaluated before the assignment occurs. <lang Maple> > a, b := 2, "foo": > a;
2
> b;
"foo"
> a, b := b, a: # SWAP > a;
"foo"
> b;
2
</lang>
Mathematica / Wolfram Language
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>
MATLAB / Octave
Numercial swaps are trivial operations. In fact, they are so natural to the language that multiple swaps can be performed simultaneously.
Example: <lang MATLAB>>> 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</lang>
A generic swap (compatible with any variable type) can be performed with the deal command:
<lang MATLAB> >> a = 12 a = 12
>> b = 'foo' b = foo
>> [b, a] = deal (a, b) b = 12 a = foo </lang>
Maxima
<lang maxima>a: 10$ b: foo$
/* A simple way to swap values */ [a, b]: [b, a]$
a; /* foo */ b; /* 10 */
/* A macro to hide this */ swap(x, y) ::= buildq([x, y], ([x, y]: [y, x], 'done))$
swap(a, b)$
a; /* 10 */ b; /* foo */</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>
min
Like many other stack languages, this is trivial. <lang min>swap</lang>
MiniScript
Like many other languages, MiniScript passes references by value, so a straightforward swap is impossible. However, there is a trick: given the map the variales are in (e.g. locals
) and the names of the variables, we can swap them.
<lang MiniScript>swap = function(map, a, b)
temp = map[a] map[a] = map[b] map[b] = temp
end function
x = 1 y = 2 print "BEFORE: x=" + x + ", y=" + y swap(locals, "x", "y") print "AFTER: x=" + x + ", y=" + y</lang> {{out}
BEFORE: x=1, y=2 AFTER: x=2, y=1
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
Nemerle
For pairs, namespace Nemerle.Utility.Pair contains Swap(): <lang Nemerle>def coords = (1, -1); def invcoords = Swap(coords);</lang> Or to swap two mutable variables of the same type:<lang Nemerle>a <-> b;</lang> But, enough about built in functionality, let's demonstrate using generics: <lang Nemerle>Swap[T, U] (a : T, b : U) : U * T {
(b, a)
}</lang>
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. <lang NetRexx>/* 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
</lang>
- 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>
NewLISP
<lang NewLISP>(swap a b)</lang>
Nial
Like J <lang nial>|reverse 1 2 =2 1</lang>
Nim
Builtin procedure swap
. Example usage:
<lang nim>swap(a, b)</lang>
OASYS Assembler
You can swap variable %A# with %B# by writing: <lang oasys_oaa>%A#%B#<%B#%A#<>></lang> A method which can be called to implement it can be written like: <lang oasys_oaa>[&SW,A^,B^],A^<,B^<<,B^<,A^<<>></lang> To call such method: <lang oasys_oaa>+%A#%B#&SW</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>
Oforth
<lang Oforth>swap</lang>
OxygenBasic
<lang>
macro Swap(a,b, c) typeof(a) c c=a a=b b=c end macro
'demo with compound types: '========================= type point { float x,y} point p={1,2} point q={3,4} swap p,q print "p: " p.x "," p.y 'p: 3,4 print "q: " q.x "," q.y 'q: 1,2
</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>
PARI/GP
Pari is near-typeless—everything is a GEN. <lang parigp>my(tmp=a); a=b; b=tmp;</lang>
<lang parigp>[a,b]=[b,a]</lang>
Pascal
Standard Pascal does not have generics, but FreePascal has a start: <lang pascal>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.</lang>
- Output:
4 3 3 4
since FreePascal version 3.2.0: <lang pascal>program generic_test; {$mode objfpc}{H+} uses
SysUtils;
generic procedure GSwap<T>(var L, R: T); var
Tmp: T;
begin
Tmp := L; L := R; R := Tmp;
end;
var
I, J: Integer;
begin
I := 100; J := 11; WriteLn('I = ', I, ', J = ', J); specialize GSwap<Integer>(I, J); WriteLn('I = ', I, ', J = ', J);
end.</lang>
- Output:
I = 100, J = 11 I = 11, J = 100
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>
Phix
The following applies to any types. Subscripting and nesting may also be used freely on either side.
{a,b} = {b,a}
Phixmonti
Applies to any types. <lang Phixmonti>a b var a var b</lang>
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)
PL/I
Using the preprocessor
<lang pli> %swap: procedure (a, b);
declare (a, b) character; return ( 't=' || a || ';' || a || '=' || b || ';' || b '=t;' );
%end swap; %activate swap;</lang>
The statement:-
swap (p, q);
is replaced, at compile time, by the three statements as in-line code:
t = p; p = q; q = t;
Using generic procedures
<lang pli>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);</lang>
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)
Completely generic code using the pre-processor
<lang pli>%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);</lang>
The code generated by 'swap(c1, c2);' looks like
<lang pli> 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;</lang>
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;
Or, using "Like"
The key problem is that a temporary storage area is needed (there alas being no compiler-recognised "swap" statement), and the waystation variable must have the correct type, nor can there be reliance on a suitable "t" variable being available for use. Devising a different Swap for each type of parameter would be tedious and tiresome to use, however one could employ the "generic" facility as above demonstrated, and use the pre-processor to generate a collection of Swap routines by it employing a template and stepping through a list of accommodated types.
Instead, the first example can be generalised via two steps. Firstly, it is possible to declare a variable to be of a type "like" some named variable (otherwise a third parameter naming the type could be supplied), and secondly, placing the in-line code between Begin ... End; means that any declaration is local to within that block only. Further, this bracketing allows a Swap to be invoked via an if-statement, as in If ... then Swap(x,y);
- otherwise there would be a mess. Thus:
<lang pli>
%Swap:Procedure(a,b);
declare (a,b) character; /*These are proper strings of arbitrary length, pre-processor only.*/ return ('Begin; declare t like '|| a ||'; t='|| a ||';'|| a ||'='|| b ||';'|| b ||'=t; End;');
%End Swap;</lang> Whereupon a Swap(this,that); would generate a rather longer text of in-line source code. This and other text expansions caused odd difficulties, because the 1980s compiler replaced the invocation by the expansion and then reformatted the result into lines of 71 characters (not 72) as necessary, and then, since any additional lines were given the same source sequence number as the original line, added 100000 as needed to generate strictly increasing sequence numbers. If many lines overflowed, eventually the sequence field (eight digits) overflowed, and all following source lines thereby acquired the same source sequence number. For this and other reasons, one approach was two-stage compilation: the output from the pre-processor stage could be saved and further compilation cancelled. That file could then be resequenced and fed to the pl/i compiler afresh.
Such a file would have the expansion of Swap(this,that) as follows (but with added layout here): <lang pli> Begin;
declare t like this; t = this; this = that; that = t;
End;</lang>
There would however be trouble if the type of this differed from the type of that, and a pl/i compiler may not generate a warning because it handles many type conversions in an assignment without complaint. There are no pre-processor enquiry functions to inspect the types at pre-processor time - if there were, a more accomplished Swap procedure could produce suitable error reports, which can be classed as "warning" or "severe", etc. The "storage" function produces its result at run time, but, each invocation of Swap being compiled would have its actual parameters known as the compiler dealt with the code produced by that invocation of Swap, and so for each invocation, the results of "storage" would be constants - except for items that were allocated at run time.
The bracketing could be via DO; ... END;
instead of BEGIN; ... END;
but in that case the declared temporary variable would be visible outside its fragment and there could be conflicts, either of differing type for the same name or of multiple declaration. This could be solved by adjusting Swap to generate a different name each time. One could try a prefix (or suffix) to the name of the first parameter (thus generating say SwapTemp_this
or similar), but there would still be difficulty if there were multiple swaps involving the same variable. Instead, Swap could count its invocations and generate a name involving that. Temporary variables would then litter the storage area, and they could consume a lot of space. On the other hand, the BEGIN; ... END;
arrangement, though typically involving temporary space on the data stack, could have its own constraints. In the 1980s, the IBM mainframe pl/i compiler had a limit of no more than 240 (or so) BEGIN; ... END;
blocks, plus procedure blocks, plus a few other items, in any one compilation otherwise there would be a failure "in phase PI". Separate compilation and the linking of pieces introduced its own oddities, as when pieces had been compiled with different compiler options.
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".
PostScript
Works with anything you can put on the operand stack:<lang PostScript>exch</lang>
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
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.
Quackery
Quackery objects reside on the stack while in use. The word swap exchanges the top and second item on the stack. The closest thing Quackery has to variables are ancillary stacks. The word exchange defined here exchanges the top items on two ancillary stacks.
<lang Quackery>[ over take over take
2swap dip put put ] is exchange ( s s --> )</lang>
R
R function arguments are passed by value, not by reference. You can work around this, however, by using their names and environment:
<lang R>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)
}</lang>
Usage:
> x <- 1 > y <- 2 > swap('x', 'y') > cat(x, y) 2 1
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>
- 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))
</lang>
Raku
(formerly Perl 6)
Similar to Perl 5. Raku 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:
<lang perl6>($x, $y) .= reverse;</lang>
REBOL
<lang REBOL>REBOL [ Title: "Generic Swap" 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.
Retro
<lang Retro>swap</lang>
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.)
using temp
<lang rexx>a = 'I see you.' b = -6
_temp_ = a /*swap ··· */
a = b /* A ··· */ b = _temp_ /* and B */ </lang>
using VALUE
This version will work with any values. <lang rexx>a = "bull feathers" b = 10
a= value('b', a) /*swap A and B */</lang>
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.)
<lang rexx>a = -199e-12
b = 12.
parse value a b with b a /*swap A and B */</lang>
Note that some REXX interpreters handle whitespace differently, some honor whitespace other than blanks,
others don't (particularly the older versions).
Ring
<lang ring> a = 1 b = 2 temp = a a = b b = temp see "a = " + a + nl see "b = " + b + nl </lang>
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 <lang RLaB> 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 </lang>
Ruby
Ruby has support for swapping built in:
<lang ruby>a, b = b, a</lang>
But the task calls for a "generic swap method", so here it is:
<lang ruby>def swap(a, b)
return b, a
end</lang>
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:
<lang ruby>x = 42 y = "string" x, y = swap x, y puts x # prints string puts y # prints 42</lang>
Run BASIC
Run BASIC does not have support for swapping built in: <lang runbasic>a = 1 b = 2 '----- swap ---- tmp = a a = b b = tmp end</lang>
Rust
Rust does not allow for swapping the value of two variables with different types, but if the types are the same it can be done using generic types and lifetimes. <lang rust> fn generic_swap<'a, T>(var1: &'a mut T, var2: &'a mut T) {
std::mem::swap(var1, var2)
} </lang> This function can be used in e.g. the following ways: <lang rust> fn main() {
let mut a: String = "Alice".to_owned(); let mut b: String = "Bob".to_owned(); let mut c: i32 = 1; let mut d: i32 = 2;
generic_swap(&mut a, &mut b); generic_swap(&mut c, &mut d);
println!("a={}, b={}", a, b); println!("c={}, d={}", c, d);
} </lang>
- Output:
a=Bob, b=Alice c=2, d=1
Sather
A possible way that needs the type of the objects to be specified:
<lang sather>class SWAP{T} is
swap(inout a, inout b:T) is t ::= a; a := b; b := t; end;
end;</lang>
<lang sather>class MAIN is
main is x ::= 10; y ::= 20; SWAP{INT}::swap(inout x, inout y); #OUT + x + ", " + y + "\n"; end;
end;</lang>
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.
<lang scala>def swap[A,B](a: A, b: B): (B, A) = (b, a)</lang>
Scheme
<lang 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)</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>
SenseTalk
<lang sensetalk> set [x,y] to [13,"Hello"] -- assign values to two variables put x,y put set [x,y] to [y,x] -- swap the variable values put x,y </lang> Output: <lang sensetalk> 13 Hello
Hello 13 </lang>
Sidef
<lang ruby>func swap(Ref a, Ref b) {
var tmp = *a; *a = *b; *b = tmp;
}</lang>
or: <lang ruby>func swap(Ref a, Ref b) {
(*a, *b) = (*b, *a);
}</lang>
or: <lang ruby>func swap(Ref a, Ref b) {
[*a, *b] » (b, a);
}</lang>
The swap functions must be called with variable references.
<lang ruby>var (x, y) = (1, 2); swap(\x, \y);</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." [
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
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>
Stata
The Mata swap function is built-in.
<lang stata>mata a=1,2,3 b="ars longa vita brevis" swap(a, b) end</lang>
Notice that swap only works with variables, not with indexed arrays. For instance, swap(a[i],a[j]) does not work. One would instead write a[(i,j)]=a[(j,i)].
Swift
<lang swift>func swap<T>(inout a: T, inout b: T) {
(a, b) = (b, a)
}</lang>
Note: The Swift standard library has already a swap function.
Tcl
<lang tcl>proc swap {aName bName} {
upvar 1 $aName a $bName b lassign [list $a $b] b a
}</lang>
<lang tcl>proc swap {aName bName} {
upvar 1 $aName a $bName b foreach {b a} [list $a $b] break
}</lang>
alternatively:
<lang tcl>proc swap {aName bName} {
upvar 1 $aName a $bName b set a $b[set b $a; list]
}</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>
- Output:
before a=1 b=2 after a=2 b=1
An idiomatic method:
<lang tcl>set a 1 set b 2 puts "before\ta=$a\tb=$b" set a $b[set b $a;lindex {}] puts "after\ta=$a\tb=$b"</lang>
- Output:
before a=1 b=2 after a=2 b=1
ThinBASIC
Generic function, swap the content of two variables. <lang ThinBASIC>Swap Var1, Var2</lang>
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.
<lang ti89b>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</lang>
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: <lang trith>swap</lang>
TXR
TXR Lisp has a swap
macro operator. However, an operator just like it can be user-defined (let us call it swp
). Moreover, the user-defined version can be just as robust, ensuring once-only evaluation for both expressions.
Swapping can be achieved with pset
and rotate
also. We won't use these in the following examples.
Naive macro
This allows multiple evaluation of the argument expressions.
<lang txrlisp>(defmacro swp (left right)
(with-gensyms (tmp) ^(let ((,tmp ,left)) (set ,left ,right ,right ,tmp))))</lang>
Using placelet
TXR Lisp's placelet
macro allows the programmer to bind a lexically scoped alias for a syntactic place. The place can be accessed and stored through this alias. Yet, the place is evaluated only once. With placelet
it is easy to write many kinds of place-manipulating macros very simply. We can write a robust swap which evaluates the left and right expressions just once:
<lang txrlisp>(defmacro swp (left right)
(with-gensyms (tmp lpl rpl) ^(placelet ((,lpl ,left) (,rpl ,right)) (let ((,tmp ,lpl)) (set ,lpl ,rpl ,rpl ,tmp)))))</lang>
Using place expanders
Finally, the following is closely based on how swap
is actually implemented in TXR Lisp's library. This explicitly uses the general mechanism for handling places, on which placelet
is based also:
<lang txrlisp>(defmacro swp (left right :env env)
(with-gensyms (tmp) (with-update-expander (l-getter l-setter) left env (with-update-expander (r-getter r-setter) right env ^(let ((,tmp (,l-getter))) (,l-setter (,r-getter)) (,r-setter ,tmp))))))</lang>
with-update-expander
is a macro which writes code for accessing and updating a place, and makes that code available as local macros. The result is wrapped around the body of code passed to the macro; the body can access these functions, using a backquote to insert the symbols which refer to them. For instance the macro call (,l-getter)
expands to code which accesses the prior value of the left
place, and (,r-setter ,tmp)
stores the value of the temporary variable into the right
place.
uBasic/4tH
Since uBasic/4tH has a stack (just like Forth) and it is an integer BASIC only, this is quite trivial. However, making a function or procedure with the same functionality is impossible, because there is no way to pass variables by reference. <lang>a = 5 : b = 7 Print a,b Push a,b : a = Pop() : b = Pop() Print a,b</lang>
UNIX Shell
<lang bash>$ swap() { typeset -n var1=$1 var2=$2; set -- "$var1" "$var2"; var1=$2; var2=$1; } $ a=1 b=2 $ echo $a $b 1 2 $ swap a b $ echo $a $b 2 1 $ swap a b $ echo $a $b 1 2</lang>
<lang bash>$ swap() { local var1=$1 var2=$2; set -- "${!var1}" "${!var2}"; declare -g "$var1"="$2" "$var2"="$1"; } $ a=1 b=2 $ echo $a $b 1 2 $ swap a b $ echo $a $b 2 1 $ swap a b $ echo $a $b 1 2</lang>
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
- 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>
Verbexx
<lang verbexx>// user-defined swap verb -- parms are passed by alias, not value, so they can be updated:
'<==> [_a] @FN [_b] { _a _b = _b _a } by_alias: ;
// test out swap verb
@VAR a = 12345; @VAR b = "*****";
@SAY "a=" a " b=" b;
\b <==> \a; // "\" verb prevents evaluation of a and b here,
// so they can be passed by alias to <==>
@SAY "a=" a " b=" b;
a b = b a; // swap them back, just using the usual = verb
@SAY "a=" a " b=" b;</lang>
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.
Visual Basic .NET
Semantically identical to C# <lang vbnet>Sub Swap(Of T)(ByRef a As T, ByRef b As T)
Dim temp = a a = b b = temp
End Sub</lang>
Usage: <lang vbnet>Dim a = 1, b = 2 Swap(a, b)</lang>
−
Visual FoxPro
Since Visual FoxPro is not strongly typed, this will work with any data types. <lang vfp> *!* Swap two variables LOCAL a, b a = 1 b = "Hallo" ? a, b *!* Pass a and b by reference Swap(@a, @b) ? a, b
PROCEDURE Swap(v1, v2) LOCAL dum dum = v1 v1 = v2 v2 = dum ENDPROC
</lang>
- Output:
1 Hallo Hallo 1
Wart
There's a primitive for modifying bindings. <lang wart>(swap! x y)</lang>
New bindings can be created in parallel. <lang wart>let (x y) (list y x)
...</lang>
Wren
Wren is dynamically typed and, once a variable has been declared, a value of any type can be assigned to it. Generic programming is not therefore a problem here.
However, it is still not possible to write a generic swap function. This is because all variables are passed to functions or methods by value and prescribing that they should be passed by reference instead is not supported. Moreover, variables of simple types (numbers, bools and nulls) are never boxed and so a function cannot mutate the original variable.
Perhaps the nearest we can get to a generic swap function is to pass the variables in a list (the list's address is then passed by value under the hood), swap the list elements and then unpack the list to the original variables after the function returns.
Another approach would be to box simple variables (using a user defined class) so that they can be mutated. However, the problem with this is that they usually need to be 'unboxed' when the function returns.
Both approaches are illustrated below. <lang ecmascript>var swap = Fn.new { |l|
var t = l[0] l[0] = l[1] l[1] = t
}
var a = 6 var b = 3 var c = [a, b] swap.call(c) // pass a list instead of individual variables a = c[0] // unpack b = c[1] // ditto System.print("a is now %(a)") System.print("b is now %(b)") System.print()
// all user defined classes are reference types class Box {
construct new(v) { _v = v } v { _v } v=(value) { _v = value }
}
// by passing boxed arguments we can mutate them var boxSwap = Fn.new { |a, b|
var t = a.v a.v = b.v b.v = t
}
var d = Box.new(4) var e = Box.new(8) boxSwap.call(d, e) d = d.v // unbox e = e.v // ditto System.print("d is now %(d)") System.print("e is now %(e)")</lang>
- Output:
a is now 3 b is now 6 d is now 8 e is now 4
XBS
There is a keyword for swapping variables. Here is an example of 2 ways to swap variables
Swap Keyword
<lang XBS>set x=1; set y=2; log("Before Swap"); log(x); log(y); swap x y; log("After Swap"); log(x); log(y);</lang>
- Output:
Before Swap 1 2 After Swap 2 1
Swap Function
<lang XBS>set x = 1; set y = 2; func Swap(a,b){ send[b,a]; } set z = Swap(x,y); x=z[0]; y=z[1]; log(x) log(y);</lang>
- Output:
2 1
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.
<lang XPL0>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);
]</lang>
- Output:
4.00000 3.00000
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]
Z80 Assembly
Zilog Z80
The Z80 has a few commands for swapping register contents:
EX DE,HL
will swap the contents ofDE
with the contents ofHL
. This is helpful because many instructions are only compatible withHL
.EXX
will swap outBC
,DE
, andHL
with their "shadow registers." To switch back to the standard registers useEXX
again. The accumulator and flags have their own shadow registers, which can be swapped withEX AF,AF'
.EX (SP),HL
will exchange HL with the top two bytes of the stack.- Any two registers that you can
PUSH/POP
can be exchanged by pushing both registers and popping them in the "wrong" order on purpose. For example, to swap theIX
andIY
registers:
<lang z80>push ix push iy pop ix ;the value that was once in IY is now in IX pop iy ;the value that was once in IX is now in IY</lang>
Swapping two memory locations takes a bit more work. The Z80 can do an 8-bit swap or a 16-bit swap on memory. There are several ways to do this, but the methods differ slightly depending on which addressing modes you use. Only the accumulator can load/store a single byte directly from/to memory, but the register pairs BC
, DE
, HL
, SP
, IX
, and IY
can all load a 16-bit word directly from memory, or vice versa.
<lang z80>;8-bit swap using the stack.
ld a,(&C000) push af
ld a,(&D000) ld (&C000),a ;store the byte at &D000 into &C000
pop af ;now a = the byte at &C000 ld (&D000),a ;now the byte at &D000 equals the byte that was originally at &C000</lang>
<lang z80>;16-bit swap: ld hl,(&C000) ;load the byte at &C000 into L and the byte at &C001 into H. ld de,(&D000) ;load the byte at &D000 into E and the byte at &D001 into D. ld (&D000),hl ;store the contents of L into &D000 and H into &D001. ld (&C000),de ;store the contents of E into &C000 and D into &C001.</lang>
Game Boy
The Game Boy is missing all the exchange commands that the Z80 and 8080 both have. There are no shadow registers, EX
, or EXX
, as well as loading/storing 16-bit register pairs directly from/to memory. The only register that can store directly to memory is the stack pointer (SP
), and it can only store, not load! But not all is lost. EX DE,HL
can be mimicked with the following sequence; although it's much slower than the Zilog's EX DE,HL
, it's as quick as it possibly can be.
<lang z80>push hl ld h,d ld L,e ;store de into HL. This is much faster than "push de pop hl." pop de ;put old HL into DE</lang>
Swapping from memory must be done one byte at a time on the Game Boy. The Game Boy exclusive LDI/LDD
commands can help us in this task.
<lang z80>ld hl,&C000
push bc
ldi a,(hl) ;equivalent of "ld a,(hl) inc hl" but is faster than the two separately. Some assemblers call this "ld a,(hl+)"
ld c,a
ld a,(hl) ;we don't need to increment hl this time. There's no wasted time or bytecode if we did however.
ld b,a ;on Zilog Z80 we would have just done "LD BC,(&C000)" but Game Boy can't do that.
- now we do the swap.
ld hl,&D000
ld a,(hl) ;get the byte at &D000 ld (&C000),a ;store it into &C000 ld (hl),c ;store the old byte at &C000 into &D000
inc hl ;inc HL to &D001
ld a,(hl) ;get the byte at &D001 ld (&C001),a ;store it at &C001 ld (hl),b ;store the old byte at &C001 into &D001 pop bc</lang>
zkl
As a general case, no. Here a fake around for two known classes (which are the same for ease of example): <lang zkl>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);</lang>
- Output:
1 : 2 2 : 1
- Programming Tasks
- Basic language learning
- 11l
- 360 Assembly
- 6502 Assembly
- 8086 Assembly
- 8th
- ACL2
- Action!
- Action! Tool Kit
- Ada
- Aime
- ALGOL 68
- Amazing Hopper
- AmigaE
- AppleScript
- Arc
- Arturo
- AutoHotkey
- AWK
- Applesoft BASIC
- Axe
- Batch File
- BaCon
- BBC BASIC
- Beads
- BQN
- Bracmat
- Burlesque
- C
- C sharp
- C++
- Chapel
- Clojure
- CMake
- COBOL
- ColdFusion
- Common Lisp
- Crystal
- D
- Dc
- DCL
- Delphi
- Déjà Vu
- E
- EchoLisp
- Elena
- Elixir
- Emacs Lisp
- Erlang
- Euphoria/Omit
- Euphoria
- F Sharp
- Factor
- Falcon
- Fish
- Forth
- Fortran
- Free Pascal
- FreeBASIC
- Frink
- FutureBasic
- Fōrmulæ
- Gambas
- Gecho
- Go
- Gri
- Groovy
- Harbour
- Haskell
- Icon
- Unicon
- IDL
- IS-BASIC
- J
- Java
- JavaScript
- Joy
- Jq
- Julia
- Kotlin
- Lambdatalk
- Lang5
- Langur
- Lasso
- Lhogho
- Lingo
- Lisaac
- LiveCode
- Logo
- Logtalk
- LOLCODE
- Lua
- M2000 Interpreter
- M4
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- Maxima
- MAXScript
- Metafont
- Min
- MiniScript
- Modula-3
- Nemerle
- NetRexx
- NewLISP
- Nial
- Nim
- OASYS Assembler
- OCaml
- Oforth
- OxygenBasic
- Oz
- PARI/GP
- Pascal
- Perl
- Phix
- Phix/basics
- Phixmonti
- PHP
- PicoLisp
- PL/I
- Pop11
- PostScript
- PowerShell
- Prolog
- PureBasic
- Python
- Quackery
- R
- Racket
- Raku
- REBOL
- Retro
- REXX
- Ring
- RLaB
- Ruby
- Run BASIC
- Rust
- Sather
- Scala
- Scheme
- Seed7
- SenseTalk
- Sidef
- Slate
- Smalltalk
- SNOBOL4
- Standard ML
- Stata
- Swift
- Tcl
- ThinBASIC
- TI-89 BASIC
- Trith
- TXR
- UBasic/4tH
- UNIX Shell
- Ursala
- V
- VBScript
- Verbexx
- Visual Basic
- Visual Basic .NET
- Visual FoxPro
- Wart
- Wren
- XBS
- XPL0
- Yorick
- Z80 Assembly
- Zkl
- Bc/Omit
- XSLT/Omit