string concatenation is expensive, use lists of chars