83 comments

[ 2.7 ms ] story [ 140 ms ] thread
The set of supported platforms and operating systems is nuts!
Even Nintendo Wii. ;)
Would be interesting to know the total number of active users out there.
I'm writing a major system using FPC/Lazarus right now, and will fund additional dev as soon I can get a reference mvp done.

No idea how many people are using this toolchain to produce real work, but I consider it to be my secret weapon. I've never seen a truly multi-platform, batteries-included dev tool that is so coherent and comprehensive. At this point, the only add I would love to see is better macro expansion beyond the simple code macros that are provided now.

At any rate, depending on your definition of success, if you want to see an example of a decades old, open source project that really does work, throw the FPC/Lazarus project in with Linux itself. I'll spend the day today writing code on both a Windows and a Linux machine for the same project, producing the same ui heavy app with hardly any differences, thanks to this toolchain that runs pretty much exactly the same in either environment.

Seeing the love and dedication put into this project by contributors is a great way to remember how cool writing software really is. All devs should at least fiddle around with FPC/Lazarus just so they know what it is.

For me FPC/Lazarus are also a secret weapon. We use them at my company in production apps (mostly web and commnand line programs) since ages.
I did a good bit of my high school programming classes in Pascal; only much later in my life do I realize how much it taught me. Kind of miss it, actually.
Why doesn't Rust adopt a running cheetah or similar to show that it is just as fast as Free Pascal?
Free Pascal compiler is blazing fast.
Yes! A Cheetah with muzzle and mittens because it's also safe.
First they have to reach Delphi/Free Pascal compilation speeds.

Now with creekshaw being integrated we might be reaching there though.

> Now with creekshaw being integrated we might be reaching there though.

I believe you meant cranelift.

Yep, that is what happens when I type something without searching for it, thanks for the correction.
I’ve never had any direct experience with Pascal (though I remember my dad telling me a story of an assignment he had in college to write a queue of queues in Pascal).

From the perspective of the Alan Perlis quote “A language that doesn’t affect the way you think about programming is not worth knowing,” is it worth it for me to give FreePascal a try? Or if I have experience in other procedural languages have I pretty much seen what it has to offer already?

If you know C you 'know' Pascal. What the best thing about Pascal (and its successor Delphi) was the blazing fast compilation time and I am not sure that freePascal has that.

Also what I really hate about Pascal is it is dishonest. It tells you it is very structured and your code will be better because of limited expressiveness. But then the 'writeln' 'function' needs to be intruduced at the compiler level - you cannot write such a function in the Pascal grammar. (maybe with freepascal you can nowadays)

What I liked though is that it didnt have the empty statement ';' so you really had to understand the semantics. Sometimes you were not allowed to end you statements with ';' (since they were ended by the block, so this would require the emptystatement). I think freepascal does not have this feature anymore (which is the thinking changing).

And just one more thing: Personally I would try to learn ADA before diving into Pascal.

No, sets. Sets are amazing. I still miss them to this day. Pascal also had sub ranges long before C# and the type system was very good. Delphi dereferenced its object model be default, so you could use dots rather than the awkward ^. Of pascal (-> in c++ and C)
Implementations sucked. They were bit vectors, limited to one machine word in length. So they were 16, 32 or 64 limited depending on where your program ran.
I'm pretty sure sets supported up to 256 elements (32 bytes) in Turbo Pascal on 16 bit systems, because you could manage ASCII characters with them. Yes, didn't scale. Yes, tons of use cases nonetheless.
That is always so in Pascal

It has the best possible ideas, and then fuck up the implementation.

Recently, I tried to use a set on a three valued enum. With three values it should have worked perfectly. But no, the set was not allowed. Because the values were -1, 0, 1 and FPC apparently only can create set on non-negative integers

> What the best thing about Pascal (and its successor Delphi) was the blazing fast compilation time and I am not sure that freePascal has that.

I'm not sure how FreePascal compares to Delphi in compilation speed, but I expect both are blazing fast. The compilation speed is a result of the language design of Pascal, and the fact that compilation can use a "single pass compiler". Go is another language that has this feature. Compilation times are so fast that development can feel similar to using an interpreted language.

> ... it didnt have the empty statement ';' ... > Sometimes you were not allowed to end you statements with ';' (since they were ended by the block, so this would require the emptystatement).

Pascal has empty statements. They are exactly that - empty. In C syntax ; is a statement end token, so the empty statement is ‘;’. In Pascal ; is a statement separator token, so the empty statement is ‘’, and ‘;’ is two empty statements. So the typical error is to write “....... ;” where only one statement is syntactically allowed.

Example:

  if x > y
  then x := y ;
  else ...  Syntax error. 
      Only one statement allowed between then and else.

  then { x := y ; }
  else ...    is Ok. 
      The blocking makes two statements into one.
Ada and Pascal have some syntactic similarities, but I'm not sure they cover the same kind of niche enough for someone to say "I'd learn Ada prior to Pascal".

Today, Delphi is used in some shops the same way C# or Java is used in others. Free Pascal with Lazarus is kind of like a free version of that. You can quickly build desktop apps.

Ada is nothing like that. It's almost exclusively used in the defense industry and others like aviation and infrastructure where the code is likely to be embedded and can NOT fail.

One is for standard business and one for critical infrastructure.

I agree, but then you wouldnt start new programs with Delphi these days, would you? (To me Delphi is the Cobol of GUI, will be still around forever, but less and less new projects)
I don't think many start new projects in Ada either unless you're working for Lockheed Martin or another contractor and even then, they've largely gone the C++ route.

What do people use today? Java, C#, C, C++, Python, R, JavaScript, Php.

What might become popular someday? Rust.

Yes, which worries me. I talked to a guy working in safety related software design (safety like car breaks), and they are going to C++, since there are not enough Ada/Spark developers. Which is a pity, since Spark allows you to prove correctness (in a special sense)
Why don't you try out and see what it is about? Any experience is just a plus.
From such perspective it won't teach you anything new if you already know C.

I would say Pascal's killer app today is Lazarus. An open source, multi platform GUI RAD IDE.

https://www.lazarus-ide.org

The modules (called units) are a huge improvement for managing large projects. Also extremely fast in compilations.

The string handling are much better than C. Most is just automatically. You would not even encounter any difficulties until you start to interface with C libraries. And then it is still easy.

Due to this and strong typing and bounds-checking you automatically avoid most memory errors that you get in C. But you can make it as complicated as C, with pointers to pointers to arrays, disable bounds-checking/type-checking, etc. There are some limited parametric type possibilities.

The disadvantage is the absence of closures/lambdas. Instead you have to make pointers to functions, like in C. Or use Objects like in Java. But with manual memory management.

The manual memory management and type declarations give extra overhead. Like in C. A lot would be avoided with inline variable declarations with automatic typing.

In some ways, pascal had such an impact that many of its revolutionary ideas (structured programming) are now so commonplace as to be unremarkable.

The way primitive sets and enumerated types fit together is still a rarity, as far as I know. (You can accomplish the same things in any low-level language, but the pascal syntax make it really nice.)

Interfaces in pascal are fairly interesting because they allow you to implement your own addref/decref routines for automatic reference counting. This was made for COM, but you can plug it into whatever reference counting scheme you like (say if you want to write python extensions or whatever).

The main thing is still probably the component system though, and the tight integration with the development environment.

It's kind of a trip the first time you configure an IDE plugin and realize it just recompiled the whole IDE for you.

>Interfaces in pascal are fairly interesting because they allow you to implement your own addref/decref routines for automatic reference counting. This was made for COM, but you can plug it into whatever reference counting scheme you like (say if you want to write python extensions or whatever).

Free Pascal now has a new way for that, stack objects/record with custom init/cleanup code. Real RAII. But not if used with inheritance

Pascal is unsurprising in a mostly good and sometimes frustrating way.

The syntax will be the primary barrier. Things like nested if-else with multiple conditionals are just a little more persnickity if you've been using C braces for decades. But the language, in the Borland dialects that most are using now, is somewhere in between C and C++ in terms of power overall: it's a little safer by default, still manual memory, but without needing to fling around quite so many pointers. And those compile times! A pretty well-suited language for game coding, actually.

And in terms of writing production code, libraries may or may not be a barrier. Basically, Pascal's current ecosystem exists in the shadow of one of the best RAD environments of the 90's - Delphi. That's where a lot of the code got written, and there's a definite focus on native desktop apps that remains. There are certainly good libraries available, but many are old, Delphi-centric, and lack polish - haphazard accumulations from developers that are very "get-er-done" and unconcerned about reuse. You can always bind C code, of course, but today it's easy to end up saying, "well, but I could just get a working library in (Go/Python/Node/etc) and be done" and thus end your Pascal journey before it starts.

It would be interesting to compare compilation speeds with Delphi. On a 2020 laptop I7 9900) with 16 GB of ram, I can compile a 1.3 million LOC Delphi program in 11 seconds. That's the 32-bit XE7, the 64-bit takes typically 25 seconds.

There are some of us who still work in Delphi. (Yes I know its not Freepascal)

I am aware of a Belgian company whose most software that they deliver is still done in Delphi.

Also here in Germany there is still a big enough community to warrant having Delphi conferences and articles in all major magazines that are language neutral, like Windows Developer one.

Most of the Nordic ski industry runs on software written in Delphi: property management, cabin rentals, equipment, scheduling of classes and private lessons; the whole thing.

I spent 13 years developing and maintaining that system, around 2-3 MLOC at the time I left.

I found Delphi awesome in many ways but too enterprisey and too far removed from reality in others. Every few years a new technology would appear to replace the previous half baked attempt at solving the same problem, or dropped completely and replaced by third party components. Long term I found the software very frustrating to work with since everything about it was so volatile and there were so many random gaps in quality and functionality.

Their database, Interbase, was pretty good; and well integrated into the language/IDE. Open sourced and forked as Firebird SQL at one point.

I've been working through the Advent of Code, doing it all in Lazarus/Free Pascal... the main limitation I've hit so far is in working out the logic, some of the puzzles are tricky. https://github.com/mikewarot/Advent_of_Code_in_Pascal

[Edit] One of the nice things about pascal strings, and variable parameters, is that you can write functions like

getinteger(var s : string):integer;

Which literally pulls a sign plus digits from s, skipping spaces, until it hits a space, comma, etc... s gets shorter, you get the integer, and it just works.

I don't think that type of thing is even possible in C because of null terminated unmanaged strings.

For "out" variables, you can increase the indirection and pass a char** (pointer to a pointer) to the method as the argument.

Then the pointed-at pointer can be manipulated within the method body and changes will be visible on the outside as well, giving you both the numeric return value as well as the shortened string as the output. This is what the second argument of the strto{d,f,ld} function does: https://devdocs.io/c/string/byte/strtof

I appreciate that in C pointers are the coin of the realm, I really do appreciate not having to deal all the time, stuff just works.

[Edit] For example, you can also insert into a string, making it longer, without having to worry about it.

However, such pointers are unsafe, since someone could pass an invalid or null pointer

var/out variables are much safer, since the variable exists at the calling site , is valid and not null.

It is also much safer than C++'s & references. It is very subtle, but rather amazing if you think about it. Because C++ can return a & reference, it can return a reference to a value on the stack frame of the callee, which then becomes invalid. But the var/out variable always exists on caller's site, so it is always safe.

(at least if it a reference to the stack. a reference to the heap could be freed indirectly through another reference. )

I am not a heavyweight C++ user (also a very lightweight C and a, uhm... featherweight Pascal user), but I'd think using a C++ reference as a method argument should be as safe as Pascal's var parameters.

Is returning references frequently done in C++? I have only seen it in ostream's << operator-like constructs where you want to chain multiple calls to the same object.

Not necessarily, although it is seldom seen I the wild, you can cast a null pointer into a reference.

Another source of issues might be the creation of temporaries.

Yes, in index operator as well.

>Is returning references frequently done in C++?

It is rather common to avoid copying returned objects. (perhaps it becomes less common with std::move ?)

For example, the [] operator on the standard collections returns a reference, so the item can be modified

There Pascal has another clever idea. You can overload [] for reading and writing separately. Then x[k] := v becomes x.setItem(k, v)

Maybe

  int getint(const char **s) {
    int res = 0;
    for (; **s && isspace(**s); (*s)++);
    for (; **s && isdigit(**s); (*s)++)
      res = 10 * res + **s - '0';
    return res;
  }
Here's the same code in pascal.

    function getnum(var s : string):integer;
    var
      c : char;
      value : integer;
    begin
      value := 0;
      while (length(s) <> 0) and NOT(s[1] in ['0'..'9']) do
        delete(s,1,1);
      while (length(s) <> 0) and (s[1] in ['0'..'9']) do
      begin
        value := value * 10 + (ord(s[1])-ord('0'));
        delete(s,1,1);
      end;
      getnum := value;
    end;
And that would be faster than the Pascal version

But it is unsafe. Someone might mistype * * s as *s and then bad things happen.

Pascal strings are basically memory safe. With range checking enabled, you can write whatever and it can only access characters in the string.

Ofc, then people disable the range checking in release builds to make it faster

However, you should not actually do that, because changing s reallocates it, so you get O(n^2) runtime

Should be like, getinteger(const s : string; var startPos: sizeint):integer;

Pascal always has the best possible ideas, and then fucks up the implementation.

> However, you should not actually do that, because changing s reallocates it, so you get O(n^2) runtime

Confirmed by experiment.

Parsing 1,2,...1000 string 1000 times 0.355 seconds

Parsing 1,2,....10000 string 1000 times 42.835 seconds

A given string might have 1-10 parameters in it, so the actual execution time isn't going to be that bad. I always think in terms of those 10 Mhz 286s, and how much faster it is these days. ;-)

Obviously, if I were reading Gigabytes of text, I might optimize a bit.

For Windows users, just use chocolatey and run: `choco install lazarus`

...and you'll be up and running with (1) FreePascal compiler (2) Lazarus IDE (https://lazarus-ide.org) with integrated debugger and RAD (Rapid Application Development) GUI designer.

Lazarus and FPC can create high-quality native GUI's for macOS, Linux, and Windows. And many open-source 3rd party GUI components can be installed right from within the Lazarus IDE via the "Package" > "Online Package Manager" menu option.

I've been using Delphi and/or Lazarus + FPC for 15 years. It's truly the most productive way to build a GUI desktop application, and makes it extremely easy to build powerful console apps.

A sore point for me in .NET, given that Anders was on the team, was the lack of proper AOT compilation (NGEN did not really cut it), Delphi style.

We had to wait until Windows 8 to properly get it, and still its being rebooted due to the way WinRT went, whereas it could bave been there since v1.0.

https://github.com/dotnet/designs/blob/main/accepted/2020/fo...

Sometimes I need to create a small GUI application for my Windows colleagues. Using Qt or .NET I get huge binaries/dependencies. What is the final binary size (all deps included) with your solution for a "hello world" GUI exe?
This was written a few years ago with FPC v2.2 (latest is FPC v3.2), but generally matches my experience: https://wiki.freepascal.org/Size_Matters#Analysis_of_various...

tl;dr is that if you create a RELEASE build, should be about 2 - 5mb for a GUI app, depending on the platform. And if you run `upx` against the resulting binary, it will be even smaller.

  Win 7 x64:  
  ------------  
  - 12.3 mb == Default build      
  -  3.2 mb == Default build without debug info
  -  2.1 mb == Optimized compiler
  -  2.1 mb == Optimized compiler without debug info
  
  Ubuntu x64:  
  ------------  
  - 13.4 mb == Default build     
  -  7.5 mb == Default build without debug info
  -  4.4 mb == Optimized compiler
  -  2.7 mb == Optimized compiler without debug info
Optimized compiler means:

    1. Project|Compiler Options|Code|Smart Linkable (-CX) -> Checked
    2. Project|Compiler Options|Linking|Debugging| Uncheck all except `Strip Symbols From Executable (-Xs) -> Checked`Strip Symbols From Executable (-Xs) -> Checked
    3. Project|Compiler Options|Linking|Link Style|Link Smart (-XX) -> Checked
    4. (Optional) Project|Compiler Options|Code|Optimizations|smaller rather than faster -> Checked (Warning: this might decrease performance)
I get 2.1 MB win32 and 6.9 MB Ubuntu x64 with fpc 3.2

Which is rather bad. I used to use Delphi 4 and it would create 350 KB programs by default.

Which was also bad, so I sometimes used that Delphi without the GUI designer and without the VCL, using the win32 API directly, to create 50 KB programs. That is a reasonable software size. Software keeps getting worse every year

How do third party GUI components work? Are they custom drawn? And how does that work with the various supported toolkit backends of Lazarus?
It has bindings for practically everything (Win32 UI, GTK, GTk2, GTK3, QT, OSX) and also you can custom drae yours.
Do you have any references to good examples of console apps built with FreePascal?
Console apps? For the terminal?

The strength of Lazarus was creating Windows GUI apps not console apps..

But I made a console app with it: http://www.videlibri.de/xidel.html

A query language for HTML, XML, and JSON

Yeah I know it sounded weird but I'm not really that interested in GUI apps but I am interested in different languages. Nice project page by the way. Thanks for the link.
(comment deleted)
It's truly the most productive way to build a GUI desktop application, and makes it extremely easy to build powerful console apps.

How does the experience compare to C#, .NET Core, and Visual Studio?

Very closely.

The original architect of Turbo Pascal is Anders Hejlsberg (https://en.wikipedia.org/wiki/Anders_Hejlsberg), who also was recruited to Microsoft directly by Bill Gates.

Anders went on to architect J++, the .NET Framework and C#, and TypeScript.

C# is heavily influenced by Turbo Pascal / Delphi because they have the same original architect. And Lazarus + FPC are open-source implementations of the Delphi 7 IDE + Object-Pascal language (same as Delphi).

If you are at home in Visual Studio, using Lazarus will feel very familiar.

Object-Pascal is easy to learn. A great site to bookmark when learning Delphi or Lazarus + FPC is: http://www.delphibasics.co.uk/

I remember Pascal from highschool. It's a pretty good language, hard to believe it's 50 years old already. I remember how impressive it was that multiple different implementations existed, not just the the famous one from Borland, Turbo Pascal, but also the fact that it was implemented on 8 bit computers.

It's a real language. Skype for Windows was originally written in the Delphi dialect.

If you are doing any native Windows development and also need to interact with a lot of COM objects and apis it's really hard to beat Delphi. It's so much nicer than dealing with C++ and WTL.
Agree++

The "WMI Delphi Code Creator" (written in Delphi) is a great example of this.

"The WMI Delphi Code Creator (WDCC), allows you to generate Object Pascal, Oxygene, C++ and C# code to access the WMI (Windows Management Instrumentation) classes, events and methods. Also includes a set of tools to explorer and Query the content of the WMI."

Note that Object Pascal == Delphi == FreePascal (generally)

https://github.com/RRUZ/wmi-delphi-code-creator

Also a note that the original Object Pascal was created for Mac OS, before Borland took up the term and Apple's extensions.
Saw this quote in Wikipedia, I find it amusing:

"Bill Gates saw the success of Turbo Pascal "in very personal terms, and 'couldn't understand why [Microsoft's] stuff was so slow. He would bring in Greg Whitten [programming director of Microsoft languages] and yell at him for half an hour.' He couldn't understand why Kahn had been able to beat an established competitor like Microsoft.""

I came across a copy of QuickPascal for $19.99 from Surplus Software and used that for a while because my version of Turbo Pascal was old (2.0) and am the current one was $69.99, a lot of money since I was just a kid.
Something that has boggled my mind everytime I tried out Freepascal is its link time. This is something that I feel tends to get glanced over in Nim or D circles.

Both advertise fast compilation, and they do compile quickly, but my experience with even 5-10k loc projects with those languages start to see some time sunk into the linker, even with Gold. This will inevitably lead to the change-execute cycle taking 1-3 seconds, while I have had no issue with substantially larger fpc code bases compiling and running in milliseconds.

For Rust and C++ devs a change-execute cycle sub 10 seconds is incredibly enticing. However, fpc has ruined me for what fast compilation really means. It also makes me really wish Nim had stuck to fpc as a backend.

I know very little about what is actually going on behind the scenes here. If anyone has any info about pascals compilation as well as linkers in general I would love to know more.

It's funny you should say that, because to me FPC feels very slow. Delphi got me spoiled. Especially the older versions build (quite literally) in a blink.
I'm not sure if it's good form to reply to yourself here, but I did find this: https://lwn.net/Articles/276782/. It appears to be a 20 part series from a(the?) Gold developer on Linkers.

I checked HN and it looks like there is an old discussion here: https://news.ycombinator.com/item?id=9597406

So, I'll probably give this a read when I find time. Hopefully someone else will find it useful as well.

Compiling an echo "hello world" module in Nim from scratch to a fully linked executable can be under 200 milliseconds on modern hardware with the TinyC/tcc backend. tcc has its own assembler and ELF linker built in to get that speed. I don't know much about fpc/free Pascal, but maybe it also does very little optimization of generated code and has its own assembler/linker. It think these are the Big Three things for a fast compile.

To get a fast edit/compile/test workflow I just set up my default backend to be tcc and automatically switch to gcc if "-d:release" or "-d:danger" is given on the compile line { really I abbreviate that to "-d:r" :-) } This makes it easy to develop quickly and then switch right over to quick timing tests.

Nim also has an interpreter whose startup is more like 100 ms, but which is limited to only what its virtual machine target (also used for compile-time computation) supports.

This is the main reason why Go compilation times, while very welcomed, fail to impress me.

Turbo Pascal has spoiled me in 1990's hardware.

FreePascal 3.2 released!

Would have been a better title

Sure, that happened months ago, but there was no announcement thread on HN. It is sad. So many programming languages get an announcement thread, but FPC is forgotten all the time.

edit: actually there was such a thread. I just missed it. But it had no comments