Each of these relatively new languages takes after Wirth family languages like Pascal or Oberon, and particularly Turbo Pascal. In spirit or small details or tooling you’ll find something familiar. Here are my sort of random observations on Nim, Kotlin, Go

Nim

Of the three languages, Nim is most directly inspired by Pascal.

It has real enumeration types. Notice the explicit ‘type’ declaration, something I feel the lack of in most programming languages.

    type
        Direction = enum
            north, east, south, west

They even made an easy way to stringify your enums. You can use the’$’ operator to get a string of the name, or you can set the stringified value:

    type
        MyEnum = enum
            valueA = (0, "my value A"),
            valueB = "value B",
            valueC = 2,
            valueD = (3, "abc")

This is wonderful.

Like Pascal you get ordinal range types


    type
        Subrange = range[0..5]
        PositiveFloat = range[0.0..Inf]

As you can see, Nim uses significant whitespace. I’m not the biggest fan, but it does make for a very readable Pascal successor.

Nim has a ‘set’ type and it supports the set operations. You may have sets of ‘enum’, chars or integers.


    type
        CharSet = set[char]
        
    var
        x: CharSet
        x = {'a'..'z', '0'..'9'} 
                     

Instead of record types, Nim has tuples with named fields:


    type
        Person = tuple
            name: string
            age: int
                                         
    var
       person: Person
       
   person = (name: "Peter", age: 30)

Notice the var section just like in Pascal.

Nim prefers value based datatypes allocated on the stack. For instance the ‘array’ type is a value type, not a reference as it would be in Java. So, the ‘=’ operator copies arrays instead of assigning a new reference. While you can put things on the heap if desired, Nim like Pascal defaults to the stack. In practice this results in fewer bugs though performance may suffer with large data structures.

Finally, you can use the type declaration section to make different types derived from simple types. Something like this in Pascal is useful for preventing mixing of currencies:


type
	dollar = integer;
	euro = integer;

var
	my_dollars:dollar = 25;
	my_euros:euro = 35;   
    money:integer = 0;

This will prevent you from recklessly passing around the wrong units to the wrong functions and returning incorrect types; but it doesn’t prevent this part from compiling:

begin
    money := my_euros + my_dollars;
    money := money * 3 * euros;	
    writeln('My money: ', money);
end.

Nim has a ‘distinct’ type:


    type
        Dollar = distinct int
        Euro = distinct int

    var
        d: Dollar
        e: Euro

    echo d + 12
        
    # Error: cannot add a number with no unit and a ``Dollar``

You must define a “+” for the dollar + integer operation, and similarly the other operators handling different types when one type is distinct. With some template work you can build up a typesafe way to deal with units of measure however you want.

Kotlin

Kotlin might be thought of as a minimalist Scala. It has a number of superficial similarities to Pascal syntax, and some deeper ones:

Variables get passed as name : type (as in Scala and Pascal.)

You can nest function declarations, something that on occasion is extremely convenient, which you could also do in Turbo Pascal. It looks like this in Kotlin:

Kotlin allows local functions to be declared inside of other functions or methods.


    class User(val id: Int, val name: String, val address: String)
    
    fun saveUserToDb(user: User) {

        fun validate(user: User, value: String, fieldName: String) {
            require(value.isNotEmpty()) { "Can't save user ${user.id}: empty $fieldName" }
        }
   
        validate(user, user.name, "Name") 

        validate(user, user.address, "Address")
        // Save user to the database 
...

    }
    

Enums are nicely supported also


    enum class RGB { RED, GREEN, BLUE }

    inline fun <reified T : Enum<T>> printAllValues() {
        print(enumValues<T>().joinToString { it.name })
    }

    printAllValues<RGB>() // prints RED, GREEN, BLUE

As with Nim, Kotlin addresses the enum stringify problem.

On the whole, Kotlin isn’t that similar to Pascal but the overall feel of the language is in the spirit of Object Pascal if not the letter. Features such as data classes take the place of Pascal’s record types for instance. They’re quite different in implementation and the Kotlin data classes are more powerful, but in practice they both provide very convenient serialization for data and encapsulation of data, something seriously lacking in many languages.

Go

The Go language – search for “go-lang” to find it – has some qualities that make it the modern successor to Turbo Pascal in a practical sense:

  • Extremely fast compiler, giving a fast code - compile - test loop for great productivity
  • Relatively type-safe compared to C
  • Types are declared and passed name type (no colon in-between, but in Pascal order.)
  • “var” and “const” keywords preceed a block of declarations
  • The Go compiler does some extra work with no additional tooling: All packages source files in a module ccan be compiled together into a single program. This is quite different from C or Java. This is similar to Turbo Pascal’s easy build process and unlike so many other compilers.
  • Go packages resemble Turbo Pascal “units”. You would typically compose a large Pascal program out of many units and import only the “interface” part of the units while the “implementation” section remained private. You might make a larger unit out of many smaller units, then use only that higher-level unit (something like a Go module.) It made for good re-use and allowed for organizing very large programs and the same is true of Go modules and packages. The module in Go is the unit of code you would normally distribute as a library. In Turbo Pascal you made functions, types and variables (any identifiers) exportable by placing them in the “interface” section of a unit’s definition (sort of like a header in C.) In Go, you name the identifiers you wish to make importable with a capital letter.
  • A small thing, but the “if-then” statements in Go, like Pascal, don’t require parentheses around the expression part of the statement like in C-like languages, because of how the language grammar is defined. It’s something that’s always felt a bit off about C and Java to me though I understand why it has to be that way. Nim has this also.
  • Built-in unit testing. keeping tests in the packages they test, making running tests super easy. Turbo Pascal had no such tools built-in but it’s in the spirit of TPC.

With Go, the biggest similarities to Turbo Pascal are in the fast development and simple deployment you get.

Free Pascal

You can always use the actual Pascal language and Object Pascal supported by the ‘fpc’ compiler. Free Pascal It’s still maintained and available in most Linux distributions.

To develop native GUI applications for Windows, MacOS or Linux try the Lazarus IDE. It’s free and open source. It’s similar to Delphi.