2017-06-26 12:45:18 +03:00
|
|
|
## The Language
|
|
|
|
|
2017-06-26 16:58:23 +03:00
|
|
|
### Introduction
|
2017-06-26 16:50:51 +03:00
|
|
|
Carp borrows its looks from Clojure but the runtime semantics are much closer to those of ML or Rust.
|
|
|
|
Types are inferred but can be annoted for readability using the ```the``` keyword (see below).
|
2017-06-26 12:45:18 +03:00
|
|
|
|
2017-06-26 16:58:23 +03:00
|
|
|
Memory management is handled by static analysis, a value is owned by the function where it was created.
|
|
|
|
When a value is returned or passed to another function the initial function will give up ownership of it
|
|
|
|
and any subsequent use will lead to a compiler error. To temporarily lend a value to another function
|
|
|
|
(i.e. to print it) a reference must be created, using the ```ref``` special form (or the ```&``` reader macro).
|
|
|
|
|
2017-06-26 12:45:18 +03:00
|
|
|
### Data Literals
|
2017-06-26 16:50:51 +03:00
|
|
|
```
|
|
|
|
100 ; Int
|
|
|
|
3.14f ; Float
|
|
|
|
10.0 ; Double
|
|
|
|
true ; Bool
|
2017-06-26 12:45:18 +03:00
|
|
|
"hello" ; String
|
2017-06-26 16:50:51 +03:00
|
|
|
\e ; Char
|
2017-06-26 12:45:18 +03:00
|
|
|
[1 2 3] ; (Array Int)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Dynamic-only Data Literals
|
|
|
|
Right now the following data types are only available for manipulation in non-compiled code.
|
|
|
|
|
2017-06-26 16:50:51 +03:00
|
|
|
```
|
2017-06-26 12:45:18 +03:00
|
|
|
(1 2 3) ; list
|
|
|
|
foo ; symbol
|
|
|
|
```
|
|
|
|
|
|
|
|
### Special Forms
|
2017-06-26 16:50:51 +03:00
|
|
|
```
|
2017-06-26 12:45:18 +03:00
|
|
|
(def variable-name value)
|
2017-06-26 16:50:51 +03:00
|
|
|
(defn function-name [<arg1> <arg2> ...] <body>)
|
|
|
|
(let [<var1> <expr1> <var2> <expr2> ...] <body>)
|
|
|
|
(do <expr1> <expr2> ... <return-expression>)
|
|
|
|
(if <expression> <true-branch> <false-branch>)
|
|
|
|
(while <expression> <body>)
|
|
|
|
(ref <expression>) ;; Turns an owned value into an unowned one
|
|
|
|
(address <expression>) ;; Takes the memory address of a value, returns a C-style pointer
|
|
|
|
(set! <variable> <expression>) ;; Mutate a variable
|
|
|
|
(the Int <expression>) ;; Explicitly declare the type of an expression
|
2017-06-26 12:45:18 +03:00
|
|
|
```
|
|
|
|
|
2017-06-26 16:58:23 +03:00
|
|
|
### Reader Macros
|
|
|
|
```
|
|
|
|
&x ; same as (ref x)
|
|
|
|
@x ; same as (copy x)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Named Holes
|
2017-06-26 16:50:51 +03:00
|
|
|
When using a statically typed language like Carp it can sometimes be hard to know what value should
|
|
|
|
be used at a specific point in your program. In such cases the concept of 'holes' can be useful. Just
|
|
|
|
add a hole in your source code and reload (":r") to let the Carp compiler figure out what type goes there.
|
|
|
|
|
|
|
|
```
|
2017-06-26 16:58:23 +03:00
|
|
|
(String.append ?w00t "!") ;; Will generate a type error telling you that the type of '?w00t' is String
|
2017-06-26 12:45:18 +03:00
|
|
|
```
|
|
|
|
|
|
|
|
### Dynamic-only Special Forms
|
2017-06-26 16:58:23 +03:00
|
|
|
These can only be used at the REPL and during macro evaluation.
|
2017-06-26 16:50:51 +03:00
|
|
|
|
2017-06-26 12:45:18 +03:00
|
|
|
```
|
2017-06-26 16:50:51 +03:00
|
|
|
(defmacro <name> [<arg1> <arg2> ...] <macro-body>)
|
|
|
|
(dynamic <name> [<arg1> <arg2> ...] <function-body>)
|
|
|
|
(quote <expr>)
|
|
|
|
(car <collection>)
|
|
|
|
(cdr <collection>)
|
|
|
|
(list <expr1> <expr2> ...)
|
2017-06-26 14:45:51 +03:00
|
|
|
```
|
|
|
|
|
2017-06-26 16:58:23 +03:00
|
|
|
### Modules and Name Lookup
|
2017-06-26 14:45:51 +03:00
|
|
|
Functions and variables can be stored in modules which are named and can be nested. To use a symbol inside a module
|
|
|
|
you need to qualify it with the module name, like this: ```Float.cos```.
|
|
|
|
|
|
|
|
Importing a module makes it possible to access its members without qualifying them:
|
|
|
|
|
2017-06-26 16:50:51 +03:00
|
|
|
```
|
2017-06-26 14:45:51 +03:00
|
|
|
(import Float)
|
|
|
|
|
|
|
|
(defn f []
|
|
|
|
(cos 3.2f))
|
|
|
|
```
|
|
|
|
|
|
|
|
If there are several imported modules that contain symbols with the same name, the type inferer will try to figure
|
|
|
|
out which one of the symbols you really mean (based on the types in your code). If it can't, it will display an error.
|
|
|
|
For example, both the module ```String``` and ```Array``` contain a function named 'count'. In the following code it's
|
|
|
|
possible to see that it's the array version that is needed, and that one will be called:
|
|
|
|
|
2017-06-26 16:50:51 +03:00
|
|
|
```
|
2017-06-26 14:45:51 +03:00
|
|
|
(import String)
|
|
|
|
(import Array)
|
|
|
|
|
|
|
|
(defn f []
|
|
|
|
(count [1 2 3 4 5]))
|
|
|
|
```
|
|
|
|
|
|
|
|
In the following example it's not possible to figure out which type is intended:
|
2017-06-26 16:50:51 +03:00
|
|
|
```
|
2017-06-26 14:45:51 +03:00
|
|
|
(import String)
|
|
|
|
(import Array)
|
|
|
|
|
|
|
|
(defn f [x]
|
|
|
|
(count x))
|
|
|
|
```
|
|
|
|
|
|
|
|
Specifying the type solves this error:
|
2017-06-26 16:50:51 +03:00
|
|
|
```
|
2017-06-26 14:45:51 +03:00
|
|
|
(import String)
|
|
|
|
(import Array)
|
|
|
|
|
|
|
|
(defn f [x]
|
|
|
|
(String.count x))
|
2017-06-26 12:45:18 +03:00
|
|
|
```
|
|
|
|
|
|
|
|
### Structs
|
2017-06-26 16:50:51 +03:00
|
|
|
```
|
|
|
|
(deftype Vector2 [x Int, y Int])
|
2017-06-26 12:45:18 +03:00
|
|
|
|
2017-06-26 16:50:51 +03:00
|
|
|
(let [my-pos (Vector2.init 10 20)]
|
2017-06-26 12:45:18 +03:00
|
|
|
...)
|
|
|
|
|
|
|
|
;; A 'lens' is automatically generated for each member:
|
2017-06-26 16:50:51 +03:00
|
|
|
(Vector2.x my-pos) ;; => 10
|
|
|
|
(Vector2.set-x my-pos 30) ;; => (Vector2 30 20)
|
|
|
|
(Vector2.update-x my-pos inc) ;; => (Vector2 11 20)
|
2017-06-26 12:45:18 +03:00
|
|
|
```
|
|
|
|
|
2017-06-26 16:58:23 +03:00
|
|
|
### C Interop
|
2017-06-26 16:50:51 +03:00
|
|
|
```
|
|
|
|
(register blah (Fn (Int Int) String)) ;; Will register the function 'blah' that takes two Int:s and returns a String
|
|
|
|
(register pi Double) ;; Will register the global variable 'pi' of type Double
|
2017-06-26 12:45:18 +03:00
|
|
|
```
|
|
|
|
|