zoukankan      html  css  js  c++  java
  • free pascal

    工具: lazarus, codetyphon, fpcupdeluxe

    大提纲

    https://dubst3pp4.github.io/post/2017-10-03-why-i-use-object-pascal/#fn:3

    学习完成
    https://wiki.freepascal.org/Basic_Pascal_Tutorial

    正在学习, 4.4 节
    https://castle-engine.io/modern_pascal_introduction.html

    https://www.davidghoyle.co.uk/WordPress/?page_id=1327

    https://files-cdn.cnblogs.com/files/stevenlaz/Lazarus_ZeosDBO_FireBird%E5%BC%80%E5%8F%91%E8%80%85%E6%8C%87%E5%8D%97Ver5.pdf

    待学习:
    https://www.tutorialspoint.com/pascal/pascal_classes.htm
    https://synopse.info/files/html/Synopse%20mORMot%20Framework%20SAD%201.18.html#TITL_114

    https://stackoverflow.com/questions/44848371/is-free-pascal-a-programming-language-by-itself-or-just-a-compiler-supporting


    语法简单实用: 没有那些看起来很炫的语法糖, 一切都很直接, 一切都很直白.

    语法稳定: 1969年就开始的编程语言, 语法稳定,  命名空间, 泛型, Unicode

    语法罗嗦: 相比与C和JVM家族的语言, Delphi 语法看起来很罗嗦, 但代码易读性更强.

    You can try delphi-rest-client-api
    Original project
    https://github.com/fabriciocolombo/delphi-rest-client-api
    Lazarus fork
    https://github.com/esvignolo/delphi-rest-client-api


    https://stackoverflow.com/questions/29374336/passing-value-of-json-data-to-free-pascal-variable

    https://forum.lazarus.freepascal.org/index.php/topic,10125.0.html

    https://github.com/fabriciocolombo/delphi-rest-client-api

      client: fphttpclient, fpjson, jsonparser;
     
      server: fphttpapp, httpdefs, httproute, fpjson;

    ============

    Hacker News new | past | comments | ask | show | jobs | submit login
      Modern Object Pascal Introduction for Programmers (newpascal.org)
      130 points by eatonphil 3 months ago | hide | past | favorite | 71 comments



    In my experience Free Pascal, that is what the article refers to as "modern pascal", is a great language and compiler. It compiles to native code, to JVM bytecode, and there is even a tool to transpile to Javascript.

    Unfortunately it suffers from a stigma inherited from it's origins as an old "teaching you how to code" language rather than a real language. Never mind the fact that Delphi (the precursor to "modern pascal") was the brain child of Anders Hejlsberg before he was snatched from Borland by Microsoft, when Anders had remade Turbo Pascal (already great) into a fantastic product. Bill Gates said "The only thing wrong with Delphi is that it's not made by Microsoft".

    In short, Free Pascal a fantastic multi platform language and compiler, but suffers from a lack of popularity due to being considered something old and not very modern, even though it has all the modern features one might need.


    As an IDE, Freepascal does seem dated, not including many details that we've gotten used to in recent decades.

    The language itself feels also frozen in the early 00's, have a look at string handling for instance. Very verbose methods, and a problem that's true for the Freepascal dialect in general: small incompatibilities with Delphi Pascal, the dialect any old veteran will be used to and as such also much documentation/discussion online. Add to that a near invisibily in places like Github, and it does not make for a very attractive platform, compared to some others. Freepascal/Lazarus has a nice forum, and if you happen to be working in the same niches as other guests, that may be enough, but otherwise... I also couldn't help but notice that the practices passing around zipped code bases/fragments is alive and well on there, mirroring the culture of small but closed source tools the Delphi ecosystem was famous for around 2000. While friendly, very dated and 'source hidden' in its ways.


    The textmode IDE is largely a fallback for platforms that Lazarus doesn't support yet, pretty much everyone nowadays uses Lazarus which is very featureful (and very fast, IMO it puts pretty much other IDE to shame considering the functionality it has and its responsiveness and resource requirements).

    Verbose methods are a convention that you'll find in other languages too (e.g. Java and C# and also some C++ projects).

    What is the issue with string handling?

    Free Pascal has several language modes, one of them being Delphi which should be compatible enough to share and port code between the the two compilers (though the default mode in Lazarus is ObjFPC which is different and IMO the better mode). In practice the differences are small enough that unless they refer to very internal stuff (e.g. memory layout of RTTI data), anything you find online about Delphi also applies to Free Pascal (assuming of course that FPC has implemented the functionality, but since you refer to old veterans, i think everything those veterans and old discussions will be there).

    I'm not sure what you mean with passing around zipped codebases, there are a ton of projects on GitHub. And how can a codebase be 'source hidden' when it is available as a zip?


    I did mean Lazarus. Just the text editor component feels alien. Things like block selection by default. It just doesn't work the same as any other text edit component I've ever used.

    The issue with string handling is (or was) that there seem to be different string types but that 'string' is used to describe all of them. Some of those methods require or produce ASCII, and it may be difficult to know what your problem is when you have one

    The language modes suffer from incomplete support. The differences aren't large,but that does mean they re easy to fix. My previous employer, a Delphi shop for more than 2 decades, was unable to be compatible with Freepascal over some of these issues.

    With limited source I mean that things like history will not be there, or its just a single file of part of a single file bundled up, so you're missing out on context. All makes it hard for a newbie, even for someone with some experience.


    Agreed. Lazarus is one of the prime reasons that my journey back to Pascal stopped. To say it's dated is rather understated in my opinion.

    Step 1. A one window IDE please! (Even Gimp finally moved in that direction after years and years of pleading from the community).


    I prefer the multiwindow IDE myself, but you can make Lazarus single windowed. To do that go Packages -> Install/Uninstall Packages -> find the "anchordockingdsgn" package and install it (Lazarus is quite modular and packages can alter the IDE) by hitting the "Save and rebuild IDE" button. Note that this will have the form designer still as a floating window, if you want it to also be inside the IDE also install the "sparta_dockedformeditor".

    These aren't very obvious (in another comment i wrote that Lazarus can feel a bit messy and unpolished... this is one of the reasons i think that :-P) though and IMO it should be something that you get asked when you run Lazarus for the first time.


    > Step 1. A one window IDE please!

    Done. Here you go: https://www.getlazarus.org/


    That link doesn't open.
     

    > I did mean Lazarus. Just the text editor component feels alien. Things like block selection by default. It just doesn't work the same as any other text edit component I've ever used.

    Are you sure you didn't configure it like that or something was broken? Lazarus' text editor behaves pretty much like every other text editor i've used on Windows, be it native (Notepad) or custom (Scintilla via Notepad++). Block selection only happens when you alt+click+drag (like in Notepad++ and several other editors), by default it should work the same way as any other modern editor (ie. shift+arrows should expand the selection which happens character-wise and select lines by expanding up/down - or just using the mouse to select...).

    > The issue with string handling is (or was) that there seem to be different string types but that 'string' is used to describe all of them. Some of those methods require or produce ASCII, and it may be difficult to know what your problem is when you have one

    As of version 3.0, plain 'String' is an alias for a mode-specific string type. For the default mode (FPC) it is 'ShortString' (the classic Turbo Pascal string), though the default mode is rarely used and only exists for backwards compatibility. When creating new projects and units, Lazarus uses the 'ObjFPC' mode, where 'String' maps to 'AnsiString' with a system-specific default codepage that you can optionally change. Note that LCL (via the LazUtils unit) does that to ensure UTF-8 on all platforms, so if you use Lazarus and LCL you can assume that 'String' means UTF-8 string. In 'Delphi' mode 'String' behaves like in 'ObjFPC' mode whereas in 'DelphiUnicode' it maps to 'UnicodeString' (which is really UTF-16 string, the name is for historical reasons).

    For all practical purposes, with Lazarus and LCL you can simply use 'string' which will give you UTF-8 strings. If needed, the compiler will do any conversions for you, though most of the library has been extended to avoid any conversions. Older string stuff still exist for backwards compatibility, but you'll get warnings if you use them (the warnings will also usually tell you what to replace them with).

    Note that this is new functionality introduced in Free Pascal 3.0 ~5 years ago. It is a bit more complicated than ideal, but AFAIK it was necessary to avoid breaking existing code - keep in mind that Free Pascal exists since the 90s and some people use code in it they wrote in Turbo Pascal / Delphi before FPK even started writing his compiler. Personally i only had to change a single type declaration (where i was using a string as a byte buffer - i replaced it with 'RawByteString' which is... well, a string of raw bytes :-P) in my code (which i wrote ages ago) after switching to FPC 3.0.

    > The differences aren't large,but that does mean they re easy to fix. My previous employer, a Delphi shop for more than 2 decades, was unable to be compatible with Freepascal over some of these issues.

    Makes sense but this isn't really Free Pascal's fault IMO, after all it is a single sided endeavor (FPC developers are trying to be compatible with Delphi but Delphi developers do not seem to have any such interest). If you need compatibility it should be something that you write your code with in mind and use functionality that exists in all the Object Pascal dialects you want to target.

    > With limited source I mean that things like history will not be there, or its just a single file of part of a single file bundled up, so you're missing out on context. All makes it hard for a newbie, even for someone with some experience.

    You wrote 'hidden source' not limited :-P. I'm not sure where history helps if you are not a developer of the project. In any case not everyone is on or likes GitHub or even interested in collaborative projects. Personally i use Fossil on my own PC and only release .zip extracts of my code (though the .zip extract does contain the change log at least). But i'm not interested in collaborative projects either :-P.


    I started to learn Delphi/Pascal yesterday and didn't like the IDEs either (I'm used to VIM keybinds, better autocompletions and automatic indentation). But VSCode has a plugin for Delphi/Pascal that seems to work fine for console programs. I guess that if you need to develop a GUI app you'll still need Lazarus/Embarcadero IDE for the visual frontend of the app.
     

    "..remade Turbo Pascal..." - translation: C#. Yup, that's right, C# is a clone of Delphi and then some.

    Anyone knowing Pascal will have no problem jumping to C# because it will swim in familiar waters, only difference is that being a Microsoft product has C style syntax.


    Well you have said what I always think. For those familiar C# feels like the next iteration of Delphi, but with curly braces. Both Delphi and Free Pascal haven't stopped though. They've added generics, extension methods, attributes, and many of the other features that have also been added onto C#.

    Free Pascal has gone further to add management operators, vector math intrinsics, and improved array features.


    Delphi has those too, and with latest iteration (read May 2020) they added inline variable declaration (which on Free Pascal will raise a syntax error)
     

    Note that inline variable declaration had been discussed at the past by the Free Pascal developers and was rejected by most of them - this is a (rare) case where they decided that they wont follow Delphi. Reasons, IIRC, are mainly due to how weird the syntax is and it feels too un-Pascal-ish to have mixed declarations and code (in Pascal pretty much everything is declared in its own section) and with Pascal supporting nested functions/procedures and the IDE being able to autocomplete variable declarations for you, it is more of a code smell than something necessary.
     

    From what I've read/understood, the reason Delphi folks decided to do this is to allow even better compiler optimization. This way it's easier for optimizer to see the local variable needs to be a CPU registry and no memory access, speeding its performance.
     

    Hm, i guess this depends on the compiler, but if that was the case then first use should be enough to figure out this. I guess classic Delphi had a very simple compiler so perhaps it needs this, but AFAIK modern Delphi has an LLVM backend whose optimizations shouldn't be affected by variable placement.

    In any case, i think Free Pascal does have variable lifetime analysis so its optimizations shouldn't need that either.


    > with curly braces

    ...and .NET in tow.


    Early .NET also copied liberally from VCL. The entire System.Windows.Forms namespace, with base classes like Component and Control, feels very familiar to anybody who made GUI apps in Delphi before.
     

    Yeah, FPC can target an absurd collection of systems; can C# handle that level of portability?
     

    Only in the same way as Java can (run the .NET VM) and the GUI story is far less clear.
     

    Is this some inside joke that I am not getting? C# is nothing like Pascal. Java is the language closest to C#.
     

    One person, Anders Hejlsberg, was a leading architect on Delphi and then on C#

    His work on C# is widely thought to be a continuation of his work on Delphi.

    https://en.wikipedia.org/wiki/Anders_Hejlsberg


    There's also plenty of other cross-pollination, e.g. the influence that Cedar or even Modula-3 had on Java.

    Still, I can understand the issues. Let's not forget that despite his work in the field, Hejlsberg isn't Mr. Pascal, that would be Niklaus Wirth. Who always had a way more minimalistic design perspective than others, starting with Algol-W and ending with Oberon-7. Comparing that to the kitchen sink approach of C# (and arguably even Object Pascal) shows two philosophies that can hardly be more different.


    I also prefer the minimalist approach to language design and even though I like Pascal, the modern incarnation of the language in FreePascal is simply too large. I feel the same about many popular languages. Perhaps it's inevitable as developers demand more features and the language accrues more features with each release. Even languages that start small(ish) over time grow to be quite large (e.g. Python).
     

    > I also prefer the minimalist approach to language design and even though I like Pascal, the modern incarnation of the language in FreePascal is simply too large.

    Then don't look at c# version 9. There's an expressive and modern (immutable and null safe by default) language somewhere in there struggling under the weight of previous syntax and semantics.


    > the kitchen sink approach of C# (and arguably even Object Pascal)

    When Free Pascal is concerned there is no argument here... consider that the compiler has a special language "submode" that enables syntax just for interfacing with Cocoa/Objective-C objects (...or even the whole idea behind having different language modes and submodes in the first place - that is totally antithetical to Wirth's ideas, but in practice it is very useful).


    I think that Delphi took a bit of a "kitchen sink" approach when compared to classic Pascal, for practical reasons of being most useful to a working programmer, rather than being academic.

    Specifically the infamous yet influential essay "Why Pascal is Not My Favorite Programming Language" has a laundry list of reasons why academic Pascal is hard to use "for serious programming", and many of them have been corrected in Delphi.


    Many of them were already corrected in ISO Extended Pascal, UCSD Pascal and Apple's Object Pascal, before Borland happened.
     

    His work on C# was a continuation on his work on J++ actually.
     

    Anyone knowing pascal will have made the jump to C# in 2006, everyone left are quite happy with Pascal, nobodies going to make the jump in 2020 IMHO
     

    First he did J++, though.
     

    Actually he decided to go to Microsoft after being disillusioned how things were going at Borland.

    Also what people keep forgetting, J++ was actually what he first did after joining Microsoft.


    One thing i find interesting about J++ (i have Visual J++ that came with VS6, though i never used it myself - and i do not think it even works in modern Windows) is that it also had its own relatively big framework that pretty much died with the language. It is like this language was made, existed for one or two versions and then the entire effort was thrown out of the window.
     

    IIRC parts of that framework were the basis for .NET libraries, e.g. WFC -> System.Drawing / WinForms. Just compare the class names:

    https://docs.microsoft.com/en-us/previous-versions/visualstu...

    https://docs.microsoft.com/en-us/dotnet/api/system.windows.f...

    https://docs.microsoft.com/en-us/dotnet/api/system.drawing


    They couldn't have done otherwise given Sun's lawsuit.

    If you read Ext-VOS paper and the history of F#, that was how the upcoming COM Runtime was rebooted to use a managed language runtime.

    Hence why when one knows all these puzzle pieces, UWP seems so close to what they were trying out back then.


    Since I cannot edit it any longer, here is one of the podcasts where he mentions it (first episode).

    https://www.microsoft.com/en-us/behind-the-tech


    Seems Pascal is having a field day today. Makes this old Pascal fan happy! The other piece is about Castle Game engine, written by the same author, Michalis Kamburelis.

    About the only issue I'd take with this piece, and it's minor, is that it's slightly modified from the original and pushes the use of Delphi mode over the default ObjFPC mode in the Free Pascal compiler. To see the original:

    https://castle-engine.io/modern_pascal_introduction.html

    While there's nothing wrong with preferring Delphi mode or ObjFPC mode, since the differences between them aren't that great [1], a piece that aims to describe the language should at least offer some rationale for a preference that is urged so strongly on readers.

    But otherwise this is an excellent piece for anyone wondering what Pascal looks like in 2020.

    [1] https://www.freepascal.org/docs-html/prog/progap4.html#progs...


    Alright, sooo... Pascal kind of seems like the holy land of "get shit done" that isn't C or C/C++. At least as far as cross platform UI development goes that isn't _electron_.

    How is it maintaining a Object Pascal project in 2020? What are it's weak points? Anyone have some examples of "modern" apps written in Object Pascal or problem spaces it's still vastly better than the competition? Are there any like magical libraries, frameworks, or patterns?


    The main magical part is largely Lazarus and LCL for desktop application development. The slightly less magical part is that the language has many features that you often find in languages targeting a VM but instead it generates native executables (pure Free Pascal executables can be less than 50KB) with no mandatory external dependencies outside what comes with the OS. It also target a ton of platforms.

    But TBH outside of GUI development there isn't anything particularly special about Free Pascal that you wont find in any other language, especially if you do not care about requiring a VM (in which case something like C# will probably be the closest equivalent).

    One thing that it has though and personally i find it very important when it comes to maintenance is that the developers care a lot about backwards compatibility - existing code you wrote even 20 years ago will keep working either as-is or with very minor changes. Personally two issues i remember having were in one case when character encoding aware strings were introduced, i was treating a string as a byte buffer (prior to that change they were basically byte buffers) so i had to change a declaration from using "String" to use "RawByteString" (which behaves as a byte buffer) - that was a single line change. The other change was when at some point some years ago (i think it was when Delphi-compatible generics were introduced) the ClassName of a specialized generic class changed format.

    One issue Free Pascal and Lazarus have is that sometimes they feel a bit "messy" and unorganized or unpolished. But they are projects that are 100% community driven by many people, going back decades (especially FPC) so i guess that is to be expected, especially when they do not want to break people's code in pursuit of some ideal purity.


    Main thing holding me back is very small online community, most is using Delphi Pascal, not Freepascal, on very corporate and closed source projects, usually old codebases thus no new nice features, and those nice new features are often different between Freepascal and Delphi. So if you manage to get to see someone's code, it may be using features not implemented in or coded in modern Freepascal. And old Delphi Pascal suffers from similar things as 90ies C or C++: it skips modern features and uses a style that is contrary to what people now learn, expect or even enforce.

    Also, there are a few incompatibilities/differences in stdlib between Delphi and Freepascal, and it was very easy for me to run into them.


    > And old Delphi Pascal suffers from similar things as 90ies C or C++: it skips modern features and uses a style that is contrary to what people now learn, expect or even enforce.

    Eh, even Delphi 1 has a lot more features than modern C and while there are new features added in Free Pascal over the years, the old stuff never got outdated or obsolete the same way that (theoretically) nobody writes C++98 (though in practice many do anyway, but they do it at night, hidden from all eyes :-P). Pretty much all Delphi-like Object Pascal compilers (Delphi itself, Free Pascal, Oxygen and i think a couple of others) use Delphi 7 as a common denominator and the main thing missing from Delphi 7 as a language is support for generics (but it still has a few collection classes).

    If you read a book about even, say, Delphi 3, most of it (outside the Borland-specific database stuff) will be valid in Lazarus. You'll just miss some additional features modern Free Pascal and Lazarus provides, but the older stuff aren't really obsolete or invalidated (this is also a neat thing about Free Pascal and Lazarus - the time you invest in learning them won't be wasted because the developers decided that now they'll try to do the same stuff but in a different way).


    I meant, from a modern day perspective of the respective languages.

    Oh and people write old dialects, the old Delphi geezers at the previous workplace also wrote pre C++98 C++, today. Impressive isn't it ;) Bigco's are all about decades old code bases.


    Right, that is what i meant too. You are more likely to find today people not using C++98 in their new C++ codebases than you are to find people not using Free Pascal 0.99-era code in their new Free Pascal codebases - largely because there haven't been any dramatic changes in the language over the years that require changing how you work with it. When you get new stuff they enable new features, but rarely things change in how they work - at most you get more conveniences (e.g. you can use a for-each loop in iterators instead of a manual for I:=0 to iterator.count - 1 do..., but that is just a convenience, it doesn't change anything).
     

    As a 20+ years Pascal/Delphi lover, this read is too much for beginners. I had no problem going through it in one go, but it did felt a lot of energy was spent even by me. Maybe it's better to be split in chapters, giving a potential inquiry mind time to breath.

    And yes, I do realize it has a left ToC. So maybe instead of one big document with a lot of inline anchors, should be made separate files. Or perhaps both, giving readers the opportunity to choose whichever they like.


    > Or perhaps both, giving readers the opportunity to choose whichever they like.

    Yeah, good old texinfo-style entirely-on-one-page and one-page-per-node model (as seen on the documentation page of any GNU project, e.g. https://www.gnu.org/software/texinfo/manual/texinfo/) is heavily underrated and underutilized in “modern” documentation systems.

    Want to quickly search for something in the entire manual? Use the one page version. Want to read cover to cover or link to a specific topic? Use the split up version.

    Btw, this book is apparently written in AsciiDoc and generated by Asciidoctor. There seems to be a multi-page plugin available, although I haven’t tried it myself.

    https://github.com/owenh000/asciidoctor-multipage

    https://github.com/asciidoctor/asciidoctor/issues/626


    The first time I've played around with Borland Delphi was I think 99-00 and it was good experience. Then moved on and kind of forgot it. Last weekend I thought to look if Delphi still alive, found out that it's now owned by Embarcadero, downloaded their latest architect edition trial (they have community edition now too) and was surprised how easy it is to write cross platform apps. Stuff which I've remembered from ~1999 - still works the same way, and you can have Android, Windows, iOS, Linux GUI apps on the same codebase in one go.

    It's just pleasure to work with. If only Embarcadero modified their licencing terms, e.g not charging ~5k for Architect edition and did some marketing they could win over some space in software development world. Something like Microsoft did with Linux and Open Source world when they changed their view on it.

    Even if you don't plan to use it, it's worth a try, just to see how joyful and easy it can be to write cross platform apps. It also somehow reminds me Smalltalk/Pharo experience in some ways.


    Pascal was the first language I played around with after Amiga era BASIC. I still don't really understand why it faded into relative obscurity. To this day, I feel like it's close to a perfect language. It's fast, it's productive. It's not a "safe" language, but its design from very beginning steered you away from danger.

    With Lazarus, it is probably the most pain free way to write GUI apps.

    But more than anything else, it is so, so readable. This is often expressed as criticism: it's verbose. But that verbosity is absolutely a small price to pay for code that is often shockingly easy to understand.


    I "grew up on" Object Pascal as a developer — first Turbo Pascal, then Borland Pascal (for DOS and Windows), then Delphi, up until the early 2000s.

    Back then, I wrote GUI apps and commercial games, but I also did a lot of non-GUI development in Delphi, using technologies like COM, MAPI, etc. While Delphi itself wasn't "meant" for non-GUI development, it was still a very nice experience. The interactive debugger was fantastic, as it always was in Borland's tools.

    Nowadays, I don't see room for Object Pascal. While later versions of Delphi have improved on the syntax (e.g. generics), it's still a fairly old-fashioned language. It doesn't really have anything special to offer someone who already knows C#, Go, Rust, Java, Nim, etc. There's a strong Object Pascal influence on both Go and Nim, and those languages improve on it in every way, including the size of the communities, the available libraries, and so on.

    Delphi's killer app used to be GUI development on Windows, but these days you need to target multiple platforms, and I'm not a believer in cross-platform GUI toolkits; you end up with something that doesn't look great on any platform.

    I look at Object Pascal with a lot of fondness, but it's mostly nostalgia.


    Nice. While I suppose Pascal did suffer a bit from its "learning language" beginnings, it was wildly popular as Delphi.

    If only Anders/Borland had designed Delphi as a VM, similar to the JVM. Of course he did that for MS with J++ (and then C#), but had Borland done it first with Delphi, would MS still have squashed them? Probably.

    As for the Introduction posted here, Nice! Well written and densely informative. Refreshing to see some focus on Pascal.

    One feature I'd like to see borrowed in other languages: Class references. In my experience this feature would be extremely useful for code generators, say in Java. For instance, you get virtual static methods and constructors. Man, that would be nice.


    >*"If only Anders/Borland had designed Delphi as a VM."

    That would've been enough reason for me not to use it. Targeting whatever VM as yet another platform to compile to would be fine I think. It was actually done for Java and .NET but hardly used. I guess it has no benefits compared to native.


    "By default FPC programs and libraries do not use the C library on most platforms" (1) is what makes Free Pascal potentially interesting on Linuxes: sometimes the dependencies that exist when producing the binary using C or C++ simply disappear if one could write a Free Pascal program.

    I haven't been able to use it in the environment I worked recently, but I had to waste so much time on the C and C++ library dependencies, different on different systems. Free Pascal seems to be a possible solution to that.

    --------------

    1) https://wiki.freepascal.org/libc_library


    Using libc on Linux shouldn't introduce any incompatibilities (also you can use libc with Free Pascal, e.g. when using threads you link against the pthreads library which in turn needs libc and you can use libc's memory management functions instead of Free Pascal's own functions which can be faster), at least as far as glibc is concerned, since they are supposed to be backwards compatible. For example I have binaries compiled on 1998 Red Hat and linked against libc and libX11 working on two decades later distros just fine.

    It is usually the libraries you use on top of libc and libX11 that tend to break and introduce incompatibilities.

    C++ is another topic though, but i think there is an effort nowadays to avoid breaking that too.


    > I have binaries compiled on 1998 Red Hat and linked against libc and libX11 working on two decades later distros just fine.

    The goal was avoiding to use "1998 Red Hat" to compile today something that should work on a few years old system. That is the direction that is typically broken with C and C++, to the point that only safe approach is, indeed, to use 1998 Red Hat. But using 1998 Red Hat forces you to use the very old compilers and old anything else on that same Red Hat, which is what could be very inconvenient in 2020, when one has to use other tools with newer features in the process. If I understand, I can use 2020 OS and using Free Pascal trivially produce binaries that would work on the older systems on which the C and C++ binaries produced on the 2020 OS just wouldn't.

    Edit, answer to the post below:

    > i'm not sure if you link against libc if it'll generate versioned symbols

    If I understand correctly, one can produce Linux binaries with Free Pascal while depending only on Free Pascal's libraries which don't have libc dependencies at all. And that is what I see as a huge potential to produce the binaries that don't break on older Linux version, the way libc-linked typically do not because Linux kernel is incompatible, since it isn't, but just because GNU libc infrastructure allowing only "build on older Os for newer" but not at all the opposite scenario.


    Yeah i was mainly referring to backwards compatibility.

    And yes, AFAIK you can do that with Free Pascal, but i'm not sure if you link against libc if it'll generate versioned symbols (which cause the issue you mention) or not. I think it doesn't because you can crosscompile from Windows (or other OSes) to Linux so it shouldn't need any OS-specific dependencies. However it shouldn't be much of an issue even if it does since you can run the latest version of Free Pascal even on very old Linux distributions.


    There are many cases where binaries compiled on older systems will not work on newer, despite no differences in APIs - this is due to Glibc going for "versioned symbols" instead of versioning ABI.

    And of course there are cases, especially if you have C++ somewhere, where you have to bring not just glibc but also ld.so from the ancient system... (There's a big chunk of such libs packaged together to run Loki games ports on recent distros)


    At least in my experience this has never been an issue with C programs (or C++ programs after getting the older C++ stdlib). I have a collection of old Linux game demos from late 90s and early 2000s and i tried them a couple of years ago in a modern distro and most of them worked (i had to use the oss-to-alsa bridge though). The games that didn't work were because of missing libraries that the distro didn't include, like -IIRC- Shogo needing Qt1.

    Note that glibc also has non-versioned symbols. Versioning was introduced much later than the binaries i've mentioned i compiled with 1998 Red Hat were made. In addition the reason behind versioned symbols is to be backwards compatible so older binaries not working on newer systems because of versioned symbols would defeat the entire point of them existing in the first place.


    > I have a collection of old Linux game demos from late 90s and early 2000s and i tried them a couple of years ago in a modern distro

    Let me point again: I started the thread describing the opposite scenario:

    Developing a program and delivering the binaries to the clients, including those who installed the OS on their server farms 10 years ago and not upgrading them, and who expect the binaries to "just work" there too.

    That's why Red Hat and "Long Term Support" concepts exists: so that companies don't have to spend more time chasing the latest and greatest and totally irrelevant newest version of everything.

    One wants to be able to deliver the products to them too, and avoid developing only on these old system, working around the bugs that were solved years ago.

    The resulting binaries should just use what is available in kernel, and that's it. It's a real problem and it should be recognized.


    Well, as i wrote in the other reply i think this should work in FPC.
     

    Yes, versioning was introduced much later.

    Which results in funky situations where 22 year old binaries run, but a binary that is less than 4 year old can't - because unless you do extra work, you will get versioned symbols linked and you might be unlucky enough to fall out of the window of supported versions quicker than you think (Happened to me ~2013 when dealing with GHC at university, made for some really annoying weekend fixing binaries around)


    There is very little that can be done with C-style syntax that can't be done with Pascal-style (or Oberon-style) syntax.

    I find the Pascal-style syntax to be easier to read. I also like that Pascal has always had enumerated types and ranges. I'm neutral on nested scope, but I think it could be occasionally useful.

    After using C-like languages for so many years it is a little jarring to see function calls without parentheses, but I think I like those as well.


    Related HN thread of interest (IMO):

    Delphi – why won't it die? (2013)

    https://news.ycombinator.com/item?id=7613543

    It is about:

    http://stevepeacocke.blogspot.com/2013/05/delphi-why-wont-it...


    > 5.1. Remember to free the class instances

    > The class instances have to be manually freed, otherwise you get memory leaks.

    This was the most annoying part back in the Turbo Pascal days, I am surprised it is still there. I'd think with all the changes (generics, etc..) they could have added a smart pointer class?


    I am not very familiar with Free Pascal. Does it have coroutines ? Modula2 does but there aren't that many free and maintained implementations around. There is of course GNU's Modula, but it wasn't very easy to install.
     

    fpc has no coroutines. Delphi has them. In fpc, You can declare a procedure or function within another, but that's about it. Authors are skeptical of its utility.

    https://forum.lazarus.freepascal.org/index.php?topic=45818.4...


    You are confusing coroutines with anonymous functions / lambdas.
     

    Wow, silly me I misread that thanks for the correction sorry gp. Yes, it has coroutines in the sense that you can queue functions to be run as soon as the event queue is drained, so that it looks like your UI is responsive, but they probably won't be able to run concurrently unless said event loop runs on a separate thread which I don't think it does correct me if I'm wrong.
     

    Coroutines do not really run concurrently unless you yield explicitly or call functions that do async io (those yield automatically).

    The main reason it is directly available in languages like Go is that they are meant for building servers that do lots of network/file interactions and very little actual calculations. In this pattern coroutine looks rather natural and your code is not riddled with endless explicit yields. As soon as you step out of that pattern coroutines became headache where once must constantly watch and make sure that the interval between yields is not too big and they do not block each other.

    In my opinion coroutines are an artificial construct that is very specific to the OS (Windows has fibers for example) and one can argue that it belongs to some standard library rather than first order language construct.

    Well Delphi is guilty in this department as well. It has direct language support for automation services on Windows for example.


    > In my opinion coroutines are an artificial construct that is very specific to the OS

    Coroutines are very convenient outside of OS too. Pipeline of operations, alternative to event loops, agents in a game, ETL all seem (to me) a lot more natural with coroutines than say with OOP. In some languages one has to resort to (preemptive) OS threads for these. Those end up being very heavy weight.


    100+ points for this waste of time and piece of crap and dont even get me started on their game engine
     

    I would agree that state of game engines/libraries in Delphi/FreePascal is far from ideal. Pasvulkan on github might be possible exception as it is done very professionally but is also very opinionated.

    As for the subject itself you seem to be overreacting. Delphi and FreePascal/Lazarus are very decent tools.


    I literally went over the entire thing and tried to find anything which is adding value and did not find any. As of now I see this project as novelty or a hobby project. You are free to think that I am overreacting but a piece of crap will be called a piece of crap specially if it's getting hyped for no good reason.
     


     

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

    Search:
    ============

    Topic: Problem Casting String/pWideChar with {$MODE DelphiUnicode}  (Read 1809 times)

    kevin.black

    • Full Member
    • ***
    • Posts: 122
    Problem Casting String/pWideChar with {$MODE DelphiUnicode}
    « on: March 19, 2019, 11:51:19 pm »
    Hi all,

    I thought I posted this, but maybe I wrote it and forgot to post. Apologies if you find the other one :o

    Firstly I need to do this because:

    It's Delphi to FPC and now Strings are Unicode strings and pChars are actually pWideChars
    It's in a DYLIB that is used by C/C++ so the only parameters to be safe, are integer, boolean and pWideChar
    The C++ calling routine uses Char IIRC which maps to pWideChar

    So again, not being narked. but don't need any questions like 'why?', it just is.

    I have looked at the posts and Wiki and what I am doing 'should' work. I'm trying to be as compatible with the current (10.3.xx) version of Delphi which is what I am converting from. So here's the theory, strings are unicode string  type therefore setting x: string means x is a unicode string and and if I have a Edit then the text Edit.Text is also a string ergo it should be a unicode string (see {$MODE DelphiUnicode}).

    My issue:
    • I have set the compiler directive {$MODE DELPHIUNICODE}
    • Stings are AFAICT unicode strings
    • I thought I could just cast a unicode String to a pWideChar
    Code: Pascal  [Select][+]
    1. var
    2.   loginemail: pWideChar;
    3. ...
    4. ...
    5. WriteLog('DEBUG', 'Unicode String checkUserStatusEmailEdit.Text: ' + checkUserStatusEmailEdit.Text); // shows gobbledygook
    6. loginemail := pWideChar(checkUserStatusEmailEdit.Text);                                              // loginemail is pWideChar    xxx.Text is Unicode (Wide) string
    7. WriteLog('DEBUG', 'pWideChar Loginemail: ' + loginemail);                                            // has been cast to pWideChar and is crap
    8. WriteLog('DEBUG', 'Unicode String Loginemail: ' + string(loginemail));
    9.  


    And noting that string 'should' be a unicode string as should the TEdit of checkUserStatusEmailEdit.Text (just an input field). This is what I get:

    Code: Pascal  [Select][+]
    1. [2019-03-19 11:45:23] DEBUG [EMPServerTest] Unicode String checkUserStatusEmailEdit.Text: dbid:AAD4_bi4MP1qQDCvIciNh3x-9sa3bciOtRA
    2. [2019-03-19 11:45:26] DEBUG [EMPServerTest] pWideChar Loginemail: 扤摩䄺䑁弴楢䴴ㅐ共䍄䥶楣桎砳㤭慳戳楣瑏䅒栀䔮偍敓畣敲
    3. [2019-03-19 11:45:27] DEBUG [EMPServerTest] Unicode String Loginemail: 扤摩䄺䑁弴楢䴴ㅐ共䍄䥶楣桎砳㤭慳戳楣瑏䅒栀䔮偍敓畣敲
    4.  
    BUT if I do this (I simply copy checkUserStatusEmailEdit.Text to a string variable (LE)) everything is goodness:
       
    Code: Pascal  [Select][+]
    1. var
    2.   loginemail: pWideChar;
    3.   LE: string;
    4. ...
    5. ...
    6. WriteLog('DEBUG', 'Unicode String checkUserStatusEmailEdit.Text: ' + checkUserStatusEmailEdit.Text); // shows gobbledygook
    7. LE := checkUserStatusEmailEdit.Text;
    8. Loginemail := pWideChar(LE);
    9. WriteLog('DEBUG', 'pWideChar Loginemail: ' + loginemail);                                            // has been cast to pWideChar and is crap
    10. WriteLog('DEBUG', 'Unicode String Loginemail: ' + string(loginemail));
    11.  


    I get this (perfectly):

    Code: Pascal  [Select][+]
    1. [2019-03-19 11:43:09] DEBUG [EMPServerTest] Unicode String checkUserStatusEmailEdit.Text: dbid:AAD4_bi4MP1qQDCvIciNh3x-9sa3bciOtRA
    2. [2019-03-19 11:43:11] DEBUG [EMPServerTest] pWideChar Loginemail: dbid:AAD4_bi4MP1qQDCvIciNh3x-9sa3bciOtRA
    3. [2019-03-19 11:43:12] DEBUG [EMPServerTest] Unicode String Loginemail: dbid:AAD4_bi4MP1qQDCvIciNh3x-9sa3bciOtRA
    4.  
    So my question (in several parts):

    If I have {$MODE DelphiUnicode} does that ONLY apply to type 'string' and NOT to the result of say any component, ie a TEdit text like Edit.text IS AN ANSISTRING OR A WIDESTRING, but not a Unicode string (I understand Widestring and Unicodestring are not the same)?

    And is that because the TEDIT has not been built with {$MODE DelphiUnicode} (clutching at straws here)?

    And could I build the IDE with etc with {$MODE DelphiUnicode}?

    Thanks
     

    engkin

    • Hero Member
    • *****
    • Posts: 2513
    Re: Problem Casting String/pWideChar with {$MODE DelphiUnicode}
    « Reply #1 on: March 20, 2019, 08:11:22 am »
    1-{$mode DelphiUnicode} affects only the unit it is being used in.

    2-TEdit.Text is of type TCaption. TCaption is AnsiString because the unit holds its declaration has {$mode objfpc}{$H+}

    3-LCL (and its TEdit), as is today, expects String to be UTF8. For instance GetSelText:
    Code: Pascal  [Select][+]
    1. function TCustomEdit.GetSelText : string;
    2. begin
    3.   Result := UTF8Copy(Text, SelStart + 1, SelLength)
    4. end;

    4-RTL is planned to support UTF16. AFAIK it is not there yet, not 100%.
     

    PascalDragon

    • Hero Member
    • *****
    • Posts: 2295
    • Compiler Developer
    Re: Problem Casting String/pWideChar with {$MODE DelphiUnicode}
    « Reply #2 on: March 20, 2019, 09:46:35 am »
    It's Delphi to FPC and now Strings are Unicode strings and pChars are actually pWideChars
    It's in a DYLIB that is used by C/C++ so the only parameters to be safe, are integer, boolean and pWideChar
    The C++ calling routine uses Char IIRC which maps to pWideChar
    You should really check the declaration of the C++ code. The base types are char for single byte characters and wchar_t for multibyte characters, though in the C++ world wchar_t might be for UTF-32 characters, not UTF-16 ones as FPC's/Delphi's WideChar (e.g. on every non-Windows system). If the C++ code uses some other type you should check what base types it matches to.

    If I have {$MODE DelphiUnicode} does that ONLY apply to type 'string' and NOT to the result of say any component, ie a TEdit text like Edit.text IS AN ANSISTRING OR A WIDESTRING, but not a Unicode string (I understand Widestring and Unicodestring are not the same)?
    Correct. Compiled code is not influenced by modeswitches in another unit.

    And is that because the TEDIT has not been built with {$MODE DelphiUnicode} (clutching at straws here)?
    Correct.

    And could I build the IDE with etc with {$MODE DelphiUnicode}?
    I doubt it. The LCL is currently geared towards UTF-8, checking for UTF-16 will probably only be done once FPC also begins to switch targets to UTF-16.

    Long story short: assign the Text property of the edit to a UnicodeString variable (or use a typecast) and then cast that to PWideChar (just as you did in your example).
     

    kevin.black

    • Full Member
    • ***
    • Posts: 122
    Re: Problem Casting String/pWideChar with {$MODE DelphiUnicode}
    « Reply #3 on: March 20, 2019, 11:21:39 pm »
    1-{$mode DelphiUnicode} affects only the unit it is being used in.
    Of course it does (BFO - Blinding Flash of the Obvious).

    2-TEdit.Text is of type TCaption. TCaption is AnsiString because the unit holds its declaration has {$mode objfpc}{$H+}
    As above, and a BFO....

    3-LCL (and its TEdit), as is today, expects String to be UTF8.
    OK, I get that now.

    4-RTL is planned to support UTF16. AFAIK it is not there yet, not 100%.
    I think that would be good. And had I not been in the Delphi world converting code to FPC/Lazarus, it probably would not be an issue.

    You should really check the declaration of the C++ code. The base types are char for single byte characters and wchar_t for multibyte characters, though in the C++ world wchar_t might be for UTF-32 characters, not UTF-16 ones as FPC's/Delphi's WideChar (e.g. on every non-Windows system). If the C++ code uses some other type you should check what base types it matches to.
    I have, the C++ developer and I did a dance a number of years ago when he was C++ and I was Delphi. Delphi is Unicode/ pChar (pWideChar) so the C++ parameters he expects are pWideChar(TChar in his speak), integers and booleans. if a pChar is necessary as in pAnsiChar it is explicitly called out.

    I doubt it. The LCL is currently geared towards UTF-8, checking for UTF-16 will probably only be done once FPC also begins to switch targets to UTF-16.
    Yes, I suspect that's pretty solid advice.

    Long story short: assign the Text property of the edit to a UnicodeString variable (or use a typecast) and then cast that to PWideChar (just as you did in your example).
    Yes, absolutely agree. I think (sic) I was overthinking the whole exercise. Yours and engikin's  advice now make it quite clear. At least my strings will be unicode in the unit where I use the {$MODE DELPHIUNICODE} which reduces the pain significantly.

    Thanks guys, clear in my head now.
    « Last Edit: March 20, 2019, 11:31:47 pm by kevin.black »
     
  • 相关阅读:
    OpenJudge 6042 雇佣兵
    POJ 1741 树上 点的 分治
    Codevs 1695 Windows2013
    复制书稿
    乘积最大
    编辑距离问题
    石子合并
    最大正方形子矩阵
    选菜
    混合背包
  • 原文地址:https://www.cnblogs.com/harrychinese/p/free_pascal.html
Copyright © 2011-2022 走看看