Skip to content

Instantly share code, notes, and snippets.

@VictorKoenders
Last active October 27, 2024 14:32
Show Gist options
  • Save VictorKoenders/06725780a79f6f18806de41fbfd170d4 to your computer and use it in GitHub Desktop.
Save VictorKoenders/06725780a79f6f18806de41fbfd170d4 to your computer and use it in GitHub Desktop.
Idea for a typescript-esque compiled language

struct is an actual implementation

// explicit
struct Foo { name: String };

const foo: Foo = { name: "bob" };
// ^= struct Foo { name: String };

// implicit
const bar = { age: 18 };
// ^= anonymous struct { age: number };

type is anything that matches the given type

type Foo = { name: String };
fn bar(f: Foo) {
   stdout.println(f.name);
   // f = type { name: String };
}

const person = { name: "Bob", age: 18 };
// ^= anonymous struct { name: String, age: number };
bar(person); // ok
const restaurant = { name: "Snackbar", location: "1st street, some place" };
// ^= anonymous struct { name: String, location: String };
bar(restaurant); // ok

Allow generic functions over types with fields

fn foo(a: impl { name: String }) {
    stdout.print(a.name);
}

// or:

fn foo<A>(a: A) 
    where A: impl { name: String }
{
    stdout.print(a.name);
}

// or:

type FooArg = { name: String };

fn foo(a: FooArg) {
}

Allow multiple where conditions per function

type foo<T>(t: T)
  where T: { name: String },
  T: SomeInterface
{
    stdout.print(a.name);
}

Allow remapping types by key

struct Foo {
    name: String,
}

type Bar = {
    [for key in Foo]: i32,
};
// ^= type Bar = { name: i32 }

Allow appending fields & types

type Foo = { name: String };
type Bar = { age: i32 } & Foo;
// ^= type Bar = { name: String, age: i32 };

Allow removing fields with never

type Foo = { name: String, age: i32 };
type Bar = Foo & {
    age: never
};
//^ type Bar = { name: String };

Getters & setters

struct Foo {
    get name() { return "Foo"; }
    set name(value: String) { stdout.print("New name is", value); }
}

underscore variables are private

struct Foo {
    _name: String;
}

Example for making a struct readonly:

struct Foo {
    name: String
}

type Bar<T> = {
    _inner: T,
    [for key in T]: get() -> T[key] {
        return _inner[key];
    }
}

How to do memory management?

  • Reference counted? <- probably starting with this
  • Borrow checker?
  • RAII?

How to do C interop?

How to compile?

  • Transpile to C?
  • Direct LLVM-IR? <- probably starting with this

Allow function overloading?

trait Display { ... }
fn Foo(params: impl Display) {
   const lock = stdout.lock();
   for param in params {
       lock.write(param);
   }
   lock.writeline();
}

How to do interfaces/traits?

How to implement functions for structs/types?

  • Always have the first argument be the context?
type Foo = {};
function foo(this: Foo) {
    stdout.print("Hello world");
}
const f: Foo = {};
f.foo();

How to do inheritance?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment