Stof adds types and structure to data so that it can be more easily worked with. A major part of this is adding object types.
The default and most common object type is obj, which we've already seen many times on the Objectspage and in examples. This type is implied on object declarations that are not given an explicit type.
However, for more structured scenarios, Stof users can define a type for their objects, adding functions and expected fields with optional default values.
> stof run example.stof
2.24cm
3.74cm
2.24cm
3.74cm
2.24cm
3.74cm
Scoped Types
Just like functions, types are associated with an object in which they are defined. By default, Stof uses the closest type with a certain name.
Partial paths can also be used to reference types. In this example, one could use new first.Hello {} instead of new self.first.Hello {}. Stof will start its search with the first object it finds, matching the name with the start of the path.
A real-world use case for this is the Formata.Http.Request interface. If you know it's the only Http scope you have loaded into the document, you can use new Http.Request {} or new Request {} instead of new Formata.Http.Request {}.
first: {typeHello {fnhello():str {return"first"; } }}second: {typeHello {fnhello():str {return"second"; } }}#[main]fnrun() {let first = new self.first.Hello {};let second = new self.second.Hello {};pln(first.hello());pln(second.hello());}
> stof run example.stof
first
second
Casting
Function Signature Casting
typeBase {fnisBase():bool {returntrue; }}obj empty: {}fncreate_base():Base {return self.empty; // casts self.empty to Base because of return type}#[test]fncast_on_return() {let base = self.create_base();assertEq(typename base, 'Base');assert(base.isBase());}
typeNoDefaults { x: int; y: int;}#[test]#[errors]fnno_defaults() {let inst = new NoDefualts {}; // Does not provide an x an y}#[test]#[errors]fnwrong_types() {let inst = new NoDefaults { x:'hi'// wrong type and fails cast to an int y:5 };}