In determining the "goodness" of a programming language, you must find a good balance of what you're looking for — things like readability, writability, reliability, etc.
Syntax issues arise, such as, "How am I going to represent a collection or list — commas, spaces, square brackets, curly braces?"
A lot of things will affect the cost of a language. If you know some Java, it's probably going to be easier to learn C than if you had come from Fortran (you're familiar with int, float, curly braces, etc). You spend less time becoming productive and more time being productive. Because many of our current languages are modeled after existing languages, so the history of programming languages is important.
The movement from machine language to any kind of symbolic (e.g. assembly) language was a big step forward. That jump added readability and writability because it was hard to read and write machine language. The assembly languages did not, however, move toward thinking link a human. You had to think like the architecture (Von Neumann).
Fortran proved that a high level language could be devised that could adjust to the programmer and be useful. There were a lot of constraints on the languages, and their developers didn't make the best choices with array dimensions, statements to include in the langauge, words to represent things, symbols that could be used in more than one way, etc.
One way to improve a language is to find out what the language does to allow programmers to make common errors. New languages can make errors easy to catch and correct or just disallow the error altogether.
Pointers were seen as a step backwards, but they had the ability to deal with dynamic data structures. Pointers made things less readable and more writable. We understand that pointers are error-prone, so languages like Java create dynamic data structures and have all the error-prone pointer functions running in the background.
Support was added to Turbo Pascal that enabled us to deal with objects and instances of objects. We had a sorted dynamic list notion; initial lists were declared to have an initial size and a grow factor. It grows and cleans up after itself and returns to the function when the list needs to grow. Some of the burdens on C programmers have been lifted in languages like Java and Turbo Pascal.