The real Bourne shell problem
The Bourne shell's real problem for writing shell scripts is that it doesn't have a real data structure for lists. This leads to putting lists in strings, which leads to reparsing strings, which leads to hideous doom and all of those problems with filenames that have whitespace in them.
(When lists are represented as strings, every string might be a list, so every time the Bourne shell expands a variable it must try to turn it into a list unless the expansion is specifically marked as not doing that.)
This matters twice over. First, because lists of things come up all the time in shell scripts (lists of arguments, lists of files, etc). Second, because of the reparsing, everything that is not carefully guarded may be reinterpreted as a list and explode.
(The other consequence is that people create all sorts of conventions
for how to represent lists of things, like the colon-separated
and imitators. In a sane shell you would be able to write '
in $PATH'; in the Bourne shell, you can't.)
The issue of exporting real lists into the environment need not have blocked implementing them. Bourne could have defined a canonical exported form, or just forbidden exporting real lists into the environment. Even unexportable real lists would make Bourne shell scripting much less irritatingly explosive.
(This insight is not original to me; I got it from Tom Duff's paper on rc, the Plan 9 shell, where he lays out a lucid explanation of the Bourne shell's flaws.)
Sidebar: a nitpick
Technically, the Bourne shell has one real list: the list of arguments.
Sufficiently determined shell scripts (that have saved everything
important from their arguments) can reuse this reliable storage via
set --', and some do.