Skip to content

Commit

Permalink
[ideas] Add ideas for model classes
Browse files Browse the repository at this point in the history
  • Loading branch information
titzer committed Jun 27, 2024
1 parent 41709fb commit dd6de13
Showing 1 changed file with 128 additions and 0 deletions.
128 changes: 128 additions & 0 deletions doc/ideas/Model.v3
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Ideas for programmable meta objects and meta classes.
* Instead of using the vague and slightly intimidating "meta" word, we'll use "model".
*/

/*
* Example A: Vehicles.
* 1. Vehicles have models which describe the shape of their wheels.
* 2. Vehicles have object identity, but the only other distinguishing characteristics of a vehicle are its color and its model.
* 3. Cars are vehicles that have a number of doors, fixed by the model of car, that can be broken off doing stunts.
* 4. Motorcycles are two-wheeled vehicles may optionally have a windshield or a chopper configuration.
* 5. The wheel configuration of a vehicle is extremely often used, because roads only interface with wheels.
* 6. Assume cars and vehicles are allocated frequently, models less so. Optimize space usage.
*/

// Preliminaries: wheel configs and colors.
type WheelConfig {
case Unicycle;
case Bicycle;
case Tricycle;
case Quad;
case More(count: u7);
}
enum Color {
BLACK, RED, YELLOW, BLUE
}

/*
* Option 1: new Virgil syntax for declaring a "model".
* The syntax is:
model MyClass.link {
class MyClass { ... }
}
* A /model/ is the "metaclass" of a class and syntactically has the class nested inside it.
* Every instance of the (inner) class has a reference to an instance of the model (outer) class that created it.
* The two occurrences of "MyClass" in the syntax must be the same valid identifier.
* The "link" name must be a valid identifier or the keyword "model".
* The (outer) model class is like a regular class when used by itself. It can extend another
class, have methods, be instantiated with "new", etc. It just has a special dotted name.
* The inner class "MyClass" has its name available at the top level. Its name is not
"MyClass.link.MyClass"--its "MyClass", because it is the common thing which is frequently written.
* The ".link" part of the model name also indicates the name of a field implicitly declared
in "MyClass" that will point to the enclosing "MyClass.link" instance.
* Instances of "MyClass" can only be allocated in the scope of "MyClass.link".
Their implicit "link" field will be initialized to point to the containing model instance,
which is guaranteed to be non-null and definitely initialized.
*/

// Option 1 defining a vehicle.
// A basic vehicle has a color and a model. We store the color directly in the car, but
// factor out the wheel config into the Vehicle.model.
// - vehicle.model points to instance of Vehicle.model, which can't be null
// => can be packed into single 64-bit object
model Vehicle.model(wheels: WheelConfig) { // "Vehicle.model" name lifted to top level
class Vehicle(color: Color) { // "Vehicle" name lifted to top level
def dup() -> Vehicle; // abstrat method to make a copy
}
// no methods here, which means no way to make a Vehicle directly.
}

// Option 1: define a car, which is a subclass of vehicle.
// Cars are limited in that they always have a quad wheel config.
// Cars are special in that they also have doors. They start having a number of doors dictated by their model.
// Then cars can lose doors in stunts. We want cars to always have a Car.model that stores the number
// of doors cars are expected to start with.
// - Car has a {color} field and a new {doors} field.
// - object header points to an instance of Car.model, which can't be null
// => can be packed into a single 64-bit object
model Car.model(doors: u6) extends Vehicle.model(WheelConfig.Quad) { // "Car.model" name lifted to top level
class Car extends Vehicle { // "Car" name lifted to top level
def var doors: u6;
new(color: Color, doors) super(color) { }

def dup() -> Car { return Car.new(color, doors); } // makes a copy
def doStunt(random: int -> int) -> this {
if (doors > 0 && random(6) == 0) doors--; // unlucky stunt busted off a door
}
}
// It's only legal to make a Car inside Car.model.
def make(color: Color) -> Car {
return Car.new(color, doors);
}
}

// Option 1: define a motorcyle, which is a subclass of vehicle.
// Motorcycles are limited in that they always have a bicycle wheel config.
// Motorcycles are special in that they can have a windshield and might be a chopper.
// Motorcycles are not mutable, and they can't do stunts like cars. Motorcycles are
// also limited to Color.BLACK.
model Motorcycle.model(windshield: bool, chopper: bool) extends Vehicle.model(WheelConfig.Bicycle) {
class Motorcycle extends Vehicle(Color.BLACK) { // "Motorcycle" lifted to top level
def dup() -> Motorcycle { return Motorcycle.new(); } // makes a copy
}
// It's only legal to make a Motorcycle in a Motorcycle.model.
def make() -> Motorcycle {
return Motorcycle.new();
}
}

// Example usages of the above definitions.
def main() {
def v1 = Vehicle.new(); // ERROR: illegal outside model

def m1 = Vehicle.model.new(WheelConfig.Bicycle); // create new model of vehicle

def m2 = Car.model.new(4); // create new 4-door car model
def c1: Car = m2.make(Color.RED); // create new red car
assert(m2 == c1.model); // every car remembers its model
var r = c1.doStunt().doStunt(); // do two stunts in a row

def m3 = JetCar.model.new(JetEngineDesign.TURBOFAN); // create a new jetcar model
def c1: Car = m3.make(Color.RED); // create a new jetcar, which is just a Car

def m4 = Motorcyle.model.new(true, false); // create a new motorcycle model
def mc1 = m4.make(); // create a new motorcycle
}

// This file has a secret jet engine project!
private enum JetEngineDesign {
TURBOFAN, AERO_SPIKE
}

// Option 1: define a private JetCar.model, which is a special kind of model.
// JetCar models can only have 2 doors.
// Private means it cannot be named outside this file.
private model JetCar.model(jet: JetEngineDesign) extends Car.model(2) {
// JetCar instances are not special (i.e. no subclass of Car). Only the model is special.
}

0 comments on commit dd6de13

Please sign in to comment.