soma.cell

Reverse word order — "hello world" -> "world hello"

Splits on spaces, reverses the resulting list, and re-joins. Also offers a per-word character reversal that keeps word positions. Demonstrates the difference between reversing the word list vs. reversing each word. Run: soma run reverse_words.cell --signal reverse_order "the quick brown fox"

A Soma program from the text part of the verified corpus: 46 lines, cells ReverseWords, ReverseWordsTest. It passes soma check with soma 3.2.4.

How it is built

The cell ReverseWords declares 2 signals in its face: reverse_order(text: String) -> String and reverse_each(text: String) -> String. Handlers: reverse_order (line 17) and reverse_each (line 30). Private helpers: _flip.

The file also holds 1 test cell (ReverseWordsTest) with 5 assertions, run by soma test.

Generated from soma describe on this file.

The source

reverse_words.cell

// ============================================================================
// Reverse word order — "hello world" -> "world hello"
// ============================================================================
//
// Splits on spaces, reverses the resulting list, and re-joins. Also offers a
// per-word character reversal that keeps word positions. Demonstrates the
// difference between reversing the word list vs. reversing each word.
//
// Run: soma run reverse_words.cell --signal reverse_order "the quick brown fox"

cell ReverseWords {
    face {
        signal reverse_order(text: String) -> String
        signal reverse_each(text: String) -> String
    }

    on reverse_order(text: String) {
        let words = split(text, " ")
        return join(words.reverse(), " ")
    }

    on _flip(w: String) {
        let out = ""
        for i in range(len(w) - 1, -1, -1) {
            out = out + w[i]
        }
        return out
    }

    on reverse_each(text: String) {
        let words = split(text, " ")
        let flipped = words |> map(w => _flip(w))
        return join(flipped, " ")
    }
}

cell test ReverseWordsTest {
    rules {
        assert reverse_order("hello world") == "world hello"
        assert reverse_order("a b c d") == "d c b a"
        assert reverse_each("hello world") == "olleh dlrow"
        assert reverse_each("abc") == "cba"
        assert reverse_order("single") == "single"
    }
}

What the toolchain says

Run on a fresh copy of the program at build time; the outputs are pasted unedited.

$ soma check reverse_words.cell
warning: `out` grows by concatenation inside a loop — each step copies the whole value, so the loop is quadratic (8 MB took 32 s, a list + join() 30 ms): push the pieces to a List and `join(parts, "")` once
  --> reverse_words.cell:25:13
   |
25 |             out = out + w[i]
   |             ^
✓ 1 warning(s), no errors.
$ soma test reverse_words.cell
test ReverseWordsTest ...
  ✓ assert reverse_order("hello world") == "world hello"
  ✓ assert reverse_order("a b c d") == "d c b a"
  ✓ assert reverse_each("hello world") == "olleh dlrow"
  ✓ assert reverse_each("abc") == "cba"
  ✓ assert reverse_order("single") == "single"

5 tests: 5 passed, 0 failed
$ soma verify reverse_words.cell
Verifying reverse_words.cell...
No state machine in this program: nothing to prove beyond `soma check` (invariants and lifecycles are what verify proves).
VERIFY OK (vacuous — no state machine)

Builtins used

join, len, map, range, split

Source file: /corpus/text/reverse_words.cell · examples/corpus/text/reverse_words.cell