Skip to content

Commit

Permalink
[ideas] Some other ideas for packages and traits
Browse files Browse the repository at this point in the history
  • Loading branch information
titzer committed Jun 27, 2024
1 parent 97f2854 commit f9626a2
Show file tree
Hide file tree
Showing 2 changed files with 300 additions and 0 deletions.
101 changes: 101 additions & 0 deletions doc/ideas/Packages.v3
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
Ideas for Virgil packages
-----------------------------

Goals:
- add namespacing capabilities for Virgil
- x86-linux constants vs x86-64-linux, etc
- v3.util.Vector
- better build system
- more ergonomic simple programs
- faster builds

Example packages:
- v3c.magic - Virgil compiler magic
- v3c.x86-linux - target-specific magic
- v3c.x86 - CPU-specific magic
- v3c.wasm - Wasm-specific magic
- v3rt.magic - runtime magic
- v3rt.gc
- v3rt.code
- v3rt.safety
- v3.cli - command-line utilities (env, etc)
- v3.util - data structures and strings
- v3.io - I/O
- v3.net - networking
- v3.file.macho
- v3.file.elf - ELF processing
- v3.file.jar - JAR
- v3.file.zip - ZIP files
- v3.file.class - Java class files
- v3.file.wasm
- v3.file.gpx
- v3.kernel.linux - Linux kernel constants and layouts
- v3.kernel.darwin - Darwin kernel constants
- v3.kernel.wali
- v3.kernel.zephyr
- aeneas.ir
- aeneas.ssa
- aeneas.mach
.x86
.x86-64
.arm
.arm64
.wasm
.jvm
- aeneas.os
.darwin
.linux
.none
- aeneas.tools
- aeneas.main
- aeneas.test
- aeneas.ast

Usage:
*/

//#File: lib/util/package.v3
//----------------------------------------
package v3.lib;
private XYZ;
add *.v3;
target x86-linux: add f*.x86*.v3
target jvm: add f*.jvm*.v3
using v3.lib;

//#File: lib/util/StringBuilder.v3
//----------------------------------------
// Copyright
class StringBuilder { ... }

//#File: MyFile.v3
//----------------------------------------
using v3.lib;

var map = Strings.newMap() with {
["foo"] = bar,
["foo1"] = bar2,
["foo2"] = bar3,
};
var b = StringBuilder.new() with {
.resize(44),
.puts("things"),
.putd(48),
.x = 99
}
System.puts(Arrays.reverse("Hello World!"));

/*
====================================
Index files: transparently cache modules/packages
Binary format, easy to mmap + parse header
package v3.lib
<versioning information>
<hash index>
name:offset, name:offset, name:offset
<reachability cache>
<bytecode>
<machine code?>
<source at end>
*/
199 changes: 199 additions & 0 deletions doc/ideas/Traits.v3
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
// Idea: traits are constraints on type parameters, analogous to Haskell Type Classes or C++ concepts.

type Value {
case I32(val: i32);
case I64(val: i64);
}

// An trait for boxable things, {Boxable} requires a type to have a method for boxing a {T} into a {Value}.
// The {T} binds a type parameter so that signatures of methods can refer to the type that {Boxable} constrains.
trait<T> Boxable {
def box(t: T) -> Value;
}

// An trait for unboxable things, {Boxable} requires a type to have a method for unboxing a {Value} into a {T}.
// The {T} binds a type parameter so that signatures of methods can refer to the type that {Unboxable} constrains.
trait<T> Unboxable {
def unbox(v: Value) -> T;
}

// An trait is used to limit what type arguments can be supplied at a given point.
// A polymorphic method to search an array for a given element type {T}. Given a range of boxed values, search
// through the range, unboxing and checking each value.
def find<T: Unboxable>(vs: Range<Value>, elem: T) -> int {
for (i < vs.length) if (T.unbox(vs[i]) == elem) return i;
return -1;
}

adapt i32 {
Boxable {
def box(t: i32) -> Value { return Value.I32(t); }
}
Unboxable {
def unbox(v: Value) -> i32 { return Value.I32.!(v).val; }
}
}

adapt i64 {
Boxable {
def box(t: i64) -> Value { return Value.I64(t); }
}
Unboxable {
def unbox(v: Value) -> i64 { return Value.I64.!(v).val; }
}
}

// Define the union of traits.
trait<T: Boxable&Unboxable> Boxed {
}

trait<T> group {
def one: T; // multiplicative identity

def "*"(a: T, b: T) -> T; // multiply operation

require(v: T) v == one * v; // strength-reduce multiply
require(a: T, b: T) (a * b) == (b * a); // commutative
require(a: T, b: T, c: T) a * (b * c) == (a * b) * c; // associative
}


trait<T> ring {
def zero: T; // additive identity
def one: T; // multiplicative identity

def inverse(a: T) -> T;
def "+"(a: T, b: T) -> T; // add operation
def "*"(a: T, b: T) -> T; // multiply operation

def "-"(a: T, b: T) => a + inverse(b); // define subtract operation

require(v: T) v == inverse(inverse(v)); // invertable
require(v: T) v == zero + v; // strength-reduce add
require(v: T) v == one * v; // strength-reduce multiply

require(a: T, b: T) (a + b) == (b + a); // commutative addition
require(a: T, b: T, c: T) (a + b) + c == a + (b + c); // associative addition
require(a: T, b: T) (a * b) == (b * a); // commutative multiplication
require(a: T, b: T, c: T) (a * b) * c == a * (b * c); // associative multiplication

require(a: T, b: T, c: T) (a - b) - c == a - (b + c); // reassociative subtraction
require(a: T, b: T, c: T) (a - b) + c == a - (c - b); // reassociative subtraction

require(a: T, b: T, c: T) a * (b + c) == (a * b) + (a * c); // distributive multiplication
require(a: T, b: T, c: T) (b + c) * a == (b * a) + (c * a); // distributive multiplication
}

type Vec2<T>(x: T, y: T) #unboxed {
def unop(f: T -> R) => Vec2<R>(f(this.x), f(this.y));
def binop(that: Vec2<T>, f: (T, T) -> T) => Vec2<T>(f(this.x, that.x), f(this.y, that.y));
}

type Vec3<T>(x: T, y: T, z: T) #unboxed {
def unop(f: T -> R) => Vec3<R>(f(this.x), f(this.y), f(this.z));
def binop(that: Vec3<U>, f: (T, U) -> R) => Vec3<R>(f(this.x, that.x), f(this.y, that.y), f(this.z, that.z));
}

// For any T that implements ring, Vec2<T> can implement ring.
implements<T: ring> Vec2<T> {
ring {
def zero = Vec2<T>(T.zero, T.zero);
def one = Vec2<T>(T.one, T.one);

def inverse(a: Vec2<T>) => a.unop(T.inverse);
def "+"(a: Vec2<T>, b: Vec2<T>) => a.binop(b, T.+);
def "*"(a: Vec2<T>, b: Vec2<T>) => a.binop(b, T.*);
}
}

// For any T that implements ring, Vec3<T> can implement ring.
implements<T: ring> Vec3<T> {
ring {
def zero = Vec3<T>(T.zero, T.zero, T.zero);
def one = Vec3<T>(T.one, T.one, T.one);

def inverse(a: Vec3<T>) => a.unop(T.inverse);
def "+"(a: Vec3<T>, b: Vec3<T>) => a.binop(b, T.+);
def "*"(a: Vec3<T>, b: Vec3<T>) => a.binop(b, T.*);
}
}

// For any two A and B that implement ring, (A, B) will also implement ring.
implements<A: ring, B: ring> (A, B) {
ring {
def zero = (A.zero, B.zero);
def one = (A.zero, B.zero);

def inverse(v: (A, B)) => (A.inverse(v.0), B.inverse(v.1));
def "+"(a: (A, B), b: (A, B)) => (a.0 + b.0, a.1 + b.1);
def "*"(a: (A, B), b: (A, B)) => (a.0.binop(b.0, A.*), (a.1.binop(b.1, B.*)));
}
}

trait<T: equal> integral {
def zero: T;
def max: T;
def min: T;

def "+"(a: T, b: T) -> T;
def "-"(a: T, b: T) -> T;
def "*"(a: T, b: T) -> T;
def "/"(a: T, b: T) -> T;
def "%"(a: T, b: T) -> T;
def "<"(a: T, b: T) -> T;

def ">"(a: T, b: T) => b < a;
def "<="(a: T, b: T) => a < b || a == b;
def ">="(a: T, b: T) => a > b || a == b;

def "<<"(a: T, b: shiftor) -> T;
def ">>"(a: T, b: shiftor) -> T;
def ">>>"(a: T, b: shiftor) -> T;
}

trait<T> Closeable {
def T.close();
}

class File implements Closeable {
def revoke() -> this;
def flush() -> this;
def close() => flush().revoke();
}

def run<R: Closeable>(resource: R) {
computeStuff();
resource.close();
}

trait<T, I, E> Indexable<I, E> {
def [index: I] -> E;
def [index: I] = val: E;
}

def search<M: Indexable<Key, Value>>(map: M) -> Value {
for (key in allKeys) {
var v = map[key];
if (v == null) return map[key] = Value.new();
return v;
}
}

def linearSearch<M: Indexable<int, Value>>(map: M, max: int) -> Value {
for (i < max) {
var v = map[i];
if (v == null) return map[i] = Value.new();
return v;
}
}

class HashMap<K, V> implements Indexable<K, V> { }

trait<T, V> Stack<V> {
def isEmpty() -> bool;
def push(v: V) -> this;
def pop() -> V?;
}

class ArrayStack<E> implements Stack<E> { ... }
class ListStack<E> implements Stack<E> { ... }

0 comments on commit f9626a2

Please sign in to comment.