Note for people who don't know much about FreePascal. It is a full-featured and very fast compiler. The resulting program is a rival for the best output of C/CPP compilers. It can be used in the style of simpler languages like Go and is almost as safe as Rust in a much faster manner. It has a great but old-looking IDE, Lazarus. It has been under active development for decades and is used for proper projects like:
As far as I know, there is no toolkit out there that lets you make fine looking applications for multiple platforms with proper speed.
The old Pascal you may know is not the new Pascal. The development of Pascal is mostly focused on ease of development while maintaining low-level programming and backward compatibility. It looks old on its face, but it is young at heart.
I recommend starting with Lazarus, https://www.lazarus-ide.org, a much lighter IDE compared to so-called light projects like VSCode, with many more features and components to play with.
Friendly word: don't let the comments with outdated information make you miss a great and fun tool.
I don't believe you regarding "as safe as Rust." It's been a minute since I've messed with FreePascal, but as far as I know and can ascertain at a glance, it lacks any true modelling of memory safety to even match Go, and certainly not memory ownership to match Rust. It is surely possible to write correct programs in Pascal, and maybe even easier than C, but it would not be accurate to describe it as "as safe as Rust." It's not really even close...
Don't get me wrong, though. I do think Lazarus/FreePascal are underrated, but some of these claims are exaggerated. FPC generates good code, but on par with GCC/LLVM? I'd guess it's probably sitting closer to Go in terms of performance characteristics. More than good enough, but surely a ways away from the ridiculously complicated optimization systems in LLVM and GCC which aggressively vectorize, constant-fold, DCE, inline calls, interchange loops, and so forth.
That's reasonable to not believe me, but can you enlighten me with more samples? If you mean managing pointers in Pascal, you can code in a style of high-level language like JS and never see a pointer to manage, thanks to managed records, objects, strings, and arrays.
And if you are doing low-level stuff that needs getmem, alloc, and pointers, you better know what you are doing with your memory; otherwise, what is the point of writing these low-level codes? speed and control. Furthermore, pointers are typed and managed at compile time, with plenty of hints and warnings to show you the correct behaviour.
I stand by what I said about speed: I've been comparing the resulting code of GCC or Clang and FPC for years, and if you know what you're doing, the resulting speed will be almost the same. Sure, Clang does some quirky things, but at the end of the day, I've never seen a piece of code written by the same person in both languages (the result of one mind with one style of code) that resulted in a different speed. To be fair, GCC or Clang are a step ahead because they are the result of millions of dollars in corporate support, but my response was to emphasize that the speed is not what people remember from decades ago.
As a sample, you can try the Dadroit tool, I linked, I am on the team, and you can compare a result of Pascal with similar tools.
And I agree with you. Don't get me wrong; despite my passionate response about Pascal, I am not saying that Pascal is a one-to-one replacement for new languages; my thesis is that you have most of the cool stuff you hear in this old language too, just without the hype, to encourage people to give it a try and not repeat the old "Pascal is old."
> That's reasonable to not believe me, but can you enlighten me with more samples? If you mean managing pointers in Pascal, you can code in a style of high-level language like JS and never see a pointer to manage, thanks to managed records, objects, strings, and arrays.
Exactly.
When I hear "safety" I think of what guarantees the language is able to give me and how. As an example, if I don't import "unsafe" in Go, pure Go code is guaranteed to be "memory safe" except for concurrency hazards. In general, this means that pure, safe Go code cannot ever trigger a use-after-free, double free, out-of-bounds memory access, etc. Of course, this doesn't prevent bugs, but the guarantees provided do prevent certain classes of security issues entirely. Bugs that trigger Go panics are almost never exploitable, whereas bugs that trigger segfaults often are.
With Go, it's possible to disallow unsafe code entirely, because the safe subset of the language includes almost the whole thing. The only real escape hatch is the unsafe package.
Rust is similar, but instead of unsafe as a package, it has unsafe blocks. And instead of still allowing concurrency errors, Rust enforces memory ownership tracking via referential lifetime checking. Lifetime checking still applies even when using unsafe blocks. Lifetime checks prevent bugs like double free, use-after-free and more, but they also prevent concurrency errors by entirely disallowing multiple mutable references to exist to the same data, as well as disallowing a mutable and non-mutable reference to the same data simultaneously. The only way I'm aware of to crash safe Rust code outside of panics is by causing a stack overflow, but this condition is not exploitable. Thus Rust has one of the most impressive definitions of a "safe subset" that I'm aware of. The only way you can really do better is probably using theorem provers to prove correctness, or maybe you could make bounds checking a bit more runtime-efficient using a SAT solver to disprove possible out of bounds errors.
As far as example code goes, I think it's moot. The point is that FreePascal doesn't really have an explicitly safe subset. As you are describing, it is possible to use FreePascal safely. In fact, it's easier to do so than many other languages. I hear you. However, that having been said, technically, most languages have a "safe" subset of operations that can not have any runtime hazards. FPC's safe subset is probably bigger and more useful than C's, but it isn't explicitly defined like Go or Rust. That alone puts it in a different class. Having safe subsets be well-defined allows you to net hard guarantees by enabling one to enforce the use of only safe subsets. It allows you to turn "probably never" into "absolutely never, ever." (Until you get hit by a hardware bug like rowhammer or a faulty CPU... But, you know.)
> I stand by what I said about speed: I've been comparing the resulting code of GCC or Clang and FPC for years, and if you know what you're doing, the resulting speed will be almost the same.
I mean, if you write good Go code, it will also optimize very nicely. The FPC optimizer is no slouch: it has all of the basic optimizer passes you could hope for. It's documented as such. It's probably a good compile time trade-off. But the documentation reveals it does indeed lack certain advanced passes like auto vectorization, and I'd find it surprising if the optimization passes were as sophisticated as LLVM/GCC.
Despite that Go is similar with regards to optimizer passes, nobody would consider Go particularly slow. In fact, it is considered to be very fast.
I do understand that you are telling the truth. I have no doubt you did compare GCC and LLVM to FPC and found that it is often similar in performance. That's generally true among a lot of languages for most code. Of course, there will be code where GCC/LLVM will do inscrutable things that less complex optimizers are definitely not going to do. Does it matter? I mean, it depends. Sometimes it matters. I believe that it is most likely going to matter in particularly complex and large software like web browsers, not the type of stuff most people are doing.
Anyway, I think Lazarus is still a great sell. Delphi always had one of the better UI libraries back in the day, and today, having a decent UI library at all is honestly quite a chore. Therefore the LCL alone has become quite a selling point. It's so bad that there is in fact Go bindings to the LCL, because Go and Rust lack decent, mature GUI options.
People definitely undersell Object Pascal and FPC because Pascal is old and weird looking. I feel the plight.
Sorry, but the question regarding language safety is very clear-cut: either the language has an explicit model for memory safety, or it doesn't. FPC/Pascal doesn't. I am aware that it has some useful primitives which provide better safety than idiomatic C, but that isn't really what is implied by the claim that it is safer than Rust.
Similarly, C++ has memory-safe strings and arrays in the STL, with automatic memory management, allocation, etc., but it is also not "as safe as Rust." On top of that, FPC lacks any equivalent of the borrow checker. Automated reference counting is a good feature, but it won't stop you from writing race conditions. Borrow checking can, which is pretty powerful.
Using FPC with LLVM will indeed give you LLVM optimization passes, but it's got quite a lot of limitations. I'd probably opt to use the FPC native code gen.
But Pascal strings and arrays are much safer than C++'s
C++ does not have bound checking on [].
And people write std::string& as return type or new/delete std::string, or use iterators, and that is all unsafe. Pascal does not have anything like that
Yeah, but it's not hip, and it's too wordy with BEGIN/END, and the data structures are too restrictive, and the compiler nags you, and the like. And you can write an 8M line codebase in it, touched in all kinds of foul ways, and it still works. That's the biggest codebase I've ever worked on at least.
Take that as a small (subjective) clue. Anything that is great about Rust or Nim or <..> could also have extended Pascal or M2 for the same result, and much sooner. Especially goes for M2, because the grammar was so small, thus avoiding the old PL1 traps from an overloaded parser.
FPC needs smart macros, needs to backport M2 interfaces, and the solid green thread spec* backported from M2, but it really is in the ballpark. You want gc? Well, fair enough, but you can write a pretty good mark/release* facsimile with RTTI. Or how about Eiffel simulated contracts with open arrays?
And Lazarus, good grief what a 30 year old premiere open source project. No point in even talking about how awesome it is.
Co-Pascal has been doing co-routines for 45 years.
In turbo pascal, you could create mini-heaps that could be dumped most anytime. They weren't smart, but still a cool feature.
I really wish I could figure out why your comment grates on my nerves so much. There's nothing untrue in it, yet I feel compelled to comment.
Macros would be a horrible thing to add to Lazarus/Free Pascal, in my opinion. They would make the reader have to second guess everything they see. Also, it would likely slow down things by not allowing single pass compilation any more.
>Co-Pascal has been doing co-routines for 45 years.
I wrote a Turbo Pascal implementation of co-routines back in 1987[1], although I'm just learning of that term now. I was frankly amazed at how simple it was to get working, though I did surprise myself the first time fork returned twice, and I was confused as to why it did ;-)
You mention that Pascal is almost as safe as Rust. This comes as a great surprise to me, because I was under the impression that Pascal and C are very similar.
(Though I hear the strings, at least, know their own size!)
I learned programming at school in Pascal and didn't have troubles with memory safety. FreePascal/Delphi has good standard library to work with strings and dynamic arrays and objects, and as long as you follow very simple convention with TObject.Create() and TObject.Free; you won't have memory safety problems.
I didn't really have a need to work with pointers and do pointer math in Pascal, because language itself provided facilities to work with heap objects safely.
Also standard Pascal compiler added array bounds safety and many other checks, and you would easily find these errors during program execution (there wont be a silent exception).
Also because Pascal compiler is LL(1) single pass compiler, you could easily do a cycle of: edit code, compile (<1 second on 333Mhz Pentium-II), and run.
That compiler enabled developer experience of like modern Python/Javascript
Unlike C++ which spent enormous time evaluating macros, compiling, linking, etc
not only that, Object pascal has very nice way of separating code and avoiding globals, and variables were constrained within certain scope. Each module is compiled independently and no macro hell.
if you were to pass reference around, then compiler would warn about potentially dangerous Free.
I don't remember ever seeing Pascal code where you received raw pointer and then directly casted it to your object type for example. Pascal has very powerful and expressive type system
Pascal is type safe and generally catches most errors at compile time, you can still create run-time errors such as indexes outside arrays but these will cause errors not bad return data.
eg I use C a lot and find myself referencing array index [0] a lot, in pascal arrays starts at [1] if not specifically defined so I know this from experience, frustratingly I have a different problem in C which will either return random data or crash if writing.
Pascal arrays can use any sub-range of an ordinal type as the index. You should define the distinct type of the index instead of using integers then you will get an exception if you attempt to use an out of range index.
I'm pretty sure that FreePascal and Delphi can do run-time bounds checking (it's a compile-time option).
Pascal also avoids buffer overrun errors on strings, because strings are dynamically resized as necessary.
You can also avoid having to free objects if you declare them as implementing a certain Interface (I forget the exact one). They will automatically be freed when the number of references drops to 0.
I have no experience with Free Pascal, but its predecessor Delphi was a lot safer (and easier) to use because of dynamic strings and arrays. You could use it almost without touching pointers ever (Win apis were the main reason for using pointers, as they were C based). In those days when stack overflows were the main security issue for majority of apps, Delphi apps were considered way safer than VC++ apps.
I am fairly sure FPC protects against out of bounds access in some cases. I ported a Pascal game fairly verbatim to C for fun, and many segfaults later I realised it seemed to be relying on this behaviour of the language. Maybe I'm wrong, it's the only Pascal I've ever read.
> It can be used in the style of simpler languages like Go and is almost as safe as Rust in a much faster manner.
What does this mean, exactly? Usage in the style of Go requires garbage collection and being safe like Rust (without GC) requires a borrow-checker, and as far as I know Free Pascal doesn't have either.
A borrow-checker isn't the most practical or the only way to provide safety. For example, a string type can have an offset for creating O(1) string slices and point to a shared counter. That way when mutating the string, it creates a fresh copy iff the counter is bigger than 0.
Object Pascal has two magic types, dynamic arrays and AnsiStrings. These are automatically reference counted. Objects and classes have to be managed by hand, yes.
In general, expect a lot more compiler magic out of Pascal, a lot of concepts were hacked into the Borland compilers over time.
Pascal gets an underserved bad reputation.
I am showing my age but Turbo Pascal was (is) great.
Extensions from Turbo and Delphi Object Pascal is great as well.
I hate the insane pricing Embarcado has imposed on Delphi.
They have had cross platform GUIs in Delphi for a long time.
Something for some reason other tools struggle and mostly fail to do.
I have not been able to "sell" it to clients mostly due to price.
I think this was a reason for C’s success back in the day. If C compilers were a little cheaper and easier to get, then they’d completely take over, long-term.
I remember that Pascal was the norm for Mac programming for a time during the late 1980s or so. You could use THINK Pascal (later Symantec) or MPW Pascal. Pretty soon everyone was programming in C and compiling their programs with Metrowerks CodeWarrior.
I think this was a reason for C’s success back in the day.
Nop, more like the other way around in the 80's. Before, there were two reasons: lack of a standard (Pascal was a learning language, not intended for professional use) and the VM fever: very often so-called P-Code systems were the quick and dirty way to have a programming language for a new system. The result was slow, incompatible, cumbersome access to machine resources.
C was always compiled and had a clear standard that included direct memory access. Also UNIX.
But in the 80s, TurboPascal was $50, had everything that C had + an IDE + compiled x100 faster. Later there was a nice text-mode GUI (TurboVision), then Delphi. Microsoft defused it poaching most Borland talent.
> lack of a standard (Pascal was a learning language, not intended for professional use)
The parenthetical is correct, what is outside is not; Pascal had a standard (ISO 7185:1983), but the standard lacks features needed for serious use, so Pascal implementations were either standard and hobbled or useful but not interoperable.
I don't mean to snark. Maybe my comment wasn't clear enough. I've talked of two different periods: the first in the seventies, the second in the eighties and later. The starndar was late. By that time, it wasn't needed because the only Pascal that was widely used was Borland's.
That it was finalized around the same time Turbo Pascal 1.0, which only ran on DOS and CP/M, was released.
> The starndard was late. By that time, it wasn't needed because the only Pascal that was widely used was Borland's.
The ISO standard closely followed the 1974 language description, which served largely the same purpose and had generally the same shortcomings on utility, so that the “interoperable but not useful because following a very limited common description, or useful but not interoperable because of proprietary extensions on top of the common description” predates the ISO standard; the lack of a common labguage spec was never as much of a problem as the focus of the spec.
And, no, by December 1983, Turbo Pascal (released the month before) was not the only Pascal that mattered. Nor would it be later in the 1980s, as Apple's Object Pascal (which influenced later versions of Turbo Pascal) became important.
Embarcadero insane pricing of Delphi is the reason I haven't continued beyond my old version Xe2. I guess they are making hay while the sun shines with the locked-in customers.
In these days, Lazarus and FPC are a valid choice instead of Delphi, except when you are doing some heavy component based codes, like organization oriented projects. Plus side is Lazarus can produce a project and UI for almost any OS.
Do they have the yellow-on-blue syntax highlighting trademarked or something? I've looked for vim and vscode color schemes to match the original turbo c++ but to no avail. I remember borland builder had a setting to switch back to it.
That's a nice color scheme, but what really made those text-mode IDE's intuitive was the TUI widgets and support for multiple views. Probably easier to do in neovim than plain old vi/vim of course. With modern devtooling support as found in neovim you could also have inline help, which was also very useful in those older environments.
Well said. If not for the insane pricing and the fact that Delphi does not run on non-Windows platforms, it is a great product with a basically unmatched GUI app development capability
A peculiar aspect of Lazarus (Free Pascal's Delphi-like IDE) is that it either cross-compiles for other architectures or can run itself on them, therefore generating native GUI software that runs immediately on the target platform.
That is, you can develop ARM executables on a Raspberry PI using Lazarus running on the Pi itself.
I would also suggest to take a look at FPCUpDeluxe, an installer that does all the tedious job of dealing with dependencies for installing FPC, Lazarus and a great number of modules and components.
A personal dream: having something like Lazarus that works with other languages too; that would likely become a game changer for desktop apps development.
I think the popularity of pascal has something to with Modula-2 (the successor of Pascal invented by Wirth) having been recently included as an officially supported language in gcc alongside Rust. I tried lazarus again, I was amazed. It is as simple as using VB6 for creating quick GUIs that run everywhere. Turbopascal is blazingly fast, produces efficient and small binaries.
I used to be a hard Delphi/Pascal guy and still think it is much better than C for it's strong typing and overall "squareness". But I'd have a hard time going back to it nowadays. The 'var' section, magic "Result" variable and begin/end pairs are just from another age.
Programming languages have advanced _a lot_ since Pascal was created. It's core principles remain valid (safety by default, readability, flexibility). But the feedback loop between language design and actual usage is much tighter thanks to the Internet and open source.
Some things I still miss from my Delphi days are the language-level enumsets, near-instant compilation and RAD tooling (GUI builder).
I pretty much started programming in Delphi (which was very popular in this part of the world, and still is to some extent).
After using VCL for a year or two, I started branching to other, much more popular programming environments, and was shocked about how bad they were for GUI development. Why would anyone put themselves through the pain of writing interfaces manually using programming languages not designed for it (like C) when you could design everything in a convenient GUI builder?
It's sad they decided to focus on the "enterprise" market and buried themselves in the long term. Writing GUI stuff in Delphi was (probably is) a pleasure: they compiled quickly, looked native, and ran fast on my shitty hardware.
"The 'var' section, magic "Result" variable and begin/end pairs are just from another age...Programming languages have advanced _a lot_ since Pascal was created."
I understand why some programmers dislike Pascal's syntax, but C and C++ are also old and still popular (including for new projects). Syntax and semantics are closely entwined but C and C++ syntax still influence "modern" languages.
It's not magic in how it works, it's just magic in it's syntax. It's a variable you don't have to declare. It's ripe for abuse / mistakes and would be one of the things I'd have lints for and watch closely in PRs.
Nim has the same result variable[1] and I absolutely love it.
It helps avoid the classic "oh, I forgot to return it" bug. Also makes the code more succinct and saves you from having to type an extra line for explicit return.
I kind of get why you would be wary of it, as it is a special variable but compared to other messed up stuff like for example Rust treating a line without semicolon as implicit return, it is a relatively tame solution for this problem and can be easily figured out.
Did you ever had any actual bugs caused by the use of result?
If you forgot to return a value, a function shouldn't have compiled. In Nim you can easily forget to return something or have a hole in your branching and get a defaulted value, instead of a compiler error.
In some cases an implicitly declared variable feels neat and convenient, but I'm not sure it's worth it.
Ha, I'm quite used to Rust's last-expression-is-the-value and I also get why some would think it's weird but I find it actually works quite well in practice. Each language has its gymnastics and special moves, I guess. Back to Pascal, I'm not opposed to Result usage per se and I understand the appeal since it's what I grew on. My concerns are more about code maintenance in long-ish functions - I don't have a particular example of mis-usage, but I'd be wary of late reassignments overriding a previously set value. Separating exit points from return value assignment could let code become hard to follow and create situations where it's easy to misread the actual outcome.
Pascal killed my interest in programming for a while as it was force fed in both high school and earlier collage years. Reflecting back, it was the pessimistic approach to teaching of just pushing math problems via programming.
Ca. 1994 we had Pascal as the language for AP computer science. Later, they started adding other languages. In my school the options were Basic (TrueBasic) which was offered as a stepping stone to APCS and pascal. I also had the opportunity to study Scheme through CTY's excellent summer class.
At the time, I remember pascal feeling like "real programming". The programs were compiled and they operated at various levels of abstraction, from pointers up through advanced data structures and interfaces/ADTs. I didn't see Scheme as more than a toy, which was partly because the MIT Scheme implementation was just an interpreter. And I hated Basic and still do.
Pascal was great because it was pretty easy to learn and somewhat consistent. Its most annoying feature, semicolon-as-separator, was easily handled by the terrific Think pascal editor.
In its time, Pascal was a great choice. There were real-world things that you could do immediately using Think Pascal and Turbo Pascal. Making the switch to C and Unix wasn't simple but probably easier than starting with Basic. However, I was left with a bias towards wordy languages like Pascal, Ada and Modula-3 that took a while to get over :)
Free Pascal was originally derived from Object Pascal and later Delphi, both of which added more object oriented programming features to Pascal. Additionally, it supports some of the more advanced features introduced to Pascal with later releases of Delphi including managed types, interface types, operator overloading, generics, implicit and explicit conversions, extension properties and methods, as well and user defined initializers and finalizers for your custom types, and more.
I could write an article about each of these features, but in summary they each are powerful and help users write more useful programming code when leveraged correctly.
I also had mandatory pascal during my high school years. Although I knew a little of C, C++ and python at that time and felt a bit obscured about learning pascal, today, I deeply admire my teacher's choice of pascal. Pascal has a nice beginner terminal IDE with a debugger and breakpoints; it has types, stack allocation and memory planning before the program is being run; recursion is possible, and it does not have many obscure features like pointers and OOP obscurities. Today, perhaps I would suggest Julia as the first language to teach, but pascal is still at the top.
Luckily for me I've never received any formal training in programming back in school. My introduction to programming happened in University and research labs in a very simple way - I needed to process and interpret some experimental data live and the only way I could do it was a computer. So I got me a user guide for particular one and bunch of books. In a few days I was already coding away. In exactly the same way I was introduced to electronics. Had to make some equipment for my research as you could not by one. Started with machine codes but over the time I've used many languages including Pascal from Borland. Programming was far from my main job but at some point I switched from science to creating commercial products as I was good at it. Some products I own and some I develop for clients. Most of products are ether pure software or contain some good chunk of it so I am still happily coding away even though I am 60 already.
Pascal is great as a teaching language because of its simple syntax. It is also a pre-OO language, so you don't need to spend time explaining what classes and objects are. For an introductory programming course it is a very good language.
This was all people knew. Most people saw programming as a branch of math. When a high school offered a programming class, it was often taught by a math teacher. The smaller colleges in my state, that were beginning to add computer science, did so by combining it with the math department.
My mom taught programming in the early 80s. She took a course at the nearby community college, and a year later, was teaching the course. Her background was... high school math teacher. She said: "Programming is just math, a program is like a proof." Fortunately I loved math and proofs, so that way of thinking wasn't an obstacle for me. Clearly we know differently now.
they could approach the same math from the other side, by starting to write games. and gradually come to game math. that would be more interesting, and then it would become obvious why one may need some math while programming.
Back Then. When was that? At University (1978) we used Pascal as the first language to learn (if you exclude CDC Cyber 6600 assembly). Yes we did the Discrete math problems common in CS (https://mathworld.wolfram.com/Floyd-WarshallAlgorithm.html). We did other things as well. The professors were a mix of hippies, math geeks, and the Doctors from Doctor Who. Most knew both the academic and fun side of programming.
I guess it depends on the school and people there to create a fun but educational culture.
Heh, now you've made me consider an "abstract algebra for kids" tutorial, with data representations for simple games as the overarching conceit. Unfortunately, as a cishumanist, my finite lifetime expectation means I'll leave this project for some other interested party?
Personally I read the programmer manual for FP. You can do both Object Pascal OOP and Delphi OOP.
Wild. Also nice units for doing mmap and all libc stuff. I really ought to finish learning Pascal and actually write something in it. Not a bad language.
not only libc. what is very cool is that most of the parts of very rich fpc library has no libc dependency.
so necessary parts get linked statically to the resulting binaries, and those binaries do not require libc. most of the library goes with roots to kernel calls, bypassing libc.
once you start using threads or link to other c libraries (like gtk) then libc becomes a dependency.
When I looked into learning Free Pascal (not that many years ago) it seemed to me like Ada was the more well-developed, actively used language of that sort of heritage.
Have any of you used both languages? What made you stick with Free Pascal instead?
(To be clear, I'm interested in a comparison that goes beyond the price point of the commercial compilers, which is a tired subject at this point.)
Don't download the bundled Free Pascal and Lazarus distributions from this site, they're very outdated. Just get the normal releases from the actual Free Pascal and Lazarus sites which are linked at the top of the page. Lazarus comes with Free Pascal bundled by default anyways, so you don't need to grab the compiler separately if using Lazarus.
I downloaded Lazarus from its release page on Github and after installing it didn’t work, saying it needed extra binaries that it couldn’t find. Now I have to see what it’s talking about, what to install, etc. Kind of a hassle.
Some recent personal projects with laz and fp got me pretty interested in it.
I have nothing impressive to show for my work except for a lot of retro-pride when I type in e.g. the snippet which triggers the Pascal program which tells me how old I am. With some bells and maybe a couple whistles.
I was surprised to learn that there was Pascal for the C64, which I thought was more of a "BASIC or bare metal" system.
I too was a victim of the great AP Pascal force-feed in my HS comp. sci. class...but fortunately at the same time there were demoscene programmers around the world blowing my mind with Pascal programs and it seemed like there were new projects to appreciate online (BBS) every day after school.
To whit: Someday I would like to write a Pascal raytracer that tells me how old I am, with emoji output, since my other ride is a text editor. (And if you don't like my driving, get off the sidewalk!)
Heh - I didn't do great in AP with Pascal either. I remember though trying to make it worth buying CodeWarrior for Mac OS (oh how the Internet changed everything ... :D ), which had a Pascal compiler, but I got overwhelmed looking at the Mac Toolbox docs and couldn't make much sense of it. (I know there was also MPW, but I didn't know how to get my hands on it.) The school computers ran Turbo Pascal on MS-DOS. I vaguely remember having to write programs on paper without a lot of access to those computers.
But, I tried FP last year. I wrote a program to mimic a small tool in the company I worked for. It was fun actually. At the time, I sort of wanted a lot to write stuff in Emacs. There is an LSP server for FP but it's not really complete.
Back when I learned computing, I had an old Apple ][+ with a Z80 card. There were only a few choices to program it. Apple and Z80 BASIC, Apple Logo, 6502 assembly (I did not have access to a Z80 assembler) and UCSD Pascal.
Pascal was awesome. So much better than the others. It really launched my interest in coding once it clicked.
I remember discovering that the early Apple game Wizardry was written in it one day when I was hacking around with it.
I still remember that the thesis of a fellow student back in the university 20 years ago was to create an educational version of Pascal called... "Paschool".
I laugh out loud when I remember it, definitely the programming language with the most funny/catchy name ever!
Coincidentally i tried to install Lazarus yesterday and hit issue after issue, two being some missing dependencies, which were items that I found in the documentation to be downloads as well. It then complained about lack of gdb, which I do understand (on an older Macos here) but it did occur to me, if you know it is needed, why not include it in the download?
Cut a long story short, Ive installed Dr Racket today and working through the tutorials.
Qt and wxWidgets are also worth considering assuming you would just be "writing" the code and not taking advantage of the visual designers. These do have visual designers, but Lazarus if far easier to use, IMHO, following the footsteps of Delphi and VB classic.
https://cppcast.com/cpp-builder/ - this is the podcast where embarcadero devs tell about how they maintain number of patches to llvm's compiler to make it compatible with necessary non-standard features like closures.
this also tells us that c++ became so big and complicated that one company (embarcadero size company) is not able anymore to support own compiler, they need to maintain own patches.
If you look at C++ standard support in major compilers, you'll find that no compiler on earth supports the whole C++20 standard. Gcc is the one that gets closest, but still has several "partially supported" features.
You can have your C/C++ code exposed to Free Pascal via a C API loadable as a shared library / DLL, but beyond that there isn't much you can do (Free Pascal comes with a `h2pas` tool to help convert C headers to Free Pascal units for such use).
This is of course far from having something like C++ Builder.
To have something like C++ Builder it'd need a lot of things to work together:
1. A C++ compiler will need to be extended so it can use Free Pascal classes (in terms of memory layout) and add any necessary language functionality for "published" sections (RTTI data that allows FPC objects to describe themselves and be streamed/serialized), metaclasses (classes in FPC are objects and can have their own virtual methods, including virtual constructors), delegates (basically "fat" pointers) as well as data types like sets, strings, etc that FPC has. LCL (Lazarus' framework) relies heavily on pretty much all of FPC features.
2. FPC will need to somehow be able to import classes defined on the C++ side too so that components written in C++ will be usable in Lazarus. Also almost goes without saying but it should be possible to statically link programs using both FPC and C++ in the same executable.
3. The C and C++ runtime libraries will need to use FPC runtime library functionality for things like memory management (FPC's memory manager is pluggable) so that "crossing" memory management will work fine - even across dynamic library boundaries (e.g. calling `malloc` on the C++ side and then "FreeMem" on the Free Pascal side, even when the latter is in a dynamic library that shares a memory manager with the host program, should Just Work).
4. Lazarus' "codetools" will need to be expanded to support parsing C++ in addition to Free Pascal so that all of the IDE's automatic code writing and refactoring functionality will work for C++ too - things as simple as double clicking on a button and having the methods be written automatically in the editor with the cursor placed in the method body rely on this working.
These are from the top of my head, there might be other issues to handle, but even from the above it should be clear that it requires not only a lot of work but also a lot of different projects to work together (unless FPC and/or Lazarus devs decide to implement their own C++ compiler and runtime).
In the short term it might be easier to use Qt Creator which has some RAD-ish features. It is certainly clunkier, the API feels to be made with a code-first (as opposed to LCL's WYSIWYG-designer-first) approach and the IDE isn't as featureful (also at least for me it never works out of the box on Linux) but it is the closest open source project you can find for C++.
https://dadroit.com/ https://peazip.github.io/ https://cudatext.github.io/ https://lazpaint.github.io/
As far as I know, there is no toolkit out there that lets you make fine looking applications for multiple platforms with proper speed.
The old Pascal you may know is not the new Pascal. The development of Pascal is mostly focused on ease of development while maintaining low-level programming and backward compatibility. It looks old on its face, but it is young at heart.
I recommend starting with Lazarus, https://www.lazarus-ide.org, a much lighter IDE compared to so-called light projects like VSCode, with many more features and components to play with.
Friendly word: don't let the comments with outdated information make you miss a great and fun tool.