Turbo Pascal was my second language after QBasic.
Unfortunately there doesn't seem to be any easy way to run Turbo Pascal on modern hardware, so I'll do the next best thing and give Free Pascal a try.
Hello, World!
Pascal code starts with program Name
. Statements are separated by ;
and the whole thing with .
. It's case insensitive, so you can do writeln
, WriteLn
, or even WrItElN
if you wanted, but I'll stick to all lowercase.
program Hello;
begin
writeln('Hello, World!');
end.
$ fpc hello.pas
$ ./hello
Hello, World!
Fibonacci
Let's try something a bit more ambitious - Fibonacci numbers.
program Fibonacci;
function fib(n:integer):integer;
begin
if n<=2 then
fib := 1
else
fib := fib(n-1) + fib(n-2);
end;
var
n:integer;
begin
for n := 1 to 20 do
begin
writeln('fib(', n, ')=', fib(n));
end;
end.
Step by step:
- we declare full list of variables used by something before the
begin
part - in this case we declarevar n:integer;
- that's the list of all variables our program uses - assignment uses
:=
-
for n := 1 to 20 do
is a for loop - we can pass any number of arguments to
writeln
, and mix strings and integers, it all works - to define a function we use
function name(arguments):return_type;
, followed byvar
block with any additional local variables, thenbegin...end
with the code - to return from a function, we assign to variable with same name as the function, there's no
return
in Pascal -
if condition then ... else ...;
is conditionals
FizzBuzz
program FizzBuzz;
var
n:integer;
begin
for n := 1 to 100 do
begin
if n mod 15 = 0 then
writeln('FizzBuzz')
else if n mod 5 = 0 then
writeln('Buzz')
else if n mod 3 = 0 then
writeln('Fizz')
else
writeln(n);
end;
end.
The only new thing here is slightly unusual syntax - =
for equality check, and mod
for modulo.
But you might have noticed something really weird - placement of semicolons. There's a lot of semicolon using languages and none of them would do this.
In every other language semicolons end statements. In Pascal semicolons separate statements.
Because those writeln
s are still continuing with else
, we cannot put semicolons after them - it will refuse to compile. Some semicolons like the one after the final end
are optional, just because there's no more statements there. But if there were some, you'd need semicolons.
There's some logic to it, but it will likely just annoy you if you're used to the usual system every other language uses, and modern languages don't use semicolons anyway.
Unicode
Obviously Turbo Pascal didn't support Unicode, as it predated is by very long time, but sadly neither than Free Pascal:
program Unicode;
begin
writeln(length('Hello'));
writeln(length('Żółw'));
writeln(length('💩'));
writeln(upcase('Żółw'));
writeln(lowercase('Żółw'));
end.
$ fpc unicode.pas
$ ./unicode
5
7
4
ŻółW
Żółw
Unicode, attempt two
Apparently Free Pascal supports annotations like {$codepage UTF8}
, so let's see how that goes:
{$codepage UTF8}
program Unicode;
begin
writeln(length('Hello'));
writeln(length('Żółw'));
writeln(length('💩'));
writeln(upcase('Żółw'));
writeln(lowercase('Żółw'));
end.
$ fpc unicode2.pas
$ ./unicode2
5
4
2
This binary has no string conversion support compiled in.
Recompile the application with a unit that installs a unicodestring manager in the program uses clause.
Runtime error 234 at $000000010E719BCD
$000000010E719BCD
Even more disastrously. Not only the length were incorrect in different way (5/7/4, then 5/4/2, correct is 5/4/1), the whole thing just crashed instead of even trying to convert strings to upper or lower case.
I think "just straight crashes on Unicode" is pretty much the worst performance of any language so far.
Classes
Let's close this episode by defining a class. Not really something Turbo Pascal had.
{$mode objfpc}
program PointProgram;
type Point = class
public
x: integer;
y: integer;
constructor Create(_x, _y:integer);
function ToString: string;
end;
constructor Point.Create(_x, _y:integer);
begin
x := _x;
y := _y;
end;
function Point.ToString: string;
var
xs, ys: string;
begin
str(x, xs);
str(y, ys);
result := '<' + xs + ',' + ys + '>'
end;
operator + (p1, p2: Point): Point;
begin
result := Point.Create(p1.x + p2.x, p1.y + p2.y)
end;
var
a: Point;
b: Point;
c: Point;
begin
a := Point.Create(200, 30);
b := Point.Create(220, 39);
c := a + b;
writeln(c.ToString);
end.
$ fpc point.pas
$ ./point
<420,69>
Step by step:
- we need to turn on classes support with
{$mode objfpc}
- there's a lot of switches like that, they change with dialect of Pascal you'll be using, and a lot of other things -
type Point = class
- how we declare a class; there are othertype
declarations, likeenum
s etc. - for simplicity I only specified
public
properties,costructor Create
, and overriddenToString
- we specify implementations of the methods separately from their declarations
-
constructor Point.Create
just assigns the right fields -
function Point.ToString: string;
returns default representation of aPoint
- we can first convertx
andy
to strings with classic Pascalstr(anything, aString)
, then concatenate them with<
and>
- there are many other solutions to this - we can declare
operator +
, but it's not a method, and in fact it's completely separate from the class stuff - in addition to assigning to name of the function to set return value, we can also assign to
result
- this is a pretty useful, as we can't exactly+ := Point.Create(p1.x + p2.x, p1.y + p2.y)
- we still need to call
writeln(c.ToString)
explicitly, it will not.ToString
for us; it's just a convention, not language feature
Should you use Free Pascal?
No.
Weirdly Free Pascal is occasionally used to build real programs, most notable Cheat Engine but it's basically boomers who learned programming with Turbo Pascal or Delphi, and never moved on.
There's no real reason to use Pascal of any kind.
I'm not saying it was all bad. For example even though it's been decades since I last coded Pascal, and I forgot most of the syntax, error messages for that were really top quality, with exact issue at exactly specified location.
But overall, no.
Code
All code examples for the series will be in this repository.
Top comments (2)
FP is cool. It compiles and runs very fast, doesn't need makefiles of any kind, is very portable and makes it super easy to build GUIs with Lazarus. It contains abstractions for many stuff you do by hand in C, and doesn't feel as bloated as C++. If anything, case insensivity and interfaces are the things that I don't like about it.
Also, there's much more built than just cheat engine. Delphi uses a dialect of Pascal that FPC has compatibility mode for. Lazarus can import delphi projects. And Delphi was used to build a bunch of stuff, including FLStudio. There's also Castle Game Engine written in FP, which in turn is used to build games for a bunch of platforms.
Should you read these language speedruns?
No. Despite my bias towards Polish people, I have to say the author is a superficial edgelord who couldn't get further than a couple of hot takes per language. Ironically enough, these short posts often contain grammar mistakes as well - the high standards apparently don't apply to everything.