shithub: limbobyexample

Download patch

ref: 1dbebd5fe59f27106a4dfa553c9ee8b893d6008e
parent: a609ffb20226eba3d4dc628d7b4d284eddd1c114
author: seh <henesy.dev@gmail.com>
date: Sun Mar 17 22:44:37 EDT 2019

add ADT example

--- /dev/null
+++ b/ADTs/README.md
@@ -1,0 +1,51 @@
+# ADT's
+
+Limbo supports Abstract Data Types (ADT's). These are analogous, but not equivocal to, structs in C and Go. 
+
+For further reading on ADT's and how they compose in different contexts, see [Modules](../Modules) and [Generics](../Generics).
+
+## Source
+
+### adts.b:12,16
+
+The type `Person` is an ADT declared within a module definition possessing an integer, string, and function reference member. 
+
+The function is named stringify and takes an argument named `p` which is a reference to the adt variable instance which called the function. This function could be thought as being analogous to a method. 
+
+Method-like function references declared with `self` as a keyword for an argument are not required to be called with said argument being passed. 
+
+Note: Modules are a form of ADT with some special rules associated with them that differentiates them from a normal ADT.
+
+### adts.b:19,23
+
+The type `Town` is an ADT declared outside of a module definition possessing an array of references to Person ADT's, a string, and a function reference. 
+
+### adts.b:28,29
+
+The variable `p` is created as a reference to an instance of a `Person` type which is instantiated using constructor-like syntax. The `Person` element `name` is then printed. 
+
+Note: Although the syntax used to instantiate the `Person` type instance appears to be a function, it is closer to a tuple being passed into an instance of a `Person`, but used in an in-line fashion. That is, the tuple must contain all non-function reference types contained within the ADT. 
+
+### adts.b:31,36
+
+The variable `t` is created as an instance of a `Town` ADT. The non-function reference elements are then initialized manually. Note that the `ref Person(...)` instantiation can be used as a valid variable instance. 
+
+### adts.b:41,52
+
+The method-like function references are declared with a bit of special syntax. That is, the function name takes the form of `ADT.func()`. 
+
+## Demo
+
+	; adts
+	Spike
+	Name: Mars
+	Size: 2
+	Members:
+	→ Spike
+	→ Ed
+	; 
+
+## Exercises
+
+- Can you instantiate an ADT via its constructor without all its non-function reference members?
+- How would you format the constructor-style instantiation of a `ref Town`?
--- /dev/null
+++ b/ADTs/adts.b
@@ -1,0 +1,52 @@
+implement ADTs;
+
+include "sys.m";
+include "draw.m";
+
+sys: Sys;
+print: import sys;
+
+ADTs: module {
+	init: fn(nil: ref Draw->Context, nil: list of string);
+
+	Person: adt {
+		age:	int;
+		name:	string;
+		stringify: fn(p: self ref Person): string;
+	};
+};
+
+Town: adt {
+	pop: array of ref Person;
+	name: string;
+	stringify: fn(t: self ref Town): string;
+};
+
+init(nil: ref Draw->Context, nil: list of string) {
+	sys = load Sys Sys->PATH;
+
+	p := ref Person(27, "Spike");
+	print("%s\n", p.name);
+
+	t: Town;
+	t.pop = array[] of {p, ref Person(13, "Ed")};
+	t.name = "Mars";
+
+	town := ref t;
+	print("%s\n", town.stringify());
+
+	exit;
+}
+
+Person.stringify(p: self ref Person): string {
+	return p.name;
+}
+
+Town.stringify(t: self ref Town): string {
+	s := "Name: " + t.name + "\nSize: " + string len t.pop + "\nMembers:";
+
+	for(i := 0; i < len t.pop; i++)
+		s += "\n→ " + t.pop[i].stringify();
+
+	return s;
+}
--- a/README.md
+++ b/README.md
@@ -38,6 +38,7 @@
 - [Slices](./Slices)
 - [Functions](./Functions)
 - [Function References](./Function-Refs)
+- [Abstract Data Types](./ADTs)
 - [Generics, Picks, and Interfaces (kind of)](./Generics)
 - [Exceptions](./Exceptions)