Strings

Strings are immutable sequences of grapheme clusters. All string operations use the string/ prefix. @"..." creates a mutable string.

Access and length

(length "hello")                   # => 5 (grapheme count)
(string/size-of "hello")           # => 5 (byte count)
(get "hello" 0)                    # => "h" (grapheme cluster)
(get "hello" -1)                   # => "o" (negative indexes)
(slice "hello" 1 4)                # => "ell"

Grapheme count and byte count differ for multi-byte characters:

(length "👋🏽")                      # => 1 (one grapheme cluster)
(string/size-of "👋🏽")              # => 8 (4+4 bytes UTF-8)

Concatenation

# string converts all args to strings and concatenates
(string "hello " "world")          # => "hello world"
(string "count: " 42)              # => "count: 42"

# join a collection with a separator
(string/join ["a" "b" "c"] ",")    # => "a,b,c"

# format with placeholders
(string/format "{} + {} = {}" 1 2 3)  # => "1 + 2 = 3"

Search and test

(string/find "hello" "ll")        # => 2 (grapheme index, or nil if not found)
(string/find "hello" "xx")        # => nil
(string/find "hello" "lo" 3)      # => 3 (with optional start offset)
(string/index-of "hello" "ll")    # => 2 (alias for string/find)
(string/contains? "hello" "ell")   # => true
(string/starts-with? "hello" "he") # => true
(string/ends-with? "hello" "lo")   # => true

string/find returns the grapheme index of the first occurrence, or nil if the substring is not found. An optional third argument sets the start offset. string/index-of is an alias.

Transformation

(string/upcase "hello")            # => "HELLO"
(string/downcase "HELLO")          # => "hello"
(string/trim "  hi  ")             # => "hi"
(string/replace "foo-bar" "-" "_") # => "foo_bar"
(string/repeat "-" 20)             # => "--------------------"

Splitting

(string/split "a,b,c" ",")        # => ["a" "b" "c"] (returns array)
(string/split "one two three" " ") # => ["one" "two" "three"]
(string/split "a,,b" ",")         # => ["a" "" "b"] (empty strings between consecutive delimiters)

string/split returns an array of substrings. Consecutive delimiters produce empty strings in the result. The delimiter cannot be empty.

Mutable @strings

@"..." creates a mutable string. get, put, length, push, and pop are all grapheme-indexed. put mutates in place and returns the @string.

(def s @"hello")
(get s 0)                          # => "h"
(put s 0 "H")                     # mutates and returns s; s is now @"Hello"
(push s "!")                       # mutates and returns s; s is now @"Hello!"
(pop s)                            # => "!" (removes and returns last)

Conversion

(thaw "hello")                     # => @"hello"
(freeze @"hello")                  # => "hello"
(string 42)                        # => "42"
(string :foo)                      # => "foo" (no colon)

See also