(Note: since Racket supports exact bignums, in a sense numbers are not atomic either! Only Booleans ;-)
Linked lists are not a fixed lenth. To add an element to a linked list, you allocate a new cons, point its car to the new element, and point its cdr to the old list. There is no "and then allocate a new, larger fixed-length list, copy everything over, and delete the old one" step.
That's all language-agnostic, but in Scheme specifically, the interface it provides for strings does not simulate arbitrary length, either. The only way to add onto strings is using string-append, which returns a newly allocated string.
Strings are mutable in standard Scheme (unlike, say, Java):
#;1> (let ((string (string-copy "foo")))
(string-set! string 0 #\b)
string)
"boo"
They're still a fixed length (as they are in virtually every language) because the only way to add onto them is to allocate a new string and copy everything over (this might be hidden behind a method, and you can avoid actually doing this every time by initially allocating more space than you need and using a fill pointer, but they're still fundamentally a fixed length). For example, the 4th edition of the Scheme Programming Language[0] gives this example definition of string-append: (define string-append
(lambda args
(let f ([ls args] [n 0])
(if (null? ls)
(make-string n)
(let* ([s1 (car ls)]
[m (string-length s1)]
[s2 (f (cdr ls) (+ n m))])
(do ([i 0 (+ i 1)] [j n (+ j 1)])
((= i m) s2)
(string-set! s2 j (string-ref s1 i))))))))
Even in a language that helpfully assigned the result of this function to the first argument under the covers, this is more or less what you fundamentally have to do, as long as strings are represented by arrays (in Haskell, strings are linked lists, so this doesn't apply).