- FP is an interesting language. In my opinion, it is somewhat problematic that different language concepts (Delphi, etc.) have been more or less merged into FP, resulting in redundant object models, for example. Pascal as a language also has various historical legacy issues (dangling else, block overhead, global namespace, etc.), which Wirth corrected in Modula and Oberon. The compiler is huge and apparently difficult to maintain (see e.g. https://github.com/rochus-keller/freepascal/). The resulting, optimized x86 code achieves about 70% of GCC compiled C code (see e.g. https://forum.lazarus.freepascal.org/index.php?topic=64261.0), and it turned out that desctructors and some built-in data structures are extremely slow. So I went on to implement my own Pascal/Oberon descendant (see https://github.com/rochus-keller/micron/, work in progress).
- > In my opinion, it is somewhat problematic that different language concepts (Delphi, etc.) have been more or less merged into FP, resulting in redundant object models, for example.
That was not an FP invention, though. Delphi already did it - they kept the Apple's Object Pascal constructs from Turbo Pascal, and then bolted a whole new object system in parallel. FP inherited that mess and has to maintain it for backwards compatibility reasons. That said, given that the two systems are completely orthogonal, you can simply ignore the older one.
The biggest thing going in favor of FP is that it has been around for almost 30 years now, so it's very mature.
- > it has been around for almost 30 years now, so it's very mature.
The compiler is insanely large and complex, more than the sum of the implemented languages would suggest. I can't imagine that anyone still has a complete understanding of it. See e.g. https://github.com/rochus-keller/FreePascal/blob/master/Read....
- Also corrected in Ada: https://annexi-strayline.com/blog/posts/1
- Thanks! I will check it out
- If you consider Go as a low level language, you might want to try C# which can be as low level as Go while having a lot of high level features. NativeAOT compiler allows you to statically link native libraries or create native shared libraries (.dll/.dylib/.so) that can be consumed from other languages. It's kind of 2-in-1 language, but the ecosystem is primarily focused on the high level part, so you can only depend on small portion of it.
If you are OK with less popular languages you can check any of these: Nim, Hylo (formely Val), Vale, D, or Zig.
I haven't tried any of these yet, but they all have piqued my interest. Nim is probably the easiest one.
- You can get very low-level in C# but at the point you start using unsafe the nature of the language changes very suddenly.
Unsafe C# is the most unsafe language I've ever worked with. Really terrifying stuff.
- Fortunately, there have been a lot of improvements to low-level C# since v7 that make unsafe unnecessary in a lot of situations. E.g. ref structs, ref local variables, ref returns, stackalloc improvements etc.
There's an interesting comparison of these C# features with Rust: https://em-tg.github.io/csborrow/
- Recently created a smart card reading n writing tool for internal use.
Manipulating bits with c# was very pleasant. Building the UI was incredibly quick and easy.
Can recommend.
- Would also recommend. We've integrated many different hardware devices with an app, and the process has consistently been very straightforward.
- Patriots of Pascal language family are expected to prefer Oxygene over C#
- Last time I checked, NativeAOT was only for console apps, i.e. didn't support any GUI frameworks.
- Avalonia and Uno both support NativeAOT:
- I was even able to statically link native dependencies during NativeAOT compilation of Avalonia app to produce a single binary. It's not the default mode for AOT compiled Avalonia, but it's possible.
ImGui.Forms is another one that supports NativeAOT.
- I've been using it for a while. The string handling is magic compared to that of C/C++ with pointers and nulls and the constant need to allocate and free memory to get things done.
The only downside is the documentation. Listing the parameters of a function and not explaining the purpose of the function, or what those parameters actually mean, is not proper documentation.
Borland set a fairly high bar with the Turbo Pascal 3 manual.
- I see Free Pascal mentioned quite often on HN, so I suspect many are. I recently attended a Delphi conference where several people were using Free Pascal, including one session presenter.
I've also been using Oxygene, which is a different Object Pascal dialect. (This started because I have begun working with RemObjects - I have to admit, I have wondered why I never used it earlier.) It had design decisions to evolve it more like newer languages (eg it has inbuilt async/await and did on .Net before C#, tuples, nullables etc) and sanitised the syntax somewhat. I like it a lot. https://www.remobjects.com/elements/oxygene/language
- Pascal is not a low level language - quite the opposite. That being said, various implementations provide low level facilities, including turbo pascal back in the days , and free pascal which I did use in the early 2000s.
If I were you, if you like fpc, I’d actually look into Ada ( the OO part is a bit odd granted but works ). You’ll get extremely high control over low level stuff ( it’s used in the embedded world ) along with high expressivity and excellent performance.
- > Pascal is not a low level language - quite the opposite.
Why do you say that?
Back in the 80s and early 90s it was the primary competitor to C, and in an alternate universe we might have ended up using Pascal decedents instead of C decedents.
For example the original Mac Toolbox was first written in Pascal: https://apple.fandom.com/wiki/Macintosh_Toolbox
The original Mac API were all native Pascal: https://wiki.freepascal.org/Basic_Pascal_Tutorial/History
- I learned to program in VAX Pascal, and didn't learn VAX C until later. I always found Pascal more intuitive, especially for string handling than C, and combined with the VAX/VMS System library and Runtime Libraries was able to build quite complex systems in Pascal. I found out later, after I joined DEC, that VAX Pascal was a popular Systems Programming language for a while.
- You are wrong, Pascal has always allowed pure raw pointer and data manipulation as well as self memory management, the strong type enforcement and auto management for some types (strings, dynamic arrays) is just on the surface so you don't shoot yourself in the foot but it never stops you from doing any low level programming.
- The problem with Ada is tooling other than the compiler. Last I checked, GnatStudio still doesn't work well on Apple Silicon, for example, and VSCode support was decidedly meh.
With Free Pascal, though, you get a TUI IDE working basically everywhere, plus Lazarus across all major desktop platforms.
- In what way is the OO part a bit odd?
- The way you express it is different from most other languages I’ve come across. It doesn’t make it bad in any way ( I’ve written Ada professionally), just unusual. Basically Ada already provides natively substantial capabilities relative to encapsulation, modularities, generics etc but in a procedural context. The designers bolted on OO facilities on top of said existing mechanisms.
While it may look reasonably clean in the link below, I’ve always found it integrates badly with an existing codebase, the primary problem being that the ‘boundaries’ of the objects are not clearly visible.
https://learn.adacore.com/courses/Ada_For_The_CPP_Java_Devel...
I will add that the existing non oo features are excellent and I would even argue that in many cases you don’t need OO.
- Thanks.
>I will add that the existing non oo features are excellent and I would even argue that in many cases you don’t need OO.
Somewhat the same in Python, because of the built-in data structures such as lists, dicts and sets, and the ability to compose them.
- Yes, I still use FreePascal for utilities, libraries and console apps. I write these in Lazarus on Linux, and run them on local machines or (for some console apps) on our Intel Synology NAS. It's nice knowing I can easily recompile for other operating systems if I need to.
For some tasks FreePascal is quite clunky, but the lower level the task, the quicker it is to write a solution.
- Not me personally, but I just finished playing a retro FPS set in 1980s Czechoslovakia whose game engine is written in Pascal: https://store.steampowered.com/app/824600/HROT/
- Checkout Nim! Despite its Python like syntax it inherits concepts from Pascal.
- If you like go, modern pascal is basically that with less curly braces. The other way around is true, too.
There’s zero technical reasons to not use pascal. Popularity, library availability, programmer availability and LLM quality of responses may be, but the technical foundation is there and has been for at least a decade (if not since turbo pascal from early nineties.)
- An important reason against Pascal is the tiny community. It's so easy to cobble things together because there's a huge package base, or even just projects on Git forges. Also, to the extent people put their Pascal packages up, I have found them often dated, and written in outdated Pascal styles (a lot of manual Freeing for instance, another project's functions never return anything but ask for an output structure as last function parameter). Kinda hard to see what a nice and modern codebase looks like.
- I was so disappointed with Go. Pascal, Delphi and Ada are the roads not taken.
- One of the languages taught in high school in South Africa is Object Pascal (via Borland Delphi), so this is actually the first programming language I learned.
I think Object Pascal is quite a nice language, it feels like OO without a whole bunch of messy package protected Java nonsense.
- Not as my primary language, but I wrote two or three small command-line tools for my own use in recent years. Cross-compilation and platform support is excellent, so it is convenient for writing something once to run on multiple systems as just a static binary without having to mess with installing any dependencies on the target systems.
Sticking to very basic, procedural, non-OO, Pascal though. At its core Free Pascal, like early Turbo Pascal, is very small and simple, even compared to C, and there is value in that, especially since it is also a whole lot safer than C (but still has things like pointers and inline ASM when you need that).
- I've been enjoying writing a Gameboy emulator in Odin - it interfaces nicely with C libraries (I've been using SDL and its been much easier to set up than with C++)
Tooling it a bit lacking, but the language is simple enough you can get away with using a semi-broken LSP.
The language feels light and expressive, and has generally gotten out of my way - the only thing I've been really craving is closures.
You might not like it because it has errors as return values like Rust/Go, however there are some directives/macros/keywords such as `or_return` which work a lot like `?` in Rust.
- Ada is more serious than Pascal. There is Ada-to-C(++) translator called AdaMagic. It is limited to Ada 95, but Ada was ahead of time and so 95 is fine. On most platforms GCC is available, and Ada is the most interesting language in GCC, but just in case there is AdaMagic.
- The paper "C is not a low level language as we are not programming a PDP11" (something like that anyway) made a good point that C is only fast on a multi core machine because c fans work hard at keeping the laurel. What does a low level language look like when you have 8 cores? Conversely what would a high level language look like for (low level) verilog and FPGAs?
- The referred paper C isn't a low level language - your computer isn't a fast PDP11[1] was not really addressing multicore parallelism. It was discussing instruction-level parallelism, which is done within an execution thread and is achieved by speculative and out-of-order execution of instructions that do not have sequential dependency on previous instructions.
- The article does go into cache coherency which is very much intertwined with multicore parallellism:
> The cache coherency protocol is one of the hardest parts of a modern CPU to make both fast and correct. Most of the complexity involved comes from supporting a language in which data is expected to be both shared and mutable as a matter of course.
I feel like we live in a world where everyone works very hard to pretend that C is our best low-level language, when in reality an APL-like purely functional array language would be a better candidate.
- Fair enough, though I still think even there the headspace of the author was more in line with proving single-threaded C virtual machine model does not map to how CPU actually behaves, not that a natively parallel language would be best suited to model a contemporary multicore or data parallel processor.
- APL? Sure, but CSP perhaps? ... I am going to have to think about a FPGA implementation of APL... perhaps..
- Out of curiosity, where were your pain points with Go regarding lack of classes? Go offers types, methods & interfaces, that gets you pretty far while avoiding inheritance. I found it pretty reasonable and not limiting (coming from a background with C/C++/Java then years of python).
- After so many years as a Java dev my brain thinks in classes so not having classes or exceptions made it a constant struggle. Nothing against Go, more about me.
- Interesting fact: lately I've been benchmarking few things around and I have found out that the same algorithms in JavaScript tend to outperform C in O0.
Why does that relate to your post? Because if you're going lower level for performance you may actually find your assumptions to not hold true unless a good compiler optimization phase is involved.
- The OP made their reasons clear and performance wasn't part of it.
- I hope Swift gets more cross-platform love, including GUI toolkits.
- I do!
I love it so much, it has a great balance between: readability, fast write/compile/debug cycle and great performance.
On tip: LLM is God send for it. So many times I find what I was looking for written in some other language and the LLM does the conversion.
- Check out Lazarus IDE, it's really good, especially for beginnerd.
- [dead]
- [flagged]
- Real men don't eat quiche.