Reverse a string

From Rosetta Code
Revision as of 07:49, 16 September 2024 by Aartaka (talk | contribs) (Add ed example)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Reverse a string
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Take a string and reverse it.

For example, "asdf" becomes "fdsa".


Extra credit

Preserve Unicode combining characters.

For example, "as⃝df̅" becomes "f̅ds⃝a", not "̅fd⃝sa".


Other tasks related to string operations:
Metrics
Counting
Remove/replace
Anagrams/Derangements/shuffling
Find/Search/Determine
Formatting
Song lyrics/poems/Mad Libs/phrases
Tokenize
Sequences



0815

This program reverses each line of its input.

}:r:     Start reader loop.
  !~>&   Push a character to the "stack".
  <:a:=- Stop reading on newline.
^:r:
@>       Rotate the newline to the end and enqueue a sentinel 0.
{~       Dequeue and rotate the first character into place.
}:p:
  ${~    Print the current character until it's 0.
^:p:
#:r:     Read again.
Output:
echo -e "foo\nbar" | 0815 rev.0
oof
rab

11l

reversed(string)

360 Assembly

For maximum compatibility, this program uses only the basic instruction set (S/360) and an ASSIST macro (XPRNT) to keep the code as short as possible.

*        Reverse a string          21/05/2016
REVERSE  CSECT
         USING  REVERSE,R13        base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         STM    R14,R12,12(R13)    prolog
         ST     R13,4(R15)         "
         ST     R15,8(R13)         "
         LR     R13,R15            "
         MVC    TMP(L'C),C         tmp=c
         LA     R8,C               @c[1]
         LA     R9,TMP+L'C-1       @tmp[n-1]
         LA     R6,1               i=1
         LA     R7,L'C             n=length(c)
LOOPI    CR     R6,R7              do i=1 to n 
         BH     ELOOPI             leave i
         MVC    0(1,R8),0(R9)        substr(c,i,1)=substr(tmp,n-i+1,1)
         LA     R8,1(R8)             @c=@c+1
         BCTR   R9,0                 @tmp=@tmp-1
         LA     R6,1(R6)             i=i+1
         B      LOOPI              next i
ELOOPI   XPRNT  C,L'C              print c
         L      R13,4(0,R13)       epilog
         LM     R14,R12,12(R13)    "
         XR     R15,R15            "
         BR     R14                exit
C        DC     CL12'edoC attesoR'
TMP      DS     CL12
         REGEQU
         END    REVERSE
Output:
Rosetta Code

This second example uses MVCIN introduced in S/370 architecture.

*        Reverse a string          25/04/2020
REVERSEI CSECT
         USING  REVERSEI,R13       base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         STM    R14,R12,12(R13)    prolog
         ST     R13,4(R15)         "
         ST     R15,8(R13)         "
         LR     R13,R15            "
         MVCIN  BB,AA+L'AA-1
         XPRNT  BB,L'BB            print bb
         L      R13,4(0,R13)       epilog
         LM     R14,R12,12(R13)    "
         XR     R15,R15            "
         BR     R14                exit
AA       DC     CL12'edoC attesoR' a
BB       DS     CL(L'AA)           b
         REGEQU
         END    REVERSEI
Output:
Rosetta Code

8080 Assembly

This is a routine that reverses a string with a terminator in place.

Back when the 8080 was commonly used, there wasn't really a set standard about how to store strings. Zero-terminated strings were already in use by the C language (and therefore, programs written in it). CP/M, on the other hand, used $ as a string terminator. (Later versions would even allow the programmer to set it himself with a system call!) Therefore, to allow for some flexibility, this routine also allows you to set it yourself, using the A register.

There were other ways of representing strings, like setting the high bit of the last character to mark the end (saves a byte per string, but halves the character set size), or prepending the length (making it unnecessary to scan through the string to find the end, but capping string size at 255 bytes), or even storing tuples of lengths and pointers (easy for a garbage collector to manage). These are not supported, as they would be completely different routines, though the arrayrev entry point will reverse a byte array if you already have its start and end.

Unicode is not supported either. While it wouldn't be impossible to do, I think writing a full UTF-8 implementation is beyond the scope of the task.


		org	100h
		jmp	test

		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;; Reverse a string under HL in place
		;; strrev0: reverse a zero-terminated string
		;; strrev: reverse a string terminated by the value in A
		;; arrayrev: reverse bytes starting at DE and ending at HL
		;; Destroys a, b, d, e, h, l registers. 

strrev0:	xra	a	; Zero A
strrev:		mov	d,h	; Copy string begin to DE
		mov	e,l
		dcx	h	
strrev_end:	inx	h	; Find string end in HL
		cmp	m
		jnz	strrev_end
		dcx	h	; Point HL to last character
arrayrev:	mov	a,h	; If HL<DE, we're done
		cmp	d		
		rc
		mov	a,l
		cmp	e
		rc
		ldax	d	; Get low character in string
		mov	b,m	; Get high character in string
		mov	m,a	; Swap them
		mov	a,b
		stax	d
		inx	d	; Move the low pointer up,
		dcx	h	; and the high pointer down
		jmp	arrayrev

		
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;; Test code (CP/M): ask the user for a string, and reverse it
		
prompt:		db	" :gnirts a retne esaelP$"
bufdef:		db	127, 0
buf:		ds	128		; one extra byte that will remain 0

newline:	lxi	d,newline_str
		mvi	c,9
		jmp	5
newline_str:	db	13, 10, "$"

test:		;; Reverse and output the prompt
		mvi	a,'$'		; CP/M string is $-terminated
		lxi	h,prompt	; Reverse the string
		call	strrev
		lxi	d,prompt	; Output the string
		mvi	c,9
		call	5
		
		;; Get input and reverse it
		lxi	d,bufdef	
		mvi	c,10
		call	5
		call	newline
		lxi	h,buf
		call	strrev0		; 0-terminated due to buffer definition
		
		;; Output reversed input
		lxi	h,buf
loop:		mov	e,m		
		xra	a
		ora	e
		rz			; Stop when done
		mvi	c,2
		push	h
		call	5
		pop	h
		inx	h
		jmp	loop

8th

In 8th strings are UTF-8 and the language retains characters per-se:

"abc" s:rev
Output:
"cba"

ACL2

(reverse "hello")

ACL2 does not support unicode.

Action!

PROC Reverse(CHAR ARRAY src,dst)
  BYTE i,j

  i=1 j=src(0) dst(0)=j
  WHILE j>0
  DO
    dst(j)=src(i)
    i==+1 j==-1
  OD
RETURN

PROC Test(CHAR ARRAY src)
  CHAR ARRAY dst(40)
  
  Reverse(src,dst)
  PrintF("'%S' -> '%S'%E",src,dst)
RETURN

PROC Main()
  Test("Hello World!")
  Test("123456789")
  Test("!noitcA iratA")
RETURN
Output:

Screenshot from Atari 8-bit computer

'Hello World!' -> '!dlroW olleH'
'123456789' -> '987654321'
'!noitcA iratA' -> 'Atari Action!'

ActionScript

function reverseString(string:String):String
{
	var reversed:String = new String();
	for(var i:int = string.length -1; i >= 0; i--)
		reversed += string.charAt(i);
	return reversed;
}

function reverseStringCQAlternative(string:String):String
{
	return string.split('').reverse().join('');
}

Ada

with Ada.Text_IO; use Ada.Text_IO;
 
procedure Reverse_String is
   function Reverse_It (Item : String) return String is
      Result : String (Item'Range);
   begin
      for I in Item'range loop
         Result (Result'Last - I + Item'First) := Item (I);
      end loop;
      return Result;
   end Reverse_It;
begin
   Put_Line (Reverse_It (Get_Line));
end Reverse_String;

Agda

Using the Agda standard library, version 1.7 .

module ReverseString where

open import Data.String using (String ; fromList ; toList)
open import Data.List using (reverse)

reverse-string : String  String
reverse-string s = fromList (reverse (toList s))

Aime

o_(b_reverse("Hello, World!"), "\n");

ALGOL 68

Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386
PROC reverse = (REF STRING s)VOID:
  FOR i TO UPB s OVER 2 DO
    CHAR c = s[i];
    s[i] := s[UPB s - i + 1];
    s[UPB s - i + 1] := c
  OD;
 
main:
(
  STRING text := "Was it a cat I saw";
  reverse(text);
  print((text, new line))
)
Output:
was I tac a ti saW

Amazing Hopper

#include <hopper.h>

main:
   s="mañana será otro día"
   reverse(s),strtoutf8, println
{0}return
Output:
aíd orto áres anañam

Apex

String str = 'Hello World!';
str = str.reverse();
system.debug(str);

APL

      'asdf'
fdsa

AppleScript

Works with: AppleScript version 2.0 or newer.
reverseString("Hello World!")

on reverseString(str)
    reverse of characters of str as string
end reverseString

NB. Since coercing lists to string involves the interpolation of the current value of AppleScript's text item delimiters between the list items, it's considered best practice to set the delimiters explicitly to their default value of {""} (or just "") before doing an operation like this, in case they've been set to something else elsewhere in the script:

reverseString("Hello World!")

on reverseString(str)
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to ""
    set reversedString to reverse of characters of str as text
    set AppleScript's text item delimiters to astid
    return reversedString
end reverseString

Or, if we want a polymorphic reverse() for both strings and lists, we can define it either in terms of a generic fold/reduce, or using the built-in method for lists:

-- Using either a generic foldr(f, a, xs)

-- reverse1 :: [a] -> [a]
on reverse1(xs)
    script rev
        on |λ|(a, x)
            a & x
        end |λ|
    end script
    
    if class of xs is text then
        foldr(rev, {}, xs) as text
    else
        foldr(rev, {}, xs)
    end if
end reverse1

-- or the built-in reverse method for lists

-- reverse2 :: [a] -> [a]
on reverse2(xs)
    if class of xs is text then
        (reverse of characters of xs) as text
    else
        reverse of xs
    end if
end reverse2


-- TESTING reverse1 and reverse2 with same string and list ---------------------------------------------------------------------------
on run
    script test
        on |λ|(f)
            map(f, ["Hello there !", {1, 2, 3, 4, 5}])
        end |λ|
    end script
    
    map(test, [reverse1, reverse2])
end run


-- GENERIC FUNCTIONS ---------------------------------------------------------------------------

-- foldr :: (a -> b -> a) -> a -> [b] -> a
on foldr(f, startValue, xs)
    tell mReturn(f)
        set v to startValue
        set lng to length of xs
        repeat with i from lng to 1 by -1
            set v to |λ|(v, item i of xs, i, xs)
        end repeat
        return v
    end tell
end foldr

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- Lift 2nd class handler function into 1st class script wrapper 
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn
Output:
{{"! ereht olleH", {5, 4, 3, 2, 1}}, 
 {"! ereht olleH", {5, 4, 3, 2, 1}}}

Arturo

str: "Hello World"

print reverse str
Output:
dlroW olleH

AutoHotkey

"Normal" version:
MsgBox % reverse("asdf")

reverse(string)
{
  Loop, Parse, string
    reversed := A_LoopField . reversed
  Return reversed
}
A ''much'' slower version:
Reverse(String){ ; credit to Rseding91
   If (A_IsUnicode){
      SLen := StrLen(String) * 2
      VarSetCapacity(RString,SLen)
      
      Loop,Parse,String
         NumPut(Asc(A_LoopField),RString,SLen-(A_Index * 2),"UShort")
   } Else {
      SLen := StrLen(String)
      VarSetCapacity(RString,SLen)
      
      Loop,Parse,String
         NumPut(Asc(A_LoopField),RString,SLen-A_Index,"UChar")
   }
   
   VarSetCapacity(RString,-1)
   
   Return RString
}

AutoIt

#AutoIt Version: 3.2.10.0
$mystring="asdf"
$reverse_string = ""
$string_length = StringLen($mystring)

For $i = 1 to $string_length
   $last_n_chrs = StringRight($mystring, $i)
   $nth_chr = StringTrimRight($last_n_chrs, $i-1)
   $reverse_string= $reverse_string & $nth_chr 
Next

MsgBox(0, "Reversed string is:", $reverse_string)

Avail

"asfd" reversed

AWK

function reverse(s)
{
  p = ""
  for(i=length(s); i > 0; i--) { p = p substr(s, i, 1) }
  return p
}

BEGIN {
  print reverse("edoCattesoR")
}
Recursive
function reverse(s   ,l)
{
  l = length(s)
  return l < 2 ? s:( substr(s,l,1) reverse(substr(s,1,l-1)) )
}

BEGIN {
  print reverse("edoCattesoR")
}
using split, then joining in front
# Usage: awk -f reverse.awk -v s=Rosetta

function rev(s,   i,len,a,r) {
   len = split(s, a, "")
  #for (i in a) r = a[i] r	# may not work - order is not guaranteed !
   for (i=1; i<=len; i++) r = a[i] r
   return r
}
BEGIN { 
   if(!s) s = "Hello, world!" 
   print s, "<-->", rev(s)
}
Output:
 Rosetta <--> attesoR

Babel

This example will handle UTF-8 encoded Unicode but doesn't handle combining characters.

strrev: { str2ar ar2ls reverse ls2lf ar2str }
  • str2ar - this operator converts a UTF-8 encoded string to an array of Unicode codepoints
  • ar2ls - this operator converts the array to a linked-list
  • reverse - this operator reverses a linked-list
  • ls2lf - this operator undoes the effect of ar2ls
  • ar2str - this operator undoes the effect of str2ar

BaCon

OPTION UTF8 TRUE
s$ = "asdf"
PRINT REVERSE$(s$)

Unicode preservation works in BaCon 3.6 and higher.

BASIC

Applesoft BASIC

10 A$ = "THE FIVE BOXING WIZARDS JUMP QUICKLY"
20 GOSUB 100REVERSE
30 PRINT R$
40 END

100 REMREVERSE A$
110 R$ = ""
120 FOR I = 1 TO LEN(A$)
130    R$ = MID$(A$, I, 1) + R$
140 NEXT I
150 RETURN

BASIC256

s = "asdf"
print "'"; s; "' reversed is '"; reverse(s); "'"
end

function reverse(a)
	b = ""
	for i = 1 to length(a)
		b = mid(a, i, 1) + b
	next i
	return b
end function
Output:
'asdf' reversed is 'fdsa'

Commodore BASIC

Works with: Commodore BASIC version 3.5,7.0

Commodore BASIC 3.5 turned MID$ into an lvalue function, and assigning a string of the same length to MID$ replaces the characters instead of allocating a new string, so the reversal can be done in-place:

100 INPUT "STRING";S$
110 FOR I=1 TO INT(LEN(S$)/2)
120 : J=LEN(S$)+1-I
130 : T$=MID$(S$,I,1)
140 : MID$(S$,I,1) = MID$(S$,J,1)
150 : MID$(S$,J,1) = T$
160 NEXT I
170 PRINT S$
Output:
STRING? THIS IS A TEST
TSET A SI SIHT

READY.

IS-BASIC

100 INPUT PROMPT "String: ":TX$
120 LET REV$=""
130 FOR I=LEN(TX$) TO 1 STEP-1
140   LET REV$=REV$&TX$(I)
150 NEXT 
160 PRINT REV$

QuickBASIC

Works with: QBasic version 1.1
Works with: QuickBasic version 4.5
function reverse$(a$)
   b$ = ""
   for i = 1 to len(a$)
      b$ = mid$(a$, i, 1) + b$
   next i
   reverse$ = b$
end function

Sinclair ZX81 BASIC

10 INPUT S$
20 LET T$=""
30 FOR I=LEN S$ TO 1 STEP -1
40 LET T$=T$+S$(I)
50 NEXT I
60 PRINT T$

True BASIC

FUNCTION reverse$(a$)
    LET b$ = ""
    FOR i = 1 TO LEN(a$)
        LET b$ = (a$)[i:i+1-1] & b$
    NEXT i
    LET reverse$ = b$
END FUNCTION

LET s$ = "asdf"
PRINT "'"; s$; "' reversed is '"; reverse$(s$); "'"
END
Output:
'asdf' reversed is 'fdsa'

XBasic

Works with: Windows XBasic
PROGRAM	"progname"
VERSION	"0.0000"

DECLARE FUNCTION Entry ()
DECLARE FUNCTION reverse$ (a$)

FUNCTION  Entry ()
    s$ = "asdf"
    PRINT "'"; s$; "' reversed is '"; reverse$(s$); "'"
END FUNCTION

FUNCTION reverse$ (a$)
    b$ = ""
    FOR i = 1 TO LEN(a$)
        b$ = MID$(a$, i, 1) + b$
    NEXT i
    RETURN b$
END FUNCTION
END PROGRAM
Output:
'asdf' reversed is 'fdsa'

Yabasic

s$ = "asdf"
print "'", s$, "' reversed is '", reverse$(s$), "'"
end

sub reverse$(a$)
	b$ = ""
	for i = 1 to len(a$)
		b$ = mid$(a$, i, 1) + b$
	next i
	return b$
end sub
Output:
'asdf' reversed is 'fdsa'

Batch File

@echo off
setlocal enabledelayedexpansion
call :reverse %1 res
echo %res%
goto :eof

:reverse
set str=%~1
set cnt=0
:loop
if "%str%" equ "" (
	goto :eof
	)
set chr=!str:~0,1!
set str=%str:~1%
set %2=%chr%!%2! 
goto loop

BBC BASIC

      PRINT FNreverse("The five boxing wizards jump quickly")
      END
      
      DEF FNreverse(A$)
      LOCAL B$, C%
      FOR C% = LEN(A$) TO 1 STEP -1
        B$ += MID$(A$,C%,1)
      NEXT
      = B$

Beef

Beef does not have a built-in Reverse method for strings, however one can 'extend' the builtin String class to provide a Reverse function.

using System;

namespace System
{
	extension String
	{
		public void Reverse()
		{
			int i = 0;
			int j = mLength - 1;
			while (i < j)
			{
				Swap!(Ptr[i++], Ptr[j--]);
			}
		}
	}
}

namespace StringReverse
{
	class Program
	{
		static void Main()
		{
			String s = scope .("abcdef");
			s.Reverse();
			Console.WriteLine(s);
		}
	}
}

Befunge

Reads a line from stdin and write the reverse to stdout. Can be made to repeat indefinitely by removing the final @ command.

55+~>:48>*#8\#4`#:!#<#~_$>:#,_@

Binary Lambda Calculus

This 9 byte program, featured on https://www.ioccc.org/2012/tromp/hint.html, reverses its input in byte-oriented BLC:

16 46 80 17 3e f0 b7 b0 40

BQN

BQN has a reverse builtin, given as .

  "racecar"
"racecar"

Bracmat

  ( reverse
  = L x
    .     :?L
        & @( !arg
           :   ?
               ( %?x
               & utf$!x
               & !x !L:?L
               & ~`
               )
               ?
           )
      | str$!L
  )
& out$reverse$Ελληνικά
Output:
άκινηλλΕ

Brainf***

[-]>,[>,]<[.<]

Another solution:

,----- ----- [+++++ +++++ > , ----- -----]	If a newline is hit counter will be zero and input loop ends
<[.<]	run all chars backwards and print them

just because it looks good we print CRLF
+++++ +++++ +++ . --- .

Brat

p "olleh".reverse  #Prints "hello"

Burlesque

"Hello, world!"<-

C

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>

const char *sa = "abcdef";
const char *su = "as⃝df̅"; /* Should be in your native locale encoding. Mine is UTF-8 */

int is_comb(wchar_t c)
{
	if (c >= 0x300 && c <= 0x36f) return 1;
	if (c >= 0x1dc0 && c <= 0x1dff) return 1;
	if (c >= 0x20d0 && c <= 0x20ff) return 1;
	if (c >= 0xfe20 && c <= 0xfe2f) return 1;
	return 0;
}

wchar_t* mb_to_wchar(const char *s)
{
	wchar_t *u;
	size_t len = mbstowcs(0, s, 0) + 1;
	if (!len) return 0;

	u = malloc(sizeof(wchar_t) * len);
	mbstowcs(u, s, len);
	return u;
}

wchar_t* ws_reverse(const wchar_t* u)
{
	size_t len, i, j;
	wchar_t *out;
	for (len = 0; u[len]; len++);
	out = malloc(sizeof(wchar_t) * (len + 1));
	out[len] = 0;
	j = 0;
	while (len) {
		for (i = len - 1; i && is_comb(u[i]); i--);
		wcsncpy(out + j, u + i, len - i);
		j += len - i;
		len = i;
	}
	return out;
}

char *mb_reverse(const char *in)
{
	size_t len;
	char *out;
	wchar_t *u = mb_to_wchar(in);
	wchar_t *r = ws_reverse(u);
	len = wcstombs(0, r, 0) + 1;
	out = malloc(len);
	wcstombs(out, r, len);
	free(u);
	free(r);
	return out;
}

int main(void)
{
	setlocale(LC_CTYPE, "");

	printf("%s => %s\n", sa, mb_reverse(sa));
	printf("%s => %s\n", su, mb_reverse(su));
	return 0;
}
Output:
abcdef => fedcba
as⃝df̅ => f̅ds⃝a
Library: GLib
#include <glib.h>
gchar *srev (const gchar *s) {
    if (g_utf8_validate(s,-1,NULL)) {
        return g_utf8_strreverse (s,-1);
}   }
// main
int main (void) {
    const gchar *t="asdf";
    const gchar *u="as⃝df̅";
    printf ("%s\n",srev(t));
    printf ("%s\n",srev(u));
    return 0;
}

C#

C# does not have a built-in Reverse method for strings, and cannot reverse them in place because they are immutable. One way to implement this is to convert the string to an array of characters, reverse that, and return a new string from the reversed array:

static string ReverseString(string input)
{
    char[] inputChars = input.ToCharArray();
    Array.Reverse(inputChars);
    return new string(inputChars);
}

As of .Net 3.5 the LINQ-to-objects allows the Reverse() extension method to be called on a string, since String implements the IEnumerable<char> interface. Because of this, the return type of Reverse is IEnumerable<char>. Fortunately, LINQ also provides the ToArray extension method, which can be used in conjunction with the constructor of string that accepts a char array:

using System.Linq;

// ...

return new string(input.Reverse().ToArray());

// ...

Version supporting combining characters:

System.Globalization.StringInfo provides a means of separating a string into individual graphemes.

public string ReverseElements(string s)
{
    // In .NET, a text element is series of code units that is displayed as one character, and so reversing the text
    // elements of the string correctly handles combining character sequences and surrogate pairs.
    var elements = System.Globalization.StringInfo.GetTextElementEnumerator(s);
    return string.Concat(AsEnumerable(elements).OfType<string>().Reverse());
}

// Wraps an IEnumerator, allowing it to be used as an IEnumerable.
public IEnumerable AsEnumerable(IEnumerator enumerator)
{
    while (enumerator.MoveNext())
        yield return enumerator.Current;
}

C++

#include <string>
#include <iostream>
#include <algorithm>

int main() {
  std::string s;
  std::getline(std::cin, s);
  std::reverse(s.begin(), s.end()); // modifies s
  std::cout << s << '\n';
}

Caché ObjectScript

USER>Write $Reverse("Hello, World")

dlroW ,olleH

Ceylon

shared void run() {

   while(true) {
      process.write("> ");
      String? text = process.readLine();
      if (is String text) {
      print(text.reversed);
      }
      else {
      break;
      }
    }
}

Clipper

Works with versions since 5, because LOCAL variables and the += operator was not implemented before.

FUNCTION Reverse(sIn)
   LOCAL sOut := "", i
   FOR i := Len(sIn) TO 1 STEP -1
      sOut += Substr(sIn, i, 1)
   NEXT
RETURN sOut

Clojure

A Simple implementation with the magic of "conj" function

(defn reverse-string [s]
  "Returns a string with all characters in reverse"
  (apply str (reduce conj '() s)))

Other alternatives (resorting to the "reverse" function in the standard library)

For normal strings, the reverse function can be used to do the bulk of the work. However, it returns a character sequence, which has to be converted back to a string.

a)

(defn str-reverse [s] (apply str (reverse s)))

b)

(apply str (interpose " " (reverse (.split "the quick brown fox" " "))))

Supporting combining characters

Handling combining characters present a trickier task. We need to protect the relative ordering of the combining character and the character to its left. Thus, before reversing, the characters need to be grouped.

(defn combining? [c]
  (let [type (Character/getType c)]
    ;; currently hardcoded to the types taken from the sample string
    (or (= type 6) (= type 7))))

(defn group
  "Group normal characters with their combining characters"
  [chars]
  (cond (empty? chars) chars
	(empty? (next chars)) (list chars)
	:else
	(let [dres (group (next chars))]
	  (cond (combining? (second chars)) (cons (cons (first chars)
							(first dres))
						  (rest dres))
		:else (cons (list (first chars)) dres)))))

(defn str-reverse
  "Unicode-safe string reverse"
  [s]
  (apply str (apply concat (reverse (group s)))))
Output:
user=> s
"as⃝df̅"
user=> (str-reverse s)
"f̅ds⃝a"[
user=> (str-reverse (str-reverse s))
"as⃝df̅"
user=>

CLU

reverse = proc (s: string) returns (string)
    rslt: array[char] := array[char]$predict(1,string$size(s))
    for c: char in string$chars(s) do 
        array[char]$addl(rslt,c) 
    end
    return(string$ac2s(rslt))
end reverse

start_up = proc ()
    po: stream := stream$primary_output()
    stream$putl(po, reverse("!dlrow ,olleH"))
end start_up
Output:
Hello, world!

COBOL

FUNCTION REVERSE('QWERTY')

CoffeeScript

"qwerty".split("").reverse().join ""

ColdFusion

You can reverse anything that can be written to the document in hashmarks (i.e. strings, numbers, now( ), etc.).

<cfset myString  = "asdf" />
<cfset myString  = reverse( myString ) />

Common Lisp

(reverse my-string)

Component Pascal

BlackBox Component Builder

MODULE BbtReverseString;
IMPORT StdLog;

PROCEDURE ReverseStr(str: ARRAY OF CHAR): POINTER TO ARRAY OF CHAR;
VAR
	top,middle,i: INTEGER;
	c: CHAR;
	rStr: POINTER TO ARRAY OF CHAR;
BEGIN
	NEW(rStr,LEN(str$) + 1);
	top := LEN(str$) - 1; middle := (top - 1) DIV 2;
	FOR i := 0 TO middle DO
		rStr[i] := str[top - i];
		rStr[top - i] := str[i];
	END;
	IF ODD(LEN(str$)) THEN rStr[middle + 1] := str[middle + 1] END;
	RETURN rStr;
END ReverseStr;

PROCEDURE Do*;
VAR
	x: CHAR;
BEGIN
	StdLog.String("'asdf' reversed:> ");StdLog.String(ReverseStr("asdf"));StdLog.Ln
END Do;
END BbtReverseString.

Execute: ^Q BbtReverseString.Do

Output:
'asdf' reversed:> fdsa

Cowgol

include "cowgol.coh";
include "strings.coh";

# Reverse a string in place
sub StrRev(s: [uint8]): (r: [uint8]) is
    r := s;
    var e := s;
    while [e] != 0 loop 
        e := @next e; 
    end loop;
    e := @prev e;
    while e > s loop
        var c := [s];
        [s] := [e];
        [e] := c;
        s := @next s;
        e := @prev e;
    end loop;
end sub;

# Test
var buf: uint8[32];
var str: [uint8] := "\nesreveR";
CopyString(str, &buf[0]);
print(StrRev(&buf[0]));
Output:
Reverse

Crystal

# version 0.21.1

strings = ["asdf", "as⃝df̅"]
strings.each do |s|
  puts "#{s} -> #{s.reverse}"
end
Output:
asdf -> fdsa
as⃝df̅ -> f̅ds⃝a

D

void main() {
	import std.range, std.conv;

	string s1 = "hello"; // UTF-8
	assert(s1.retro.text == "olleh");

	wstring s2 = "hello"w; // UTF-16
	assert(s2.retro.wtext == "olleh"w);

	dstring s3 = "hello"d; // UTF-32
	assert(s3.retro.dtext == "olleh"d);

	// without using std.range:
	dstring s4 = "hello"d;
	assert(s4.dup.reverse == "olleh"d); // simple but inefficient (copies first, then reverses)
}

Dart

Since Dart strings are sequences of UTF-16 code units, it would not be sufficient to simply reverse the characters in strings, as this would not work with UTF-16 surrogate pairs (pairs of UTF-16 code units that represent single characters outside the Unicode BMP). However, Dart provides a method to convert strings to sequences of unicode code points (called "runes" in Dart), and these sequences can easily be reversed and used to create new strings, so a string reversal function can be written with a single line of Dart code:

String reverse(String s) => new String.fromCharCodes(s.runes.toList().reversed);

A more complete example with unit tests would look like this:

import 'package:unittest/unittest.dart';

String reverse(String s) => new String.fromCharCodes(s.runes.toList().reversed);

main() {
  group("Reverse a string -", () {
    test("Strings with ASCII characters are reversed correctly.", () {
      expect(reverse("hello, world"), equals("dlrow ,olleh"));
    });
    test("Strings with non-ASCII BMP characters are reversed correctly.", () {
      expect(reverse("\u4F60\u4EEC\u597D"), equals("\u597D\u4EEC\u4F60"));
    });
    test("Strings with non-BMP characters are reversed correctly.", () {
      expect(reverse("hello, \u{1F310}"), equals("\u{1F310} ,olleh"));
    });
  });
}


DBL

K=
STR_OUT=
FOR J=%TRIM(STR_IN) STEP -1 UNTIL 1
DO BEGIN
      INCR K
      STR_OUT(K:1)=STR_IN(J:1)
   END


Dc

Reversing "Hello world!" which is "22405534230753963835153736737" in Dc's numerical string representaion.
Due to using "~" this example needs GNU Dc or OpenBSD Dc.

22405534230753963835153736737 [ 256 ~ d SS 0<F LS SR 1+ ] d sF x 1 - [ 1 - d 0<F 256 * LR + ] d sF x P
!dlrow olleH

Delphi

function ReverseString(const InString: string): string;
var
  i: integer;
begin
  for i := Length(InString) downto 1 do
    Result := Result + InString[i];
end;

You could also use this RTL function Introduced in Delphi 6:

StrUtils.ReverseString

Another alternative.

function Reverse(const s: string): string;
var
  i, aLength, ahalfLength: Integer;
  c: Char;
begin
  Result := s;
  aLength := Length(s);
  ahalfLength := aLength div 2;
  if aLength > 1 then
    for i := 1 to ahalfLength do
    begin
      c := result[i];
      result[i] := result[aLength - i + 1];
      result[aLength - i + 1] := c;
    end;
end;

All versions has the same perfomance, then StrUtils is recomended.

Draco

/* Reverse string in place */
proc nonrec reverse(*char s) void:
    *char e;
    char t;
    e := s;
    while e* /= '\e' do
        e := e + 1
    od;
    while
        e := e - 1;
        s < e
    do
        t := e*;
        e* := s*;
        s* := t;
        s := s + 1
    od
corp

proc nonrec main() void:
    *char testString = "!dlrow ,olleH";
    reverse(testString);
    writeln(testString)
corp
Output:
Hello, world!

dt

"asdf" rev

DuckDB

DuckDB strings are Unicode strings, but they are not always displayed as neatly as one might expect.

This entry highlights how expressions in a SELECT statement can reference values created to their left.

create or replace table t (s varchar, expected varchar);
insert into t values
  ('asdf',   'fdsa'),
  ('as⃝df̅', 'f̅ds⃝a');
 
select s, expected, reverse(s) as reversed, (expected=reversed) as equal
  from t;
Output:
┌─────────┬──────────┬──────────┬─────────┐
│    s    │ expected │ reversed │  equal  │
│ varchar │ varchar  │ varchar  │ boolean │
├─────────┼──────────┼──────────┼─────────┤
│ asdf    │ fdsa     │ fdsa     │ true    │
│ as⃝df̅    │ f̅ds⃝a     │ f̅ds⃝a     │ true    │
└─────────┴──────────┴──────────┴─────────┘

DWScript

See Delphi.

Dyalect

let str = "asdf"
 
func String.Reverse() {
    var cs = []
    let len = this.Length()
    for n in 1..len {
        cs.Add(this[len - n])
    }
    String(values: cs)
}
 
str.Reverse()

Déjà Vu

!print concat chars "Hello"
Output:
olleH

E

pragma.enable("accumulator")
def reverse(string) {
  return accum "" for i in (0..!(string.size())).descending() { _ + string[i] }
}

EasyLang

func$ reverse s$ .
   a$[] = strchars s$
   for i = 1 to len a$[] div 2
      swap a$[i] a$[len a$[] - i + 1]
   .
   return strjoin a$[]
.
print reverse "hello"


EchoLisp

(define (string-reverse string) 
    (list->string (reverse (string->list string))))

(string-reverse "ghij")
     jihg
(string-reverse "un roc lamina l animal cornu")
     unroc lamina l animal cor nu

ed

# by Artyom Bologov
H
,p
g/./s/\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)/\9\8\7\6\5\4\3\2\1/
,p
Q
Output:
$ ed -s reverse-string.in < reverse-string.ed 
Newline appended
asdf
as⃝df̅
fdsa
̅fd⃝sa


EGL

function reverse( str string ) returns( string )
	result string;
	for ( i int from StrLib.characterLen( str ) to 1 decrement by 1 )
		result ::= str[i:i];
	end
	return( result );
end

Eiffel

class
    APPLICATION
create
    make
feature
    make
            -- Demonstrate string reversal.
        do
            my_string := "Hello World!"
            my_string.mirror
            print (my_string)
        end
    my_string: STRING
            -- Used for reversal
end
Output:
!dlroW olleH

Ela

reverse_string str = rev len str 
  where len = length str
        rev 0 str = ""
        rev n str = toString (str : nn) +> rev nn str
          where nn = n - 1

reverse_string "Hello"
Output:
"olleH"

Another approach is to covert a string to a list, reverse a list and then convert it back to a string:

open string
fromList <| reverse <| toList "Hello" ::: String

Elena

ELENA 4.x:

import system'routines;
import extensions;
import extensions'text;
 
extension extension
{
    reversedLiteral()
        = self.toArray().sequenceReverse().summarize(new StringWriter());
}
 
public program()
{    
    console.printLine("Hello World".reversedLiteral())
}
Output:
dlroW olleH

Elixir

Elixir handles Unicode graphemes correctly by default.

IO.puts (String.reverse "asdf")
IO.puts (String.reverse "as⃝df̅")
Output:
fdsa
f̅ds⃝a

Elm

module Main exposing (main)

import Html exposing (Html, text, div, p)
import Html.Attributes exposing (style)


change myText =
   text ("reverse " ++ myText
    ++ " = " ++ String.reverse myText)


main =
   div [style "margin" "5%", style "font-size" "1.5em"]
    [change "as⃝da"
    , p [] [change "a⃝su-as⃝u"]
    , p [] [change "Hello!"]
    ]

Link to live demo: https://ellie-app.com/qdg6RP3DGCBa1

Output:
reverse as⃝da = ad⃝sa
reverse a⃝su-as⃝u = u⃝sa-us⃝a
reverse Hello! = !olleH

Emacs Lisp

(reverse "Hello World")
Output:
"dlroW olleH"

Erlang

1> lists:reverse("reverse!").
"!esrever"

Erlang also supports binary strings, which uses its binary format. There is no standard function to reverse a binary sequence, but the following one does the job well enough. It works by changing the endianness (from little to big or the opposite) of the whole sequence, effectively reversing the string.

reverse(Bin) ->
    Size = size(Bin)*8,
    <<T:Size/integer-little>> = Bin,
    <<T:Size/integer-big>>.
Output:
1> test:reverse(<<"hello">>).
<<"olleh">>

ERRE

PROGRAM REVERSE_STRING

PROCEDURE REVERSE(A$->R$)
   LOCAL I%
   R$=""
   FOR I=1 TO LEN(A$) DO
     R$=MID$(A$,I,1)+R$
   END FOR
END PROCEDURE

BEGIN
   A$="THE FIVE BOXING WIZARDS JUMP QUICKLY"
   REVERSE(A$->R$)
   PRINT(R$)
END PROGRAM

Euler Math Toolbox

>function strrev (s) := chartostr(fliplr(strtochar(s)))
>strrev("This is a test!")
 !tset a si sihT

Euphoria

include std/sequence.e
printf(1, "%s\n", {reverse("abcdef") })

Explore

The Scratch solution, which requires making variables named "i" and "inv" first, works, unmodified:
https://i.ibb.co/3c9k641/Reverse-a-string-in-Explore-using-the-Scratch-solution.png

This example uses a special block located in the Strings category:
https://i.ibb.co/4pM9G8b/Reverse-a-string-in-Explore-using-a-special-block.png

Ezhil

## இந்த நிரல் தரப்படும் சரம் ஒன்றைத் தலைகீழாகத் திருப்பி அச்சிடும்
## உதாரணமாக "abc" என்ற சரம் தரப்பட்டால் அதனைத் திருப்பி "cba" என அச்சிடும்
## "எழில்" மொழியின்மூலம் இரண்டு வகைகளில் இதனைச் செய்யலாம். இரண்டு உதாரணங்களும் இங்கே தரப்பட்டுள்ளன

நிரல்பாகம் திருப்புக (சரம்1)

    ## முதல் வகை

    சரம்2 = ""

    @( சரம்1  இல் ) ஒவ்வொன்றாக
          சரம்2 =   + சரம்2
        முடி

    பின்கொடு சரம்2

முடி

நிரல்பாகம் மீண்டும்திருப்புக (சரம்1)

    ## இரண்டாம் வகை
    
    சரநீளம் = len(சரம்1)
    
    சரம்2 = ""

    @(எண் = 0, எண் < சரநீளம், எண் = எண் + 1) ஆக

      சரம்2 = எடு(சரம்1, எண்) + சரம்2

    முடி

    பின்கொடு சரம்2

முடி


 = உள்ளீடு("ஓர் எழுத்துச் சரத்தைத் தாருங்கள் ")

பதிப்பி "நீங்கள் தந்த எழுத்துச் சரம்" 

பதிப்பி "அதனை முதல் வகையில் திருப்பியுள்ளோம்: " திருப்புக()

பதிப்பி "வேறொரு வகையில் திருப்பியுள்ளோம்: " மீண்டும்திருப்புக()

F#

The function

// Reverse a string. Nigel Galloway: August 14th., 2019
let strRev α=let N=System.Globalization.StringInfo.GetTextElementEnumerator(α)
             List.unfold(fun n->if n then Some(N.GetTextElement(),N.MoveNext()) else None)(N.MoveNext())|>List.rev|>String.concat ""

The Task

I was a little concerned when entering this task because in the edit window the overline appears above the d, but when previewed it is correctly above the f, using Firefox anyway. Using XTERM the output is correct with the s inside a circle but appears as sO in Firefox.

printfn "%s" (strRev "as⃝df̅")
printfn "%s" (strRev "Nigel")
Output:
f̅ds⃝a
legiN

Factor

A string is a sequence and there is a default reverse implementation for those.

"hello" reverse

string-reverse preserves graphemes:

"as⃝df̅" string-reverse "f̅ds⃝a" = .

FALSE

This solution does not take into account combination characters:

1_
[^$1_=~][]#%
[$1_=~][,]#

This solution does take into account combination characters (except for half-marks):

1_
[^$1_=~][
  $$767>\879\>&
  1ø$7615>\7620\>&|
  1ø$8399>\8428\>&|
  [\]?
]#%
[$1_=~][,]#

Fancy

"hello world!" reverse

FBSL

A slow way

Function StrRev1(ByVal $p1)
	dim $b = ""
	REPEAT len(p1)
		b = b & RIGHT(p1,1)
		p1 = LEFT(p1,LEN(p1)-1)
	END REPEAT
	return b
End Function

A much faster (twice at least) way

Function StrRev2(ByVal $p1)
	dim $b = "", %i
	for i = len(p1) DOWNTO 1
		b = b & MID(p1,i,1)
	next
	return b
End Function

An even faster way using PEEK, POKE, double-calls and quantity-in-hand

Function StrRev3( $s )
	FOR DIM x = 1 TO LEN(s) \ 2
		PEEK(@s + LEN - x, $1)
		POKE(@s + LEN - x, s{x})(@s + x - 1, PEEK)
	NEXT
	RETURN s
end function

An even faster way using the DynC (Dynamic C) mode

DynC StringRev($theString) As String
   void rev(char *str)
   {
		int len = strlen(str);
		char *HEAD = str;
		char *TAIL = str + len - 1;
		char temp;
		int i;
		for ( i = 0; i <= len / 2; i++, HEAD++, TAIL--) {
			temp = *HEAD;
			*HEAD = *TAIL;
			*TAIL = temp;
		}
   }
   char *main(char* theString)
   {
      rev(theString);
      return theString;
   }
End DynC

Using DynASM, the Dynamic Assembler mode.

DYNASM RevStr(BYVAL s AS STRING) AS STRING
   // get length of string
   // divide by two
   // setup pointers to head and tail
   // iterate from 1 to (length \ 2)
   //   swap head with tail
   //   increment head pointer
   //   decrement tail pointer

   ENTER 0, 0 // = PUSH EBP: MOV EBP, ESP
   PUSH EBX // by Windows convention EBX, EDI, ESI must be saved before modification
   
   MOV EAX, s // get string pointer
   MOV ECX, EAX // duplicate it
   
   .WHILE BYTE PTR [ECX] <> 0

	INC ECX // propagate to tail 

   .WEND
   
   MOV EDX, ECX // duplicate tail pointer
   DEC EDX // set it to last byte before trailing zero
   
   SUB ECX, EAX // get length in ECX in 1 CPU cycle
   SHR ECX, 1 // get length \ 2 in 1 CPU cycle; that's the beauty of power-of-two division

   .WHILE ECX > 0
      
      MOV BL, [EDX] // no need to XOR; just overwrite BL and BH contents
      MOV BH, [EAX] // DynAsm deduces data size from destination register sizes
      
      MOV [EDX], BH // ditto, source register sizes
      MOV [EAX], BL
      
      INC EAX // propagate pointers
      DEC EDX
      
      DEC ECX // decrement counter
      
   .WEND
   
   // point to start of string again
   MOV EAX, s // MOV = 1 CPU cycle, PUSH + POP = 2 CPU cycles
   
   POP EBX // by Windows convention ESI, EDI, EBX must be restored if modified
   LEAVE // = POP EBP
   RET
END DYNASM

Fe

In this language, strings are very limited and are not designed to store large text data, so there are no built-in operations to work with strings. But with the C API you can make functions that convert a string to a list and vice versa.

#define MAXSTRINGLEN ( 1024 )

/* chop string to list of single character strings */
static fe_Object* chop(fe_Context *ctx, fe_Object *args) {
  char buf[MAXSTRINGLEN];
  int len = fe_tostring(ctx, fe_nextarg(ctx, &args), buf, sizeof(buf));
  int gc = fe_savegc(ctx); 
  args = fe_bool(ctx, 0);  
  while (len > 0) {
    buf[len--] = '\0';
    args = fe_cons(ctx, fe_string(ctx, buf + len), args);
    fe_restoregc(ctx, gc);
    fe_pushgc(ctx, args);
  }
  return args;
}

/* pack list of strings to single string */
static fe_Object* pack(fe_Context *ctx, fe_Object *args) {
  char buf[MAXSTRINGLEN], *ptr = buf;
  for (args = fe_nextarg(ctx, &args); !fe_isnil(ctx, args);) {
    ptr += fe_tostring(ctx, fe_nextarg(ctx, &args), ptr, buf + sizeof(buf) - ptr);
  }
  return fe_string(ctx, buf);
}

So, we can manipulate strings like lists:

; reverse list
(= reverse (fn (lst)
  (let res nil)
  (while lst
    (= res (cons (car lst) res))
    (= lst (cdr lst)))
  res))

; chop string to list, reverse list and pack it back to string 
(print (pack (reverse (chop "Hello world!"))))

Output:

!dlrow olleH

Fennel

Uses the same methods (and suffers from the same limitations) as the Lua example.

(let [example :asdf]
  (string.reverse example) ; fdsa
  (example:reverse) ; fdsa
nil)

Forth

Method 1

: exchange ( a1 a2 -- )
  2dup c@ swap c@ rot c! swap c! ;
: reverse ( c-addr u -- )
  1- bounds begin 2dup > while
    2dup exchange
    -1 /string
  repeat 2drop ;

s" testing" 2dup reverse type   \ gnitset

Method 2 Using the stack

\ reverse a string using the data stack for temporary storage

: mystring ( -- caddr len) S" ABCDEFGHIJKLMNOPQRSTUVWXYZ987654321" ; 
 
: pushstr ( caddr len -- c..c[n])   bounds  do  I c@  loop ;
: popstr  ( c.. c[n] caddr len -- ) bounds  do  I c!  loop ;
: reverse ( caddr len  -- ) 2dup 2>r  pushstr  2r> popstr ;

Forth Console Output

mystring type ABCDEFGHIJKLMNOPQRSTUVWXYZ987654321 ok
mystring 2dup reverse type 123456789ZYXWVUTSRQPONMLKJIHGFEDCBA ok

Using the Forth-2012 Xchars wordset to handle multi-byte characters

Characters accessed with C@ C! are usually bytes and can therefore only represent characters in 8-bit encodings (e.g., Latin-1). Forth-2012 added the Xchars wordset for dealing with multi-byte encodings such as UTF-8; actually these words are not needed much, because the magic of UTF-8 means that most byte-oriented code works as intended, but the present task is one of the few examples where that is not good enough.

The xchars wordset offers several ways to skin this cat; this is just one way to do it, not necessarily the best one. Because the xchars wordset currently does not support recognizing combining characters, this code does not get extra credit.

: xreverse {: c-addr u -- c-addr2 u :}
    u allocate throw u + c-addr swap over u + >r begin ( from to r:end)
	over r@ u< while
	    over r@ over - x-size dup >r - 2dup r@ cmove
	    swap r> + swap repeat
    r> drop nip u ;

\ example use
s" ώщыē" xreverse type \ outputs "ēыщώ"

Fortran

Works with: Fortran version 90 and later
PROGRAM Example

  CHARACTER(80) :: str = "This is a string"
  CHARACTER :: temp
  INTEGER :: i, length

  WRITE (*,*) str
  length = LEN_TRIM(str) ! Ignores trailing blanks. Use LEN(str) to reverse those as well
  DO i = 1, length/2
     temp = str(i:i)
     str(i:i) = str(length+1-i:length+1-i)
     str(length+1-i:length+1-i) = temp
  END DO
  WRITE(*,*) str

END PROGRAM Example
Output:
This is a string
gnirts a si sihT

Another implementation that uses a recursive not-in-place algorithm:

program reverse_string

  implicit none
  character (*), parameter :: string = 'no devil lived on'

  write (*, '(a)') string
  write (*, '(a)') reverse (string)

contains

  recursive function reverse (string) result (res)

    implicit none
    character (*), intent (in) :: string
    character (len (string)) :: res

    if (len (string) == 0) then
      res = ''
    else
      res = string (len (string) :) // reverse (string (: len (string) - 1))
    end if

  end function reverse

end program reverse_string
Output:
no devil lived on
no devil lived on

Another shorter implementation (adapted version from stackoverflow question 10605574 how-to-reverse-a-chain-of-character-fortran-90):

 program reverse_string
  implicit none
  character (80) :: cadena
  integer :: k, n
  !
  cadena = "abcdefgh"
  n = len_trim (cadena)
  !
  write (*,*) cadena
  forall (k=1:n) cadena (k:k) = cadena (n-k+1:n-k+1)
  write (*,*) cadena
  !
end program reverse_string
Output:
abcdefgh
hgfedcba 

FreeBASIC

' FB 1.05.0 Win64

Function ReverseString(s As Const String) As String
  If s = "" Then Return s
  Dim length As Integer = Len(s)
  Dim r As String = Space(length)
  For i As Integer = 0 To length - 1
     r[i] = s[length - 1 - i]
  Next
  Return r
End Function

Dim s As String = "asdf"
Print "'"; s; "' reversed is '"; ReverseString(s); "'"
Output:
'asdf' reversed is 'fdsa'

Frink

The built-in reverse function reverses a string or the elements of a list.

Frink's built-in reverse[string] is quite smart and uses a grapheme-based algorithm to handle Unicode correctly. That is, it preserves "user-perceived characters" that may consist of characters, combining accents, high-plane Unicode characters (that is, above U+FFFF,) surrogate pairs, etc. correctly.

Many languages will not work correctly with upper-plane Unicode characters because they are represented as Unicode "surrogate pairs" which are represented as two characters in a UTF-16 stream.

For example, the string "g\u0308o" represents a g with combining diaeresis, followed by the letter o. Or, in other words, "g̈o". Note that while there are three Unicode codepoints, only two "graphemes" are displayed. Using Frink's smart "reverse" function preserves these combined graphemes. A naive reverse would move the diaeresis over the o instead of the g.

println[reverse["abcdef"]]

Futhark

Futhark has no real strings beyond a little bit of syntactic sugar, so this is the same as reversing an array.

fun main(s: []i32) = s[::-1]

FutureBasic

void local fn DoIt
  CFStringRef s1 = @"asdf", s2 = @""
  long index
  for index = len(s1) - 1 to 0 step -1
    s2 = fn StringByAppendingString( s2, mid(s1,index,1) )
  next
  print s1,s2
end fn

window 1

fn DoIt

HandleEvents

Output:

asdf    fdsa

Gambas

Click this link to run this code

Public Sub Main()
Dim sString As String = "asdf"
Dim sOutput As String
Dim siCount As Short

For siCount = Len(sString) DownTo 1
  sOutput &= Mid(sString, siCount, 1)
Next
 
Print sOutput
 
End

Output:

fdsa

GAP

Reversed("abcdef");
# "fedcba"

Gema

Reverse each line in the input stream. Using built in function:

\L<U>=@reverse{$1}

Not using built in function (recursively apply substring to same rule):

\L<U1><U>=@{$2}$1

Genie

Pretty sure the output capture fails the extra credit, but that may be more local setup and font installs rather than the glib functions used.

[indent=4]
/*
   Reverse a string, in Genie
   valac reverse.gs
*/

init
    utf8:string = "asdf"
    combining:string = "asdf̅"

    print utf8
    print utf8.reverse()

    print combining
    print combining.reverse()
Output:
prompt$ valac reverse.gs     
prompt$ ./reverse        
asdf
fdsa
as?df?
?fd?sa

GFA Basic

PRINT @reverse$("asdf")
'
FUNCTION reverse$(string$)
  LOCAL result$,i%
  result$=""
  FOR i%=1 TO LEN(string$)
    result$=MID$(string$,i%,1)+result$
  NEXT i%
  RETURN result$
ENDFUNC

Go

Functions below assume UTF-8 encoding. (The task mentions Unicode but does not specify an encoding.) Strings in Go are not restricted to be UTF-8, but Go has good support for it and works with UTF-8 most natually. As shown below, certain string conversions work in UTF-8 and the range clause over a string works in UTF-8. Go also has a Unicode package in the standard library that makes easy work of recognizing combining characters for this task.

package main

import (
    "fmt"
    "unicode"
    "unicode/utf8"
)

// no encoding
func reverseBytes(s string) string {
    r := make([]byte, len(s))
    for i := 0; i < len(s); i++ {
        r[i] = s[len(s)-1-i]
    }
    return string(r)
}

// reverseCodePoints interprets its argument as UTF-8 and ignores bytes
// that do not form valid UTF-8.  return value is UTF-8.
func reverseCodePoints(s string) string {
    r := make([]rune, len(s))
    start := len(s)
    for _, c := range s {
        // quietly skip invalid UTF-8
        if c != utf8.RuneError {
            start--
            r[start] = c
        }
    }
    return string(r[start:])
}

// reversePreservingCombiningCharacters interprets its argument as UTF-8
// and ignores bytes that do not form valid UTF-8.  return value is UTF-8.
func reversePreservingCombiningCharacters(s string) string {
    if s == "" {
        return ""
    }
    p := []rune(s)
    r := make([]rune, len(p))
    start := len(r)
    for i := 0; i < len(p); {
        // quietly skip invalid UTF-8
        if p[i] == utf8.RuneError {
            i++
            continue
        }
        j := i + 1
        for j < len(p) && (unicode.Is(unicode.Mn, p[j]) ||
            unicode.Is(unicode.Me, p[j]) || unicode.Is(unicode.Mc, p[j])) {
            j++
        }
        for k := j - 1; k >= i; k-- {
            start--
            r[start] = p[k]
        }
        i = j
    }
    return (string(r[start:]))
}

func main() {
    test("asdf")
    test("as⃝df̅")
}

func test(s string) {
    fmt.Println("\noriginal:      ", []byte(s), s)
    r := reverseBytes(s)
    fmt.Println("reversed bytes:", []byte(r), r)
    fmt.Println("original code points:", []rune(s), s)
    r = reverseCodePoints(s)
    fmt.Println("reversed code points:", []rune(r), r)
    r = reversePreservingCombiningCharacters(s)
    fmt.Println("combining characters:", []rune(r), r)
}
Output:
original:       [97 115 100 102] asdf
reversed bytes: [102 100 115 97] fdsa
original code points: [97 115 100 102] asdf
reversed code points: [102 100 115 97] fdsa
combining characters: [102 100 115 97] fdsa

original:       [97 115 226 131 157 100 102 204 133] as⃝df̅
reversed bytes: [133 204 102 100 157 131 226 115 97] ��fd���sa
original code points: [97 115 8413 100 102 773] as⃝df̅
reversed code points: [773 102 100 8413 115 97] ̅fd⃝sa
combining characters: [102 773 100 115 8413 97] f̅ds⃝a

Groovy

Solution:
println "Able was I, 'ere I saw Elba.".reverse()
Output:
.ablE was I ere' ,I saw elbA
Extra Credit:
def string = "as⃝df̅"

List combiningBlocks = [
    Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS,
    Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS_SUPPLEMENT,
    Character.UnicodeBlock.COMBINING_HALF_MARKS,
    Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS
]
List chars = string as List
chars[1..-1].eachWithIndex { ch, i ->
    if (Character.UnicodeBlock.of((char)ch) in combiningBlocks) {
        chars[i..(i+1)] = chars[(i+1)..i]
    }
}
println chars.reverse().join()
Output:
f̅ds⃝a

Harbour

FUNCTION Reverse( sIn )

   LOCAL cOut := "", i

   FOR i := Len( sIn ) TO 1 STEP -1
      cOut += Substr( sIn, i, 1 )
   NEXT

   RETURN cOut

Haskell

reverse = foldl (flip (:)) []

This function as defined in the Haskell Prelude.

Though variants using a helper function with an additional accumulator argument are more efficient, and are now used by default in GHC.List unless the USE_REPORT_PRELUDE key is set.

Perhaps, for example:

accumulatingReverse :: [a] -> [a]
accumulatingReverse lst =
  let rev xs a = foldl (flip (:)) a xs
  in rev lst []

Supporting combining characters

import Data.Char (isMark)
import Data.List (groupBy)
myReverse = concat . reverse . groupBy (const isMark)

groupBy (const isMark) is an unusual way of splitting a string into its combined characters

HicEst

CHARACTER string = "Hello World", tmp

L = LEN( string )
DO i = 1, L/2
  tmp = string(i)
  string(i) = string(L-i+1)
  string(L-i+1) = tmp
ENDDO

WRITE(Messagebox, Name) string

Icon and Unicon

procedure main(arglist)
s := \arglist[1] | "asdf"
write(s," <-> ", reverse(s))    # reverse is built-in
end

Io

"asdf" reverse

Insitux

(reverse "hello")

J

Reverse (|.) reverses a list of items (of any shape or type).

   |.'asdf'
fdsa

Extra credit: First, a function to determine whether a Unicode character is a combining character:

   ranges=.16b02ff 16b036f, 16b1dbf 16b1dff, 16b20cf 16b20ff, 16bfe1f 16bfe2f
   iscombining=. 2 | ranges&I.

Then we need to box groups of letters and combining characters, reverse, and unbox. The boxing function can be carried out easily with dyad cut, which uses the indices of the ones on the right as the starting points for groups of characters. For clarity, its inverse will be defined as raze, which simply runs together the items inside boxes of its argument.

   split=. (<;.1~ -.@iscombining) :. ;

After this, the solution is just to reverse under the split transformation. This also takes place under J code to convert from Unicode to integers.

   |.&.split&.(3 u: 7&u:) 'as⃝df̅'
f̅ds⃝a

Java

Reverse Unicode Codepoints

Reversing codepoints works in most cases when reversing single characters wherever they are encoded on multi-bytes or not. But this doesn't work for composed characters.

String reversed = new StringBuilder("as⃝df̅").reverse().toString(); // fd⃝sa
String reversed = new StringBuffer("as⃝df̅").reverse().toString(); // fd⃝sa

Alternately, you could use a for-loop with the same issue.

String string = "as⃝df̅";
StringBuilder reversed = new StringBuilder();
for (int index = string.length() - 1; index >= 0; index--)
    reversed.append(string.charAt(index));
reversed; // fd⃝sa

Reverse Unicode Graphemes

A third-party solution is to use ICU4J.

A native solution, since JDK 15, is to use Pattern.compile( "\\X" ) from java.util.regex to parse grapemes.

Another native solution, since JDK 20, is to use java.text.BreakIterator class that now parse graphemes correctly[1].

import java.text.BreakIterator;

public class Reverse {
  /* works with Java 20+ only
   * cf. https://bugs.openjdk.org/browse/JDK-8291660
   */
  public static StringBuilder graphemeReverse(String text) {
    BreakIterator boundary = BreakIterator.getCharacterInstance();
    boundary.setText(text);
    StringBuilder reversed = new StringBuilder();
    int end = boundary.last();
    int start = boundary.previous();
    while (start != BreakIterator.DONE) {
      reversed.append(text.substring(start, end));
      end = start;
      start = boundary.previous();
    }
    return reversed;
  }
  public static void main(String[] args) throws Exception {
    String a = "as⃝df̅";
    System.out.println(graphemeReverse(a)); // f̅ds⃝a
  }
}

JavaScript

Unicode

Split code points

split('') (with empty string argument) works only for ASCII. For Unicode strings, one of the two following methods can be used.

example = 'Tux 🐧 penguin';

// array expansion operator
[...example].reverse().join('') // 'niugnep 🐧 xuT'
// split regexp separator with Unicode mode
example.split(/(?:)/u).reverse().join('') // 'niugnep 🐧 xuT'

// do not use
example.split('').reverse().join(''); // 'niugnep \udc27\ud83d xuT'

Split graphemes =

More generally, one would want to combine characters such as joining emojis or diacritics to be handled properly so enumerating over graphemes is a must.

a = "\u{1F466}\u{1F3FB}\u{1f44b}"; // '👦🏻👋'

// wrong behavior - ASCII sequences
a.split('').reverse().join(''); // '\udc4b🁦\ud83d'

// wrong behavior - Unicode code points
[...a].reverse().join(''); // '👋🏻👦'
a.split(/(?:)/u).reverse().join(''); // '👋🏻👦'

// correct behavior - Unicode graphemes
[...new Intl.Segmenter().segment(a)].map(x => x.segment).reverse().join('') // 👋👦🏻

ASCII

ES5

//using chained methods
function reverseStr(s) {
  return s.split('').reverse().join('');
}

//fast method using for loop
function reverseStr(s) {
  for (var i = s.length - 1, o = ''; i >= 0; o += s[i--]) { }
  return o;
}

//fast method using while loop (faster with long strings in some browsers when compared with for loop)
function reverseStr(s) {
  var i = s.length, o = '';
  while (i--) o += s[i];
  return o;
}

ES6

(() => {

    // .reduceRight() can be useful when reversals
    // are composed with some other process

    let reverse1 = s => Array.from(s)
        .reduceRight((a, x) => a + (x !== ' ' ? x : ' <- '), ''),

        // but ( join . reverse . split ) is faster for
        // simple string reversals in isolation

        reverse2 = s => s.split('').reverse().join('');


    return [reverse1, reverse2]
        .map(f => f("Some string to be reversed"));

})();
Output:
["desrever <- eb <- ot <- gnirts <- emoS", "desrever eb ot gnirts emoS"]

Joy

DEFINE reverse == "" [swons] fold.

"asdf" reverse putchars.
Output:
fdsa

jq

jq's explode/implode filters are based on codepoints, and therefore "reverse_string" as defined here will reverse the sequence of codepoints. The topic of Unicode combining characters is a large one that is not touched on here.

def reverse_string: explode | reverse | implode;

Examples:

"nöel" | reverse_string  # => "leön"
"as⃝df̅" | reverse_string  # => "̅fd⃝sa"

Jsish

ECMAScript has no builtin string reversal, so split the characters into an array, reverse the array and join it back together.

Jsi only supports UTF-8 literals so far (in release 2.8), character by character manipulation routines of multibyte UTF-8 data will not be correct. No extra credit, yet.

var str = "Never odd or even";
puts(str);
puts(str.split('').reverse().join(''));
Output:
Never odd or even
neve ro ddo reveN

Julia

julia> reverse("hey")
"yeh"

The reverse function reverses codepoints (because this is the right behavior for the main application of string reversal: reversed string processing by external C libraries). However, starting in Julia 0.4, you can also reverse the graphemes if you want (i.e. to reverse "visual order" including combining characters etc.) by:

julia> join(reverse(collect(graphemes("as⃝df̅"))))
"f̅ds⃝a"

K

Monadic reverse (| ) verb reverses a string or list of any shape

     |"asdf"
"fdsa"

     | 23 4 5 1
1 5 4 23

Kotlin

fun main(args: Array<String>) {
    println("asdf".reversed())
}

L++

(include "string" "algorithm")
(main
  (decl std::string s)
  (std::getline std::cin s)
  (std::reverse (s.begin) (s.end))
  (prn s))

LabVIEW

This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.

Lambdatalk

{S.reverse hello brave new world} 
-> world new brave hello

Lang

# Inv operator
fn.println(parser.op(-asdf))
# Ouput: fdsa

# Inv operator function
fn.println(fn.inv(asdf))
# Ouput: fdsa

Lang5

: flip "" split reverse "" join ;
"qwer asdf" flip .

langur

The reverse() function will reverse a string according to graphemes.

writeln reverse("don't you know")
Output:
wonk uoy t'nod

Lasso

local(input) = 'asdf'
#input->reverse

Using Query Expression & Array

More verbose than the string->reverse method, but this example illustrates different techniques to achieve the same result: using string->values to iterate over a string in order, inserting at position 1, and joining the resulting array as a string.

local(input = 'asdf', output = array)
with i in #input->values 
do #output->insertFirst(#i)
#output->join

LC3 Assembly

A string is stored as a zero-terminated array of character codes. To reverse it, we first scan forwards until we find the end; we then move backwards again, copying each code into a block of memory we have reserved for the purpose; and finally, when we have got back to the beginning, we append a terminal zero to the new string we have created. We can then call PUTS to print it.

        .ORIG      0x3000

        LEA        R1,STRING
        LEA        R2,GNIRTS
        LD         R3,MINUS1
        NOT        R5,R1
        ADD        R5,R5,1

SCAN    LDR        R4,R1,0
        BRZ        COPY
        ADD        R1,R1,1
        BRNZP      SCAN

COPY    ADD        R1,R1,R3
        ADD        R4,R1,R5
        BRN        COPIED
        LDR        R4,R1,0
        STR        R4,R2,0
        ADD        R2,R2,1
        BRNZP      COPY

COPIED  AND        R4,R4,0
        STR        R4,R2,0

        LEA        R0,GNIRTS
        PUTS

        HALT

MINUS1  .FILL      0xFFFF

STRING  .STRINGZ   "If thou beest he -- but O how fall'n! how chang'd"
GNIRTS  .BLKW      128

        .END
Output:
d'gnahc woh !n'llaf woh O tub -- eh tseeb uoht fI

LFE

Ordinary string:

> (lists:reverse "asdf")
"fdsa"

Create a UTF-8 encoded string:

> (set encoded (binary ("åäö ð" utf8)))
#B(195 165 195 164 195 182 32 195 176)

Display it, to be sure:

> (io:format "~tp~n" (list encoded))
<<"åäö ð"/utf8>>

Reverse it:

> (lists:reverse (unicode:characters_to_list encoded))
"ð öäå"

Liberty BASIC

Works with: Just BASIC
Works with: Run BASIC
input$ ="abcdefgABCDEFG012345"
print input$
print ReversedStr$( input$)

end

function ReversedStr$(in$)
    for i =len(in$) to 1 step -1
    ReversedStr$ =ReversedStr$ +mid$( in$, i, 1)
    next i
end function

Lingo

Lingo strings are always UTF-8 encoded and string operations are based on Unicode code points, so the "extra credit" is built-in:

on reverse (str)
  res = ""
  repeat with i = str.length down to 1
    put str.char[i] after res
  end repeat
  return res
end

To reverse a string byte-wise, the ByteArray data type has to be used:

on reverseBytes (str)
  ba = byteArray(str)
  res = byteArray()
  repeat with i = ba.length down to 1
    res[res.length+1] = ba[i]
  end repeat
  return res
end

LiveCode

function reverseString S
   repeat with i = length(S) down to 1
      put char i of S after R
   end repeat
   return R
end reverseString

LLVM

; This is not strictly LLVM, as it uses the C library function "printf".
; LLVM does not provide a way to print values, so the alternative would be
; to just load the string into memory, and that would be boring.

; Additional comments have been inserted, as well as changes made from the output produced by clang such as putting more meaningful labels for the jumps

$"main.printf" = comdat any

@main.str = private unnamed_addr constant [12 x i8] c"Hello world\00", align 1
@"main.printf" = linkonce_odr unnamed_addr constant [4 x i8] c"%s\0A\00", comdat, align 1

define void @reverse(i64, i8*) {
  %3 = alloca i8*, align 8          ; allocate str (local)
  %4 = alloca i64, align 8          ; allocate len (local)
  %5 = alloca i64, align 8          ; allocate i
  %6 = alloca i64, align 8          ; allocate j
  %7 = alloca i8, align 1           ; allocate t
  store i8* %1, i8** %3, align 8    ; set str (local) to the parameter str
  store i64 %0, i64* %4, align 8    ; set len (local) to the paremeter len
  store i64 0, i64* %5, align 8     ; i = 0
  %8 = load i64, i64* %4, align 8   ; load len
  %9 = sub i64 %8, 1                ; decrement len
  store i64 %9, i64* %6, align 8    ; j =
  br label %loop

loop:
  %10 = load i64, i64* %5, align 8  ; load i
  %11 = load i64, i64* %6, align 8  ; load j
  %12 = icmp ult i64 %10, %11       ; i < j
  br i1 %12, label %loop_body, label %exit

loop_body:
  %13 = load i8*, i8** %3, align 8                  ; load str
  %14 = load i64, i64* %5, align 8                  ; load i
  %15 = getelementptr inbounds i8, i8* %13, i64 %14 ; address of str[i]
  %16 = load i8, i8* %15, align 1                   ; load str[i]
  store i8 %16, i8* %7, align 1                     ; t = str[i]
  %17 = load i64, i64* %6, align 8                  ; load j
  %18 = getelementptr inbounds i8, i8* %13, i64 %17 ; address of str[j]
  %19 = load i8, i8* %18, align 1                   ; load str[j]
  %20 = getelementptr inbounds i8, i8* %13, i64 %14 ; address of str[i]
  store i8 %19, i8* %20, align 1                    ; str[i] = str[j]
  %21 = load i8, i8* %7, align 1                    ; load t
  %22 = getelementptr inbounds i8, i8* %13, i64 %17 ; address of str[j]
  store i8 %21, i8* %22, align 1                    ; str[j] = t

;-- loop increment
  %23 = load i64, i64* %5, align 8  ; load i
  %24 = add i64 %23, 1              ; increment i
  store i64 %24, i64* %5, align 8   ; store i
  %25 = load i64, i64* %6, align 8  ; load j
  %26 = add i64 %25, -1             ; decrement j
  store i64 %26, i64* %6, align 8   ; store j
  br label %loop

exit:
  ret void
}

define i32 @main() {
;-- char str[]
  %1 = alloca [12 x i8], align 1
;-- memcpy(str, "Hello world")
  %2 = bitcast [12 x i8]* %1 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @main.str, i32 0, i32 0), i64 12, i32 1, i1 false)
;-- printf("%s\n", str)
  %3 = getelementptr inbounds [12 x i8], [12 x i8]* %1, i32 0, i32 0
  %4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main.printf", i32 0, i32 0), i8* %3)
;-- %7 = strlen(str)
  %5 = getelementptr inbounds [12 x i8], [12 x i8]* %1, i32 0, i32 0
  %6 = call i64 @strlen(i8* %5)
;-- reverse(%6, str)
  call void @reverse(i64 %6, i8* %5)
;-- printf("%s\n", str)
  %7 = getelementptr inbounds [12 x i8], [12 x i8]* %1, i32 0, i32 0
  %8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main.printf", i32 0, i32 0), i8* %7)
;-- end of main
  ret i32 0
}

;--- The declaration for the external C printf function.
declare i32 @printf(i8*, ...)

; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1)

declare i64 @strlen(i8*)
Output:
Hello world
dlrow olleH

REVERSE works on both words and lists.

print reverse "cat   ; tac

Lua

Built-in string.reverse(s) or s:reverse().

ASCII

example = 'asdf'
string.reverse(example) -- fdsa
example:reverse() -- fdsa

Unicode

Lua doesn't support Unicode strings.

M2000 Interpreter

Using Custom Function

Version 2, using insert to string (with no copies of strings)

Module ReverseString {
      a$="as⃝df̅"
      Print Len(a$), len.disp(a$)
      Let i=1, j=Len(a$)
      z$=String$(" ",j)
      j++
      do {
            k$=mid$(a$, i, 1)
            if i<len(a$) then {
                  while len.disp(k$+mid$(a$, i+1,1)) =len.disp(k$)  {
                        k$+=mid$(a$, i+1,1)
                        i++ 
                        if i>len(a$) then exit
                        j--
                  }
                  j--
                  insert j, len(k$) Z$=K$
            } else j-- :Insert j,1 z$=k$ 
            if i>=len(a$) then exit
            i++
      } Always
      Print len(z$), len.disp(z$)
      Print z$="f̅ds⃝a"
      Print z$
}
ReverseString

using StrRev$()

this function (new to 9.5 version) use StrReverse from Vb6

a$="as⃝df̅"
b$=strrev$(a$)
clipboard b$
Print b$="̅fd⃝sa"

M4

define(`invert',`ifelse(len(`$1'),0,,`invert(substr(`$1',1))'`'substr(`$1',0,1))')

Maclisp

(readlist (reverse (explode "my-string")))

Output:

"gnirts-ym"

MACRO-11

        .TITLE  REVERS
        .MCALL  .GTLIN,.PRINT,.EXIT
REVERS::.GTLIN  #1$             ; READ STRING
        MOV     #1$,R0
        JSR     PC,REV          ; REVERSE IT
        .PRINT  #1$             ; PRINT RESULT
        .EXIT
1$:     .BLKB   200

        ; REVERSE STRING AT R0
REV:    MOV     R0,R1
1$:     TSTB    (R1)+           ; FIND END OF STRING
        BNE     1$
        DEC     R1              ; MOVE BACK TO LAST CHAR
2$:     MOVB    -(R1),R2        ; SWAP CHARS
        MOVB    (R0),(R1)
        MOVB    R2,(R0)+
        CMP     R0,R1           ; STOP WHEN POINTERS MEET
        BLT     2$
        RTS     PC

        .END    REVERS
Output:
.revers
A man, a plan, a canal: Panama
amanaP :lanac a ,nalp a ,nam A

Maple

> StringTools:-Reverse( "foo" );
                                 "oof"

Mathematica /Wolfram Language

StringReverse["asdf"]

MATLAB

A built-in function, "fliplr(string)" handles reversing a string of ASCII characters. Unicode is a whole other beast, if you need this functionality test to see if "fliplr()" properly handles the unicode characters you use. If it doesn't then you will need to code a function that is specific to your application.

Sample Usage:

>> fliplr(['She told me that she spoke English and I said great. '...
'Grabbed her hand out the club and I said let''s skate.'])

ans =

.etaks s'tel dias I dna bulc eht tuo dnah reh debbarG .taerg dias I dna hsilgnE ekops ehs taht em dlot ehS

Maxima

sreverse("abcdef");         /* "fedcba" */

sreverse("rats live on no evil star");   /* not a bug :o) */

MAXScript

fn reverseString s =
(
    local reversed = ""
    for i in s.count to 1 by -1 do reversed += s[i]
    reversed
)

min

Works with: min version 0.19.3
("" split reverse "" join) :reverse-str

MiniScript

str = "This is a string"
print "Forward: " + str
newStr = ""
for i in range(str.len-1, 0)
    newStr = newStr + str[i]
end for
print "Reversed: " + newStr
Output:
Forward: This is a string
Reversed: gnirts a si sihT

MIPS Assembly

# First, it gets the length of the original string
# Then, it allocates memory from the copy
# Then it copies the pointer to the original string, and adds the strlen
#     subtract 1, then that new pointer is at the last char.
# while(strlen)
#     copy char
#     decrement strlen
#     decrement source pointer
#     increment target pointer

.text

strcpy:
  addi $sp, $sp, -4
  sw $s0, 0($sp)
  add $s0, $zero, $zero

L1: 
  add $t1, $s0, $a1
  lb $t2, 0($t1)
  add $t3, $s0, $a0
  sb $t2, 0($t3)
  beq $t2, $zero, L2
  addi $s0, $s0, 1
  j L1

L2:
  lw $s0, 0($sp)
  addi $sp, $sp, 4
  jr $ra

.data 
	ex_msg_og: .asciiz "Original string:\n"
	ex_msg_cpy: .asciiz "\nCopied string:\n"
	string: .asciiz "Nice string you got there!\n"

Mirah

def reverse(s:string) 
    StringBuilder.new(s).reverse
end

puts reverse('reversed')

Miranda

main :: [sys_message]
main = [Stdout (reverse "esreveR"),
        Stdout "\n"]
Output:
Reverse

Modula-2

MODULE ReverseStr;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT Write,WriteString,WriteLn,ReadChar;

PROCEDURE WriteInt(n : INTEGER);
VAR buf : ARRAY[0..15] OF CHAR;
BEGIN
    FormatString("%i", buf, n);
    WriteString(buf)
END WriteInt;

PROCEDURE ReverseStr(in : ARRAY OF CHAR; VAR out : ARRAY OF CHAR);
VAR ip,op : INTEGER;
BEGIN
    ip := 0;
    op := 0;
    WHILE in[ip] # 0C DO
        INC(ip)
    END;
    DEC(ip);
    WHILE ip>=0 DO
        out[op] := in[ip];
        INC(op);
        DEC(ip)
    END
END ReverseStr;

TYPE A = ARRAY[0..63] OF CHAR;
VAR is,os : A;
BEGIN
    is := "Hello World";
    ReverseStr(is, os);

    WriteString(is);
    WriteLn;
    WriteString(os);
    WriteLn;

    ReadChar
END ReverseStr.

Modula-3

MODULE Reverse EXPORTS Main;

IMPORT IO, Text;

PROCEDURE String(item: TEXT): TEXT =
  VAR result: TEXT := "";
  BEGIN
    FOR i := Text.Length(item) - 1 TO 0 BY - 1 DO
      result := Text.Cat(result, Text.FromChar(Text.GetChar(item, i)));
    END;
    RETURN result;
  END String;

BEGIN
  IO.Put(String("Foobarbaz") & "\n");
END Reverse.
Output:
zabrabooF

MUMPS

REVERSE
 ;Take in a string and reverse it using the built in function $REVERSE
 NEW S
 READ:30 "Enter a string: ",S
 WRITE !,$REVERSE(S)
 QUIT
Output:
USER>D REVERSE^ROSETTA
Enter a string: Hello, World!
!dlroW ,olleH

Nanoquery

def reverse(string)
        l = ""

        for char in list(str(string)).reverse()
                l += char
        end

        return l
end

Neko

No extra credit for UTF in this example.

/* Reverse a string, in Neko */

var reverse = function(s) {
  var len = $ssize(s)
  if len < 2 return s

  var reverse = $smake(len)
  var pos = 0
  while len > 0 $sset(reverse, pos ++= 1, $sget(s, len -= 1))
  return reverse
}

var str = "never odd or even"
$print(str, "\n")
$print(reverse(str), "\n\n")

str = "abcdefghijklmnopqrstuvwxyz"
$print(str, "\n")
$print(reverse(str), "\n\n")

$print("single test\n")
str = "a"
$print(str, "\n")
$print(reverse(str), "\n\n")


$print("empty test\n")
str = ""
$print(str, "\n")
$print(reverse(str), "\n")
Output:
prompt$ nekoc reverse.neko
prompt$ neko reverse.n
never odd or even
neve ro ddo reven

abcdefghijklmnopqrstuvwxyz
zyxwvutsrqponmlkjihgfedcba

single test
a
a

empty test

Nemerle

Supporting Combining Characters

Compile with:

ncc -reference:System.Windows.Forms reverse.n
using System;
using System.Globalization;
using System.Windows.Forms;
using System.Console;
using Nemerle.Utility.NString;

module StrReverse
{
    UReverse(text : string) : string
    {
        mutable output = [];
        def elements = StringInfo.GetTextElementEnumerator(text);
        while (elements.MoveNext())
            output ::= elements.GetTextElement().ToString();
        Concat("", output.Reverse());
    }
    
    Main() : void
    {
        def test = "as⃝df̅";
        MessageBox.Show($"$test --> $(UReverse(test))");  //for whatever reason my console didn't display Unicode properly, but a MessageBox worked
    }
}

Basic Reverse

Doesn't require the System.Globalization namespace, probably a little less overhead.

Reverse(text : string) : string
{
    mutable output = [];
    foreach (c in text.ToCharArray())
        output ::= c.ToString();
    Concat("", output)
}

NetRexx

/* NetRexx */

options replace format comments java crossref savelog symbols nobinary

reverseThis = 'asdf'
sihTesrever = reverseThis.reverse

say reverseThis
say sihTesrever

return
Output:
asdf
fdsa

NewLISP

(reverse "!dlroW olleH")

Nial

reverse 'asdf'
=fdsa

Nim

Unicode codepoints

Since Nim 0.11.0, the unicode module provides a reversed proc... Hence:

import unicode

doAssert "foobar".reversed == "raboof"
doAssert "先秦兩漢".reversed == "漢兩秦先"

This proc is enumerating codepoints so it will work with Unicode multi-bytes characters. A special handling was added so it's supports composing as well but since it's not enumerating graphemes it won't work with joining.

Unicode graphemes

There is no native method to handle grapheme currently.

NS-HUBASIC

10 STRING$="THIS TEXT IS REVERSED."
20 REVERSED$=""
30 FOR I=1 TO LEN(STRING$)
40 REVERSED$=MID$(STRING$,I,1)+REVERSED$
50 NEXT
60 PRINT REVERSED$

Nu

'äsdf' | str reverse
Output:
fdsä

Oberon-2

Tested with OBNC.

MODULE reverse;

   IMPORT Out, Strings;
   
   VAR s: ARRAY 12 + 1 OF CHAR;   
   
   PROCEDURE Swap(VAR c, d: CHAR);
      VAR oldC: CHAR;
   BEGIN
      oldC := c; c := d; d := oldC         
   END Swap;


   PROCEDURE Reverse(VAR s: ARRAY OF CHAR);
      VAR len, i: INTEGER;
   BEGIN
      len := Strings.Length(s);
      FOR i := 0 TO len DIV 2 DO
         Swap(s[i], s[len - 1 - i])
      END
   END Reverse;
   
BEGIN
   s := "hello, world";
   Reverse(s);
   Out.String(s);
   Out.Ln
END reverse.

Objeck

result := "asdf"->Reverse();

Objective-C

This extends the NSString object adding a reverseString class method.

#import <Foundation/Foundation.h>

@interface NSString (Extended)
-(NSString *)reverseString;
@end

@implementation NSString (Extended)
-(NSString *) reverseString
{
    NSUInteger len = [self length];
    NSMutableString *rtr=[NSMutableString stringWithCapacity:len];
    //        unichar buf[1];
    
    while (len > (NSUInteger)0) { 
        unichar uch = [self characterAtIndex:--len]; 
        [rtr appendString:[NSString stringWithCharacters:&uch length:1]];
    }
    return rtr;
}
@end

Usage example:

int main()
{
    @autoreleasepool {
        
        NSString *test = [@"!A string to be reverted!" reverseString];
    
        NSLog(@"%@", test);
    
    }
    return 0;
}

Supporting combining characters

Extra credit

#import <Foundation/Foundation.h>

@interface NSString (Extended)
-(NSString *)reverseString;
@end

@implementation NSString (Extended)
-(NSString *)reverseString
{
	NSInteger l = [self length] - 1;
	NSMutableString *ostr = [NSMutableString stringWithCapacity:[self length]];
	while (l >= 0)
	{
		NSRange range = [self rangeOfComposedCharacterSequenceAtIndex:l];
		[ostr appendString:[self substringWithRange:range]];
		l -= range.length;
	}
	return ostr;
}
@end

Usage example:

int main()
{
    @autoreleasepool {
        
        NSString *test = [@"as⃝df̅" reverseString];
    
        NSLog(@"%@", test);
    
    }
    return 0;
}

OCaml

Since OCaml 4.02 we can use the handy String.init function.

Here a version that returns a new allocated string (preserving the original one):

Works with: OCaml version 4.02+
let string_rev s =
  let len = String.length s in
  String.init len (fun i -> s.[len - 1 - i])

let () =
  print_endline (string_rev "Hello world!")

for in place modification we can't use strings anymore because strings became immutable in ocaml 4.02, so the type bytes has to be used instead:

let rev_bytes bs =
  let last = Bytes.length bs - 1 in
  for i = 0 to last / 2 do
    let j = last - i in
    let c = Bytes.get bs i in
    Bytes.set bs i (Bytes.get bs j);
    Bytes.set bs j c;
  done

let () =
  let s = Bytes.of_string "Hello World" in
  rev_bytes s;
  print_bytes s;
  print_newline ();
;;

Here is a 100% functionnal string reversing function:

let rec revs_aux strin list index =
  if List.length list = String.length strin
  then String.concat "" list
  else revs_aux strin ((String.sub strin index 1)::list) (index+1)

let revs s = revs_aux s [] 0

let () =
  print_endline (revs "Hello  World!")

will return "!dlroW olleH"

Octave

s = "a string";
rev = s(length(s):-1:1)

Oforth

reverse

Ol

(define (rev s)
   (runes->string (reverse (string->runes s))))

; testing:
(print (rev "Hello, λ!"))
; ==> !λ ,olleH

OmniMark

This handles the characters U+0073,U+20DD (Latin Small Letter S + Combining Enclosing Circle; UTF-8: 73 + e2 83 9D) and U+0066,U+0305 (Latin Small Letter F + Combining Overline; UTF-8: 66 + cc 85). It would need extension to handle non-combining UTF-8 characters, but that's not been done.

macro utf8-not-ascii is
   (["%16r{C0}" to "%16r{DF}"] ["%16r{80}" to "%16r{BF}"] |
    ["%16r{E0}" to "%16r{EF}"] ["%16r{80}" to "%16r{BF}"] {2} |
    ["%16r{F0}" to "%16r{F7}"] ["%16r{80}" to "%16r{BF}"] {3}) macro-end

global stream reverse initial {''}

process
  submit 'as⃝df̅'

find (any-text utf8-not-ascii) => char
  set reverse to char || reverse

find any-text => char
  set reverse to char || reverse

process-end
  output reverse || '%n'
Output:
f̅ds⃝a

OOC

main: func {
  "asdf" reverse() println() // prints "fdsa"
}

OpenEdge/Progress

FUNCTION reverseString RETURNS CHARACTER (
   INPUT i_c AS CHARACTER
):

   DEFINE VARIABLE cresult AS CHARACTER   NO-UNDO.
   DEFINE VARIABLE ii      AS INTEGER     NO-UNDO.

   DO ii = LENGTH( i_c ) TO 1 BY -1:
      cresult = cresult + SUBSTRING( i_c, ii, 1 ).
   END.
   RETURN cresult.

END FUNCTION.

MESSAGE reverseString( "asdf" ) VIEW-AS ALERT-BOX.

OxygenBasic

'8 BIT CHARACTERS

string s="qwertyuiop"
sys a,b,i,j,le=len s
'
for i=1 to le
  j=le-i+1
  if j<=i then exit for
  a=asc s,i
  b=asc s,j
  mid s,j,chr a
  mid s,i,chr b
next
'

print s

'16 BIT CHARACTERS

wstring s="qwertyuiop"
sys a,b,i,j,le=len s
'
for i=1 to le
  j=le-i+1
  if j<=i then exit for
  a=unic s,i
  b=unic s,j
  mid s,j,wchr a
  mid s,i,wchr b
next
'
print s

OxygenBasic x86 Assembler

32 bit code, 8-bit characters:

string s="qwertyuiop"
sys p=strptr s, le=len s
mov esi,p
mov edi,esi
add edi,le
dec edi
(
 cmp esi,edi
 jge exit
 mov al,[esi]
 mov ah,[edi]
 mov [esi],ah
 mov [edi],al
 inc esi
 dec edi
 repeat
)

print s

Oz

Strings are lists. A function "Reverse" defined on lists is part of the implementation.

{System.showInfo {Reverse "!dlroW olleH"}}

An efficient (tail-recursive) implementation could look like this:

local
   fun {DoReverse Xs Ys}
      case Xs of nil then Ys
      [] X|Xr then {DoReverse Xr X|Ys}
      end
   end
in
   fun {Reverse Xs} {DoReverse Xs nil} end
end

Oz uses a single-byte encoding by default. If you decide to use a multi-byte encoding, Reverse will not work correctly.

PARI/GP

Version #1.

reverse(s)=concat(Vecrev(s))

Version #2.

Works with: PARI/GP version 2.7.4 and above
\\ Return reversed string str.
\\ 3/3/2016 aev
sreverse(str)={return(Strchr(Vecrev(Vecsmall(str))))}

{
\\ TEST1 
print(" *** Testing sreverse from Version #2:");
print(sreverse("ABCDEF"));
my(s,sr,n=10000000);
s="ABCDEFGHIJKL";
for(i=1,n, sr=sreverse(s));
}
Output:
 *** Testing sreverse from Version #2:
FEDCBA
(17:28) gp > ##
  ***   last result computed in 8,642 ms.
\\ Version #1 upgraded to complete function. Practically the same.
reverse(str)={return(concat(Vecrev(str)))}

{
\\ TEST2 
print(" *** Testing reverse from Version #1:");
print(reverse("ABCDEF"));
my(s,sr,n=10000000);
s="ABCDEFGHIJKL";
for(i=1,n, sr=reverse(s));
}
Output:
 *** Testing reverse from Version #1:
FEDCBA
(17:31) gp > ##
  ***   last result computed in 11,814 ms.

Pascal

The following examples handle correctly only single-byte encodings.

Standard Pascal

The following only works on implementations which implement Level 1 of standard Pascal (many popular compilers don't).

Standard Pascal doesn't have a separate string type, but uses arrays of char for strings. Note that Standard Pascal doesn't allow a return type of char array, therefore the destination array is passed through a var parameter (which is more efficient anyway).

{ the result array must be at least as large as the original array }
procedure reverse(s: array[min .. max: integer] of char, var result: array[min1 .. max1: integer] of char);
 var
  i, len: integer;
 begin
  len := max-min+1;
  for i := 0 to len-1 do
   result[min1 + len-1 - i] := s[min + i]
 end;
{Copy and paste it in your program}
function revstr(my_s:string):string;
    var out_s:string;
    ls,i:integer;
    begin
    ls:=length(my_s);
    for i:=1 to ls do
    out_s:=out_s+my_s[ls-i+1];
    revstr:=out_s;
    end;

Extended Pascal, Turbo Pascal, Delphi and compatible compilers

function reverse(s:string):string;
var i:integer;
var tmp:char;
begin
    for i:=1 to length(s) div 2 do
      begin
       tmp:=s[i];
       s[i]:=s[length(s)+1-i];
       s[length(s)+1-i]:=tmp;
       reverse:=s;
      end;
end;

alternative as procedure which changes the original

procedure revString(var s:string);
var
  i,j:integer;
  tmp:char;
begin
  i := 1;
  j := length(s);
  while i<j do
  begin
     tmp:=s[i];
     s[i]:=s[j];
     s[j]:=tmp;
     inc(i);
     dec(j)
  end;
end;

PascalABC.NET

## 
var s:='asdf';//ReadLnString;
ReverseString(s).Print;
Output:
fdsa 

Peloton

Padded out, variable length Chinese dialect

<# 显示 指定 变量 反转顺序 字串>集装箱|猫坐在垫子</#>

This assigns the reverse of 'the cat sat on the mat' to the variable 'container' and displays the result which is

子垫在坐猫

which Google Translate renders as

Sub-pad sitting cat

.

The same again but with everything in Korean.

<# 보이십 할당하 변물건 열거꾸 문자그>컨테이너|고양이가 매트 위에 앉아</#>

Reversing the Korean makes an untranslatable-by-Google mess of the sentence, viz

아앉 에위 트매 가이양고

.

The short-opcode version in English dialect is

<@ SAYLETVARREVLIT>集装箱|猫坐在垫子</@>

Peloton works in Unicode.

Perl

reverse() works in the context of a List or a scalar, not a string.

use utf8;
binmode STDOUT, ":utf8";

# to reverse characters (code points):
print scalar reverse('visor'), "\n";

# to reverse graphemes:
print join("", reverse "José" =~ /\X/g), "\n";

$string = 'ℵΑΩ 駱駝道 🤔 🇸🇧 🇺🇸 🇬🇧‍ 👨‍👩‍👧‍👦🆗🗺';
print join("", reverse $string =~ /\X/g), "\n";
Output:
rosiv
ésoJ
🗺🆗👨‍👩‍👧‍👦 🇬🇧‍ 🇺🇸 🇸🇧 🤔 道駝駱 ΩΑℵ

Pharo

'123' reversed


Phix

?reverse("asdf")

However that would go horribly wrong on utf8 strings, even without combining characters, so... this seems ok on "as\u203Ddf\u0305", as long as it is displayed in a message box rather than a Windows Console (even with chcp 65001 and Lucida Console, the characters do not combine). It actually works better under pwa/p2js than on desktop/Phix, you can find a copy of this code in demo/HelloUTF8.exw which outputs the result in a message box and therefore looks much better on the latter.
Note that XXXX_redacted#Phix adds some ZERO-WIDTH-JOINER handling to the inner code.

with javascript_semantics
function unicode_reverse(string utf8)
    sequence utf32 = utf8_to_utf32(utf8)
    -- The assumption is made that <char><comb1><comb2>
    -- and <char><comb2><comb1> etc would work the same.
    -- The following loop converts <char><comb1><comb2>
    -- to <comb1><comb2><char>, as a pre-reverse() step.
    for i=1 to length(utf32) do
        integer ch = utf32[i]
        if (ch>=0x300 and ch<=0x36f)
        or (ch>=0x1dc0 and ch<=0x1dff)
        or (ch>=0x20d0 and ch<=0x20ff)
        or (ch>=0xfe20 and ch<=0xfe2f) then
            utf32[i] = utf32[i-1]
            utf32[i-1] = ch
        end if
    end for
    utf32 = reverse(utf32)
    utf8 = utf32_to_utf8(utf32)
    return utf8
end function
string r4 = "as\u203Ddf\u0305",
       rt = r4&" reversed is "&unicode_reverse(r4)&"\n"
puts(1,rt)

PHP

Unicode

Code points

If you want Unicode support, you have to use some multibyte function. Sadly, PHP doesn't contain mb_strrev(). One of functions which support Unicode and is useful in this case is preg_split().

// Will split every Unicode character to array, reverse array and will convert it to string.
join('', array_reverse(preg_split('""u', $string, -1, PREG_SPLIT_NO_EMPTY)));

With PHP 7.4+ and 8+, it's also possible to use mb_str_split(), which may ends easier.

implode('', array_reverse(mb_str_split($string)));

Graphemes

When using combining characters such as diacritics or ZWJ (joining), reversing code points will mess with the result, reversing the graphemes instead is mandatory. This is generally the best and safest approach. As there is no grapheme_reverse() function or grapheme iterator, one has to implement it with grapheme_strlen and grapheme_substr. In PHP, there is no Unicode escape sequence so to specify characters by code point a tricks must be used: for example, using the escape sequence of HTML entities and then convert it to a Unicode encoding such as UTF-8.

$a = mb_convert_encoding('&#x1F466;&#x1F3FB;&#x1f44b;', 'UTF-8', 'HTML-ENTITIES'); // 👦🏻👋

function str_to_array($string)
{
  $length = grapheme_strlen($string);
  $ret = [];

  for ($i = 0; $i < $length; $i += 1) {

    $ret[] = grapheme_substr($string, $i, 1);
  }

  return $ret;
}

function utf8_strrev($string)
{
  return implode(array_reverse(str_to_array($string)));
}

print_r(utf8_strrev($a)); // 👋👦🏻

ASCII

strrev($string);

PicoLisp

(pack (flip (chop "äöüÄÖÜß")))
Output:
-> "ßÜÖÄüöä"

Pike

For simple ASCII:

reverse("foo");
Output:
"oof"

When dealing with Unicode (or any other supported encoding) care must be taken primarily in the output step to serialize the Unicode string into something the sink can handle. IO functions will throw an error if sent raw wide strings.

#charset utf8
void main()
{
    string s = "ßÜÖÄüöää ἀρχῇ";    
    write("%s\n", string_to_utf8( reverse(s) ));
}
Output:
ῇχρἀ ääöüÄÖÜß

PL/I

s = reverse(s);

Plain English

To run:
Start up.
Put "asdf" into a string.
Reverse the string.
Shut down.

Plain TeX

Works well if the string has no space (spaces are gobbled).

\def\gobtoA#1\revA{}\def\gobtoB#1\revB{}
\def\reverse#1{\reversei{}#1\revA\revB\revB\revB\revB\revB\revB\revB\revB\revA}
\def\reversei#1#2#3#4#5#6#7#8#9{\gobtoB#9\revend\revB\reversei{#9#8#7#6#5#4#3#2#1}}
\def\revend\revB\reversei#1#2\revA{\gobtoA#1}
\reverse{Rosetta}
\bye

Output:

attesoR

Pop11

define reverse_string(s);
    lvars i, l = length(s);
    for i from l by -1 to 1 do
        s(i);
    endfor;
    consstring(l);
enddefine;

PostScript

The following implementation works on arrays of numerics as well as characters ( string ).

/reverse{
/str exch def
/temp str 0 get def
/i 0 def
str length 2 idiv{
/temp str i get def
str i str str length i sub 1 sub get put
str str length i sub 1 sub temp put
/i i 1 add def
}repeat
str pstack
}def
Output:
[1 2 3] reverse % input
[3 2 1]

(Hello World) reverse % input
(dlroW olleH)

PowerBASIC

#DIM ALL
#COMPILER PBCC 6

FUNCTION PBMAIN () AS LONG
CON.PRINT STRREVERSE$("PowerBASIC")
END FUNCTION

PowerShell

For ASCII

Test string

$s = "asdf"

Array indexing

Creating a character array from the end to the string's start and join it together into a string again.

Works with: PowerShell version 1
[string]::Join('', $s[$s.Length..0])
Works with: PowerShell version 2
-join ($s[$s.Length..0])
Works with: PowerShell version 2
[array]::Reverse($s)

Regular expressions

Creating a regular expression substitution which captures every character of the string in a capture group and uses a reverse-ordered string of references to those to construct the reversed string.

Works with: PowerShell version 1
$s -replace
      ('(.)' * $s.Length),
      [string]::Join('', ($s.Length..1 | ForEach-Object { "`$$_" }))
Works with: PowerShell version 2
$s -replace
      ('(.)' * $s.Length),
      -join ($s.Length..1 | ForEach-Object { "`$$_" } )
Works with: PowerShell version 3
[Regex]::Matches($s,'.','RightToLeft').Value -join ''

For Unicode

For codepoints

Since PowerShell 7, there is a EnumerateRunes() method to enumerate Unicode codepoints. Enumerating codepoints works for multi-bytes characters but not for composing or joining.

$a = 'abc 🐧 def'
$enum = $a.EnumerateRunes() | % { "$_" }
-join $enum[$enum.length..0] # fed 🐧 cba

For graphemes

For composing or joining, enumerating graphemes is required.

$a = "aeiou`u{0308}yz"
$enum = [System.Globalization.StringInfo]::GetTextElementEnumerator($a)
$arr = @()
while($enum.MoveNext()) { $arr += $enum.GetTextElement() }
[array]::reverse($arr)
$arr -join '' # zyüoiea

Prolog

Works with: SWI Prolog
reverse("abcd", L), string_to_list(S,L).
Output:
L = [100,99,98,97],
S = "dcba". 

The main workings are hidden inside the reverse/2 predicate, so lets write one to see how it works:

accRev([H|T], A, R) :- accRev(T, [H|A], R).
accRev([], A, A).

rev(L,R) :- accRev(L,[],R).

PureBasic

Debug ReverseString("!dekrow tI")

Python

Optimized for user input

input()[::-1]

Already known string

string[::-1]

or

''.join(reversed(string))

Python: Unicode reversal

(See this article for more information from which this is improved)

Note: How this looks may be subject to how the tool you are using to view this page can render Unicode.

import unicodedata

def ureverse(ustring):
    'Reverse a string including unicode combining characters'
    groupedchars = []
    uchar = list(ustring)
    while uchar:
        if unicodedata.combining(uchar[0]) != 0:
            groupedchars[-1] += uchar.pop(0)
        else:
            groupedchars.append(uchar.pop(0))
    # Grouped reversal
    groupedchars = groupedchars[::-1]
 
    return ''.join(groupedchars)

def say_string(s):
    return ' '.join([s, '=', ' | '.join(unicodedata.name(ch, '') for ch in s)])

def say_rev(s):
    print(f"Input:              {say_string(s)}")
    print(f"Character reversed: {say_string(s[::-1])}")
    print(f"Unicode reversed:   {say_string(ureverse(s))}")
    print(f"Unicode reverse²:   {say_string(ureverse(ureverse(s)))}")
        
if __name__ == '__main__':
    ucode = ''.join(chr(int(n[2:], 16)) for n in 
                     'U+0041 U+030A U+0073 U+0074 U+0072 U+006F U+0308 U+006D'.split())
    say_rev(ucode)
Output:
Input:              Åström = LATIN CAPITAL LETTER A | COMBINING RING ABOVE | LATIN SMALL LETTER S | LATIN SMALL LETTER T | LATIN SMALL LETTER R | LATIN SMALL LETTER O | COMBINING DIAERESIS | LATIN SMALL LETTER M
Character reversed: m̈orts̊A = LATIN SMALL LETTER M | COMBINING DIAERESIS | LATIN SMALL LETTER O | LATIN SMALL LETTER R | LATIN SMALL LETTER T | LATIN SMALL LETTER S | COMBINING RING ABOVE | LATIN CAPITAL LETTER A
Unicode reversed:   mörtsÅ = LATIN SMALL LETTER M | LATIN SMALL LETTER O | COMBINING DIAERESIS | LATIN SMALL LETTER R | LATIN SMALL LETTER T | LATIN SMALL LETTER S | LATIN CAPITAL LETTER A | COMBINING RING ABOVE
Unicode reverse²:   Åström = LATIN CAPITAL LETTER A | COMBINING RING ABOVE | LATIN SMALL LETTER S | LATIN SMALL LETTER T | LATIN SMALL LETTER R | LATIN SMALL LETTER O | COMBINING DIAERESIS | LATIN SMALL LETTER M

If this code is then used:

ucode = ''.join(chr(int(n[2:], 16)) for n in 
                 'U+006B U+0301 U+0075 U+032D U+006F U+0304 U+0301 U+006E'.split())
say_rev(ucode)

It produces this output

Output:
Input:              ḱṷṓn = LATIN SMALL LETTER K | COMBINING ACUTE ACCENT | LATIN SMALL LETTER U | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER O | COMBINING MACRON | COMBINING ACUTE ACCENT | LATIN SMALL LETTER N
Character reversed: ń̄o̭úk = LATIN SMALL LETTER N | COMBINING ACUTE ACCENT | COMBINING MACRON | LATIN SMALL LETTER O | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER U | COMBINING ACUTE ACCENT | LATIN SMALL LETTER K
Unicode reversed:   nṓṷḱ = LATIN SMALL LETTER N | LATIN SMALL LETTER O | COMBINING MACRON | COMBINING ACUTE ACCENT | LATIN SMALL LETTER U | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER K | COMBINING ACUTE ACCENT
Unicode reverse²:   ḱṷṓn = LATIN SMALL LETTER K | COMBINING ACUTE ACCENT | LATIN SMALL LETTER U | COMBINING CIRCUMFLEX ACCENT BELOW | LATIN SMALL LETTER O | COMBINING MACRON | COMBINING ACUTE ACCENT | LATIN SMALL LETTER N


This uses the unicode string mentioned in the task:

ucode = ''.join(chr(int(n, 16))
                 for n in ['61', '73', '20dd', '64', '66', '305'])
say_rev(ucode)

It produces this output

Output:
Input:              as⃝df̅ = LATIN SMALL LETTER A | LATIN SMALL LETTER S | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER D | LATIN SMALL LETTER F | COMBINING OVERLINE
Character reversed: ̅fd⃝sa = COMBINING OVERLINE | LATIN SMALL LETTER F | LATIN SMALL LETTER D | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER S | LATIN SMALL LETTER A
Unicode reversed:   f̅d⃝sa = LATIN SMALL LETTER F | COMBINING OVERLINE | LATIN SMALL LETTER D | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER S | LATIN SMALL LETTER A
Unicode reverse²:   as⃝df̅ = LATIN SMALL LETTER A | LATIN SMALL LETTER S | COMBINING ENCLOSING CIRCLE | LATIN SMALL LETTER D | LATIN SMALL LETTER F | COMBINING OVERLINE

Quackery

reverse is predefined (and applies to nests in general, including strings) as:

  [ dup nest? if
      [ [] swap witheach
          [ nested
            swap join ] ] ]     is reverse      (       x --> x       )


Qi

It's simplest just to use the common lisp REVERSE function.

(REVERSE "ABCD")

R

Works with: R version 2.8.1

The following code works with UTF-8 encoded strings too.

revstring <- function(stringtorev) {
   return(
      paste(
           strsplit(stringtorev,"")[[1]][nchar(stringtorev):1]
           ,collapse="")
           )
}

Alternatively (using rev() function):

 revstring <- function(s) paste(rev(strsplit(s,"")[[1]]),collapse="")
revstring("asdf")
revstring("m\u00f8\u00f8se")
Encoding("m\u00f8\u00f8se")   # just to check if on your system it's something
                              # different!
Output:
[1] "fdsa"
[1] "esøøm"
[1] "UTF-8"

R can encode strings in Latin1 and UTF-8 (the default may depend on the locale); the Encoding(string) can be used to know if the string is encoded in Latin1 or UTF-8; the encoding can be forced (Encoding(x) <- "latin1"), or we can use iconv to properly translate between encodings whenever possible.

Racket

As in Scheme:

#lang racket

(define (string-reverse s)
  (list->string (reverse (string->list s))))

(string-reverse "aoeu")
Output:
Welcome to DrRacket, version 5.3.3.5--2013-02-20(5eddac74/d) [3m].
Language: racket; memory limit: 512 MB.
"ueoa"
> 

Raku

(formerly Perl 6)

Works with: rakudo version 2018.08

Raku handles graphemes, multi-byte characters and emoji correctly by default.

say "hello world".flip;
say "as⃝df̅".flip;
say 'ℵΑΩ 駱駝道 🤔 🇸🇧 🇺🇸 🇬🇧‍ 👨‍👩‍👧‍👦🆗🗺'.flip;
Output:
dlrow olleh
f̅ds⃝a
🗺🆗👨‍👩‍👧‍👦 🇬🇧‍ 🇺🇸 🇸🇧 🤔 道駝駱 ΩΑℵ

RapidQ

print reverse$("This is a test")

Rascal

import String;
reverse("string")

Raven

"asdf" reverse
Output:
fdsa

REBOL

print reverse "asdf"

Note the string is reversed in place. If you were using it anywhere else, you would find it reversed:

x: "asdf"
print reverse x
print x ; Now reversed.

REBOL/View 2.7.6.3.1 14-Mar-2008 does not handle Unicode strings. This is planned for REBOL 3.

Red

>> reverse "asdf"
== "fdsa"

Refal

$ENTRY Go {
    = <Prout <Reverse 'asdf'>>;
};

Reverse {
    (e.X) = e.X;
    (e.X) s.C e.Y = <Reverse (s.C e.X) e.Y>;
    e.X = <Reverse () e.X>;
};
Output:
fdsa

ReScript

let rev_string = (s) => {
  let len = Js.String2.length(s)
  let arr = []
  for i in 0 to (len-1) {
    let c = Js.String2.get(s, len - 1 - i)
    let _ = Js.Array2.push(arr, c)
  }
  Js.String2.concatMany("", arr)
}

Js.log(rev_string("abcdefg"))
Output:
$ bsc revstr.res > revstr.bs.js
$ node revstr.bs.js
gfedcba

Retro

'asdf s:reverse s:put

REXX

All methods shown below also work with   NULL   values   (strings with a zero length).

using REVERSE BIF

/*REXX program to reverse a string  (and show before and after strings).*/

string1 = 'A man, a plan, a canal, Panama!'
string2 = reverse(string1)

say ' original string: '  string1
say ' reversed string: '  string2
                                       /*stick a fork in it, we're done.*/

output

 original string:  A man, a plan, a canal, Panama!
 reversed string:  !amanaP ,lanac a ,nalp a ,nam A

using SUBSTR BIF, left to right

/*REXX program to reverse a string  (and show before and after strings).*/

string1 = 'A man, a plan, a canal, Panama!'
string2 =
                                   do j=1  for length(string1)
                                   string2 = substr(string1,j,1)string2
                                   end   /*j*/
say ' original string: '  string1
say ' reversed string: '  string2
                                       /*stick a fork in it, we're done.*/

output   is identical to the 1st REXX version.

(Regarding the previous example)   Another method of coding an abutment (an implied concatenation) is:

                                   string2 = substr(string1,j,1) || string2
                                                /*───── or ─────*/
                                   string2= substr(string1,j,1)string2

using SUBSTR BIF, right to left

/*REXX program to reverse a string  (and show before and after strings).*/

string1 = 'A man, a plan, a canal, Panama!'
string2 =
                                  do j=length(string1)  to 1  by -1
                                  string2 = string2 || substr(string1,j,1)
                                  end   /*j*/
say ' original string: '  string1
say ' reversed string: '  string2
                                       /*stick a fork in it, we're done.*/

output is identical to the 1st version.

Ring

cStr = "asdf"  cStr2 = ""
for x = len(cStr) to 1 step -1 cStr2 += cStr[x] next
See cStr2  # fdsa

RLaB

>> x = "rosettacode"
rosettacode

// script
rx = "";
for (i in strlen(x):1:-1)
{
  rx = rx + substr(x, i);
}

>> rx
edocattesor

Robotic

. "local1 = Main string"
. "local2 = Temporary string storage"
. "local3 = String length"
set "$local1" to ""
set "$local2 " to ""
set "local3" to 0

input string "String to reverse:"
set "$local1" to "&INPUT&"
set "$local2" to "$local1"
set "local3" to "$local2.length"
loop start
set "$local1.(('local3' - 1) - 'loopcount')" to "$local2.('loopcount')"
loop for "('local3' - 1)"
* "Reversed string: &$local1& (Length: &$local1.length&)"
end

RPL

Works with: Halcyon Calc version 4.2.7
≪ "" 
   OVER SIZE 1 FOR j 
      OVER j DUP SUB + 
   -1 STEP SWAP DROP
≫ 'RVSTR' STO

"ABC" RVSTR
Output:
1: "CBA"

Ruby

str = "asdf"
reversed = str.reverse
"résumé niño".reverse #=> "oñin émusér"

for extra credit

graphemes = 'as⃝df̅'.scan(/\X/)
reversed = graphemes.reverse
graphemes.join #=> "f̅ds⃝a"

Run BASIC

Works with: Just BASIC
Works with: Liberty BASIC
Works with: QBasic
Works with: Yabasic
string$ = "123456789abcdefghijk"
for i = len(string$) to 1 step -1
 print mid$(string$,i,1);
next i

Rust

Reversing ASCII byte-slice (in-place):

let mut buffer = b"abcdef".to_vec();
buffer.reverse();
assert_eq!(buffer, b"fedcba");

Reversing Unicode scalar values:

let output: String = "一二三四五六七八九十".chars().rev().collect();
assert_eq!(output, "十九八七六五四三二一");

Reversing a Chars iterator doesn't solve the complete problem, because it iterates unicode scalar values, which doesn't account for combining marks:

let output: String = "as⃝df̅".chars().rev().collect();
assert_ne!(output, "f̅ds⃝a"); // should be this
assert_eq!(output, "̅fd⃝sa");

Reversing graphemes clusters, which is provided by the unicode-segmentation crate, solves the problem:

use unicode_segmentation::UnicodeSegmentation;

let output: String = "as⃝df̅".graphemes(true).rev().collect();
assert_eq!(output, "f̅ds⃝a");

S-lang

Here is an 8-bit version:

variable sa = "Hello, World", aa = Char_Type[strlen(sa)+1];
init_char_array(aa, sa);
array_reverse(aa);
% print(aa);

% Unfortunately, strjoin() only joins strings, so we map char()
% [sadly named: actually converts char into single-length string]
% onto the array:
  
print( strjoin(array_map(String_Type, &char, aa), "") );

Output: "dlroW ,olleH"

For a Unicode version, we'll create a variant of init_char_array(). Side note: If needed, strbytelen() would give total length of string.

define init_unicode_array(a, buf)
{
  variable len = strbytelen(buf), ch, p0 = 0, p1 = 0;
  while (p1 < len) {
    (p1, ch) = strskipchar(buf, p1, 1);
    if (ch < 0) print("oops.");
    a[p0] = ch;
    p0++;
  }
}

variable su = "Σὲ γνωρίζω ἀπὸ τὴν κόψη";
variable au = Int_Type[strlen(su)+1];
init_unicode_array(au, su);
array_reverse(au);
% print(au);
print(strjoin(array_map(String_Type, &char, au), "") );

Output: "ηψόκ νὴτ ὸπἀ ωζίρωνγ ὲΣ"

Note: The init...array() functions include the terminating '\0' chars, but we don't have to filter them out as char(0) produces a zero-length string.

SAS

data _null_;
length a b $11;
a="I am Legend";
b=reverse(a);
put a;
put b;
run;

Sather

class MAIN is
  main is
    s ::= "asdf";
    reversed ::= s.reverse; 
    -- current implementation does not handle multibyte encodings correctly
  end;
end;

Scala

Easy way:

"asdf".reverse

Slightly less easy way:

"asdf".foldRight("")((a,b) => b+a)

Unicode-aware, method 1:

def reverse(s: String) = {
  import java.text.{Normalizer,BreakIterator}
  val norm = Normalizer.normalize(s, Normalizer.Form.NFKC) // waffle -> waffle (optional)
  val it = BreakIterator.getCharacterInstance
  it setText norm
  def break(it: BreakIterator, prev: Int, result: List[String] = Nil): List[String] = it.next match {
    case BreakIterator.DONE => result
    case cur => break(it, cur, norm.substring(prev, cur) :: result)
  }
  break(it, it.first).mkString
}
Output:
scala> reverse("as⃝df̅")
res0: String = f̅ds⃝a

Unicode-aware, method 2: I can't guarantee it get all the cases, but it does work with combining characters as well as supplementary characters. I did not bother to preserve the order of newline characters, and I didn't even consider directionality beyond just ruling it out.

def reverseString(s: String) = {
  import java.lang.Character._
  
  val combiningTypes = List(NON_SPACING_MARK, ENCLOSING_MARK, COMBINING_SPACING_MARK)
  def isCombiningCharacter(c: Char) = combiningTypes contains c.getType
  def isCombiningSurrogate(high: Char, low: Char) = combiningTypes contains getType(toCodePoint(high, low))
  def isCombining(l: List[Char]) = l match {
    case List(a, b) => isCombiningSurrogate(a, b)
    case List(a) => isCombiningCharacter(a)
    case Nil => true
    case _ => throw new IllegalArgumentException("isCombining expects a list of up to two characters")
  }
  
  def cleanSurrogate(l: List[Char]) = l match {
    case List(a, b) if a.isHighSurrogate && b.isLowSurrogate => l
    case List(a, b) if a.isLowSurrogate => Nil
    case List(a, b) => List(a)
    case _ => throw new IllegalArgumentException("cleanSurrogate expects lists of two characters, exactly")
  }
  
  def splitString(string: String) = (string+" ").iterator sliding 2 map (_.toList) map cleanSurrogate toList

  def recurse(fwd: List[List[Char]], rev: List[Char]): String = fwd match {
    case Nil => rev.mkString
    case c :: rest =>
      val (combining, remaining) = rest span isCombining
      recurse(remaining, c ::: combining.foldLeft(List[Char]())(_ ::: _) ::: rev)
  }
  recurse(splitString(s), Nil)
}

REPL on Windows doesn't handle Unicode, so I'll show the bytes instead:

scala> res71 map ("\\u%04x" format _.toInt)
res80: scala.collection.immutable.IndexedSeq[String] = IndexedSeq(\u0061, \u0073, \u20dd, \u0064, \u0066, \u0305)

scala> reverseString(res71) map ("\\u%04x" format _.toInt)
res81: scala.collection.immutable.IndexedSeq[String] = IndexedSeq(\u0066, \u0305, \u0064, \u0073, \u20dd, \u0061)

Scheme

(define (string-reverse s)
  (list->string (reverse (string->list s))))
> (string-reverse "asdf")
"fdsa"

Scratch

Sed

#!/bin/sed -f

/../! b

# Reverse a line.  Begin embedding the line between two newlines
s/^.*$/\
&\
/

# Move first character at the end.  The regexp matches until
# there are zero or one characters between the markers
tx
:x
s/\(\n.\)\(.*\)\(.\n\)/\3\2\1/
tx

# Remove the newline markers
s/\n//g

Seed7

Seed7 strings are encoded with UTF-32 therefore no special Unicode solution is necessary. The following demonstrates one way of reversing a string with a user-defined function.

$ include "seed7_05.s7i";

const func string: reverso(in string: stri) is func
  result
    var string: result is "";
  local
    var integer: index is 0;
  begin
    for index range length(stri) downto 1 do
      result &:= stri[index];
    end for;
  end func;

const proc: main is func
  begin
    writeln(reverso("Was it a cat I saw"));
  end func;

The following demonstrates the use of the built-in 'reverse' function:

$ include "seed7_05.s7i";

const proc: main is func
  begin
    writeln(reverse("Was it a cat I saw?"));
  end func;
Output:
was I tac a ti saW

Self

In-place reversal:

'asdf' copyMutable reverse

SenseTalk

put "asdf" reversed -- reverse on the fly

set imp to "rumpelstiltskin"
reverse imp -- reverse in place
put imp
Output:
fdsa
nikstlitslepmur

SequenceL

Using Library Function:

There is a library function to reverse any Sequence. This works for strings since strings are Sequences of characters.

import <Utilities/Sequence.sl>;

main(args(2)) := Sequence::reverse(args[1]);

The Library Function:

The following is the library implementation of the reverse function.

reverse<T> : T(1) -> T(1);	
reverse(list(1))[i] :=
	let
		range := - ((1 ... size(list)) - (size(list) + 1));
	in
		list[i] foreach i within range;

Sidef

"asdf".reverse;             # fdsa
"résumé niño".reverse;      # oñin émusér

Simula

BEGIN
   TEXT PROCEDURE REV(S); TEXT S;
   BEGIN
       TEXT T;
       INTEGER L,R;
       T :- COPY(S);
       L := 1; R := T.LENGTH;
       WHILE L < R DO
       BEGIN
           CHARACTER CL,CR;
           T.SETPOS(L); CL := T.GETCHAR;
           T.SETPOS(R); CR := T.GETCHAR;
           T.SETPOS(L); T.PUTCHAR(CR);
           T.SETPOS(R); T.PUTCHAR(CL);
           L := L+1;
           R := R-1;
        END;
        REV :- T;
   END REV;

   TEXT INP;
   INP :- "asdf";

   OUTTEXT(INP);      OUTIMAGE;
   OUTTEXT(REV(INP)); OUTIMAGE;
END
Output:
asdf
fdsa

Slate

In-place reversal:

'asdf' reverse

Non-destructive reversal:

'asdf' reversed

Smalltalk

'asdf' reverse
Works with: Smalltalk/X

the above does inplace, destructive reverse. It is usually better to use

'asdf' reversed

which returns a new string.

SNOBOL4

ASCII-only

	output = reverse(reverse("reverse"))
end
Output:
reverse

Standard ML

val str_reverse = implode o rev o explode;
val string = "asdf";
val reversed = str_reverse string;

Stata

Use strreverse if there are only ASCII characters, and ustrreverse if there are Unicode characters in the string.

. scalar s="ARS LONGA VITA BREVIS"
. di strreverse(s)
SIVERB ATIV AGNOL SRA
. scalar s="Ἐν ἀρχῇ ἐποίησεν ὁ θεὸς τὸν οὐρανὸν καὶ τὴν γῆν"
. di ustrreverse(s)
νῆγ νὴτ ὶακ νὸναρὐο νὸτ ςὸεθ ὁ νεσηίοπἐ ῇχρἀ νἘ

Stringle

This inputs a string from the user and outputs its reverse. The \ reverse operator reverses any string.

$ \$

Swift

Swift's strings are iterated by Characters, which represent "Unicode grapheme clusters", so reversing it reverses it with combining characters too:

Works with: Swift version 2.x+
func reverseString(s: String) -> String {
  return String(s.characters.reverse())
}
print(reverseString("asdf"))
print(reverseString("as⃝df̅"))
Works with: Swift version 1.x
func reverseString(s: String) -> String {
  return String(reverse(s))
}
println(reverseString("asdf"))
println(reverseString("as⃝df̅"))
Output:
fdsa
f̅ds⃝a


Symsyn

| reverse string

c : 'abcdefghijklmnopqrstuvwxyz'
d : ' '

 c []
 i
 #c j
 - j
 if i < j
    c.i d 1
    c.j c.i 1
    d c.j
    - j
    + i
    goif
 endif
 c []

OR

c : 'abcdefghijklmnopqrstuvwxyz'

 c []
 $s
 #c j
 if j > 0
    - j
    + c.j $s 1
    goif
 endif
 $s []
Output:
abcdefghijklmnopqrstuvwxyz
zyxwvutsrqponmlkjihgfedcba

Tailspin

templates reverse
  '$:[ $... ] -> $(last..first:-1)...;' !
end reverse
 
'asdf' -> reverse -> !OUT::write
 
'
' -> !OUT::write
 
'as⃝df̅' -> reverse -> !OUT::write
Output:
fdsa
f̅ds⃝a

Tcl

package require Tcl 8.5
string reverse asdf

TI-83 BASIC

Note: length( and sub( can be found in the catalog.

:Str1
:For(I,1,length(Ans)-1
:sub(Ans,2I,1)+Ans
:End
:sub(Ans,1,I→Str1

TMG

Unix TMG:

prog:   parse(str);
str:    smark any(!<<>>) scopy str/done = { 1 2 };
done:   ;

Tosh

when flag clicked
ask "Say something..." and wait
set i to (length of answer)
set inv to ""
repeat until i = 0
	set inv to (join (inv) (letter (i) of answer))
	change i by -1
end
say inv

Transd

#lang transd

MainModule : {
    _start: (lambda (with s "as⃝df̅"
        (textout (reverse s))

        // reversing user input
        (textout "\nPlease, enter a string: ")
        (textout "Input: " (reverse (read s)))
    ))
}
Output:
̅fd⃝sa
Please, enter a string: Hello!
Input: !olleH

Turing

Iterative solution, for character shovelers:

function reverse (s : string) : string
    var rs := ""
    for i : 0 .. length (s) - 1
        rs := rs + s (length (s) - i)
    end for
    result rs
end reverse

put reverse ("iterative example")
put reverse (reverse ("iterative example"))
Output:
elpmaxe evitareti
iterative example 

Recursive solution, more natural in Turing:

function reverse (s : string) : string
    if s = "" then
        result s
    else
        result reverse (s (2 .. *)) + s (1)
    end if
end reverse

put reverse ("recursive example")
put reverse (reverse ("recursive example"))
Output:
elpmaxe evisrucer
recursive example

TUSCRIPT

$$ MODE TUSCRIPT
SET input="was it really a big fat cat i saw"
SET reversetext=TURN (input)
PRINT "before: ",input
PRINT "after:  ",reversetext
Output:
before: was it really a big fat cat i saw
after:  was i tac taf gib a yllaer ti saw   

UNIX Shell

#!/bin/bash
str=abcde

for((i=${#str}-1;i>=0;i--)); do rev="$rev${str:$i:1}"; done

echo $rev

or

str='i43go1342iu 23iu4o 23iu14i324y 2i13'
rev <<< "$str"
#rev is not built-in function, though is in /usr/bin/rev

Unlambda

Reverse the whole input:

``@c`d``s`|k`@c

Ursala

#import std

#cast %s

example = ~&x 'asdf'

verbose_example = reverse 'asdf'
Output:
'fdsa'

Vala

int main (string[] args) {
	if (args.length < 2) {
		stdout.printf ("Please, input a string.\n");
		return 0;
	}
	var str = new StringBuilder ();
	for (var i = 1; i < args.length; i++) {
		str.append (args[i] + " ");
	}
	stdout.printf ("%s\n", str.str.strip ().reverse ());
	return 0;
}

VBA

Non-recursive version

Public Function Reverse(aString as String) as String
' returns the reversed string
dim L as integer        'length of string
dim newString as string

newString = ""
L = len(aString)
for i = L to 1 step -1
 newString = newString & mid$(aString, i, 1)
next
Reverse = newString
End Function

Recursive version

Public Function RReverse(aString As String) As String
'returns the reversed string
'do it recursively: cut the string in two, reverse these fragments and put them back together in reverse order
Dim L As Integer    'length of string
Dim M As Integer    'cut point

L = Len(aString)
If L <= 1 Then   'no need to reverse
  RReverse = aString
Else
  M = Int(L / 2)
  RReverse = RReverse(Right$(aString, L - M)) & RReverse(Left$(aString, M))
End If
End Function

Example dialogue

print Reverse("Public Function Reverse(aString As String) As String")
gnirtS sA )gnirtS sA gnirtSa(esreveR noitcnuF cilbuP

print RReverse("Sunday Monday Tuesday Wednesday Thursday Friday Saturday Love")
evoL yadrutaS yadirF yadsruhT yadsendeW yadseuT yadnoM yadnuS

print RReverse(Reverse("I know what you did last summer"))
I know what you did last summer

VBScript

Works with: Windows Script Host version *
WScript.Echo StrReverse("asdf")

Vedit macro language

This routine reads the text from current line, reverses it and stores the reversed string in text register 10:

Reg_Empty(10)
for (BOL; !At_EOL; Char) {
    Reg_Copy_Block(10, CP, CP+1, INSERT)
}

This routine reverses the current line in-place:

BOL
while (!At_EOL) {
    Block_Copy(EOL_pos-1, EOL_pos, DELETE)
}

Vim Script

Take a buffer with the following content:

  1. Lines 1 and 2, the strings to reverse
  2. Line 3, comment
  3. Lines 4 to 6, the Vim Script function
  4. Lines 7 and 8, calling the Vim Script function twice, in the first instance using line 1's content for the argument and in the second instance line 2's content.
  5. Line 9, comment
asdf
as⃝df̅
""""""""""""""""""""""""
function Reverse(chars)
  call append(line('$'),join(reverse(split(a:chars, '\zs')), ""))
endfunction
call Reverse(getline(1))
call Reverse(getline(2))
""""""""""""""""""""""""

On entering : (Command-line mode), then typing 4,8so (and {Enter}), the function and two call commands will be sourced and executed. Output is appended to the end of the buffer at lines 10 and 11.

Output:
fdsa
f̅ds⃝a

This illustrates reversing the simple ASCII text string as well as the one with Unicode combining characters ― the latter keeping s+combining enclosing circle (U+0073,U+20DD) together and f+macron (U+0066,U+0305) together.

Visual Basic

Works with: Visual Basic version 6
Debug.Print VBA.StrReverse("Visual Basic")

Visual Basic .NET

Compiler: >= Visual Basic 2012

Includes both a simple version and a version that uses .NET's built-in ability to enumerate strings by grapheme to support combining characters.

Since the windows console may not support Unicode, the program can optionally redirect its output to a file.

#Const REDIRECTOUT = True

Module Program
    Const OUTPATH = "out.txt"

    ReadOnly TestCases As String() = {"asdf", "as⃝df̅", "Les Misérables"}

    ' SIMPLE VERSION
    Function Reverse(s As String) As String
        Dim t = s.ToCharArray()
        Array.Reverse(t)
        Return New String(t)
    End Function

    ' EXTRA CREDIT VERSION
    Function ReverseElements(s As String) As String
        ' In .NET, a text element is series of code units that is displayed as one character, and so reversing the text
        ' elements of the string correctly handles combining character sequences and surrogate pairs.
        Dim elements = Globalization.StringInfo.GetTextElementEnumerator(s)
        Return String.Concat(AsEnumerable(elements).OfType(Of String).Reverse())
    End Function

    ' Wraps an IEnumerator, allowing it to be used as an IEnumerable.
    Iterator Function AsEnumerable(enumerator As IEnumerator) As IEnumerable
        Do While enumerator.MoveNext()
            Yield enumerator.Current
        Loop
    End Function

    Sub Main()
        Const INDENT = "    "

#If REDIRECTOUT Then
        Const OUTPATH = "out.txt"
        Using s = IO.File.Open(OUTPATH, IO.FileMode.Create),
              sw As New IO.StreamWriter(s)
            Console.SetOut(sw)
#Else
        Try
            Console.OutputEncoding = Text.Encoding.ASCII
            Console.OutputEncoding = Text.Encoding.UTF8
            Console.OutputEncoding = Text.Encoding.Unicode
        Catch ex As Exception
            Console.WriteLine("Failed to set console encoding to Unicode." & vbLf)
        End Try
#End If
            For Each c In TestCases
                Console.WriteLine(c)
                Console.WriteLine(INDENT & "SIMPLE:   " & Reverse(c))
                Console.WriteLine(INDENT & "ELEMENTS: " & ReverseElements(c))
                Console.WriteLine()
            Next
#If REDIRECTOUT Then
        End Using
#End If
    End Sub
End Module
Output (copied from Notepad):

Output is presented using non-fixed-width typeface to properly display combining characters.

asdf
    SIMPLE:   fdsa
    ELEMENTS: fdsa

as⃝df̅
    SIMPLE:   ̅fd⃝sa
    ELEMENTS: f̅ds⃝a

Les Misérables
    SIMPLE:   selbaŕesiM seL
    ELEMENTS: selbarésiM seL

Wart

(rev "asdf")

Wart doesn't support Unicode yet.

V (Vlang)

const list =
('
Hello world!
你好世界!
Salamu, Dunia!
こんにちは世界!
¡Hola Mundo!
Chào thế giới!
Hallo Welt!
')

fn main() {
    for line in list.split('\n') {if line !='' {println(reverse_string(line))}}
}

fn reverse_string(word string) string {
    return word.runes().reverse().string()
}
Output:
!dlrow olleH
!界世好你
!ainuD ,umalaS
!界世はちにんこ
!odnuM aloH¡
!iớig ếht oàhC
!tleW ollaH

Wren

Library: Wren-str
Library: Wren-upc
import "./str" for Str
import "./upc" for Graphemes

for (word in ["asdf", "josé", "møøse", "was it a car or a cat I saw", "😀🚂🦊"]) {
    System.print(Str.reverse(word))
}

for (word in ["as⃝df̅", "ℵΑΩ 駱駝道 🤔 🇸🇧 🇺🇸 🇬🇧‍ 👨‍👩‍👧‍👦🆗🗺"]) {
    System.print(Graphemes.new(word).toList[-1..0].join())
}
Output:
fdsa
ésoj
esøøm
was I tac a ro rac a ti saw
🦊🚂😀
f̅ds⃝a
🗺🆗👨‍👩‍👧‍👦 🇬🇧‍ 🇺🇸 🇸🇧 🤔 道駝駱 ΩΑℵ

Wortel

; the @rev operator reverses strings and arrays
@rev "abc" ; returns "cba"
; or the same thing using a pointer expression
!~r "abc"

XBS

Using the standard library

log(string.reverse("Hello"))
Output:
olleH

Using JavaScript methods

log("Hello"->split("")->reverse()->join(""));
Output:
olleH

Using a custom method

func ReverseString(String){
	set Final = "";
	for(i=?String-1;0;-1){
		Final+=String[i];
	}
	send Final;
}
log(ReverseString("Hello"));
Output:
elloH

XPL0

include c:\cxpl\codes;  \intrinsic 'code' declarations
string 0;               \use zero-terminated strings, instead of MSb terminated

func StrLen(Str);       \Return the number of characters in an ASCIIZ string
char Str;
int  I;
for I:= 0 to -1>>1-1 do
        if Str(I) = 0 then return I;

func RevStr(S);         \Reverse the order of the bytes in a string
char S;
int  L, I, T;
[L:= StrLen(S);
for I:= 0 to L/2-1 do
        [T:= S(I);  S(I):= S(L-I-1);  S(L-I-1):= T];
return S;
];

[Text(0, RevStr("a")); CrLf(0);
 Text(0, RevStr("ab")); CrLf(0);
 Text(0, RevStr("abc")); CrLf(0);
 Text(0, RevStr("Able was I ere I saw Elba.")); CrLf(0);
]

Output:

a
ba
cba
.ablE was I ere I saw elbA

Yorick

This only handles ASCII characters. It works by converting a string to an array of char; dropping the last character (which is the null byte); reversing the order of the characters; then converting back to a string.

strchar(strchar("asdf")(:-1)(::-1))

Z80 Assembly

This method uses the stack as a temporary store to reverse the order of characters in a string, and self-modifying code to restore the loop counter.

PrintChar equ $BB5A ;Amstrad CPC bios call
Terminator equ 0    ;null terminator for strings


org $8000
ld hl, StringA
call ReverseString

ld hl, StringA
call PrintString

ret                  ;return to basic

StringA:
byte "12345678",0

;;;; SUBROUTINES
GetStringLength:
;HL = STRING. RETURNS LENGTH IN B. LENGTH IS ONE-INDEXED AND DOES NOT INCLUDE TERMINATOR.
		ld b,0                    ;clear B
loop_getStringLength:
		ld a,(hl)                 ;read the next char
		cp Terminator             ;is it the terminator?      
		ret z                     ;if so, exit
		inc hl                    ;point HL to next character
		inc b                     ;increase tally
		jr loop_getStringLength   ;repeat

ReverseString:
	;reverse the order of letters in a text string.
	;e.g. "ABCD" -> "DCBA"
	;the terminator stays put.
	;INPUT: HL = SOURCE ADDRESS OF STRING
	push de
		push hl
			push hl
		             call GetStringLength
			pop hl
		pop de		            ;LD DE,HL
		LD a,b                      ;LOAD B INTO A
		LD (SMC_ReverseString+1),a  ;STORE IT LATER IN THE CODE SO WE CAN RETRIEVE IT.
		
; TO RECAP, BOTH HL AND DE POINT TO THE BEGINNING OF THE STRING WE WANT TO REVERSE. B EQUALS THE LENGTH OF THE STRING. 
; B HAS BEEN BACKED UP WITHOUT USING THE STACK BY STORING IT AS THE OPERAND OF A LATER INSTRUCTION THAT LOADS B WITH A NUMERIC VALUE.
; PUSH BC WOULD NOT HAVE WORKED SINCE THE PROGRAM NEEDS TO PUSH EACH LETTER OF THE STRING DURING THE LOOP.

LOOP_REVERSESTRING_PUSH:
;start at the beginning of the string and push each letter in it, except the terminator.
		ld a,(de)
		push af   
		inc de
		djnz LOOP_REVERSESTRING_PUSH
		
SMC_ReverseString:
		ld b,$42	;LETS US PRESERVE B WITHOUT PUSHING IT. THE $42 IS OVERWRITTEN WITH THE STRING'S LENGTH.
		
LOOP_REVERSESTRING_POP:
;Starting at the beginning of the string, pop A off the stack and store it into the string. This puts the letters back in the reverse
;   order.
		pop af
		ld (hl),a
		inc hl
		djnz LOOP_REVERSESTRING_POP
	pop de
	ret
Output:
87654321

zkl

These only handle ASCII characters, no extra credit.

"this is a test".reverse()

Old school ways to do it:

Build by prepending characters, creates n strings:

"this is a test".reduce(fcn(p,c){c+p})

Convert to list, reverse, convert back to string:

"this is a test".split("").reverse().concat()

Write to a byte buffer and convert to string:

"this is a test".pump(Void,Data().insert.fp(0)).text

The ".fp(0)" creates a closure so each character is fed to data.insert(0,c). pump is a method that sends each character to a function to a sink (in this case /dev/null). The output is the result of the last call, which is data.insert which is self/data. https://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28string_functions%29#reverseProperty "Wikipedia" (as page type) with input value "https://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28string_functions%29#reverse" contains invalid characters or is incomplete and therefore can cause unexpected results during a query or annotation process.

Zoea

program: reverse_string
  input: xyzzy
  output: yzzyx

Zoea Visual

Reverse string

Zig

We can use `.*` to dereference a literal string pointer to an array, and use `std.mem.reverse` to reverse the slice of that array in-place:

var s = "socat".*;
std.mem.reverse(u8, &s);

or:

var s = "socat".*;
std.mem.reverse(u8, s[0..]);

String `s` now becomes `"tacos"`. Tested on version 0.9.0. Reference: [1].