InnerAlien

InnerAlien

Hardware|Software

29 Jan 2026

Reverse a List

№5 · 99 Picat Problems
myReverse(L) = myReverse(L, []).
myReverse([], R) = R.
myReverse([X|Xs], R) = myReverse(Xs, [X|R]).

Explanation

This function reverses a list using the accumulator pattern from Problem 4. Instead of counting elements, the accumulator builds the reversed list.

Wrapper function (line 1):

myReverse(L) = myReverse(L, []).
  • Takes a single argument (the list) and calls a two-argument version with an empty list [] as the initial accumulator
  • The accumulator will collect elements in reverse order

Base case (line 2):

myReverse([], R) = R.
  • Pattern matches when the input list is empty []
  • Returns the accumulator R, which now contains all elements in reverse order

Recursive case (line 3):

myReverse([X|Xs], R) = myReverse(Xs, [X|R]).
  • Destructures the input list into head X and tail Xs
  • Recurses on the tail, but prepends X to the accumulator with [X|R]
  • Each element is moved from the front of the input to the front of the accumulator, reversing the order

Note that Picat has a built-in reverse/1 function, so in practice you'd write reverse(L). The point here is to understand how the accumulator can build a result rather than just count.

Complete Example

Here's the full runnable code:

main =>
  go_05.

go_05 =>
  A = [1,2,3,4,5],
  B = myReverse(A),
  println(B).

myReverse(L) = myReverse(L, []).
myReverse([], R) = R.
myReverse([X|Xs], R) = myReverse(Xs, [X|R]).

How it works:

  • myReverse(A) calls the wrapper, which starts with an empty accumulator []
  • Each recursive call moves one element from the input list to the front of the accumulator
  • println(B) outputs [5,4,3,2,1]

Example Execution

With A = [1,2,3,4,5]:

myReverse([1,2,3,4,5])
→ myReverse([1,2,3,4,5], [])        (wrapper adds empty accumulator)
→ myReverse([2,3,4,5], [1])         (move 1 to accumulator)
→ myReverse([3,4,5], [2,1])         (move 2 to front of accumulator)
→ myReverse([4,5], [3,2,1])         (move 3 to front of accumulator)
→ myReverse([5], [4,3,2,1])         (move 4 to front of accumulator)
→ myReverse([], [5,4,3,2,1])        (move 5 to front of accumulator)
→ [5,4,3,2,1]                       (base case: input empty, return accumulator)

The reversal happens naturally: each element goes to the front of the accumulator, so the first element processed (1) ends up at the back, and the last element processed (5) ends up at the front.

Takeaways

  1. Accumulator as a builder: In Problem 4, the accumulator was a number that we incremented. Here it's a list that we build. Accumulators can carry any type of intermediate state.
  2. Prepending reverses order: By prepending each element to the accumulator with [X|R], we naturally reverse the list. This is O(1) per element since prepending to a list is constant time.
  3. Linear time reversal: This algorithm processes each element exactly once, making it O(n) where n is the length of the list.