Hacker Newsnew | past | comments | ask | show | jobs | submit | Peter5's commentslogin

fpcupdeluxe is great if you want to get a particular revision or build cross-compiling. If you need a stable version, just download the setup from. The docked IDE is the default option for this version.


2.5 MB is for most of the Lazarus Component Library (LCL) with minimal size increases even as program complexity grows. For example, Dadroit JSON Viewer EXE is less than 6 MB while having complicated tree views, JSON handling, networking, and more. By the way, an empty CLI EXE on Windows is less than 50KB.


Why doesn't the linker strip out unused code?


I imagine it's for the same reason Delphi can't strip much, which is that it supports run-time reflection. You can create an instance of a class using a string of the name.

Forms (windows) are deserialized during loading, which relies on this mechanism.


Yes. Try the IDE itself; on Windows it is built with Win API. PeaZip is a sample of it https://github.com/peazip/PeaZip


Ok, using WinAPI means it is not easily theme-able, unless they provide custom set of controls. I assume it is possible to use Qt back-end for Windows as well. I wish Lazarus also supported C++ akin to C++Builder. Pascal is a deal-breaker many.


Custom control set is supported too, and there are multiple alternatives.



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:

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.


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.


Strings and arrays are memory safe with automated reference counting

And they have bounds checking, which makes it almost impossible to get buffer overflows

There is an FPC-LLVM variant. Then it uses LLVM to do all the optimizations


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 ;-)

[1] https://www.pcorner.com/list/PASCAL/TASKER4.ZIP/TASKER.PAS/


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


> as long as you follow very simple convention with TObject.Create() and TObject.Free; you won't have memory safety problems

Is this the same as how in C, as long as you follow very simple convention with malloc() and free() you won't have memory safety problems?


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.

I am working towards this in https://github.com/planetis-m/cowstrings


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.


So, it's closer to C++ wrt safety, not Go or Rust.


That is accurate, yes. Borland C++ and Delphi share the same component library and are interoperable.


Should add the freepascal community is much more forgiving of noobs and generally well behaved (trolls dont like quiche I guess!)


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.


I would jump back to fpc/lazarus after twenty years if devexpress supported it.


100%. My projects are DevExpress heavy.


This website, is a collection of cool samples and sources. Check https://www.getlazarus.org/learn/tutorials/examples/ for many cool projects and the author has many nice projects including https://github.com/sysrpl/Tiny.Sim


Everything (Instant file search): https://www.voidtools.com/


does search on windows still suck? Also Listary


A good compiler is much more than just speed, but it is good to have more information on compilers speed, and there is a lot about decedents of C. Maybe some appreciate the speed of Delphi, the son of Pascal. For a more real world scenario, this video is good too: https://www.youtube.com/watch?v=9S7fM_kAmjE


I searched for it and couldn't find a match. I chose the code instead of the document, as the repository links to the paper too, and almost always, code is more welcome than a paper.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: