Top
Best
New

Posted by susam 4/13/2025

Why Pascal is not my favorite programming language (1981) [pdf](doc.cat-v.org)
71 points | 87 commentspage 2
Viliam1234 4/13/2025|
> Pascal, in common with most other Algol-inspired languages, uses the semicolon as a statement separator rather than a terminator (as it is in PL/I and C). As a result one must have a reasonably sophisticated notion of what a statement is to put semicolons in properly.

I wonder how the non-programmers succeed to write commas correctly, because those follow the same logic: e.g. "red, green, blue". In author's opinion, I guess it should be "red, green, blue," instead.

pdw 4/13/2025||
Have you ever used a Pascal compiler that's strict about this? It's surprisingly annoying even today. Now imagine it's 1981 and you're editing your programs with a line editor. In C code, you can freely swap lines around. If you try the same in Pascal code, you'll spend a lot of time fixing up semicolons.
CRConrad 4/16/2025||
> I wonder how the non-programmers succeed to write commas correctly

Usually they don't.

layer8 4/13/2025||
> There is no null string, perhaps because Pascal uses the doubled quote notation to indicate a quote embedded in a string:

    'This is a '' character'
That doesn’t seem like a good explanation. There’s nothing preventing a tokenizer from interpreting two quotes not followed by a third quote as an empty string literal. In fact, that’s what current Pascal compilers accept (e.g. `writeln('')`).

However, an empty string and nil are also the same in Pascal, there is no distinction between an empty string and the absence of a string. This is because in early computing, strings weren’t separate objects that you pointed to (and hence could be a null pointer), but more like (usually fixed-size) arrays allocated as part of a larger contiguous memory structure. The array could be empty (based on some length variable), but it couldn’t not be there as part of the fixed memory layout.

Actually, in certain systems strings couldn’t even be empty, in the sense that there was no stored size in addition to the fixed-length array. Instead you padded the rest of the array with spaces. The CHAR type in SQL (as opposed to VARCHAR) is a remnant of that practice.

int_19h 4/13/2025|
Empty string and nil are not at all the same in Pascal. Pascal, even in its most basic version, still had pointers, and nil was the null pointer. You could have pointers to strings (and other kinds of arrays), as well.

What made standard Pascal problematic wrt string handling is that it did not have array NEW nor pointer arithmetic. So if you wanted to heap-allocate ARRAY[1..100] OF CHAR, that was fine; but there was no way to get a pointer to N bytes on the heap where N is determined at runtime; and even if you could do that, somehow, you still wouldn't be able to use that pointer as an array by indexing through it.

Interestingly enough standard Pascal did support allocating variable-length data structures, but only in form of variant records (roughly analogous to discriminated unions in ML or enums in Rust, but with multi-level nesting and the ability to define a common sequence of fields shared by all variants at any level).

layer8 4/13/2025||
You are right regarding nil, I was mixing this up with Turbo Pascal/Delphi strings.
kazinator 4/13/2025||
Pascal taught a generation of coders that you test for end-of-file before trying to read any data from the stream.

When they hit C, they wrote code around fgets that processes the last line twice:

  while (!feof(instream)) {
    fgets(linebuf, sizeof linebuf, instream);
    process_line(linebuf);
  }
Or processes the EOF value from getc as a character:

  while (!feof(instream)) {
    char ch = getc(instream);
    switch (ch) ...
  }
hulium 4/13/2025||
I think almost all of those criticisms are solved in newer versions of Pascal.
pjmlp 4/13/2025|
Even in Modula-2, 1978, exactly because Niklaus Wirth was the very first to acknowledge the limitations of the original Pascal, designed as a programming language for teaching purposes.

Yes, most Pascal dialects, namely UCSD Pascal and Object Pascal also got around fixing them, as did ISO Extended Pascal, the follow up revision that was largely ignored, because by then it was all about Object Pascal.

whartung 4/13/2025||
Folks should also appreciate that BK was also working on the “Software Tools in Pascal” book.

This was an update to the earlier “Software Tools” book, which was written using RATFOR.

If you read the book, it has a very “C in Pascal” coding style, and you can see how uncomfortable it is by doing so.

HexDecOctBin 4/13/2025||
Why is it that Pascal is supposedly so good for Rapid Application Development? Is it simply a historical accident, or does Pascal have some features that make it easier? What features would need to be added to C to make C a viable language for RAD?
pkphilip 4/13/2025||
There are many unique features of Object Pascal as used in Delphi which makes it very easy to write components in:

* Components have a support for customizable UI interfaces for setting the property of components called property sheets and these property sheets are applicable on a component level or at the level of individual property fields in the component. These property sheets show up when you are trying configure a component in the design mode within the IDE. We are not talking about simple text entry type of fields - you can actually do very sophisticated property sheets with tabs, multiple forms etc and what not. It is EXTREMELY configurable and also relatively easy to develop.

* Delphi uses a binary "form" file into which each GUI form persists its interface. So everytime you place a component on a form in the GUI IDE or set its properties, the form and its components have a way of persisting their values into this "form" file. The reverse also happens - so when a form is loaded into the IDE or during runtime, the form fields are read off the "form" file by the form and its components. So the actual .pas file where you are adding code for the events etc is not filled up with a lot of UI related property setting code and so the code looks really clean with clear separation of design and code.

* Components can be installed into the IDE during development very easily

badsectoracula 4/13/2025|||
One important aspect (since the topic is the language) is there is nothing special about components in Delphi and Lazarus - they are just built on the language's RTTI features.

In Free Pascal (and Delphi) all classes have a "metaclass" (a class that describes the class) and can be used in conjunction with the RTTI to obtain information about an object at runtime - including its actual class, exposed properties and any optional metadata (like attributes in FP).

This functionality is used by Delphi/Lazarus to serialize and deserialize objects on disk (the form files you mention are such serialized objects but you can serialize other types of objects and in Lazarus -perhaps Delphi too- you can use several file formats) as well as implement the object inspector.

In a way Delphi/Lazarus work kinda like how game engines like Unreal work in that you are working with "live" instances of objects, using generic object inspectors and saving them on disk is done by serializing them (though obviously it is the opposite since Delphi predates most game engines using this approach :-P).

The important aspect with all the above isn't so much the form/component serialization but the language features that make it possible in the first place: metaclasses and RTTI that provides enough information to instantiate and describe objects and classes at runtime.

My own game engine[0] is written in Free Pascal and Lazarus and uses the exact same language features to provide object serialization, property editing and some other stuff (like object diffing that is used for many undo/redo operations). Instead of TComponent/TPersistent (the types Delphi/FCL provide for serialization), it has its own base types that use a more compact file format, optional compressed streams (e.g. for texture data) and external references (for shared assets stored in separate files), but still relies on the same base functionality provided by the language/compiler.

[0] https://i.imgur.com/fypn318.jpg

pkphilip 4/14/2025||
Cool! what is the name of your game engine? For some reason the imgur links are banned here in India and so not able to see it.
badsectoracula 4/24/2025|||
Sorry, i just saw the message. The name is Little Immersive Engine though i do not have it available anywhere publicly. If you can watch YouTube you can see it in action here[0].

FWIW a retro engine[1] i made for an MSDOS game jam a few years ago uses the same functionality, though it relies more on the existing functionality for the editor side instead of Little Immersive Engine which uses its own property editing controls and "root" object for serialization. Actually Little Immersive Engine is based on the retro engine's code (with a bunch of enhancements of course) but the serialization code is very similar (though without the ability to have external assets)[2].

[0] https://www.youtube.com/watch?v=cQEDAtmGRII

[1] https://codeberg.org/badsector/PetraEngine

[2] https://codeberg.org/badsector/PetraEngine/src/commit/14ca16...

HexDecOctBin 4/14/2025|||
What ISP are you using? I am able to open the link on Airtel broadband and both Airtel and Jio cellular.
CRConrad 4/16/2025|||
> Delphi uses a binary "form" file into which each GUI form persists its interface.

That's not necessarily binary. I don't recall if perhaps it was in Delphi 1 (the 16-bit version for Windows 3.x and Windows 95), but from Delphi 2 or 3 or so (released around the turn of the century), it could also save form definitions as plain text. oh, and of course since the height of the XML craze (shortly after the turn of the century?), in that format too.

bitwize 4/13/2025|||
Delphi and Lazarus have heritages that date back to, or are inspired by, Turbo Pascal and Object Pascal, both of which extended the language in useful ways to make it suitable for real-world use.

When we say "Pascal" today we speak of a much more ergonomic language than the Pascal of 1981.

AdrianB1 4/13/2025|||
At the time it appeared, it was more powerful than BASIC or COBOL. We learned Pascal in college and even the technically less inclined colleagues were able to do the assignments pretty well. We used Turbo Pascal, which had a decent IDE, my brother also continued to use Delphi for another ~ 10 years and loved it for being so easy to do some quick and dirty things when needed. Honestly I don't remember almost any details after 30 years, other than it was simple to use and quick to learn and write something in it, while a lot more friendly than C or C++.
api 4/13/2025||
A huge amount of BBS software from the classic pre-Internet BBS era was written in Borland Turbo Pascal.
AdrianB1 4/13/2025||
I ran a BBS for a few years in 1992-1994, at some point running under OS/2, but honestly I never bothered to find out the programming language used for it, there was no source code attached and all the software at that time was pirated.
int_19h 4/13/2025|||
It has little to do with the language itself, moreso with the tools.

One thing that very clearly distinguished (extended dialects of) Pascal from C in the era where the two were competing was that Pascal's units were self-describing. That is, when you compiled a unit, you got a single file with all the metadata for that unit as well as binary object code for linking. Then, when another unit or program did a USES declaration, that would locate the file by name and use the metadata as needed. Conversely, in C you had to deal with header files, and while on the surface it looks kinda sorta like the INTERFACE section of the Pascal unit, it's not quite that because e.g. it needs to #include things it depends on - and that is textual inclusion, not just a metadata reference.

This all meant that working with dynamically loaded type information was much easier in Pascal tooling - it just needed to parse the metadata embedded in the compiled unit files, and each file would only contain metadata for its own types and functions, without contamination from other units that it relies on. This is great for things like code completion and visual UI designers.

codr7 4/13/2025|||
Object Pascal as defined by Borland/Inprise/Embarcadero's Delphi has plenty of features that make it easier to build components. C++ Builder offers a similar experience. Straight C would certainly be possible, GTK is a step in that direction, but likely more awkward to use.
robocat 4/14/2025||
I would add that Delphi also had a culture of component libraries and sharing code.

There were free intro libraries (no code), shareware component libraries, and usually a developer version available that came with source code. Plus a culture of open source libraries.

This community was a key strength of Delphi compared to some other choices. I suspect if Borland had really leaned into a combination of open source, plus better support for commercial proprietary solutions, that would have kept the ecosystem alive.

Also of note is that Delphi came with some source code for library components (often useful when understanding usage or debugging or extending).

graemep 4/13/2025|||
I cannot see any reason why the RAD for Pascal (i.e. Delphi, and now Lazarus) could not exist for other languages. They just happen not to.

Imagine this - if those had not exists, would anyone say Pascal was a good RAD language.

I suppose what I might be missing is why Pascal was chosen as the language for Delphi.

dardeaup 4/13/2025||
One aspect of Pascal that helps is compilation speed. Pascal's nature allows for single-pass compilers. It may not sound like a big deal, but it's a huge cumulative effect.
EVa5I7bHFq9mnYK 4/13/2025|||
That definitely was a big deal in the 80s when I used it. You could compile a program in seconds, all in memory, while a C program needed 5 passes, each pass writing and reading from quite slow hard disks of the time.
WalterBright 4/13/2025||
My C and C++ compilers (Datalight, Zortech) only required 2 passes:

1. preprocessor/parser/semantic all at once

2. optimizer (optional)

3. code generator

Later on in the 80s these were merged into one executable.

EVa5I7bHFq9mnYK 4/14/2025||
CPP

C0

C1

C2

AS

LD

And an optional AR

WalterBright 4/14/2025||
I know what the conceptual passes are, but ZTC merged them, including the multiple conceptual passes the CPP does.
EVa5I7bHFq9mnYK 4/14/2025||
Those were not conceptual passes, but actual standalone programs executed in that order, to compile a C program. Each program operated within 64KB RAM, shared with the OS and all the drivers.
WalterBright 4/14/2025||
And Zortech C, for 64K machines, had two standalone programs to compile a C program to an object file.
EVa5I7bHFq9mnYK 4/14/2025||
Cudos to Zortech C
graemep 4/13/2025|||
That is a good point. Repeatedly waiting for compile of build steps is a productivity killer and I think especially relevant for RAD.

I played with Lazarus recently and the whole process of creating a simple GUI was so painless.

pjmlp 4/13/2025||
Easy, see C++ Builder.

Thing is, people complain about Borland/Embarcadero extensions, but love their GCC and clang ones.

JPLeRouzic 4/13/2025||
In the 1980s, CNET (one of France Telecom R&D labs) wrote a UNIX clone in Pascal.
musicale 4/13/2025||
Kernighan probably disliked PL/I as well, but it had better memory safety than C; Multics was never plagued with buffer overflows.

Pascal implementations typically support index and range checking, while Ada provides even more extensive memory and concurrency safety.

Fortunately for C, clang's -fbounds-safety seems to be making progress. It's implemented in Apple's LLVM fork, so this now works on macOS:

    clang -Xclang -fbounds-safety program.c
https://clang.llvm.org/docs/BoundsSafety.html
swatson741 4/13/2025||
To put it in a single statement: Pascal is only suitable to study computer science. This is why he doesn't like the language.
sumnole 4/13/2025||
Which is just not true. Pascal is going strong within the Lazarus / RAD community.
CRConrad 4/16/2025||
Which wasn't really true even when he wrote it.
deepsun 4/15/2025|
>

    type
        apple = integer;
        orange = integer;
> then any arbitrary arithmetic expression involving apples and oranges is perfectly legal

Same in Kotlin sadly. The whole point of giving a different names to a type is to make them incompatible.

More comments...