DEV Community

praisethemoon
praisethemoon

Posted on

Type-C Programming Language

logo


Greetings!

Preface:

So, yesterday I have unveiled on reddit my magnum opus on Reddit, Type-C.

Type-C was born with a very strong personal opinion of programming and practices.

To sum it up, I love TypeScript and C, hence Type-C!

About Type-C

What does the language offer? A lot of features that would expect from a programming language.

  • Static & Structural type system (classes are an exception)
  • Generics
  • Structs (exhibit similar to behavior to JS objects without "prototype")
  • Classes & Interface (class inheritance is not allowed)
  • Enums & Algebraic Types
  • Closure & Coroutines
  • Inference Engine
  • Safe functional programming (argument mutability is part of the signature!)
  • Pattern Matching
  • Nullables
  • Probably more

The language runs on top of a custom VM called Type-V.

Currently plenty of features are missing, most notably compiler errors, VM runtime and documentation could always be better.

However, I consider the language to be in a testable state (not entirely usable).

The goal of Type-C is to be a general purpose language, oriented towards Apps & Games.

Where can I get Type-C

Type-C's website lives at https://typec.praisethemoon.org/, and you can the code on github:

As for IDE support, so far we have a VSCode Extension which only supports syntax highlighting.

A Taste of Type-C:

from std.io import println
from std.string import String

fn fib(x: u32) -> u32 = match x {
    0 => 0,
    1 => 1,
    _ => fib(x-1) + fib(x-2)
}

fn main(x: String[]) -> u32 {
    println("fib(20) = " + fib(20))

    return 0
}
Enter fullscreen mode Exit fullscreen mode

Type-C needs your help

Type-C is still at its very first steps, the compiler still has flaws and so does the VM.

If you would like to try something new and provide feedback and help shape the future of Type-C, I would like to welcome you to my discord server: https://discord.gg/4ZPQsXSunn

More examples!

from std.io import println
from std.array import Array

fn main() -> u32 {
   let arr = new Array<u32>([10, 10, 20, 30])
   let arr2 = arr.map(fn(x: u32) -> String = ""+x) 

   let f = fn(i: u64, x: String) {
      println("arr2["+i+"] = "+x)
      return i
   }

   arr2.forEach(f)

   return 0
}
Enter fullscreen mode Exit fullscreen mode
// from tests/test15.tc
from std.unit.test import TestUnit, UnitSet

fn test_case_1(rn: TestUnit) {
    let x = 10
    let result = do {
        let a = 3
        let b = 4
        if x > 5 && b == 4 {
            return a * b
        }
        return a + b
    }

    rn.assert_eq(result, 12) 
}

fn main() -> u32 {
    let test_1 = new TestUnit("test 1", "Tests do-expressions", test_case_1)
    let set = new UnitSet("Do-expressions tests", "Tests do-expressions", [test_1])
    return set.run()
}
Enter fullscreen mode Exit fullscreen mode
// from tests/test9.tc
from std.unit.test import TestUnit, UnitSet

fn test_case_1(rn: TestUnit) {
    let phones: Phone[] = [
        {"Samsung Galaxy S10", 3400},  // <-
        {"iPhone 11", 3110}, 
        {"Huawei P30", 3650}
    ]

    match phones {
        [p1, {price: 3110}, ...res] {
            rn.assert_obj_eq<String>(p1.name, "Samsung Galaxy S10")
            rn.assert_eq<i32>(p1.price, 3400)
            rn.assert_eq<u64>(res.length, 1)
            rn.assert_obj_eq<String>(res[0].name, "Huawei P30")
            rn.assert_eq<i32>(res[0].price, 3650)
        }

        _ {
            rn.assert_unreachable()
        }
    }
}

fn main() -> u32 {
    let test_1 = new TestUnit("test 1", "Tests array matching", test_case_1)
    let set = new UnitSet("Matching tests", "Tests pattern matching expression and statements", [test_1])
    return set.run()
}
Enter fullscreen mode Exit fullscreen mode

What you might dislike about Type-C

It is only fair to mention that type-c does not come with some "mainstream" features, these features are omited as design choice and not a technical one.

  1. No Runtime-Exceptions or try-catch:

Instead you can use Algebraic types (Variants) or Tuples (for function return only)

type ServerResponse = variant {
    Ok(code: u32),
    Error(code: u32, message: String),
}

fn test_case_3(rn: TestUnit) {
    let res: ServerResponse = ServerResponse.Ok(200)

    match res {
        ServerResponse.Ok(code) {
            rn.assert_eq<u32>(code, 200)
        }

        ServerResponse.Error(code, message) {
            rn.assert_unreachable()
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Classes cannot be inherited:

Type-C puts more emphasis on duck typing and behaviour driven rather than objects. This will be addressed in the future in some form of traits.

  1. Mutability: Declaring a variable as const, makes the entire object immutable (nested fields, array elements, etc).
let const vec = {x: 1, y: {z: 2}}
let const z1 = vec.y // Ok
let z2 = vec.y // Error
Enter fullscreen mode Exit fullscreen mode

Function arguments are immutable by default and the mutability status of a parameter is part of the function signature.

fn addStructs(a: {x: u32}, b: {x: u32}) -> u32 {
    a.x += b.x // Error
    return a.x
}
Enter fullscreen mode Exit fullscreen mode

there is a mutate keyword but it is discouraged.

Limitations:

Type-C is still under development, and some features are still missing.

More details on limitations can be found here: https://typec.praisethemoon.org/docs/limitations

Top comments (0)