Dave Heinemann

A Survey of Native Programming Languages

In 2021, I started learning C, a goal I have had for a long time. It brought a level of excitement back to programming that I haven't felt since I was a complete beginner. I built Replicalc, a REPL-based calculator, experimented with developing a text adventure engine, and had a lot of fun. I always planned to do more with these projects, but eventually ran out of steam because…C is a pain.

I chose to develop these projects in C because I wanted to run them on both Linux and MS-DOS. That leaves few options, and C is likely the best documented and supported out of all of them. However, the reality is that C really sucks for application development, even on a small scale. It's a much slower, methodical, and error-prone process than I'd like it to be. I've enjoyed it and learned a lot from it, but it isn't practical enough for my purposes. It's time to look for something else.

What I really want is a language where I can be immediately productive and not have to worry too much about details like memory allocation. C, C++, and likely D are all too low-level for what I'm looking for. However, I don't want my software to require installation of a runtime or interpreter either, so that rules out popular high-level languages such as C#, Python, etc. Which languages lie in between these two groups?

Armed with a list of compiled languages from Wikipedia, I began looking through the options to see what suits my requirements. This blog post is an overview of the languages I've looked at, with my thoughts and impressions—it isn't intended to be an objective review.

Contents

Rust

Rust is a systems programming language that guarantees memory safety at compile-time—no garbage collector required. This makes it great for applications where security and reliability are essential, and it's lightning-fast. It's no wonder it's been voted the #1 most-loved programming language six years in a row on the annual Stack Overflow survey!

The first thing I noticed when I started diving into Rust is just how good the available documentation is. The Rust Book is thorough and well-written. Beyond that, there's an endless number of community guides and published books. Rust has experienced a surge in popularity over the past 5-odd years, so there's a massive community writing documentation and contributing to the Rust ecosystem.

On top of that, the development tools are outstanding, at least where VSCode is concerned. Its IntelliSense contains not only function and argument names, but also detailed descriptions and example code. There's a lot to like.

However, Rust has a steep learning curve. It's not insurmountable, but it's a different way of thinking to what I'm used to, and it's a bit off-putting. When it comes to my personal projects, I want a language that's dead-simple so that there are no barriers to me sitting down and writing code. Rust has a lot of potential, but it's decidedly not simple. I'd love to use it more in the future, but it's not the best choice for my current personal projects.

What I Like

What I Don't Like

Zig

Zig shows a lot of promise. It aims to provide a high level of safety while also remaining as simple as possible. In this way, it fills the middle-ground between C and Rust. It also has first-class support for integrating with existing C libraries, which should make it easy to use libraries like GTK.

I thought Zig would be a good choice for me. Safer than C, and simpler than Rust. However, I really don't like its syntax. It uses some odd choices that I can't get used to.

I also feel like the documentation is a bit lacking. In its current form, it's more like an information dump than a well-organised manual. This is understandable because Zig is still very young and yet to reach version 1.0. I'm sure we'll see this improve as it matures. But in the meantime, I found it unwieldy and difficult to find what I'm looking for.

In summary, I like where Zig is going. However, the syntax feels somewhat alien to me. Between that and the current documentation, I don't have the patience to thoroughly dive into it now. Maybe I'll revisit it in the future.

What I Like

What I Don't Like

PureBasic

PureBasic ticks a lot of the boxes I'm looking for. It compiles to native, it's high-level, and it's really simple.

What I like most about PureBasic is how intuitive it is. I was able to get productive almost immediately, and spent the afternoon developing a console-based Wordle clone. The documentation is well laid out, although more examples would be welcome. The standard library has plenty of features, including an easy-to-use (if limited) GUI library. PureBasic's included IDE is decent, and features syntax highlighting, GUI debugging, and a form designer—everything you need to get started.

However, PureBasic is not without its flaws. The most glaring is that it's a proprietary and commercial product. I wouldn't have even considered looking at PureBasic if I didn't already have a license. I bought one in 2011 and completely forgot about it, so I'm approaching PureBasic now for the first time.

The license is affordable and include updates for life. However, I couldn't justify publishing my code under a Free Software license if it required a commercial compiler to use. In fact, it's difficult to justify paying for a compiler at all in 2022, when they are nearly all free of charge and Free Software.

There are also some curious absences. For example:

These all seem like reasonable features for an established, easy-to-use language to have. I don't understand why they are absent in PureBasic.

Desite its flaws, I don't mind PureBasic. It seems somewhat stagnant, but it's charming in its own way. It might be more appealing if I were developing commercial software, but otherwise the commercial license is a deal breaker for me.

What I Like

What I Don't Like

FreeBASIC

FreeBASIC is a close competitor to PureBasic. As implied by the name, FreeBASIC is Free Software—a welcome change. Even better is that it supports MS-DOS, which I had overlooked during my previous survey of DOS-compatible programming languages. If FreeBASIC can deliver the best parts of PureBasic, but with the advantage of DOS support and a Free Software license, then it would be a serious contender for my next language. To find out, I set to work rewriting my PureBasic Wordle clone in FreeBASIC.

Like PureBasic, FreeBASIC is immediately intuitive. Its syntax is very similar to Visual Basic (both are descendents of QuickBasic). The documentation is of a fairly high quality, and more detailed than PureBasic's. Where it falls a little flat for me is the inconsistency between how different runtime library features are implemented. Many of them are implemented as methods (subroutines or functions). However, others are statements. For example, files are opened for reading with a statement like this: I suspect FreeBASIC does this to maintain compatibility with QuickBasic. Personally, I prefer the method syntax used by PureBasic and most other languages. For example:

The main downside of FreeBASIC is debugging. FreeBASIC uses GDB. There is no official IDE with integrated debugger. Although you can configure VSCode to debug FreeBASIC code with GDB, I wasn't able to get this to work without breaking my app's console features. Even when debugging with an external terminal, colors wouldn't work properly and some key presses wouldn't get handled. I'm not sure why this happens—I didn't encounter this when debugging Replicalc and other C projects with VSCode and GDB. It's possible that I've just overlooked or misconfigured something, but it makes debugging tedious.

Other than that, I haven't encountered any significant issues or annoyances. For my purposes, FreeBASIC seems like an ok alternative to C, but I would need to get GDB and VSCode co-operating before I use it seriously.

What I Like

What I Don't Like

Pascal

I came across Pascal a few times during my previous survey for MS-DOS programming languages. The classic Turbo Pascal compiler is now freeware, and Free Pascal is Free Software. Delphi is still available (and still obscenely expensive). However, I really don't enjoy Pascal syntax, and the community is tiny—maybe even smaller than what's left of the BASIC community. Pascal is a non-starter for me.

Nim

Nim looked like another good candidate. Its syntax is heavily inspired by Python, which is refreshing in a compiled language. The documentation is OK; it could be more detailed and better organised, but Nim is still relatively young.

Unfortunately, like FreeBASIC, I encountered issues with debugging in VSCode. This time it kind of worked—I could at least pause on breakpoints. However, the names of local variables would be garbled, and stepping over my code would inexplicably step into the Nim standard library instead. I tried following guides such as Jason Jones', but didn't have any luck fixing these issues. I would need to get debugging working properly in VSCode to give Nim a serious look.

What I Like

What I Don't Like

Go

Go was designed at Google for productivity, simplicity, and concurrency. Concurrency isn't very important for my personal projects, but productivity and simplicity certainly are.

After spending some time going through the Tour and building some test projects, I was really impressed. Go is dead-simple; the syntax makes sense and actively improves on the conventional C style; and the VSCode tooling and debugging just works. In addition, I didn't encounter any significant shortcomings. Go is almost a simpler, garbage collected C. Maybe it's not so surprising considering Ken Thompson co-designed them both.

My only major criticism of Go is that I don't like its error handling. In Go, functions can return multiple values (also not a fan), so the final value is often used to indicate whether an error has occurred. The main problem is that you can't nest function calls with multiple return values unless the outer function accepts multiple arguments of the same type. Instead, you're forced to call the two functions separately. I much prefer the C way of doing things, where you check for an error by passing a pointer to an integer. While you can do this in Go, it's not idiomatic and has issues due to Go's unique language features. It's not a big deal at the end of the day, so I'll just get used to it.

I've now rewritten ">Replicalc in Go. Replicalc isn't complex by any stretch, but this has been a good project to familiarise myself with the language, and it's now in a much better state for further development.

What I Like

What I Don't Like

Conclusion

Overall, I'm extremely happy with Go. It's almost exactly what I've been looking for: simple, high-level, and compiles to native. It's definitely going to be my go-to language for personal projects.

Rust has a tonne of potential. It would be my next choice after Go, and I'll likely use it in any projects where a garbage collector is unsuitable. If I could get past its syntax, Zig might be a good alternative; maybe it will grow on me.

PureBasic has a lot of charm, but its commercial license is a deal-braker. Nim and FreeBASIC are both superior, but I wouldn't consider using them unless I can get debugging to work in VSCode. And either way, I don't think they have much to offer me that Go or Rust don't.

Pascal is right out.

Do you have any thoughts or feedback? Let me know via email!

#Golang #Programming