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.
From what I recall, Pascal doesn’t support variables scoped within a specific block. But then neither do some languages with C-style curly braces too.
So {} and Begin…End are pretty much the same thing.
BASIC (and Visual Basic especially) often get a lot of criticism for their syntax but the End Thing style block terminator was very clear.
It’s a pity that the only popular alternative to C-style braces is Python because I do think ALGOL-style syntax has a lot more going for it than people give it credit.
I was using “C-style” with respect to {} syntax for compound statements rather than language specification because the GP is discussing language grammar.
I’ve written a few compilers in my time so I have some idea about scoping rules ;)
As I and other have already said, it depends on the specific language. Some languages scope local variables at the function level (irrespective of {} or Begin End), and other languages scope local variables inside the containing {} or Begin and End block.
In that regard {} and Begin End serve identical purposes of defining a local execution block and then it’s up to the language or dialect, or sometimes even the compiler authors, to decide upon the rules of variable scoping.
What you’re doing here is conflating syntax grammar with deeper rules about a languages compiler or specification.
To come back to your original point, Delphi does support variable scoping inside Begin End blocks. I don’t know if FreePascal also does but older dialects of Pascal didn’t because of the original intent of Pascal being a single pass compiler. Equally, not all languages that have C-like curly braces support variable scoping in the way you’re trying to describe. JavaScript originally didn’t and had to create a whole new keyword to add it (a little like what Delphi did, funny enough). My own shell scripting language very intentionally doesn’t support scoping despite having curly braces.
As for inlining other contexts like functions, classes, etc, it has been a while since I’ve written any Pascal so I can’t recall the nesting rules here. But like with our discussion about variables, it’s more a question of whether the specification and/or compiler has support rather than a quirk of the Begin End grammar that forbids it — just as is the case with {} too.
> As I and other have already said, it depends on the specific language. Some languages scope local variables at the function level (irrespective of {} or Begin End), and other languages scope local variables inside the containing {} or Begin and End block.
And some languages do either, depending on the keyword used to declare a variable. Looking at you JavaScript(var vs let).
this post is specifically about pascal - my comment about {} vs begin...end was intended for that context. pascal has no way of defining variables within a local scope - it was added to delphi as a kludge much later. i admit i should have said something like "... {} in C and C++".
> this post is specifically about pascal - my comment about {} vs begin...end was intended for that context
That link was Pascal. It was just one of many dialects of Pascal.
> pascal has no way of defining variables within a local scope
I just did a quick search and turns out Pascal does support nesting variable scopes too.
> it was added to delphi as a kludge much later
Is it a kludge though? Or are you just calling it that because it disproves your point? The syntax is pretty similar to a lot of C-like languages. So you’d be calling their variable declarations a kludge too.
It feels like you’re being overly dismissive.
> i admit i should have said something like "... {} in C and C++".
it certainly would have helped your case to have opened with a little more context rather than assuming other people don’t understand how scoping works ;)
But even that aside, Pascal does support scoping inside compound statements.
Begin End and {} are just tokens to denote the start and end of a compound statement. Just like how Python uses indentation to group compounds.
Everything else you put is missing the point about how language grammar is parsed.
Well the good thing about this thread is that I found out that Pascal has grown inline vars since I last used it. With type inference too by the looks of it.
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.