Jakt: A First Look

First Look: The Jakt Programming Language

Luke Zeisset Development Technologies, Programming Leave a Comment

There seems to be a renaissance in systems programming languages. Updates to C and C++ don’t seem to get the attention of a lot of developers that aren’t already interested in their development. In contrast, languages like Go, Rust, and Zig are hot topics that seem to do an excellent job recruiting people, nearly providing the level of accessibility that Python does.

A fairly new programming language appeared this year that strikes an intriguing balance between C++ and Rust. That language is Jakt, and I’d like to shine some light on it.

What Is Jakt?

The Jakt programming language began as an offshoot project from SerenityOS – a Unix-like operating system built in C++ that celebrates the computing aesthetics of the ‘90s. Announced in May 2022, Jakt was created to address concerns about memory safety and the future of the SerenityOS project.

The name Jakt comes from the Swedish word for “hunt,” which is quite appropriate. The idea is that the hunt for an appropriate language was not satisfied, so a new language was necessary to fulfill the wants and needs of the SerenityOS project.

In true hacker fashion, Jakt borrows features and syntax from other programming languages and maintains the ability to easily interop with SerenityOS by transpiling to C++. Additionally, the C++ output can be run through tools such as Emscripten to create WebAssembly modules.

A Simple Example

To demonstrate Jakt, here is a simple example with an implementation of FizzBuzz. The syntax should seem somewhat familiar. I have marked up the code with comments to highlight some points of interest.

class FizzBuzz {
    public max_number: i64

    // `throws` keyword shows that this may fail
    public function greeting(name: String) throws -> String {
        return format("Hello, {}!", name)
    }
    
    // Member functions have `this` parameter
    public function run(this) {
        // Looping, with a range
        // `..` is not inclusive, so we are adding one
        // Using `.max_number` is equivalent to `this.max_number`
        for i in 1 .. 1+.max_number {
            // Conditionals are familiar, not requiring parentheses

            if i % 15 == 0 {
                println("FizzBuzz")
                continue
            }

            if i % 3 == 0 {
                println("Fizz")
                continue
            }

            if i % 5 == 0 {
                println("Buzz")
                continue
            }

            println("{}", i)
        }
    }
}

function main() {
    // Calling a static function and storing in mutable variable
    // Note that parameters must be named by the caller
    mut my_greeting = FizzBuzz::greeting(name: "Jakt user")
    println(my_greeting)

    // Modifying my_greeting
    my_greeting = "Howdy!"

    // Referencing parameter in format string
    println("{0} {0}", my_greeting)

    // Create an instance of FizzBuzz, storing in immutable variable
    let fizzbuzzer = FizzBuzz(max_number: 20)
    // Calling a member function
    fizzbuzzer.run()
}

Even if you had zero experience with C++ or Rust, I think it’s easy to follow this example. All in all, nothing too surprising, but the main items that might trip up users actually come from other languages. These are as follows.

  • Statements do not end with a semicolon.
  • Parameters must be named when functions are called.
  • Data types follow the name of the variable or function signature.
  • Variables are immutable by default and must be declared as mut to make them mutable.

Comparing Jakt With Rust

It’s difficult for me to not bring up Rust when talking about Jakt. Both languages have the promise of memory safety. A large part of the syntax for Jakt was borrowed from Rust. Even the first implementation of the Jakt compiler was written in Rust.

However, there are some notable differences. The biggest difference would be that Rust has a very steep learning curve. There are many tutorials and videos available that go over Rust’s ownership model and lifetimes. Jakt is much easier to get started using without having to deal with those topics, making it almost Go-like in how approachable it is.

Rust does not have the “traditional” object-oriented style, but the traits system Rust employs provides some level of being object-oriented. Jakt supports classes in the traditional object-oriented way, but at least at the time of this writing, inheritance is not yet implemented. A traits system is currently planned for Jakt.

Another thing to consider is that since Jakt transpiles to C++, you can easily embed C++ in Jakt’s unsafe code blocks. This can be very beneficial for anyone porting code from C++. Not only that but interoperability is maintained between Jakt and C++, keeping many existing C++ libraries easily accessible.

Where Do We Go From Here?

Much like how C++ began as a preprocessor for the C programming language, Jakt could very well go from transpiling to C++ to being embraced as a standalone language being taught in schools. We’ll see as time goes on!

One thing to keep in mind is that Jakt is a young language that is still under heavy development. The README for the language shows many planned features that are not fully implemented as of yet.

Despite this, Jakt is quite capable, and even the popular online tool Compiler Explorer has Jakt as an option to test out the language if you do not wish to set it up locally. There are many opportunities to get on the ground floor to build libraries and tools for Jakt for anyone that is interested.

The hunt is on!

If you enjoyed this post or have questions or comments, leave me a note below. While you’re at it, check out the many more posts like this one available on the Keyhole Dev Blog.

3.3 3 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments