I owned the book "Algorithms + Data Structures = Programs" and I learned a lot out of it. And while I wrote quite a few programs in Pascal, I found myself always confined too much: I fled to C.
"
- Since the size of an array is part of its type, it is not possible to write general-purpose routines, that is, to deal with arrays of different sizes. In particular, string handling is very difficult.
- The lack of static variables, initialization and a way to communicate non-hierarchically combine to destroy the ``locality'' of a program - variables require much more scope than they ought to.
- The one-pass nature of the language forces procedures and functions to be presented in an unnatural order; the enforced separation of various declarations scatters program components that logically belong together.
- The lack of separate compilation impedes the development of large programs and makes the use of libraries impossible.
- The order of logical expression evaluation cannot be controlled, which leads to convoluted code and extraneous variables.
- The 'case' statement is emasculated because there is no default clause.
- The standard I/O is defective. There is no sensible provision for dealing with files or program arguments as part of the standard language, and no extension mechanism.
- The language lacks most of the tools needed for assembling large programs, most notably file inclusion.
- There is no escape.
"
Many of these were fixed in Borland's Object Pascal, by the way. Written by Anders Heijlsberg, who also designed C#.
Pretty much all of these were "fixed" in Modula 2 and Oberon/Oberon 2/Oberon-07 too, which Wirth designed.
Modula-2 was known from at least 1978, and pretty all commercial Pascal implementations added features that solved all or most of the issues in Kernighans article, so frankly it was a bit of a strawman. Indeed, plain, original Pascal was unsuitable for large scale non-teaching use, but very few people even had access to a Pascal implementation that implemented "just" the original Pascal.
A very few of the issues he raises are intrinsic to Wirth's philosophy of compilers, though. Such as one-pass compilation, which massively simplifies his compilers and speeds up compilation. This is a feature of Wirth languages, which one may certainly disagree with. While I prefer more flexibility, I never felt all that restricted by it, given forward declarations support in every implementation I've seen.
There are some critiques on Pascal: http://www.lysator.liu.se/c/bwk-on-pascal.html , 'Why Pascal is Not My Favorite Programming Language'. A summary from the article:
" - Since the size of an array is part of its type, it is not possible to write general-purpose routines, that is, to deal with arrays of different sizes. In particular, string handling is very difficult.
- The lack of static variables, initialization and a way to communicate non-hierarchically combine to destroy the ``locality'' of a program - variables require much more scope than they ought to.
- The one-pass nature of the language forces procedures and functions to be presented in an unnatural order; the enforced separation of various declarations scatters program components that logically belong together.
- The lack of separate compilation impedes the development of large programs and makes the use of libraries impossible.
- The order of logical expression evaluation cannot be controlled, which leads to convoluted code and extraneous variables.
- The 'case' statement is emasculated because there is no default clause.
- The standard I/O is defective. There is no sensible provision for dealing with files or program arguments as part of the standard language, and no extension mechanism.
- The language lacks most of the tools needed for assembling large programs, most notably file inclusion.
- There is no escape. "
Many of these were fixed in Borland's Object Pascal, by the way. Written by Anders Heijlsberg, who also designed C#.