[HN Gopher] Why Use Pascal? ___________________________________________________________________ Why Use Pascal? Author : mariuz Score : 176 points Date : 2023-07-08 17:54 UTC (5 hours ago) (HTM) web link (castle-engine.io) (TXT) w3m dump (castle-engine.io) | badsectoracula wrote: | I'm using Free Pascal for my 3D game engine (recent-ish | screenshot[0]). For me there is really two main simple reasons: | | 1. Lazarus. A game engine is -waaay- more than just a 3D engine | with the tools being a very important aspect. Lazarus and LCL | provide a rich and well featured WYSIWYG RAD IDE and framework | for making desktop applications. As a bonus Lazarus as an IDE | (even ignoring the LCL framework) is very fast. | | 2. The language is decent and i know it. This is important | because i'm not interested in learning a new language or | framework or whatever while also making the engine, i want to | focus on one thing. Also i have a lot of code written over the | years to cherry pick (i started the project in 2020 but some of | the code goes back to 2007-2008). And finally it has a strong | aversion to breaking existing code - there is a culture of | preserving backwards compatibility. | | Free Pascal is far from perfect though and TBH i'm annoyed by | some of its constraints - some of them being quite pointless too | IMO. For example the language has three ways to create compound | types: records, objects and classes. They are _almost_ all | identical, except each one of them has limitations that isn 't | found in others, e.g.: | | 1. Records. They are like C structs. With "advanced records" | language submode (enabled more functionality in a backwards | compatibility preserving manner) they can also have methods, | properties and "management operators" allowing the compiler to | insert calls when things enter or exit the scope (so you can e.g. | implement smart pointers, RAII or whatever). However they do not | have any form of inheritance or virtual functions. They are value | types and as such can be put in the stack, heap and their can be | part of another compound type. | | 2. Objects. They are basically records with inheritance and | virtual functions, though they cannot have management operators | or some other record-only functionality like a variant section | (allowing, e.g. functionality similar to C unions). They are also | value types and can be put in stack, heap and/or be part of | another compound type. | | 3. Classes. They are objects with extra functionality, have extra | the bells and whistles like dynamic/message-based methods, a | published section that expose properties and attributes via RTTI, | etc. However they are reference types - they can only be | allocated on the heap[1] and as such cannot be put in the stack | and cannot be part of another type (only references can be | stored). | | The thing is none of the above limitations have a technical | reason - especially those between objects and records. In fact in | the compiler source code all compound types are implemented with | mostly the same code with some specialization checks here and | there, it isn't like each of the above gets its own separate code | path. | | But this is far from the only limitation. Another is that there | is no way to expose a readonly view of an instance - something | like C/C++'s "const" - so you can't -e.g.- have a mutable | collection as a private field in a class that is exposed as an | immutable one directly, so the compiler knows it can generate | code for directly accessing the underlying field but not allowing | any modifications to it. The weirder - and misleading - aspect is | that the language _does_ have some ways of specifying readonly | views in some cases - specifically function parameters can use | "const" or "constref" (the latter ensures a value is passed by | reference, the former lets the compiler decide) which disallows | the value to be modified. However if an object is passed like | that you can still make method calls that mutate it even though | you cannot assign it to another value, which kinda makes the | whole thing feel only skin deep. | | On the topic of arbitrary limitations and types, there is also a | weird limitation on properties: you can have property getters | (and setters, but what i'll describe makes sense only for | getters) be either fields or functions. For the former the | compiler will generate code that'd be equivalent to accessing the | field directly, for the latter it'd be a function call. When you | define a property you also declare its type - but if you use a | field as a getter it must much the type _exactly_ , on the other | hand you can have a function that returns a field as another | type. This means that you cannot work around the "lack of const" | limitation for collections by making a base class collection that | only provides a readonly view and a subclass that allows mutation | and then expose the mutable instance as its immutable parent | class while letting the compiler generate code that access the | field directly - you _have_ to go through a function call and not | only the compiler is _very_ stupid at eliminating unnecessary | calls, this also changes the RTTI data if you want this to be | handled for -e.g.- serialization or via a GUI property editor. | | Also when it comes to RTTI which it is still better than what | you'd get via -e.g.- C++ (i.e. nothing), it has limitations like | only allowing primitive types (so if you have a class for a 3D | object and you want to expose its position to be edited via a | property editor that uses RTTI to figure out what to edit or to | have automatic serialization and deserialization you cannot | expose a "Position" property of a "Vector3D" type directly with | the RTTI specifying what that "Vector3D" means and instead you | have to specify separate "PositionX", "PositionY" and "PositionZ" | properties of "Single" type (which is a primitive type for 32bit | floats). You can still have a "Position" property of a "Vector3D" | outside of RTTI and you can still use a private field of | "Vector3D" to store the position and then use getters and setters | beneath the scenes to access the individual vector fields for the | "PositionX/Y/Z" properties. | | All of the above have the end results of using tons of -often | inefficient- boilerplate to work around language limitations that | in 99% of the cases have no reason to exist in the first place | (aside from nobody implementing them - which would be fine, it is | a free project, but the thing is the above are things the FPC | developers refused to acknowledge as problems - in fact i | personally tried to submit a patch that implemented the property | case). | | As an example, in my 3D game engine i have a "dynamic array" | generic (an incredibly common container you'd find in game | engines) that i want to be able to allocate on the stack, heap or | part of another object, i want it to separate allocation from | number of elements (the language itself has dynamic arrays but | they always allocate the same number of elements as the array has | which means when you insert items you do a lot of allocations and | deallocations - that not only fragments the heap but the FPC | memory manager isn't that fast in the first place) and of course | being able to automatically finalize (i.e. destroy) any managed | objects (e.g. a dynamic array of strings with string being copy- | on-write "smart" objects defined by the language itself). | | In order to get the "allocate on stack or part of object" i | couldn't use classes, only objects or records. Because i wanted | to expose it directly but without allowing mutation, i really | could only use objects since records to not support inheritance. | However objects do not support management operators so i'd have | to explicitly initialize and finalize the objects. So the | workaround there was to store the data in a separate type that is | a record with management operators and specify a single field in | the (immutable / readonly / base) object of that separate type so | that when the object goes out of scope or is finalized itself, | its contents are also finalized (remember that i mentioned how | this is an arbitrary limitation? The compiler already knows this | can happen and handles this, otherwise this workaround wouldn't | work!). And also because i cannot have the mutable field accessed | directly as its immutable/readonly base type, wherever i use it | and i want to expose it i have to use a method getter which | returns a _pointer_ to the underlying field (but as the immutable | type) - this is needed because otherwise the getter would return | a copy of it (remember these are value types). | | [0] https://i.imgur.com/zzIH4dl.png | | [1] (there are workarounds like using a proxy array with in-place | initialization but they are very bug prone so i ignore them as | they are not practical) | badsectoracula wrote: | (continued) | | These are some of the annoyances with Free Pascal as the | language, but there are others like how a unit (think module in | other languages) has an "initialization" and "finalization" | section that is executed on startup and shutdown respectively. | This is good and useful thing, however the problem is that the | initialization also has implicit code that zeroes out any | global memory in that unit. This means that if a unit A's | initialization code runs a function from unit B that accesses | some global in unit B but the initialization code in unit B | isn't called yet, any modification made by unit A calling that | method would be lost ending up with weird bugs. The order the | initialization code runs depends on the order the units are | used in a program but if there are circular dependencies this | order can be whatever the compiler encounters first. The | workaround for this is to make sure the _program_ (not any | unit) that you compile has in its "uses" section the units | that you don't want them to modify and make sure they do not | have any dependencies themselves. | | Found that the hard way because in my units the initialization | section contains RTTI registration calls that were later | clobbered by the RTTI registry unit somehow getting initialized | after some units that registered some types - this ended up | with some assets not being loaded in the engine because the | registry couldn't find the type of some serialized objects | (because these types happened to be registered before the | registry's own initialization code zeroed out its globals and | erased any registered types). | | The obvious fix would be for the global zeroing out to happen | before any initialization section code is executed (and that | only in systems which actually need it), but for whatever | reason FPC doesn't do that. | | On the positive side the compiler is relatively fast - it takes | about a couple of seconds to build the full engine + editor on | my (now 5 year old) PC. And while there are issues like i | mentioned above, the positives (which include the fast IDE, | rich framework - and also i had a much easier time when trying | to contributing to Lazarus - fast compiler... and the fact i | already have a lot of FP code and know the language) outweigh | the negatives. | | It isn't like there are many alternatives anyway, especially | when it comes to something like Lazarus (of which the only | potential alternative i can think of - which i haven't explored | much - is Qt Creator but i find Lazarus both the better IDE and | LCL easier to work with than Qt, not to mention how FPC is | _waaaaay_ faster than G++ or Clang++). | Rochus wrote: | What about performance, e.g. compared with C++? | badsectoracula wrote: | I never really had a problem with it, at least so far. | | Actually a few years ago i wrote a 3D game for DOS using Free | Pascal[0] (here is a review from a YouTuber[1]) and the | performance was decent, though i did write the rasterizer | inner loop in assembly (not that great assembly TBH but still | slightly better than what FPC generated). | | I did optimize it over time and expectedly, the biggest gains | weren't from microptimizations but from changing how | rendering works (e.g. i got a boost by adding a PVS and then | another by replacing the PVS with portals since the PVS | wasn't that great :-P and then yet another when i added mesh | occlusion culling using data from the previous frame). | | About the engine i linked at in my post, i also did a few | optimizations but again they weren't microoptimizations but | just algorithmic changes. I did write a profiler[2][3] a | couple of years ago that helped (the video shows it in | practice with the engine) but it uses some Windows-specific | functionality and i've switched to Linux since then. Perf | works fine under Linux with FPC, but FPWProf (my profiler) | has some useful functionality and i'd like to port it to | Linux at some point. | | [0] https://bad-sector.itch.io/post-apocalyptic-petra | | [1] https://www.youtube.com/watch?v=Lo7VlrYiTeE | | [2] https://www.youtube.com/watch?v=yF0wmN9J8Ts | | [3] http://runtimeterror.com/tools/fpwprof/ | dannymi wrote: | Your level editor looks awesome :) | applesan wrote: | Pascal and Logo Turtle are programming languages I learned at | school, but never used them outside of it. I hated them back | then. I don't know if this was teacher or language fault, but | these IT lessons couldn't be more boring and confusing. | oaiey wrote: | Teacher and kids not being focused. I learnt using Pascal and | it was perfect. | jes5199 wrote: | Pascal was one of my first languages and I love it for that, but | I can't imagine going back to it. It never had a modern ecosystem | and the OOP stuff was super janky | Lerc wrote: | I used to use Delphi/Pascal as my main language. In the last | decade or two I have been on a bit of a journey looking for a | language that feels right to me. I used Haxe for quite a while | but I felt Haxe fell into the trap of 'There's a Macro for that' | (Macros can do anything, but ultimately enough macros make | everyone programming in their own macro augmented language). | JavaScript developed decent improvements (but could still use | more) and I do a lot of stuff there now. | | A year or three ago I was writing some 8-bit AVR code and I gave | FreePascal another go. I found it extremely enjoyable. I got to | use the newer features and it felt like a truly modern language. | Part of what made it so enjoyable was that because I was coding | for a tiny space I was not using most of the standard library and | just building custom specific code as I went. This meant I did | not have the layers of backwards compatible namespace clutter | that FreePascal has accumulated over many years (TList, TFPList, | TFPGList, TFPGObjectList etc. My main pain point was that the | compiler did not allow constant floating point expressions on a | target without an FPU(or emulation). Since these could be done at | compile time it would have been nice. | | Having worked in other spaces, I do now find the inability to | define variables mid function to be restrictive, being able to | have sub-function scoping is nice too. Begin End vs { } doesn't | really bother me. I think I now prefer case sensitive languages | and would rather not have letter prefixes on types. I think this | is more due to the advancements in editors than anything. Syntax | highlighting and active linting can remove text clutter by moving | information into separate domains. | | I would probably be quite enthusiastic for a descendant language | of FreePascal that had a clean slate approach. A new standard | library that used the newest features as first class citizens. | Maybe when I retire I'll have a go at it. | zabzonk wrote: | > Begin End vs { } doesn't really bother me. | | but they don't really mean the same thing - {} defines a local | scope, begin...end doesn't. | oaiey wrote: | Depends a lot on the language does not it? | zabzonk wrote: | we are talking about pascal | [deleted] | dolmen wrote: | I see Go as a direct competitor to Pascal, in particular for all | the points mentioned in the article. | | But Go has a modern runtime (with garbage collection), a modern | ecosystem (with major libraries such as HTTP and TLS in stdlib) | and an active community. | oaiey wrote: | I do not. Co-routine thinking is more complex than imperative | coding regarding the teaching aspects. | | Java and more concrete C# are the one who took Pascal and | Delphi originally out of the game for day to day programming. | And Go is already so much more popular than Pascal for real | life work, that competition is a really the wrong word. | khaledh wrote: | My first project as a freshman in university was an elevator | simulator (with text graphics) in Pascal. I enjoyed the language, | there's something elegant about it when compared to C-like | languages. This is the reason I'm enjoying Nim nowadays, which | afaik is inspired by Wirthian languages (Pascal, Modula 3, | Oberon, Delphi), in addition to Ada and Python. | brd wrote: | I won't even bother clicking this click bait title. I learned | Pascal as a sophomore in high school and by my senior year I knew | I'd never touch it again. At the time it was a great introductory | language but there's very little reason anyone should even be | thinking about Pascal these days. | | Fun fact: I still have my old pascal files on floppy disks in a | box somewhere with a not so thin layer of dust on them. | oaiey wrote: | I still think it is brutal we let our industry rookies learn | complicated programming concepts in complicated languages like | Java, python, js or god forbid anything functional. | | I still think it is a huge mistake be Microsoft to let Basic | rot away and that our industry should focus teaching on | something like Pascal which does not stand in your way | dolmen wrote: | Same here. Including the fun fact. | snailtrail wrote: | </main> | maleldil wrote: | Does Pascal still require all variables to be declared at the | top? I did a quick search and that seems like the case, but I | want confirmation from someone that knows the language. | | If so, that's a immediate "no" for me. We know by now that | keeping variable declarations close to their usage is a big boost | in readability, and at times even in performance (you only | declare variables you actually use). | | I know Pascal has evolved a lot over time. If this is indeed | still a requirement, it's hard to understand why, and a barrier | to those used to scoping in "modern" languages (even C99 has | this). | badsectoracula wrote: | Delphi allows inline variable declaration but Free Pascal does | not (the developers explicitly decided against implementing | it). | | Note that in Pascal (FPC, Delphi, whatever) you can have nested | functions so this isn't that much of a limitation as it sounds. | For example if i have a procedure that is very long i often end | up splitting it in multiple nested procedures and each one has | its own variable section. | | Also from a more practical perspective Lazarus (the most common | FPC IDE) has a shortcut key to automatically insert variable | declarations so you don't have to move up and down in code even | if you have a large function body. I'd expect Delphi to have | something similar. | zabzonk wrote: | > Delphi allows inline variable declaration | | it may do so now, but for the longest time it didn't, which | made it compare poorly with C++ and even with C, which allows | definitions in a scope. in fact the OP concept of scope is a | bit crap - basically the whole function, | gaze wrote: | Seems a bit shallow. JavaScript equals is an abomination, which | to me seems like a larger issue, and people use it just fine. | maleldil wrote: | I agree that triple equals is an abomination. It's one of the | many things ensuring I use JavaScript as little as possible. | oh_my_goodness wrote: | In the future, if you ever create a teaching language, _please_ | point out clearly to the students that it 's a teaching language. | stevekemp wrote: | I'm finding myself using Pascal for fun these days due to | resource constraints. | | The old release of Borland's Turbo Pascal, version 3.00A, runs | under CP/M and provides an editor, compiler, and libraries all | under 64k. | | It's fast enough to use interactively, and produces code that is | good-enough to implement low-level utilities, simple games, and | other random hacks. | | I've not used Pascal on anything larger, or more modern, but I | have to say that my recent experience has been rewarding enough | that I wouldn't rule it out! | brightsize wrote: | Oh Pascal!, oh the nostalgia. I saved up the princely sum of | $80-$100 back in TRS-80 Model III days to buy the Pascal 80 | package, the New Classics version, which was basically a proto- | IDE, and a pretty sweet one at the time. | http://www.trs-80.org/pascal-80/ I recall it being a huge step | up from the M-III BASIC dev environment and the games and | utilities I wrote ran well enough in the 48K of RAM that was | available. I wonder what became of the Pascal-80 codebase? Not | that it would be any better than the modern tools available for | retro hardware, probably far worse. Oh yeah, "Oh Pascal!" was | the book from which I learned the language, and I doubt there | were many other options, as this predated Pascal's commercial | use by quite a few years. | netule wrote: | Turbo Pascal and later Delphi were the first time when a | programming language really spoke to me. Eventually, I went the | C and C++ route, but I've always had a desire to return to more | expressive languages. | | I had no idea that there was still a modern Pascal | implementation, so I may just have to get reacquainted with my | first love. | bluetomcat wrote: | I've also a had an early acquaintance with Borland TP 7.0 at | the time C99 was already around, and Pascal felt rather | clumsy in comparison. The strong typing, the lack of a | preprocessor, the verbosity in data declarations, the small | set of available libraries just made my early programming | self consider C superior. | baq wrote: | Nowadays you look at pascal and see go without braces. | fuzztester wrote: | Check out Free Pascal (FP) if you haven't already. It supports | many platforms. | | You can check on their site if it supports CP/M if you need | that. I would not be surprised if it did. | | The TUI IDE is very similar to Turbo Pascal, and lightning | fast. The language has a lot more (advanced) features than | Turbo Pascal, but you don't have to use them if you don't want | to. | | The generated binaries were also very small, similar to C, when | I did a quick test of it on Windows, some time ago. Under 50 or | 60 KB for a simple hello world program. | stevekemp wrote: | Sadly it seems not to be available for such systems. | | Though for reference compiling my sample "Hello World" script | on TP gives me a "hello.com" file which is 8320 bytes. 64k is | as much memory as I have on the machine, so if it were 50-60k | I'd be worried there would be no space left for anything | else! | fuzztester wrote: | Oh yeah, I realised that just after hitting submit. Had | worked on almost as low powered machines a while, much | earlier, as a hobby. Sorry for leading you down the wrong | track. | | It looks like the broad cross-platform capabilities of FP | are mainly for modern machines and platforms, even if low | powered like the RPi. | badsectoracula wrote: | Free Pascal has support for Z80 which _might_ work with | some CP /M systems (AFAIK Z80 is backwards compatible with | 8080 and some CP/M systems used Z80). You need to compile | the compiler from source but it apparently can target the | ZX Spectrum, so with some modification it might be able to | target CP/M too. | slavapestov wrote: | We need to bring back Oberon. Fast compile times, automatic | memory management, live environment. | Rochus wrote: | Oberon is even older than Delphi; a more modern version is | Oberon+: https://oberon-lang.github.io/ | cvalka wrote: | Why I prefer brainfuck. | sacnoradhq wrote: | Often overlooked, the Ada embedded ecosystem has advantages of | maturity in static analysis, debugging, and target support. | bobajeff wrote: | Does Ada support Android and iOS targets yet? Last I checked | there didn't seem to be any obvious way to build for NDK. | Jtsummers wrote: | iOS yes: https://docs.adacore.com/gnat_ugx- | docs/html/gnat_ugx/gnat_ug... | | Never used it though. | musicale wrote: | I always thought that Ada was underrated. Personally I | appreciate features like memory safety, a standard concurrency | model, support for unit/measurement types, and ahead-of-time | compilation. | | Ada's Pascal-like syntax seems verbose to me but isn't hard to | read. And VHDL is based on Ada syntax, perhaps making it easier | for people who are working in both languages. | | Swift seems to check some of those boxes (and adds many other | convenient features including closures, automatic reference | counting, type inference, etc.) I don't know about measurement | types, but it seems they should be doable. There doesn't seem | to be a Swift-like HDL yet though. | _pferreir_ wrote: | [flagged] | beefychops wrote: | [flagged] | jmorenoamor wrote: | My first languaje after BASIC was Modula2, which looks a lot like | Pascal. I studied OOP, algorithms and data structures with Pascal | in college, so it's a languaje for which I have great memeories. | | Nice to see it's still around. | Rochus wrote: | Modula-2 is a much better language than original Pascal, but if | you want OO features Oberon-2 is the corresponding Wirth | language. | nine_k wrote: | Both made it into modernity as large swaths of Golang. | Modula-2 even had coroutines. | Rochus wrote: | Go has surprisingly little in common with Oberon or Modula | (mostly the receiver syntax of Oberon-2 bound procedures). | The coroutines were not a language feature of Modula, but a | library feature; also the Oakwood guidelines of Oberon (not | by the original authors) include a coroutine API, but I'm | not sure whether there was a working implementation. | bradley13 wrote: | Why? Old languages must remain around for legacy support. | However, it's hard to see the point of shoe-horning all those | modern features into an old language. | | I write a lot of Java, and really, almost everything since Java 8 | should not have been added. Lambdas, for example, are a kludge in | Java. | | Want modern features? Use a modern language. If you want to stay | in the Java ecosystem, for example, you could use Kotlin. | | I'm talking about Java only because I haven't seen Pascal for | literally decades. I last programmed Pascal in the 1980s. Adding | that laundry list of features to Pascal is just silly. | baq wrote: | Java until recently had less going for it than Delphi 15 years | ago except the insanely large ecosystem - which trumps | everything else, admittedly. | | Java the language was misguided in its decision to use | libraries instead of language features leading to impressive | amounts of boilerplate. Yes, you can do everything you can do | in Python, Lisp or Haskell. But, you can also do that in | brainf*ck, by definition, so the actual complexity of Java | solutions is actually higher than a more featured language, | because you end up reimplementing all those language features | anyway in a slightly broken way or pull in tons of dependencies | that do that for you, in either case with added API surface to | learn. | deely3 wrote: | > because you end up reimplementing all those language | features anyway in a slightly broken way or pull in tons of | dependencies that do that for you, in either case with added | API surface to learn. | | I suppose this statement is true for absolutely all | programming languages? | | You have to use libraries in all languages, all libraries is | somehow broken because of using unique way to implement | functionality, by using any library you have to learn unique | API, etc. etc. | baq wrote: | Yes. | | Except sometimes you don't have to use libraries because | the language just does the right thing out of the box, e.g. | go with channels, selects and goroutines. This is what | Python's 'there should be only one way to do it' is really | about. | valenterry wrote: | Then we have to switch PLs much more often. Seems reasonable to | me to add/integrate new features that have proven to add a | benefit to delay this process. | thriftwy wrote: | Only in the last few years we have a competing JVM language. | | Scala was a dead end. Clojure was a fad. Rhino/JS was very | limited in its ambition. | | Java improvements allowed JVM to stay relevant and fend off | DotNet, which is a good thing considering Microsoft's history. | maleldil wrote: | > Use a modern language. If you want to stay in the Java | ecosystem, for example, you could use Kotlin. | | That's easier in Java given how easy it is to interop between | languages (see also Clojure). What if I'm using C++? There's no | easy upgrade path to anything else. | | There's still value to "shoe-horning all those modern | features". I might not start a project with C++ today, instead | choosing a modern language (e.g. Rust) instead. But there are | millions of lines of C++ already written that would be improved | by modern features (see how C++11 changed the landscape). | renewedrebecca wrote: | _lambdas_ are a kludge? Really? You prefer creating one-method | anonymous classes instead? | kagevf wrote: | I think they meant in terms of how the feature was | implemented, not the feature itself. | einpoklum wrote: | > modern, readable, fast, type-safe, cross-platform programming | language | | Let's assume this is all true (although I wouldn't say it's | particularly modern, and I don't know about some of the rest). | And let's forget that some of these adjectives are relative or | subjective. | | Even under that assumption - there are other programming | languages which meet these criteria. Why would we prefer Object | Pascal over them? Especially when it has existed for many years | and not gotten a lot of traction? | AnimalMuppet wrote: | "For those who like this sort of thing, it is the sort of thing | they like." - attributed to a number of people. | | There are other languages which meet these criteria. But if | Pascal fits the way your brain works, then it does. So use it. | | And if it doesn't fit the way your brain works, then don't. | | People are different. It doesn't hurt to have different tools. | zabzonk wrote: | I used Delph professionaly for several years in the 90s, and | liked it, but really got tired with Borland (and subsequent | owners) mis-managing the product and the language, as did Anders | Hejlsberg, who left Borland for Microsoft, where he created C# - | IMHO a much better language & architecture to invest your time | in. | didip wrote: | Pascal is actually good and perfomant. It was the second language | I picked up in high school after Basic. | | I don't understand why as an industry we had to regress to | Python, Ruby, Java, & Javascript in late 90s & early 2000. | dansalvato wrote: | I saw a talk that touched on this recently: | https://www.youtube.com/watch?v=Tml94je2edk | | He explains that dynamically-typed languages like Python, Ruby, | and JS became popular in the 90s because they offered a fast | feedback loop for website building, and they didn't need an IDE | or compilers, which were slow (and often not free). It ended up | not being worth trading your development time for the | performance increase when all your users were connecting via | 56k modem anyway. | | The talk makes a lot of other cool points about how development | has changed in the past decade or two, and why the trend is | moving back to static typing. | oaiey wrote: | Do not forget Pearl. | whatyesaid wrote: | Unless you want a C++ with a different syntax and less features | then there's no reason to learn Pascal in 2023. | | And the syntax is much worse, you can't even declare variables in | the middle of a function it has to go before the function. This | slows you down from real work (art code comes later). It also | makes worse code as declaring near the usage point makes code | more clear. | janoc wrote: | That's completely missing the point. | | While Pascal can be used for serious work, it is first and | foremost a teaching language friendly to beginners meant for | introducing people (who back in the day) likely started with | something like BASIC to concepts of structured and objects | oriented programming. The syntax is easy to learn, fairly clean | and the language has very fast compilation (C++ really can't | compete here). Which is important when teaching - permits rapid | iteration. | | Concerning archaic/rigid syntax - there are some good reasons | why the syntax is like it is. E.g. the concept of declaring a | variable in the middle of a block didn't exist in Pascal for a | reason - you had to actually allocate memory before you used | it, the compiler didn't hide this from you. That's why | variables are declared at the start of the block. | | When Pascal has been designed it was running on various 8bit | and 16bit machines and was originally compiled into bytecode | (p-code), so optimizations like statement reordering common | today (which permits to declare the variables in the middle of | blocks) didn't exist/weren't possible/common. | | These days you have a ton of abstractions between you and the | "metal" running your code, Pascal is a language designed for | much simpler time and hardware. | Al-Khwarizmi wrote: | I was teaching programming with Pascal until three years ago, | and I think the pedagogical argument might have made sense in | the past, but not in 2023 (or 10 years ago for that matter). | | The syntax is rigid in all the wrong places. For example, not | being able to declare variables anywhere doesn't really help | students, this isn't something that typically leads them to | errors. | | What _does_ lead to lots of errors? Dereferencing | uninitialized pointers or going out of bounds in arrays, for | example. And the language and compiler won 't help you one | bit there. Same opaque segmentation faults as with C, same | unpredictable behavior as with C, but with worse tooling for | debugging. | | Compilation time is not an issue in 2023 - well, maybe it is | if you compare with C++, but C++ is about the worst non-joke | language I can think of for learning (and it was my first | language!). C, Java, Python, etc. are fast enough. | | Pascal had its time but I don't think there is much reason to | use it now, outside of pure curiosity or wanting to try a | historical language. | slt2021 wrote: | >For example, not being able to declare variables anywhere | doesn't really help students, this | | Disagree. Creating variables in the middle is the reason | why beginners create spaghetti code and mix up control | flow. This is the reason for dangling pointers, memory | leaks, and de-referencing pointers in wrong places. | | If student needs to declare variable in the middle of | method, this is a good sign to split the method or rethink | control flow. | | What really I learned from Pascal is managing clean control | flow, and _var_ section in the beginning forces you to | think in advance what you are going to need in this | particular method vs what needs to be done in a separate | function. | OnlyMortal wrote: | Much of the original Mac was Pascal based with 68k for | performance pinch points. | | Of note it was faster to compile than C with MPW Shell. | oaiey wrote: | Many years ago I learned programming that way. Pascal then C, | Assembler and VB Script. I completely agree with the argument | that it is a great teaching language. Our teachers even | explained this to us. JS, C, C#, Python and Java syntax is | just crazy for real newbies. Curly braces basically do not | exist in normal life and scare people. And Go and the | functional group of languages are just not understandable | with their concepts. Imperative programming is much easier to | understand. | | Pascal is in a sweet spot. | einpoklum wrote: | > _While Pascal can be used for serious work, it is first and | foremost a teaching language friendly to beginners_ | | But that's not what the linked article argues as a reason to | use (Object) Pascal. | | > _The syntax is easy to learn, fairly clean and the language | has very fast compilation (C++ really can 't compete here). | Which is important when teaching - permits rapid iteration._ | | 1. There are other languages than C++ you know... | | 2. For language-teaching purposes, basically _any_ language | compiles essentially instantaneously on modern hardware | (including C++). | sigg3 wrote: | I seem to recall Golang being inspired by it too, but I could | be misremembering. | chinabot wrote: | recently did a conversion of a Delphi program to Java with some | C++ and this is a strange argument to use. pressing F9 at any | point in Delphi and having your program run a second later is | incredible, that plus catching the vast majority of errors | compile time certainly does not slow you down. | | Speed wise on this last conversion project with the same first | level optimizations GCC is a good 50% faster, the Java parts | feel about the same or a bit slower though, Disclaimer I never | go to extreme optimization settings on compilers, was bitten | several years back and happy to not go cutting edge. | | Also Pascal is much less toxic community for noobs I got to the | point about ten years back I would rather not ask the question | on-line for GCC due to the fact I would be branded stupid for | not knowing some obscure linker setting or such like. | | end of my career now, happy Pascal was part of it, especially | in the early Turbo Pascal DOS days, I doubt I would have | carried on at the time if I was forced to use C (I later did | and it wasnt that bad but I had to scratch my head at the time | how people thought it better) | brokenkebaby wrote: | Just a few days ago I found a bug in someone's code where a | variable was introduced twice with slightly different name, | like "var jobno", and then "var jobn". Made me think that | Pascal's approach to keep vars declarations at one place is not | a bad thing. As for slowing down - probably yes, but I doubt | that speedtyping is really a big virtue for a software | developer. Also, in a decent IDE it should be possible to make | binding/macro to insert declaration after the current function | header without jumping away from the current position (though I | don't know what Pascal devs use nowadays for IDE) | lelanthran wrote: | > Unless you want a C++ with a different syntax and less | features then there's no reason to learn Pascal in 2023. | | For me, personally, there there is a _good_ reason to learn | Pascal in 2023; the quick and almost painless ability to | produce fast GUI applications. | | The alternatives are not nearly as polished or as nice. | gmiller123456 wrote: | C used to be that way too, but Pascal stopped evolving when it | fell out of popularity. | delphi4711 wrote: | > you can't even declare variables in the middle of a function | | You can since Delphi 10.3. | | https://en.m.wikipedia.org/wiki/History_of_Delphi_(software) | nopepon wrote: | I've been playing around with Lazarus the last couple of weeks, | and I can say there is at least one reason to learn pascal in | 2023: it's fun! | musicale wrote: | Delphi/Lazarus seems like a fairly productive environment. | | Also if I recall correctly some Pascal compilers (similarly to | Ada) could actually generate somewhat memory safe code with | array bounds checking, which is something that C/C++ usually | lacks. | hulitu wrote: | > you can't even declare variables in the middle of a function | | losing time with "static declaration follows non static" in C | programs doesn't help either. | unnouinceput wrote: | I never understood why is declaring variables in the middle of | the code a "pro" for some. In my experience that's a "con" | especially because of maintainability. Same way you do a | comment before declaring a function to explain its purpose, you | do a comment for each variable to declare its goal within said | function. That's proper maintainability for a project. | | Also Delphi, for past 2 years, has this "middle" variable | declaration style, and I hate it, never used it. So your | comment missed the mark. If you want to advocate "don't learn | Pascal in 2023" please do more research and come up with better | argument. | tnecniv wrote: | Like dynamic typing and other things, declaring things in the | middle of your code block seemed like a great idea to young | me, but as I've gotten older, things like organizing variable | definitions, strict use of types (or the kind of sucky type | hints in Python), and other kinds of self-documenting | declarations have become much more appealing to me. It might | save "real work" from happening if you measure by lines of | code, but you pay that price later when debugging or reading | code you haven't touched in a long time. | Al-Khwarizmi wrote: | A clear example of why it is a pro is the index of a for | loop. Why would it be more maintainable to declare all for | loop indexes at the beginning of a function? They are | basically bound variables that are only meaningful within | their loop, and they are usually not even worth commenting. | zabzonk wrote: | defining all variables as near to their point of use as | possible is a pretty obviously good thing, for readability if | nothing else. | whobre wrote: | Can't speak about Object Pascal, but the old Pascal was | objectively better than C. You can like or dislike the | differences in syntax, but Pascal's type system was pretty | solid which can't be said about C | pmelendez wrote: | > but Pascal's type system was pretty solid | | To be honest, this is a matter of styles, coming from a | dynamic type background I don't appreciate strongly typed | systems as an advantage. | Jtsummers wrote: | Strongly typed is orthogonal to dynamic and static typing. | Python and Common Lisp are both "strongly" typed and | dynamically typed. There's no reason to shun strong typing | if you also like dynamic typing. | pmelendez wrote: | I would be curious to see references that claims that | dynamic and static typing are orthogonal with strongly | typed systems, as "strongly type" is rather ambiguous and | the only reason I used the term was because that was how | Pascal was promoted back in the day (or at least how was | taught to me) | | From Wikipedia: In 1974, Liskov and S. Zilles defined a | strongly-typed language as one in which "whenever an | object is passed from a calling function to a called | function, its type must be compatible with the type | declared in the called function." | | Note that the definition refers to type declaration, both | being optional in Python and Common Lisp, so I wouldn't | use either as an example of strongly type languages. | [deleted] | kazinator wrote: | "whenever an object is passed" clearly refers to run- | time. An object is not being passed when we are compiling | the function call. | | "declared in the function" clearly means that the | function has an internal type check. | | An interface declaration (Modula-2 interface file, C | header file with prototypes) is not "in the function"; | it's compile-time meta-data about a function. | | A function call between separately compiled translation | units has no idea what is _in_ a function. | Jtsummers wrote: | You already found the wikipedia page, try reading it. See | where it puts a lot of dynamically typed languages under | the category of "strongly typed". You've decided it's a | good enough source apparently. | | But really, I used "strongly" in quotes deliberately. | It's a terrible phrase since it means nothing in practice | because it can mean too many things (as that same page | notes) that often are at odds with each other. | | > Note that the definition refers to type declaration, | both being optional in Python and Common Lisp, so I | wouldn't use either as an example of strongly type | languages. | | Even this definition would potentially exclude SML and | OCaml where types are inferred, not declared. So | according to you those two languages are weakly typed? I | think a lot of people would be surprised to learn that. | epolanski wrote: | Dynamic and static merely point to the fact that type | analysis is either done at runtime or at compilation | time. | | It is an unrelated concept to which type rules will be | applied by the software at runtime or compilation time. | slt2021 wrote: | how can Python be strongly typed if it doesn't enforce | types for declared arguments? | | What is the value of this supposedly "strongly typed" | Python's type system? | | class Object: pass | | def f(arg:int): print("type of arg = ", | str(type(arg))) | | f(1) | | f(666.0) | | f("kek") | | f(Object()) | | type of arg = <class 'int'> | | type of arg = <class 'float'> | | type of arg = <class 'str'> | | type of arg = <class '__main__.Object'> | | and not a single error/warning thrown | Jtsummers wrote: | How is OCaml strongly typed if it doesn't have declared | types?!?!? (EDIT: In case it's not obvious, I'm being | sarcastic, I'm pretty sure some people in this discussion | won't get that though.) let f x = x + 1;; | (* What's the type?!?!? *) | | Turns out that "strong typing" is a shitty phrase that | people should stop using because it means too many | conflicting things, and, consequently, means nothing. | Static and dynamic typing have well-defined meanings, | stick with those terms instead of ones that mean nothing. | | But for a demonstration (compare to Perl) try this in | your Python REPL: >>> 1 + "1" | | Does it work? Probably not unless you futzed with the | language implementation. In Perl it does, though. So to | the extent that "strong typing" means anything, Perl is | "weakly typed", Python is "strongly typed", and both are | dynamically typed. It's an orthogonal characteristic of | the type system and language from when type checking | occurs. | | ---------- | | EDIT: BTW, formatting code blocks on HN is really easy. | Prefix each line of code with two space characters. | __Replace those _'s with spaces | | The result is much cleaner than your comment: | def foo(x): return x + x | | No extra newlines needed, more compact, easier for most | people to read. | slt2021 wrote: | people on HN often claim that Python is "strongly typed" | while PHP is loosely-typed, but I don't see the | difference honestly. both are pretty loose. | | re: 1 + "1" | | I didn't get your point really. My reply was to counter | claim that Python is supposedly "strongly typed" and I | don't understand how this strong typing helps developers. | I know that languages can infer types, which is | tangential subject. I dont know why you brought this up | Jtsummers wrote: | Try that line in both Python and Perl and see how they | behave, you'll see that one (Python) respects types (the | most useful notion of "strong typing" is no or limited | automatic type coercion and "weak typing" as an excessive | permissibility around mixing of types in operations) and | the other (Perl) does not. | | I pointed out the OCaml example because both you and your | sibling poster brought up type _declarations_ as somehow | mattering with respect to "strong typing". OCaml doesn't | require type declarations, so I guess it's weakly typed | according to both of you. Which is a surprising result. | slt2021 wrote: | I never do 1+"1" in my code, so this example is not | useful to me. | | I do however annotate types and expect Python to respect | type annotations which is not the case. Then I dont | understand what is point of annotating types if they are | not respected? | | If your argument that Python doesn't convert from one | type to another - well, it doesn't need to do that if | doesn't care about types in the first place and lets you | pass any junk into any method (and this is #1 thing that | type system is supposed to prevent) | | Is it only for documentation so that people reading code | could understand what types to pass? | TheCleric wrote: | Python type hinting is not useful at runtime (in fact | it's flat out ignored). It is useful at "linting" time | when run through mypy. | dsemi wrote: | Python type annotations were added to be used by an | external type checker, so no they are not enforced by the | interpreter itself. | | This was an explicit decision: | https://peps.python.org/pep-0484/#non-goals | dsemi wrote: | > I don't see the difference honestly. both are pretty | loose. | | There's a clear difference, in PHP 1 + "1" is 2, in | Python it's a TypeError, (and as a bonus, in Javascript 1 | + "1" is "11"). | | The definition of "strongly typed" being used is related | to type coercion, not type inference. In PHP the string | is being coerced to an integer, but Python requires you | to explicitly say 1 + int("1") if you want to add the | numbers together. This can be helpful to developers | because it requires you to make a decision about what | behavior you actually want rather than assuming you want | to add two numbers or concatenate strings when you may | have wanted the opposite. | Jtsummers wrote: | String concatenation is probably the most reasonable | result aside from a type error given how + is used in JS | for concatenation elsewhere, but JS actually gets funny. | "1"*2 // => 2 (not "2") "1"*2+3 // => 5 "1" - | 2 // => -1 "9"/3 // => 3 "9" + 3 // => "93" | | So some mathematical operators will convert string | parameters to a number, but not +. | bigbillheck wrote: | The way I remember the pascal type system is arrays of | different lengths were different types. | filmor wrote: | They are pretty much everywhere when statically allocated. | zabzonk wrote: | well, not in c. | fuzztester wrote: | There's more to it than that. You could (from early Pascal | days) and can have arrays where the array index range is a | previously defined subrange of integers, or maybe even of | an enumerated type. | | Then you have sets as a built-in type, which is big. | | Some more. | AnimalMuppet wrote: | In the _original_ Pascal, that was true. The standard (and, | I think, Jensen & Wirth) were that way. And it was a fatal | flaw. | | I had a program that I took over that did a numerical | simulation on a 2D grid with user-specified size. The | original author simulated that 2D grid with a 1D doubly- | linked list. As you might expect, this was both slow and | error-prone. But he did it because there was no possible | type that you could give to a user-sized array. There was | literally no way to talk about such a thing. | | We eventually "fixed" it by allocating the largest 2D array | possible within our memory limitations, and using only the | user-specified part of it. | | Most "real" Pascals (Turbo Pascal, but others that were | intended to be used in the real world, not just in the | classroom) developed some way to give a type to a variable- | length array (and also to do a C-ish cast). Unfortunately | they all did it in different ways, so there was no code | portability between compilers if your code needed such | things. | | So, yeah, "objectively better than C" is quite a stretch, | even just in the type system. | adastra22 wrote: | For the first couple of items on the list, Austral might be a | language worth considering: | | https://austral-lang.org | | It's new so it obviously doesn't have the community of libraries | to use, but it does have a very friendly and accessible Pascal- | like syntax, while also having a state of the art linear type | system. | stuaxo wrote: | Misread this as Rascal and thought it would be about Turbo Rascal | Syntax Error. | kazinator wrote: | > Why use Pascal? | | Because you like Niklaus Wirth's languages, and only those ... | but only up to Pascal. | | You don't think that the improvements in his subsequent Pascal- | like languages are Wirth a damn. | | You believe that Wirth went soft in the 1970's and 1980's, and | sold out Pascal. | | If that is you, you probably write code in Pascal, implement | Pascal, write about Pascal ... | | (Everyone else should probably skip Pascal and take a look at | Modula-2 and Oberon.) | badsectoracula wrote: | > (Everyone else should probably skip Pascal and take a look at | Modula-2 and Oberon.) | | I did check out Oberon-07 because of its minimalism but i | really couldn't get over the SHOUTY keywords :-P. | | (Wirth used uppercase for Pascal's keywords too but unlike | Oberon, Pascal is not case sensitive - my pet theory is that | Oberon is case sensitive as a reaction to Pascal programmers | not using shouty capitalization :-P) | Rochus wrote: | Yes, forcing uppercase keywords is rather unfortunate; have a | look at https://oberon-lang.github.io/ | [deleted] | thriftwy wrote: | As you can see in the comments, Pascal has significant anti | rating. | | I would meditate on that fact if I was Pascal evangelist, instead | of reposting such texts over and over as years go by. | thriftwy wrote: | A downvote shows a certain intolerance to criticism which is | indeed a token of Pascal community and which would lead me to | flagging this post. | riidom wrote: | Question for Castle Engine users: | | How is the file size when exporting to web, for an near-empty | project? | squarefoot wrote: | Many people using Delphi back in the day will probably already | know Lazarus, which is essentially an Open Source recreation | which runs and compiles _natively_ pretty much everywhere, | Raspberry PI and similar ARM boards included. Installing | libraries however can be tedious, therefore FpcUp and later | FpcUpDeluxe were created to automate the task of installing the | IDE along with other modules and some quite interesting addons. | | https://wiki.freepascal.org/fpcupdeluxe | | Here's a quick&dirty instrument panel widgets demo I just put | together using some free widgets available with FpcUpDeluxe. | | https://ibb.co/9bchx7T | | FpcUpDeluxe does work also under Alpine Linux (get the musl | version on the releases page), which opens possibilities for | adding instrumentation panels to very small systems. All code is | compiled native on various platforms, and runs fast: no | interpreters, no web browsers etc. | eimrine wrote: | I have found a beautiful beginner book "High-Level Languages and | Their Compilers" by Des Watson and I want to run all that | examples which are given mostly on Pascal. | tangus wrote: | I disagree with some of their reasons. | | Modern: Object Pascal isn't a modern language. It was modern in | 1998, maybe, but it hasn't evolved much since then. Latest big | change was the addition of generics, behind almost any other | language. | | Fast: FPC doesn't generate particularly fast code, and the nature | of OP objects doesn't help with locality. It's faster than | scripting languages, but generally slower than AOT compiled | languages, even those with GC. | | On the other hand, the ecosystem is great. There are lots of good | libraries and tools (the most remarkable one being Lazarus, the | Delphi clone). In my experience, people working with FPC or | Delphi don't care much about modernizing the language or things | like that, the just get things done (TM). I don't see the | language being attractive to new coders though, so I don't know | what its future will be... | Svip wrote: | > On the other hand, the ecosystem is great. | | Hard disagree. I worked with Pascal for about 10 years, and the | lack of modern libraries was a source of frequent frustration, | meaning we often had to develop the solutions ourselves, or | abandon an idea entirely. | pjmlp wrote: | In regards to Delphi there were plenty of them, sold by | companies specialised in component libraries. | | Naturally one had to be willing to pay for them. | nine_k wrote: | May we please have a few examples of what's missing? | kmoser wrote: | Yep. Unless it's part of a legacy project, or I'm developing | something as a fun experiment, I have no interest in | languages that lack modern, robust, stable, up-to-date | libraries. | musicale wrote: | > I have no interest in languages that lack modern, robust, | stable, up-to-date libraries. | | I guess JavaScript is out then. ;-) | lelanthran wrote: | > Fast: FPC doesn't generate particularly fast code, and the | nature of OP objects doesn't help with locality. It's faster | than scripting languages, but generally slower than AOT | compiled languages, even those with GC. | | You're selling it short. | | Firstly, as the other poster downthread pointed out, it | benchmarked as fast as C++ in the past. | | Secondly, it's main use is local gui apps, and there's nothing | I've seen, including C# gui apps and have gui apps, that even | comes close to how snappy it is. | | So I am curious what benchmark you used to determine that it's | about 50 times slower than it actually is. | Rochus wrote: | > _it benchmarked as fast as C++ in the past_ | | Does this mean it's no longer as fast as C++ today? Do you | have specific benchmark results? | badsectoracula wrote: | You can find some in Debian benchmark game. In general FPC | generated code is around 1.5 to 2 times slower the fastest | entry (often C++). Note though that this is with FPC's own | code generator and there is a new LLVM backend in the | development version (FPC's own code generator is the | default and will always be, the LLVM backend is for those | who really want it and is _much_ slower). | | I'd expect synthetic benchmarks like those in the Debian | benchmark game to be closer to C++'s performance with the | LLVM backend. | Rochus wrote: | When I had a look at the CLBG results last time the code | generated by FreePascal was even about three to four | times slower than C/C++; but the benchmark rules are not | particularly well suited for fair comparison (some code | is obviously written with inside knowledge of the | particular compiler/version and not what you usually see | for the given language, and the Pascal code likely | includes range and overflow checks which make it slower | compared to a language without these, etc.). The LLVM | backend is not officially supported by FP and doesn't | support all platforms as far as I know; and unfortunately | micro benchmarks are usually not representative for the | daily overall performance of an application; the Are-we- | fast-yet benchmark suite would be better in this regard. | | Anyway, I would be interested in why FP benchmarked as | fast as C++ in the past, but no longer today. | badsectoracula wrote: | > The LLVM backend is not officially supported by FP | | It used to be a separate project but these days is part | of the main development branch. Though indeed the OS and | CPU support is very limited. | | Also i agree about the micro benchmark comparison, they | tend to exaggerate differences. FWIW in my own programs i | never found Free Pascal's code generator to be | inadequate. | | I do not remember the exact difference but last year i | did compile my 3D game engine with the LLVM backend and | the difference was small enough for me to decide that i | don't want to bother with the _much_ slower compile | times. | Rochus wrote: | I read other comments of people claiming the code | generated by the LLVM backend was less than factor 1.5 | faster than the one generated by the original backend, | which is not worth the effort (and the humongous overhead | and additional dependencies) from my point of view; but | I'm still trying to find information about the specific | optimizations done in the current FP compiler. | badsectoracula wrote: | > I'm still trying to find information about the specific | optimizations done in the current FP compiler. | | AFAIK there isn't any explicit documentation but the | "toptimizerswitch" and "twpoptimizerswitch" (the latter | is for whole program optimizations) types in the compiler | define the available optimizations in globtype.pas and | have the following values: | cs_opt_level1,cs_opt_level2,cs_opt_level3,cs_opt_level4, | cs_opt_regvar,cs_opt_uncertain,cs_opt_size,cs_opt_stackfr | ame, cs_opt_peephole,cs_opt_loopunroll,cs_opt_tai | lrecursion,cs_opt_nodecse, cs_opt_nodedfa,cs_opt_ | loopstrength,cs_opt_scheduler,cs_opt_autoinline, | cs_useebp,cs_userbp,cs_opt_reorder_fields,cs_opt_fastmath | , cs_opt_dead_values,cs_opt_remove_empty_proc,cs_ | opt_constant_propagate, | cs_opt_dead_store_eliminate,cs_opt_forcenostackframe, | cs_opt_use_load_modify_store,cs_opt_unused_para,cs_opt_co | nsts, cs_opt_forloop cs_wpo_devirtua | lize_calls,cs_wpo_optimize_vmts,cs_wpo_symbol_liveness | | level1/2/3/4 are basically collections for some of the | above and are enabled for -On where n is 1 to 4. You can | enable optimizations explicitly with the -OoXXX (for per- | module optimizations) and -OwXXX (for whole program | optimizations). The -io and -iw parameters can be used to | obtain the available names for these. | | I think the names are more or less self-explanatory, at | least for the most part (not sure what "uncertain" | does... which i think is appropriate :-P). | | Some brief documentation (though _very_ brief) is | available in the programmer 's guide: | | https://www.freepascal.org/docs- | html/current/prog/progch11.h... | Rochus wrote: | Thanks for the hints. I was already concerned that I | would have to analyze the source code directly myself, | and so I started to build tools for this purpose | (https://github.com/rochus-keller/FreePascal). | | I read somewhere that there are issues with higher | optimization levels. Can you confirm that? | Rochus wrote: | > _but generally slower than AOT compiled languages, even those | with GC._ | | Is this an assessment by experience or do you have specific | performance data, e.g. comparing a set of benchmarks with C++? | What's the difference if checks (range, overflow, etc.) are | disabled? | zabzonk wrote: | FPC (if my experience with Lazarus is anything to go by) | doesn't even compile quickly - certainly not compared to the | Delphi compiler. | badsectoracula wrote: | > Latest big change was the addition of generics, behind almost | any other language. | | FPC added generics 17 years ago, that is far from recent. Also | i'd say that anonymous functions and function references | (closures) are better candidates for "big change that was added | recently". | | > FPC doesn't generate particularly fast code, and the nature | of OP objects doesn't help with locality. It's faster than | scripting languages, but generally slower than AOT compiled | languages, even those with GC. | | In practice the performance is fine and you can actually | optimize the code as much as you need for any hotspots you find | - it can be a bit more of a PITA if you use the "high level" | classes compared to C++ but it isn't impossible. | | Though if you _really_ want performance out of the box with | minimal effort from your side, there is a new LLVM backend. You | need to compile the compiler from source to enable it as the | entire runtime library, FCL, etc need to be built with the LLVM | backend, but that takes only a couple of minutes. On the other | hand the compiler becomes much slower (and IMO the difference | in performance isn 't worth it). | slt2021 wrote: | the greatest difference btw Pascal and C++ is developer | experience. | | Pascal uses a single-pass LL(1) compiler, which allows you to | compile in milliseconds. Pascal enables REPL-like experience | where you can Edit->Compile->Run in less than a second. | | C/C++ with macros and slower compilation times is worse | developer experience, at least it was the reason for me to | learn Pascal instead of C and Delphi instead of C++ | Rochus wrote: | > _Pascal uses a single-pass LL(1)_ | | No longer the case with the Pascal version used by the game | engine. | slt2021 wrote: | which Pascal compiler is it - Embarcadero or FPC? | Rochus wrote: | It's the language itself; I currently build a parser for | FP 3.2.2 and I need more look-ahead than LL(1) in | different parts of the syntax. And it has features which | require more than one pass. | weinzierl wrote: | Just to add more context: Niklaus Wirth's foresight was to | design Pascal's syntax to allow a single-pass compile. But it | took more than 15 years until we _actually had_ a blazingly | fast single-pass compiler and that is totally Anders | Hejlsberg 's merit. | musicale wrote: | Every so often a thread pops up about Turbo Pascal and I'm | astonished as to how nice an IDE you could fit onto a 64K | CP/M system. (See also comments above/below.) | weinzierl wrote: | Oh, it was very very nice. I still miss it today | sometimes. Here are a few highlights: | | - Pressing F1 gave you reliably context sensitive help | and the help content was really well put together. | | - The debugger was great and was basically what we now | know from Eclipse or IntelliJ and completely not like | gdb. It had the same keyboard shortcuts for stepping as | IntelliJ still has today. | | - Computers in the 90s really did not support more than | one display, but there was a weird trick that allowed you | to connect one color and one monochrome monitor. Turbo | Pascal fully supported that and could display the app on | the color display while you saw the debugger on the | monochrome one. This was before Windows and GUIs, | everything was fullscreen. Without that there was no way | to see debugger and app at the same time. | | - The editor was so good that I preferred it over a word | processor even for writing prose. | virgulino wrote: | Back in the days of Turbo Pascal 5.5 I had a secondary | monitor, a monochrome orange phosphor, connected to an | EGA card, I think. The main screen was VGA. Two monitors | provided a huge productivity gain, with common and cheap | hardware, and it was super cool. Turbo Pascal was the | only software I used that could display on the second | monitor. Sometimes I miss seeing everything in orange. | weinzierl wrote: | I had a VGA and a Hercules card and it's probably hard to | relay how super cool that was at a time and in an | environment where computers alone were pure magic to most | people. Then there were these kids, like us, that could | not only use these magic programs but could control and | manipulate them from a second screen:-) | Andrew_nenakhov wrote: | The best thing about built-in help was that it not only | contained documentation of a function, but usually a | short example code. That was extremely helpful and I | relied on it a lot. | yeputons wrote: | > It's faster than scripting languages, but generally slower | than AOT compiled languages, even those with GC. | | Not sure about FPC, but Delphi 7 was on par with C++ ten years | ago in competitive programming, that is about 2-3 times faster | than Java. By competitive programming I mean very short (1-3 | seconds per execution max, so any JIT is at disadvantage), CPU- | bound single-threaded heavily algorithmic computation on mostly | default compiler/runtime settings with no external libraries or | ability to tweak. The common knowledge was: you either use | C++/Pascal, or use Java and occasionally rewrite your 200-300 | line solution to C++ if you get "time limit exceeded" error, | and it passes with flying colors. | slt2021 wrote: | reasons why Delphi was/is a strong option for CP: | | 1. Fast compilation enables edit-compile-run workflow. Fast | iteration enables solving CP problems faster. | | 2. Native dynamic arrays, native String type | | 3. Easy to learn language for middle/high schoolers. | | 4. Usefulness for outside CP, for example I created GUI | programs in Delphi for clients and earned $$$ while in 8th | grade, right after I was done with competition season. | mgaunard wrote: | first word they use to justify using Pascal is that it's | "modern". | | Gave a glimpse at the code source screenshot. No, that syntax is | very much the past. | hgsgm wrote: | What makes syntax "modern"? | | Power matters more than style. | mgaunard wrote: | All imperative languages are essentially descended from | ALGOL, but in the case of Pascal, it also kept its original | syntax. | | Others have moved on. | coldtea wrote: | Yes they have "moved on". | | Which is why Alsol was "a language so far ahead of its | time, that it was not only an improvement on its | predecessors, but also on nearly all its successors." -- | Tony Hoare. | fuzztester wrote: | Too good quote :) | aap_ wrote: | - no struct/record type | | - call by name instead of call by reference | | - no bitwise operators | | - probably a lot more, I'm not too familiar with the | language | | The quote may have been closer to the truth at some | point, but certainly not today. And while begin/end | syntax may be a matter of taste I don't think it's | coincidence it's not very common anymore. | coldtea wrote: | Of course it's not true today [1]. That's a 70s or 80s | quote. | | But still, "moving on" is not always "improving upon" was | the point. | | [1] Well, mostly not true (the author has backed down | somewhat, but the post is still illuminating as a | comparison): | | http://cowlark.com/2009-11-15-go/ | weinzierl wrote: | The syntax is timeless, because it is much closer to math than | B/BCPL/C heritage. | | It has its own issues but overall it is much better thought out | than most other languages. | | Here is a comment I wrote a couple of months ago with more | arguments for Pascal's syntax: | | _" Yes, Rust does indeed and a long time before that it was | Pascal. I really love Pascal's syntax, it makes a lot of sense | when you approach it with a math background. | | - '=' is for equality only | | - assignment is ':=' which is the next best symbol you can find | in math for that purpose | | - numeric data types are 'integer' and 'real', no single/double | nonsense | | - 'functions' are for returning values, 'procedures' for side | effects | | - Function and procedure definitions can be nested. I can't | tell you what shock it was for me to discover that's not a | thing in C. | | - There is a native 'set' type | | - It has product types (records) and sum types (variants). | | - Range Types! Love'em! You need a number between 0 and 360? | You can easily express that in Pascal's type system. | | - Array indexing is your choice. Start at 0? Start at 1? Start | at 100? It's up to you. | | - To switch between call-by-value and call-by-reference all you | have to do is change your function/procedure signature. No | changes at the call sites or inside the function/procedure | body. Another bummer for me when I learned C. | | Pascal wasn't perfect but I really wish modern languages had | syntax based on Wirth's languages instead of being based on | BCPL, B and C."_ | | https://news.ycombinator.com/item?id=32983878 | badsectoracula wrote: | > numeric data types are 'integer' and 'real', no | single/double nonsense | | Actually in Free Pascal (and AFAIK Delphi) there are Single | and Double (and Extended) that map to 32bit and 64bit floats | (Extended depends on the target CPU, e.g. for 32bit x86 is | 80bit floats but for 64bit x86 is 64bit floats) since you | actually _do_ need to differentiate between the two in | practice. | | > 'functions' are for returning values, 'procedures' for side | effects | | FWIW even in Turbo Pascal (i don't remember which exact | version) functions could also be used as procedures (the | return value was ignored). While in theory separating the two | sounds nice, in practice it is often useful to be able to | ignore function results. | | > Array indexing is your choice. Start at 0? Start at 1? | Start at 100? It's up to you. | | One additional neat bit is that you don't even have to use | numbers, any ordinal type will work. Enums are ordinal types | so you can do "type Foo = (Bar, Baz, Bad); FooArray = array | [Foo] of Integer;" and then use "Bar, Baz, Bad" to access the | array. You can use ranges too. | | > To switch between call-by-value and call-by-reference all | you have to do is change your function/procedure signature. | No changes at the call sites or inside the function/procedure | body. Another bummer for me when I learned C. | | FWIW i prefer the C# approach of being explicit when you pass | something as a reference since it makes it obvious on the | call site just by reading the code. | | Beyond these i agree with your comment. | weinzierl wrote: | When it comes to real vs float I should not have called the | later nonsense. I agree that both have their place | depending whether you want to express things at a lower | (closer to hardware or wire protocol) level or more | abstractly. It is still sad that languages like C (and even | Rust) only offer the lower level types. | | What you said about functions and procedures is also true. | I still think that it is valuable to have a distinction | syntactically, even if they are relatively similar under | the hood. Maybe one day we will have a Pascal compiler that | can enforce that functions are side-effect free... | badsectoracula wrote: | > Maybe one day we will have a Pascal compiler that can | enforce that functions are side-effect free... | | Pure functions are actually one of the WIP functionality | in Free Pascal :-). AFAIK the ultimate goal is to have | the compiler evaluate them at compile time where | possible. | troupo wrote: | It's only "mathematical" if you chose very specific parts of | the language from a very specific version of Pascal when | looked at at a very specific angle. | | E.g. the argument falls apart immedately: | | - there's no assignment operator in maths | | - there are no procedures in maths, everything is a function | | - functions cannot be nested in maths (unless I'm mistaken) | | - types is maths, but Pascal uses a very narrowed down and | dumbed down version of it | | etc. etc. | | Pascal is the way Pascal is because Wirth wanted the simplest | possible language according to Wirth's own criteria that | could be compiled in a single pass on a 1980s computer. | | It's the go [1] of its time. | | That is _it_. Both the syntax and Pascal 's concept are | severely outdated. It's a very good thing that modern | languages never adopted Pascal's syntax and went for | something that is actually usable. Hell, Erlang is a more | mathematical and timeless syntax than Pascal, and it's a | trivial langauge at it's core. | | [1] Can't find the actual text now, but there was a rationale | by Rob Pike that go was amed at junior engineers, and needed | to be simple. | weinzierl wrote: | _" - there's no assignment operator in maths"_ | | There is no assignment but in math we use := to express | that two things are equal _per definition_. I never said it | was the same thing, just that it is the closest thing. From | a math perspective it makes total sense, while singular = | for assignment makes no sense at all. Especially when you | want express the concept of equality as well and cannot use | the obvious choice = anymore because you already used it | for something else. | | _" - there are no procedures in maths, everything is a | function"_ | | Exactly and that's why functions and procedures in Pascal | are separate things, like it is meant to be. Functions have | an equivalent in math, procedures don't. Mixing the two | concepts up into the weird thing C calls a function is just | wrong. | | _" - functions cannot be nested in maths (unless I'm | mistaken)"_ | | In some sense they can. In C they can't because of | technical restrictions, no one ever was fond of that | restriction, not even back in the day. | | _" - types is maths, but Pascal uses a very narrowed down | and dumbed down version of it"_ | | Pascal is a programming language, not math. My point is | solely that Pascals syntax is superior to C's because | (among other reasons) the former is closer to centuries old | tried and tested and well established syntax of | mathematical notation. It has some consistency and elegance | and certainly flaws as well. C's syntax decisions were more | driven by long gone technical restrictions than what makes | sense to a human. Now we have to live with that baggage. | troupo wrote: | Edit: In his Pascal report Wirth mentions math zero | times: http://pascal.hansotten.com/uploads/books/Pascal_U | ser_Manual... | | And in fact in 1971 he wrote that it was basically copied | from ALGOL: https://oberoncore.ru/_media/library/wirth_th | e_programming_l... | | Edit2: Most relevant part from second link: "The syntax | has been devised so that Pascal texts can be scanned by | the simplest techniques of syntactic analysis". That's | it. | | On to other comments which are basically relevant given | Wirth's own words: | | > but in math we use := to express that two things are | equal per definition. | | Then it isn't variable assignment. It's what you pretend | it is because Pascal defined variable assignment this | way, and now you're trying find an angle for which | "Pascal is closer to math" works. | | When we write "x = f(y)" or "x = y + z where z = f(t)" in | maths there's no confusion as to what this expresses. No | need for "equal by definition". | | Note: Interestingly enough, Wikipedia doesn't list `:=` | in its glossary of mathematical symbols [1] And then | there's another sign used for definitions: equality sign | with delta [2] | | > Especially when you want express the concept of | equality as well and cannot use the obvious choice = | anymore because you already used it for something else. | | Math also has the same problem, because equalities are | not equal :) | | Hence you have: | | - equal | | - equal by definition | | - ~ has six different definitions depending on context | | - [?] has two different definitions | | etc. | | > Exactly and that's why functions and procedures in | Pascal are separate things, like it is meant to be. | | It's not "meant to be". Programming languages are not | math. The distinction between functions and procedures in | Pascal exists only because Wirth decided that's how it | should be. | | > In some sense they can. | | It means that it makes no sense to pretend that nesting | functions in Pascal has anything to do with math. | | > Pascal is a programming language, not math. | | _Precisely_. And yet, just two paragraphs above you | argue for a distinction between functions and procedures | because math ;) | | > My point is solely that Pascals syntax is superior to | C's because (among other reasons) the former is closer to | centuries old tried and tested and well established | syntax of mathematical notation. | | Modern math notation didn't become "old tried and tested" | until somethig like 19th century, and even now it still | remains somewhat fluid. And it's only closer if you | arbitrarily twist definitions and meanings like "equal by | definition" is surely "variable assignment". As I said in | the very first line of my original comment: "It's only | 'mathematical' if you chose very specific parts of the | language from a very specific version of Pascal when | looked at at a very specific angle." | | It's also "better than C" only for some vague defintion | of "better" where "is closer to math" has no relation to | either reality or to being better. | | [1] https://en.wikipedia.org/wiki/Glossary_of_mathematica | l_symbo... | | [2] | https://math.stackexchange.com/questions/1289339/what-is- | mea... | AnimalMuppet wrote: | Yeah. weinzierl has his/her syntax preference, and that's | fine. As the ancients said, "There's no disputing about | tastes." But the attempt to provide a rationalization for | why the taste is _correct_ is complete nonsense. | weinzierl wrote: | Wirth doesn't mention math as inspiration because it is | obvious. | | Surely he derived the syntax from ALGOL, that is no | secret, but it was his choice to do so and not invent | something unconventional like Thompson and Ritchie did. | | In addition to that I find it quite telling that ALGOL's | designers were all mathematicians while Thompson and | Richie were Electrical Engineer and Physicist | respectively. | | I don't know why you put _equals by definition_ into | quotes as if I had invented that and also why you falsely | claim that it is not listed on the Wikipedia page you | referenced. It is there with := as symbol in the section | about equality. | | If you need another reference: | | _" := (the equal by definition sign) means "is equal by | definition to". This is a common alternate form of the | symbol "=Def ", which appears in the 1894 book Logica | Matematica by the logician Cesare Burali-Forti | (1861-1931). Other common alternate forms of the symbol | "=Def " include def "=" and "[?]", the latter being | especially common in applied mathematics."_ [1] | | Sure, there are alternative forms but := is what was | taught in Germany and Switzerland in schools and | university when I was there and I'm pretty sure also when | Niklaus Wirth was there. | | [1] https://www.math.ucdavis.edu/~anne/WQ2007/mat67-Commo | n_Math_... | zelphirkalt wrote: | > Range Types! Love'em! You need a number between 0 and 360? | You can easily express that in Pascal's type system. | | I did not know those existed that early. | | > Array indexing is your choice. Start at 0? Start at 1? | Start at 100? It's up to you. | | Reminds me again of GNU Guile's arrays, which also allow you | to specify what index an array starts with. Very flexible. | coldtea wrote: | That could just be C-style prejudice. | Toutouxc wrote: | Why? I mostly write Ruby and the code in the screenshot doesn't | offend me at all. | lelanthran wrote: | The syntax is a lot more readable than rust, or C++. | pjmlp wrote: | The syntax that has influenced Kotlin, Scala, Rust, Typescript, | and the various ML. | | Yeah, really old fashion. ___________________________________________________________________ (page generated 2023-07-08 23:00 UTC)