The Heck Programming Language
Mashpoe (13)

The Heck Programming Language

I think the best way to demonstrate what's cool about heck is to just show some working code:

func factorial(num) {

    if (num == 1) {
        return 1
    }

    return num * factorial(num - 1)
}

print("5! is:")
print(factorial(5)) // prints 120

I assume you're probably wondering what's so special about that code. It just looks like a standard scripting language; a python clone!

It's not!

Heck is an attempt to use type inference as well as other extremely smart compile-time checks to make simple code fast. Heck is a statically-typed, compiled programming language, with a one-liner hello world:

print("hello world")

The main design philosophy behind Heck is that if a human can understand your code, a computer should be able to as well. After all, the point of a programming language is to allow humans to communicate with computers more easily.

Many language features make code harder to read for humans, and others make it more tough on computers.

For example, many people believe dynamic typing is easier for humans to understand and harder for computers, because computers cannot determine data types when reading code for a dynamically-typed language, while humans can.

We believe this to be completely false. A program is only a good program if you can look through the code and quickly understand it. Most of the time, Python code is very easy to understand, and any programmer with a good amount of experience should be able to tell you the types of every variable, even though the data types aren't explicitly defined.

The only reason a computer can't tell what the types will be
is because of a few rare edge cases, such as reassigning variable types:

a = 6

if randomCondition():
    a = "hello"

# now you don't know what type "a" is, and neither does the computer :(

Heck simply removes these weird edge cases and reads through your code in two passes in order to fully understand everything that's going on:

// during the first pass,
// nothing about the function "add" is not known
print(add(5, 6))

func add(a, b) {
    return a + b
}

Many languages avoid interpreting code in two passes at all cost, but they only ever miss out because of this.

Looking through code in this manner allows other kinds of compile-time checks as well:

let A: int

func printA() {
    print(A)
}

// ERROR: use of uninitialized variable "A"
printA()

A = 6

// OK
printA()

In the future, Heck will have reference types, and this functionality will be used to automatically do lifetime checks, ensuring that your code is completely safe.

Heck also compiles extremely fast. In fact, since the challenge asked for "wild and exciting" ideas, our team thought this would be a perfect opportunity to target one of the most underappreciated modern web technologies: WebAssembly. The Heck compiler was written from scratch in C in order to be extremely lightweight, and this allows it to be packaged into a JavaScript library.

heck.js

Heck.js is an experimental JS library that allows programmers to quickly run Heck code on the web. Heck.js has a very simple JavaScript API that allows it to quickly make calls in the browser:

example.html

<html>
    <head>
        <script src="heck.js"></script>
        <script>
        heck.addImports({
            getRandomNumber: function() {
                return Math.random();
            }
        });
        </script>
    </head>
    <body>
        <script type="heck">
        // import a function from JavaScript
        import func getRandomNumber() -> float
    
        // prints a random number to the console
        print(getRandomNumber())
        </script>
    </body>
</html>

Heck supports most common programming constructs. You can try heck in the main repl. There is a folder titled "examples" that you can look through in order to get an idea of the language.

You can also check out the docs and heck.js.

Our team name is @HeckLanguage and the members are @Deadly_Ore and @Mashpoe!

(Edit: I fixed up the submission, before the repl wasn't included properly)

You are viewing a single comment. View All
MocaCDeveloper (511)

How did you make it compiled?

Like, what did you do/what did you use to make it compiled?
I really want to make a compiled language, maybe you can help give advice on how to to it?

Mashpoe (13)

@MocaCDeveloper The most common way to make a compiled language is through the use of LLVM, which is a tool that allows you to make cross-platform compilers. In order to use it, your compiler must convert source code into LLVM IR (Intermediate Representation). IR is basically just a generic assembly language that LLVM can use to generate machine code (e.g. executables) for most CPU architectures.

This version of my language doesn't use LLVM, but it does have a similar approach. I used WebAssembly, which is similar to LLVM IR because it's a generic assembly language which can be assembled for a variety of different architectures by the browser. WebAssembly and LLVM IR both have their own respective text and binary formats. The LLVM IR binary format can be used to reduce the overhead of assembling the IR, but the WebAssembly binary format proved to be too difficult to work with directly for this jam.

The Heck compiler works by reading source code, generating a syntax tree, and using the syntax tree to produce WebAssembly code, which is written to a file in text format. Then another library is used library to convert the WebAssembly code from text format to binary format. After that is all done, the WebAssembly binary can be run directly in the browser, or through Node.js.

I wouldn't recommend using WebAssembly directly unless you want your language to be able to compile and run source code directly in the browser like Heck. LLVM is more cross-platform, and LLVM IR can also be converted into WebAssembly.

If you want to see how the syntax tree is converted into IR, you can look in the folder src/compiler in my project. The code in that folder generates WebAssembly code directly from the syntax tree.