Skip to main content

Alys+

You like actuallyalys. You've always liked posts. Don't you deserve the smooth, luxury takes of...Alys Plus?

🖙Thoughts on Pascal

written by alys on

I got a very late start on Doscember, but I had some downtime over the holidays so I decided to play around with DOS, with an eye to maybe make video games in it eventually. I decided to program in Pascal as it has some interesting characteristics, was a mainstream language for DOS, has a famously good implementation in Turbo Pascal, and is slightly higher level than C.

I haven't written a ton of Pascal yet, but these are my thoughts so far. I have a pretty positive impression overall!

Some people debate the merits of recent compilers that disallow unused variables or require certain capitalization schemes. Pascal is honestly much more persnickety. All variables have to be defined up front. Similar to variables, all constants need to be defined up front, in a separate section from the variables. This is often encouraged to this day, with some exceptions, and Lisps in particular end up doing encouraging this structure as well, with their let construct. What makes Pascal's format less convenient is that you can't do many operations in the initialization. You can do math and logical operations, but little else, meaning an expression like var x: integer = my_function(5); is not allowed as far as I've been able to tell.

It especially becomes a drag when you have to define loop variables up front. Not only is defining a variable for a loop at the start or right before a loop very very common, it's common for a good reason—loop variables tend to be used for that loop and nowhere else. I think if I were designing a Pascal implementation, I would allow defining variables in loops. I believe Delphi does this.

It also becomes a drag if you're doing a series of manipulations and want to use variables for each step (e.g., processed_entries, processed_entries_no_duplicates), which I sometimes do when working with data. (Of course, data analysis isn't really a strength of Pascal's for other reasons, including its lack of libraries for basic data process, statistics, machine learning, and visualization.). I actually just read an article encouraging people to avoid these kinds of names, so perhaps discouraging naming intermediate values is not so out of step from modern practice. And this kind of code ends up being kind of throwaway code anyway, so it's really not a surprise that it doesn't fit well in a language intended to impose structure.

There's also no type inference. Given the level of IDE and editor tooling and the level of computing resources when Pascal was originally invented or even when Borland and others were extending the language, this decision was probably correct, but it definitely makes it less ergonomic than many languages in wide use today.

So while I find both the required variable section and lack of inference annoying, it's not a dealbreaker for what I want to use it for. Now, if I were writing large programs in in every day, it might start to grate on me.

Pascal is an interesting mix of high and low level. It has pointers and the data types are pretty clearly matched to exact memory sizes; however, it also has features like sets, tagged unions (which it calls "records with variant parts"), and subrange types (e.g., you can define a MonthNumber type that's limited from 1 to 12). Turbo Pascal eventually added support for object-oriented programming. Free Pascal has also added for each loops ("for in" loops) and generics. So in some ways it feels similar to the "better C" languages, like Zig or Odin, although admittedly I haven't personally tried those out yet.

As an aside, subrange types are kind of interesting. Pascal has them, Ada has them, but very few other languages have them? In fact, Oberon, the language Nicholas Wirth created after Pascal and Modula-2, doesn't have them. In many languages without them, you can do something similar by controlling object instantiation or by controlling struct creation in Rust. For example, although Python stores months as integers, datetime.datetime prevents you from assigning 13 as the month. I believe you can turn C structs into opaque pointers and fake something similar as well, although the protections aren't as strong.

Despite both Pascal and Ada having a notion of "subranges," they work pretty differently. In Ada, my understanding is that types favor the semantic and the idea is that the compiler will choose the appropriate physical size. Pascal allows for, say, giving an existing type a new name to prevent conflation, but they're pretty tied to hardware types. Even the documentation on sets emphasizes its memory usage. That's probably a pretty good tradeoff for the 1970s where you had to be mindful about memory usage for any substantial program, yet also wanted some affordances to express semantics . Originally I thought this combination had lost its luster, but upon more reflection1:, I realized Rust and other modern systems languages will sometimes straddle the line, so it may be even more popular today. You can also end up with a mixture of physical and logical type features with C# and probably will be able to in Java once they finish adding unboxed primitives. I wouldn't call these strictly systems languages, but they are kind of systems-adjacent.

Pascal shows its age in other ways as well. Its identifiers are case insensitive. This isn't a significant problem since you can mix case in your source files and the errors will print identifiers in their original casing. It does prevent you from using the Date date = new Date() convention you sometimes see in object-oriented programming, though.

So far I have found the documentation tough to navigate around, similar to how I find Javadocs difficult to navigate around. They do a good job of organizing all the information consistently and documenting all the types, methods, etc., but discoverability tends to be poor—it's hard to know where to get started out of this large mess of common tools. It's also tough to find things that work together. This varies based on the unit (what Pascal calls its modules). For units that are small or standard, like the Math unit, this isn't a big deal. Your intuitions that the rounding functions are probably named round, ceil, floor or something like that will probably get you to the right place. Although if you only look for "round", you'll find RoundTo, but might miss the others and still be at a loss for how to round an floating point number to an integer. This might actually be the hardest part for me going forward.

Also like Java, there's quite a few things kept around for backwards compatibility that don't seem to be a good idea to try to use today. However, with Java, I feel like there's still some expectation that the deprecated classes still work, which seemingly is less true for Pascal, at least if you use Free Pascal. In fairness, while there's not a standard "deprecated" tag or "compatibility warning" graphic, there does seem to be some effort to clarify the current status and steer users toward what's actually maintained. For example, the `Graph`` unit says:

The unit is provided for compatibility only: It is recommended to use more modern graphical systems. The graph unit will allow to recompile old programs. They will work to some extent, but if the application has heavy graphical needs, it's recommended to use another set of graphical routines, suited to the platform the program should work on.

My hope is that if I follow their advice, I won't get burned on compatibility issues. Although, given part of the reason I'm learning Pascal is for retrocomputer adventures, I probably will experiment with some of the older stuff and push the boundaries. At least I'll know what I'm signing up for.

One strength of Pascal's you'll sometimes hear about is Delphi, which is kind of like an alternate-timeline form of VisualBasic (pre-.NET). It also has an easy form builder. You can still buy these today from Embarcadero. or you can use the open source equivalent, Lazarus.

Another strength is that it compiles fast. This is less impressive today than when Borland was bragging about Turbo Pascal's immense speed, but of course, those hardware advancements have not made all compilation instantaneous. I'm pretty used to writing in languages that don't really require noticeable compilation, so the quick turnaround makes me feel at home and makes me miss the lack of a REPL less.

Overall, I don't see Pascal dethroning any of the languages I use most or like the most—Python, Clojure, C#, and Fennel—, in large part because of the missing ergonomic features and unfriendly documentation, but I imagine I will use it for future retrocomputing adventures. Like my other recent foray into an a programming language of yesteryear, Prolog, I'm certainly glad I learned it.


  1. I guess this is a pun, although I tend to think of reflection as being squarely on the higher-level side. Although I suppose you could theoretically use a system to analyze your memory usage at runtime and possibly optimize it, almost like building in a JIT compiler into your program.

1773 words; 73 sentences
Stats for nerds
  • 1773 words
  • 73 sentences
  • 24.29 words/sentence
  • Flesch-Kincaid Reading Ease: 11.14 (grade: 11)
  • Dale-Chall Reading Ease: 9.36 (grades: college)

posts from friends

Review: The Stardust Thief by Chelsea Abdullah

My review of the fantasy novel The Stardust Thief by Chelsea Abdullah. It was published in 2022 by Orbit.

via Nullrouted Space December 17, 2025

(watching an old movie)

interesting...it seems beer was served omakase in 1980s american bars ]]>

via topposts.net December 15, 2025

new music roundup: june 2025

hey friends, gonna start this one off with a request: i’m currently without stable housing and without employment, and i’m in extremely dire financial straits. as of this writing my account is overdrafted and i have very limited options for fixing that. i…

via BLOOD CHURCH June 6, 2025

Generated by openring

alys