Ko

A language for programming recursive circuits

Ko
2. Language
2.4. Macros
2.4.1. Generic macros
2.4.1. Generic macros

Equal

Equal determines if its argument values are equal. It expects a monadic sequence argument. It returns true if all sequence elements are equal, and false otherwise. If the sequence is empty or has a single element, Equal returns true .

Example usage:

IsFoo(arg) {
	return: Equal("foo", arg)
}

Hash

Hash computes a short hash string corresponding to its argument value. It accepts any argument structure.

Example uses:

Hash("abc")
Hash(arg1: "abc", arg2: 123)
Hash(arg1: (1, 2, 3), arg2: "123")

Pick

Pick takes two arguments, named either and or . If the value of either is not empty, Pick will return it. Otherwise, it will return the value of the or argument.

Pick is used in situations where an optional value (say *String ) is expected, but a default value is available (say String ). As a result, the value returned by Pick will be guaranteed to be non-optional ( String in this example). For example,

Say(something) {
	return: Show(Pick(either: something, or: "hello"))
}

Join

The name of the “join” macro inside the Ko programming environment is actually the empty string. The macro accepts any arguments that the user passes and returns a Ko value holding its argument structure. In other words, the “join” macro is the standard mechanism for creating ad-hoc values. Let's look at a few examples.

When join is invoked with named arguments, it returns structure values. For instance

(x: 123, y: "abc")   // of type (x: Int64, y: String)
(x: 123, y: (f: 3.13, g: "def"))   // of type (x: Int64, y: (f: Float64, g: String))

When join is invoked with a monadic (unnamed) argument, it returns the argument itself. For instance

(123)   // returns 123 of type Int64
("abc", "def")   // returns ("abc", "def") of type (String)

Memory, Remember and Recall

A trio of macros (memory, remember and recall) allow for the creation of generic type-safe hash tables, with keys and values from the full spectrum of Ko types.

Memory has no arguments. It creates a new hash table. The value returned by invoking Memory is a structure with two fields, Remember and Recall , both of which are varieties. In other words, you can view them as “methods” attached to a structure.

Remember expects two arguments, named key and value , which can be of any type. It has the effect of placing the key-and-value pair into the hash table. Note that even though the key and value can be of any types, the compiler will ensure that the key and value types of a hash table instance do not change over the course of its use.

Recall expects two arguments, named key and otherwise . The latter is optional. If a value is found in the hash table under the requested key, it is returned. Otherwise, if the otherwise argument is present its value is returned. If it is not present, the Ko type system will determine that this Recall macro returns an optional type (which will inform type checking downstream) and will return an empty value.

ShowMeTheValue(x) {
	memory: Memory()   // create a hash table
	remember: memory.Remember(key: "abc", value: x)
	found: memory.Recall(
		_: remember   // passing an unused argument ensures Recall runs after Remember
		key: "abc"
	)
	return: Show(found)   // display the looked-up value
}