Last active
May 27, 2021 06:07
-
-
Save SanderMertens/cb53ed19564a69a738a9855502d82b69 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// - each expression has a type & an optional value. | |
// | |
// - if the expression is an integer literal: | |
// - the type is Integer | |
// - the value is the integer value | |
// | |
// - if the expression is an floating point literal: | |
// - the type is Float | |
// - the value is the integer value | |
// | |
// - if the expression is an argument list, the type is a Type<args = argument list> | |
// | |
// - if the expression is of an unknown/unspecified type, the type is undefined | |
// | |
// - any program with variables/values of an undefined type cannot be executed | |
// | |
// - if the expression is a literal, its type is partially defined | |
// | |
// - a program may contain partially defined types, as long as they can be | |
// resolved to fully defined types where used | |
// | |
// - if the expression is a function (identifier + argument list): | |
// - the type is Type<kind = Function, args = argument list> | |
// - the value is the function | |
// | |
// - if the expression is a complete function call: | |
// - the type is the function return type | |
// - if the function has no body the returntype is the function | |
// | |
// - if the expression is an incomplete function call: | |
// - the type is the function type minus the provided arguments | |
// - the value is a partially constructed function call | |
// | |
// - if the expression is a function A that is assigned to a function B, | |
// the arguments of function A are matched & passed by name to function B | |
// when function A is called | |
// | |
// - when an untyped value (literal, initializer list) is assigned to a typed | |
// variable, the type function is called with the value before it is assigned. | |
// | |
// - when an untyped value (literal, initializer list) is assigned to an | |
// untyped variable, the variable assumes the equivalent type of the value. | |
// | |
// - when an untyped value is passed to a parameter of a function, it is | |
// as if the value is assigned to a variable of the type of the parameter. | |
// | |
// - if a type's argument list contains one or more named arguments, literal | |
// values of that type must use an initializer list, e.g. { } | |
// Example: position(int x, int y); position p = {10, 20} | |
// | |
// - if a type's argument list contains a single unnamed argument, literal | |
// values for that type should not use an initializer list | |
// Example: int(int); int i = 10; | |
// | |
// - a function contains zero or more immutable key-value pairs, written inside | |
// of < > | |
// | |
// - the function name together with the key-value pairs uniquely identify a | |
// function | |
// | |
// - key-value pairs may be added to a function, which creates a new function | |
// | |
// - each key may only occur once in the list | |
// | |
// - keys may be forward declared without a value | |
// | |
// - a forward declared key that is not assigned a value behaves as if the key | |
// does not exist when accessed by value but cannot be forward declared again | |
// | |
// - keys may be forward declared with an undefined value | |
// | |
// - a function that contains keys with undefined values cannot be called | |
// | |
// - a program that has one or more keys with undefined values cannot be ran. | |
// | |
// - two types with the same base but different key-value pairs are assignable | |
// as long as overlapping keys match | |
// | |
// - a type is always assignable to itself | |
// | |
// - a variable may always be assigned a value as long as its type is assignable | |
// | |
// - a function with argument types that have undefined keys is undefined | |
// | |
// - when an undefined function is (partially) called, the types of the provided arguments | |
// must specify defined values for the undefined keys. | |
// | |
// - when one or more undefined keys are deduced from function arguments, the type of | |
// the resulting expression will be the original function type where the deduced | |
// key values will have replaced the undefined values. | |
// | |
// Type bootstrap | |
Type<kind = undefined>() | |
// type == Type<kind = Function, args = ()> | |
// value == Type<kind = undefined> | |
// Bootstrap function for number types | |
Number<kind = undefined> = Type<kind = Number<kind = kind>> | |
// type == Type<kind = Function, args = ()> | |
// value == Number<kind = undefined> == Type<kind = Number<kind = undefined>> | |
// Bootstrap function for integer type | |
Integer(Integer) = Number<Integer> | |
// type == Type<kind = Function, args = (Integer)> | |
// value == Integer == Number<Integer> == Type<kind = Number<Integer>> | |
// Bootstrap function for float type | |
Float(Float) = Number<Float> | |
// type == Type<kind = Function, args = (Float)> | |
// value == Float == Number<Float> == Type<kind = Number<Float>> | |
i = 10 | |
// type == Integer | |
// value == Integer(10) == 10 | |
l = {10, 20} | |
// type = Type<kind = Initializer> | |
// value = {10, 20} | |
int = Integer | |
// type == Type<kind = Function, args = (Integer)> | |
// value == Integer == int | |
i = int(10) | |
// type == int == Integer | |
// value == int(10) == 10 | |
a = (int x, int y) | |
// type == Type<args = (int x, int y)> | |
position(int x, int y) | |
// type == Type<kind = Function, args = (int x, int y)> | |
// value === position | |
position_10 = position(10) | |
// type == Type<kind = Function, args = (int y)> | |
// value === position(x = 10) | |
p = position(10, 20) | |
// type == position | |
// value === position(x = 10, y = 20) | |
p = position_10(20) | |
// type == position | |
// value === position(x = 10, y = 20) | |
position_3d(int x, int y, int z) = position(int x, int y) | |
// type == Type<kind = Function, args = (position(int x, int y), int z)> | |
// value === position_3d | |
p = position_3d(10) | |
// type == Type<kind = Func, args = (position(int y), int z)> | |
// value === position_3d(x = 10) | |
p = position_3d(10, 20) | |
// type == Type<kind = Func, args = (int z)> | |
// value === position_3d(x = 10, y = 20) | |
p = position_3d(10, 20, 30) | |
// type == position_3d | |
// value === position_3d(x = 10, y = 20, z = 30) | |
p = position_3d(position(10, 20), 30) | |
// type == position_3d | |
// value === position_3d(x = 10, y = 20, z = 30) | |
line(int x1, int y1, int x2, int y2) = (position(int x1, int x1), position(int x2, int y2)) | |
// type == Type<kind = Function, args = (position(int x1, int y1), position(int x2, int y2))> | |
// value == line | |
l = line(10, 20, 30, 40) | |
// type == line | |
// value === line(10, 20, 30, 40) | |
line(position start, position stop) | |
// type == Type<kind = Function, args = (start = position(int x, int y), stop = position(int x, int y))> | |
l_xyx = line({10, 20}, {30}) | |
// type == Type<kind = Function, args = (stop = position(int y))> | |
// value === line(start = {x = 10, y = 20}, stop = {x = 30}) | |
l_stop = line(stop = {30, 40}) | |
// type == Type<kind = Function, args = (start = position(int x, int y))> | |
// value === line(stop = {30, 40}) | |
l = l_xyx(stop = {40}) | |
// type == line | |
// value === line({10, 20}, {30, 40}) | |
l = l_stop({10, 20}) | |
// type == line | |
// value === line({10, 20}, {30, 40}) | |
red_line = line<color = Red> | |
// type == Type<kind = Function, args = (position(int x1, int y1), position(int x2, int y2))> | |
// value == line<color = Red> | |
rl = red_line({10, 20}, {30, 40}) | |
// type == line<color = Red> | |
// value == line<color=Red>({10, 20}, {30, 40}) | |
flip(line l) { | |
return line(l.stop, l.start) | |
} | |
// type == Type<kind = Function, args = (line l)> | |
// value = line | |
flip(line l) = line(l.stop, l.start) | |
// same | |
f = flip(l) | |
// type = line | |
// value = line({30, 40}, {10, 20}) | |
sum(Number a, Number b) { | |
return a + b | |
} | |
// type = Type<kind = Function, args = (Number<kind = undefined> a, Number<kind = undefined> b)> | |
// value = Number<kind = undefined> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment