Not gonna lie, this is a weird way to reverse the order of the array. It's basically using recursion to slice the first element of the array and conjoin the elements with first element at the end.
So here's a walk though:
mystery(['h','e','l','l','o']) ->
first check if array is empty then method rest is called ->
rest(['h','e','l','l','o']) ->
rest slices the array at index 1 returning a new array of ['e','l','l','o'] ->
then mystery is called which repeats the previous steps with the return value of rest ->
mystery(['e','l','l','o']) ->
this means the mystery will be keep getting called on until rest returns an empty array ->
mystery(['e','l','l','o']) ->
mystery(['l','l','o']) ->
mystery(['l','o']) ->
mystery(['o']) ->
mystery([]) ->
when mystery has an empty array it returns the empty array and then first is called ->
first returns just the first element of the array and happens after mystery is returned it would look something like this before mystery is returned ->
mystery(['e','l','l','o']) , first(['h','e','l','l','o']) ->
so at the lowest level when mystery returns an empty array and first return the first element in ['o'] it would look like this ->
[] , ['o'] ->
conj would be called with these values ->
conj([] , ['o']) ->
conj returns the combination of the two values ->
conj([] , ['o']) ->
['o'] ->
this is then returned and repeated ->
conj([] , ['o']) ->
conj(['o'] , ['l']) ->
conj(['o','l'] , ['l']) ->
conj(['o', 'l','l'] , ['e']) ->
conj(['o', 'l','l', 'e'] , ['h']) ->
['o', 'l','l', 'e','h']