Crowbar
Jump to navigation
Jump to search
Crowbar is an experimental programming language by User:nddrylliog that borrows some of the ooc syntax, adding rules which allow the implementation of low-level stuff from a high-level point of view.
Function syntax
name: func (arg1, arg2, ...) -> ReturnType {
// body
}
The -> ReturnType part is optional.
So is the (arg1, arg2, ...) part.
Closure syntax
callTwice: func (f: Func(Int)) {
f(1)
f(2)
}
callTwice(|x| x toString() println())
Generics
Container: class [Elem] {
elem: Elem
}
c: Container[Int]
c elem = 42
c2: Container[String]
c2 elem = "Blah"
Rules
A simple rule
fac: func (i: Number) -> Number {
rule i > 0
if(i > 1) i * fac(i - 1) else 1
}
Quantifiers
\A (decl | condition) = universal quantifier (ie. "for all <decl> such that <condition>")
\E (decl | condition) = existential quantifier (ie. "there exists <decl> such that <condition>")
The | condition part is optional.
Sub-typing with rules (ie. narrowing types)
Nat: cover from Number {
rule \A (a: Nat | a >= 0)
}
Alternative, shorter form:
Nat: cover from Number {
rule this >= 0
}
Nested types
Array: class {
size: Nat
Index: cover from Nat {
rule this < size
}
get: func (i: Index) -> Elem
// ...
}
Examples
Incomplete code examples, more to come later:
// Function syntax
add := func (a, b) { a + b }
add(3, 5)
// Rule syntax!
rule add(-a, b) == add(b, -a)
// Covers can be re-used to create subtypes
Nat: cover from Int {
rule this >= 0
}
// Example of array data structure
Array: class [Elem] {
// Can't have a negative size, can have zero size
size: Nat
// dependent types
Index: cover from Nat {
rule this < size
}
// get
rule \A (i: Index)
\E (e: Elem | get(i) = e)
// add
rule \A (i: Index, e: Elem)
add(i, e) get(j) = match j {
case j < i => get(j)
case j = i => e
case j < size + 1 => get(j - 1)
}
// append
add(e) = add(e, size)
// delete
rule \A (i: Index)
delete(i) get(j) = match j {
case j < i => get(j)
case j < size - 1 => get(j + 1)
}
}
List: class [Elem] {
head, tail: Node
Node: class {
elem: Elem
next, prev: Option[This]
rule next prev = this
rule prev next = this
rule !\E head prev
rule !\E tail next
rule \A (e: Elem)
add()
}
}