2016-01-11 16:52:26 +03:00
# Carp
2016-01-11 16:55:03 +03:00
2016-01-11 17:49:04 +03:00
< img src = "https://github.com/eriksvedang/Carp/blob/master/img/temp_logo2.jpg" alt = "Logo" align = "right" / >
2016-01-11 17:46:14 +03:00
2016-01-11 22:14:48 +03:00
< i > WARNING! This is a research project and a lot of information here might become outdated and misleading without any explanation. Don't try it out just yet!< / i >
2016-01-11 17:57:24 +03:00
Carp is a small programming language designed to work well for interactive and performance sensitive use cases like games, sound synthesis and visualizations.
2016-01-11 17:46:14 +03:00
The key features of Carp are the following:
2016-01-11 18:59:43 +03:00
* Automatic and deterministic memory management (no garbage collector or VM)
2016-01-11 18:55:41 +03:00
* Inferred static types for great speed and reliability
2016-01-11 22:11:49 +03:00
* Live reloading of code, REPL-driven development, aka "fun"
2016-01-11 18:47:04 +03:00
* Ownership tracking enables a functional programming style while still using mutation for fast updating of data structures
2016-01-11 18:54:33 +03:00
* No hidden performance penalties – allocation and copying is explicit
2016-01-11 18:36:31 +03:00
* Very good integration with exisiting C code
2016-01-11 17:57:24 +03:00
## The Language
2016-01-11 18:36:31 +03:00
Carp borrows its looks from Clojure but the runtime semantics are much closer to those of ML or Rust. Here's a sample program:
2016-01-11 17:57:24 +03:00
```clojure
2016-01-11 18:36:31 +03:00
(defn fib (n)
(if (< n 2 )
1
(+ (fib (- n 2)) (fib (- n 1)))))
2016-01-11 17:57:24 +03:00
```
2016-01-11 18:50:35 +03:00
This compiles to the equivalent of the following C program:
```C
int fib(int n) {
if(n < 2 ) {
return 1;
} else {
return fib(n - 2) + fib(n - 1);
}
}
```
2016-01-11 19:07:19 +03:00
The most important thing in Carp is to work with arrays of data. Here's how that looks:
```clojure
2016-01-12 12:46:40 +03:00
(defn weird-sum (nums)
(reduce + 0 (map inc (filter even? nums))))
2016-01-11 19:07:19 +03:00
```
2016-01-12 12:46:40 +03:00
All the array modification functions like 'map', 'filter', etc. use C-style mutation of the array and return the same data structure back afterwards, no allocation or deallocation needed!
2016-01-11 19:07:19 +03:00
2016-01-12 13:02:15 +03:00
### Data Literals
```clojure
100 ; int
3.14 ; float
2016-01-12 13:08:32 +03:00
true ; bool
2016-01-12 13:02:15 +03:00
"hello" ; string
2016-01-13 01:34:29 +03:00
'e' ; char
[1 2 3] ; array
2016-01-12 13:02:15 +03:00
```
### Special Forms
```clojure
(def variable-name value)
(defn function-name (arg1 arg2 ...) (function-body ...))
(let [var1 expr1, var2 expr2, ...] body)
(do expr1 expr2 ...)
(if expression true-branch false-branch)
(while expression body)
(for (i 0 100, j 0 100) body)
(set! variable value)
```
2016-01-12 13:13:09 +03:00
### Algebraic Data Types
2016-01-12 13:02:15 +03:00
```clojure
2016-01-12 13:13:09 +03:00
(defdata Color
RGB [r :float, g :float, b :float]
Grayscale [amount :float])
2016-01-12 13:02:15 +03:00
2016-01-12 13:13:09 +03:00
(def color (Grayscale 50.0f))
2016-01-12 13:02:15 +03:00
```
2016-01-12 13:13:09 +03:00
Omit the name tag to create a data constructor with the same name as the type:
2016-01-12 13:08:32 +03:00
```clojure
2016-01-12 13:13:09 +03:00
(defdata Vector3 [x :float, y :float, z :float])
2016-01-12 13:08:32 +03:00
2016-01-12 13:13:09 +03:00
(def position (Vector3 4.0 5.0 -2.0))
(def x-position (.x position)
2016-01-12 13:13:33 +03:00
```
2016-01-12 13:08:32 +03:00
2016-01-12 13:02:15 +03:00
### C interop
```clojure
(def blah (load-dylib "./libs/blah.so"))
(register blah "foo" (:int :int) :string) ;; will register the function 'foo' in the dynamic library 'blah' that takes two ints and returns a string
```
2016-01-11 19:07:19 +03:00
2016-01-11 17:57:24 +03:00
## The Compiler
2016-01-11 20:33:04 +03:00
Carp is very tightly integrated with it's compiler which itself is written in a dynamic version of Carp (which in turn is implemented in C). To work on a Carp program you run ```carp``` which starts the REPL. Everything you want to do to your program can be controlled from here.
2016-01-11 17:57:24 +03:00
2016-01-11 18:36:31 +03:00
For example, to compile the function defined above you would enter the following:
2016-01-11 18:51:46 +03:00
```clojure
λ> (bake fib)
2016-01-11 18:36:31 +03:00
```
2016-01-11 20:33:04 +03:00
This results in the compiler analyzing the code form for 'fib' and compiling it to some very fast binary code, immediately loading this back into the REPL so that it can be called from there.
2016-01-11 18:36:31 +03:00
2016-01-11 17:57:24 +03:00
(C) Erik Svedäng 2015 - 2016