Kind2/README.md

288 lines
7.2 KiB
Markdown
Raw Normal View History

2021-02-20 02:11:49 +03:00
# Kind
2021-05-16 03:19:56 +03:00
A minimal, efficient and practical proof and programming language. Under the hoods, it is basically Haskell, except purer and with dependent types. On the surface, it looks more like TypeScript. Compared to most proof assistants, Kind has:
2021-05-16 03:05:34 +03:00
2021-05-16 05:04:09 +03:00
1. The smallest core. Check this [700-LOC](https://github.com/moonad/FormCoreJS/blob/master/FormCore.js) reference implementation. It has the whole type system!
2021-05-16 03:05:34 +03:00
2021-05-16 03:13:22 +03:00
2. More powerful type-level features. Check [this article](https://github.com/uwu-tech/Kind/blob/master/blog/1-beyond-inductive-datatypes.md) on super-inductive datatypes.
2021-05-16 03:05:34 +03:00
2021-05-16 05:03:06 +03:00
3. A collection of friendly syntax sugars that make it less scary. Check [SYNTAX.md](https://github.com/uwu-tech/Kind/blob/master/SYNTAX.md).
2021-05-16 03:05:34 +03:00
2021-05-16 05:05:43 +03:00
4. Boostrapping: the language is fully implemented in itself! Check it [here](https://github.com/uwu-tech/Kind/tree/master/base/Kind).
2021-05-16 03:09:52 +03:00
2021-05-16 05:09:24 +03:00
5. Efficient real-world compilers. Check [http://uwu.tech/](http://uwu.tech) for a list of apps.
2021-05-16 03:05:34 +03:00
2021-05-16 05:08:43 +03:00
*Most apps disabled for a major update that will bring rollback netcode. Check again on May 17!*
2021-02-20 02:11:49 +03:00
Usage
-----
2021-04-26 18:06:35 +03:00
![npm](https://img.shields.io/npm/v/kind-lang)
2021-02-20 02:11:49 +03:00
2021-02-20 04:06:17 +03:00
```bash
npm i -g kind-lang # installs Kind
git clone https://github.com/uwu-tech/Kind # clones base libs
2021-02-20 16:03:35 +03:00
cd Kind/base # enters base libs
2021-02-20 04:06:17 +03:00
kind Main # checks Main.kind
kind Main --run # runs Main
```
2021-02-20 02:11:49 +03:00
*Right now, you must be at `kind/base` to use the language.*
2021-05-16 04:39:58 +03:00
Haskell and Scheme compilers and releases expected around June.
2021-02-20 02:11:49 +03:00
Examples
--------
2021-05-16 05:51:37 +03:00
### Some programs
2021-02-20 02:11:49 +03:00
2021-05-16 04:52:12 +03:00
```javascript
2021-05-16 05:51:37 +03:00
// A 'Hello, world!"
2021-02-20 02:11:49 +03:00
Main: IO(Unit)
IO {
2021-02-20 02:11:49 +03:00
IO.print("Hello, world!")
}
```
2021-05-16 04:52:12 +03:00
```javascript
2021-05-16 05:51:37 +03:00
// Quicksort (using recursion)
2021-05-16 04:47:09 +03:00
quicksort(list: List<Nat>): List<Nat>
2021-05-16 04:45:32 +03:00
case list {
nil:
[]
cons:
2021-05-16 04:54:43 +03:00
fst = list.head
min = filter!((x) x <? list.head, list.tail)
max = filter!((x) x >? list.head, list.tail)
2021-05-16 04:47:09 +03:00
quicksort(min) ++ [fst] ++ quicksort(max)
2021-05-16 04:45:32 +03:00
}
2021-05-16 04:50:25 +03:00
```
2021-05-16 04:45:32 +03:00
2021-05-16 04:52:12 +03:00
```javascript
2021-05-16 05:51:37 +03:00
// List iteration (using folds)
some_text: String
2021-05-16 05:49:35 +03:00
List.foldl!!("",
(str, result)
str = String.to_upper(str)
str = String.reverse(str)
result | str,
["cba","fed","ihg"])
2021-05-16 04:50:25 +03:00
```
2021-02-20 02:11:49 +03:00
2021-05-16 04:52:12 +03:00
```javascript
2021-05-16 05:51:37 +03:00
// List iteration (using fors)
some_text: String
2021-05-16 05:49:35 +03:00
result = ""
for str in ["cba","fed","ihg"] with result:
str = String.to_upper(str)
str = String.reverse(str)
result | str
result
2021-05-16 04:50:25 +03:00
```
2021-05-16 04:49:28 +03:00
2021-05-16 04:50:25 +03:00
```c
2021-05-16 05:49:35 +03:00
// Map, Maybe, String and Nat sugars
2021-05-16 05:51:37 +03:00
sugars: Nat
2021-05-16 04:49:28 +03:00
key = "toe"
map = {"tic": 1, "tac": 2, key: 3} // Map.from_list!([{"tic",1}, ...])
map = map{"tic"} <- 100 // Map.set!("tic", 100, map)
map = map{"tac"} <- 200 // Map.set!("tac", 200, map)
map = map{ key } <- 300 // Map.set!(key, 300, map)
val0 = map{"tic"} <> 0 // Maybe.default!(Map.get!("tic",map), 0)
val1 = map{"tac"} <> 0 // Maybe.default!(Map.get!("tac",map), 0)
val2 = map{ key } <> 0 // Maybe.default!(Map.get!(key, map), 0)
2021-05-16 04:53:41 +03:00
val0 + val1 + val2 // Nat.add(val0, Nat.add(val1, val2))
2021-02-20 02:11:49 +03:00
```
2021-05-16 04:47:09 +03:00
Check many List algorithms on [base/List](https://github.com/uwu-tech/Kind/tree/master/base/List)!
2021-02-20 02:11:49 +03:00
### Some types
2021-05-16 04:52:12 +03:00
```javascript
2021-05-16 05:58:59 +03:00
// A boolean
type Bool {
true
false
}
```
```javascript
// A natural number
type Nat {
zero
succ(pred: Nat)
2021-02-20 02:11:49 +03:00
}
2021-05-16 05:52:23 +03:00
```
2021-02-20 02:11:49 +03:00
2021-05-16 05:52:23 +03:00
```javascript
2021-05-16 06:10:04 +03:00
// A polymorphic list
type List <A: Type> {
nil
2021-05-16 06:12:33 +03:00
cons(head: A, tail: List<A>)
2021-02-20 02:11:49 +03:00
}
2021-05-16 05:52:23 +03:00
```
2021-02-20 02:11:49 +03:00
2021-05-16 05:52:23 +03:00
```javascript
2021-05-16 06:10:04 +03:00
// A polymorphic pair
type Pair <A: Type, B: Type> {
new(fst: A, snd: B)
2021-02-20 02:11:49 +03:00
}
2021-05-16 05:52:23 +03:00
```
2021-02-20 02:11:49 +03:00
2021-05-16 05:52:23 +03:00
```javascript
2021-05-16 06:10:04 +03:00
// A polymorphic dependent pair
type Sigma <A: Type, B: A -> Type> {
new(fst: A, snd: B(fst))
2021-02-20 02:11:49 +03:00
}
2021-05-16 05:52:23 +03:00
```
2021-02-20 02:11:49 +03:00
2021-05-16 05:52:23 +03:00
```javascript
2021-05-16 06:10:04 +03:00
// A polymorphic list with a statically known size
2021-02-20 02:11:49 +03:00
type Vector <A: Type> ~ (size: Nat) {
2021-02-20 04:22:31 +03:00
nil ~ (size = 0)
2021-05-16 06:12:33 +03:00
cons(size: Nat, head: Nat, tail: Vector<A,size>) ~ (size = 1 + size)
2021-02-20 02:11:49 +03:00
}
2021-05-16 05:52:23 +03:00
```
2021-02-20 02:11:49 +03:00
2021-05-16 05:58:59 +03:00
```javascript
// A bounded natural number
type Fin ~ <lim: Nat> {
2021-05-16 06:12:33 +03:00
zero<N: Nat> ~ (lim = Nat.succ(N))
succ<N: Nat>(pred: Fin<N>) ~ (lim = Nat.succ(N))
2021-05-16 05:58:59 +03:00
}
```
2021-05-16 05:52:23 +03:00
```javascript
2021-05-16 06:03:02 +03:00
// The type used in equality proofs
2021-05-16 04:54:15 +03:00
type Equal <A: Type, a: A> ~ (b: A) {
2021-02-20 04:22:31 +03:00
refl ~ (b = a)
2021-02-20 02:11:49 +03:00
}
```
2021-05-16 06:03:02 +03:00
```javascript
// A burrito
type Monad <M: Type -> Type> {
new(
2021-05-16 06:12:33 +03:00
bind: <A: Type, B: Type> M<A> -> (A -> M<B>) -> M<B>
pure: <A: Type> A -> M<A>
2021-05-16 06:03:02 +03:00
)
}
2021-05-16 05:58:59 +03:00
```
2021-05-16 06:03:02 +03:00
```javascript
// Some game entity
2021-05-16 05:58:59 +03:00
type Entity {
player(
name: String
pos: V3
health: Nat
2021-05-16 06:12:33 +03:00
items: List<Item>
2021-05-16 05:58:59 +03:00
sprite: Image
)
wall(
2021-05-16 06:12:33 +03:00
hitbox: Pair<V3, V3>
2021-05-16 05:58:59 +03:00
collision: Entity -> Entity
sprite: Image
)
}
```
2021-05-16 04:49:28 +03:00
Check all core types on [base](https://github.com/uwu-tech/Kind/tree/master/base)!
2021-02-20 02:11:49 +03:00
### Some proofs
2021-05-16 04:52:12 +03:00
```javascript
2021-02-20 03:57:38 +03:00
// Proof that `a == a + 0`
Nat.add.zero(a: Nat): a == Nat.add(a, 0)
case a {
zero: refl
succ: apply(Nat.succ, Nat.add.zero(a.pred))
}!
2021-05-16 05:52:23 +03:00
```
2021-02-20 03:57:38 +03:00
2021-05-16 05:52:23 +03:00
```javascript
2021-02-20 04:06:17 +03:00
// Proof that `1 + (a + b) == a + (1 + b)`
2021-02-20 03:57:38 +03:00
Nat.add.succ(a: Nat, b: Nat): Nat.succ(a + b) == (a + Nat.succ(b))
case a {
zero: refl
succ: apply(Nat.succ, Nat.add.succ(a.pred, b))
}!
2021-05-16 05:52:23 +03:00
```
2021-02-20 03:57:38 +03:00
2021-05-16 05:52:23 +03:00
```javascript
2021-02-20 03:57:38 +03:00
// Proof that addition is commutative
Nat.add.comm(a: Nat, b: Nat): (a + b) == (b + a)
case a {
zero:
Nat.add.zero(b)
succ:
2021-05-16 04:54:43 +03:00
p0 = Nat.add.succ(b, a.pred)
p1 = Nat.add.comm(b, a.pred)
2021-02-20 03:57:38 +03:00
p0 :: rewrite X in Nat.succ(X) == _ with p1
}!
2021-02-20 02:11:49 +03:00
```
2021-05-16 04:47:09 +03:00
Check some Nat proofs on [base/Nat/add](https://github.com/uwu-tech/Kind/tree/master/base/Nat/add)!
2021-05-16 04:09:37 +03:00
### A web app
2021-05-16 04:04:05 +03:00
```javascript
// Render function
App.Hello.draw: App.Draw<App.Hello.State>
(state)
DOM.node("div", {}, {"border": "1px solid black"}, [
DOM.node("div", {}, {"font-weight": "bold"}, [DOM.text("Hello, world!")])
DOM.node("div", {}, {}, [DOM.text("Clicks: " | Nat.show(state@local))])
DOM.node("div", {}, {}, [DOM.text("Visits: " | Nat.show(state@global))])
])
// Event handler
App.Hello.when: App.When<App.Hello.State>
(event, state)
case event {
init: IO {
App.watch!(App.room_zero)
App.new_post!(App.room_zero, App.empty_post)
}
mouse_down: IO {
App.set_local!(state@local + 1)
}
} default App.pass!
```
2021-05-16 05:00:42 +03:00
Source: [base/App/Hello.kind](https://github.com/uwu-tech/Kind/blob/master/base/App/Hello.kind)
2021-05-16 04:04:05 +03:00
2021-05-23 21:19:51 +03:00
Live: [http://uwu.tech/App.Hello](http://uwu.tech/App.Hello)
2021-05-16 05:00:42 +03:00
2021-05-23 21:19:51 +03:00
You can create your own UwU.Tech app by adding a file to `base/App`, with an `App.YourApp` `:` [App](https://github.com/uwu-tech/Kind/blob/master/base/App.kind)`(...)` definition.
2021-05-16 05:07:14 +03:00
2021-02-20 02:11:49 +03:00
Resources
---------
- Syntax reference: [SYNTAX.md](SYNTAX.md).
- Theorem proving tutorial: [THEOREMS.md](THEOREMS.md).
- Base library: [base](https://github.com/uwu-tech/Kind/tree/master/base).
- [Telegram chat](https://t.me/formality_lang)!
- Discord server (TODO)
[trusted core]: https://github.com/moonad/FormCoreJS
[FormCore-to-Haskell]: https://github.com/moonad/FormCoreJS/blob/master/FmcToHs.js
[kind.js]: https://github.com/uwu-tech/Kind/blob/master/bin/js/base/kind.js
[Agda]: https://github.com/agda/agda
[Idris]: https://github.com/idris-lang/Idris-dev
[Coq]: https://github.com/coq/coq
[Lean]: https://github.com/leanprover/lean
[Absal]: https://medium.com/@maiavictor/solving-the-mystery-behind-abstract-algorithms-magical-optimizations-144225164b07
[JavaScript compiler]:https://github.com/moonad/FormCoreJS/blob/master/FmcToJs.js