Carp is a statically typed Lisp without a GC for high performance applications.
- Lisp is great
- Most lisps are garbage collected, won't work well for games, etc.
- But I want to make games!
- Games
- Audio and video generation
- Static type system (subset of ML)
- No garbage collection (a la Rust)
- Lisp (Clojure) syntax
- A helpful and interactive programming environment
- REPL = project
- (load ) and (reload)
- (build) and (run)
- GHCI-style shortcuts, i.e. ":rbx"
- A build system
- Functions, values & types
- Memory management
- Modules
- Defining data types
- Array processing
(defn circle-area [r] (* pi (* r r))
(defn id [x] x)
(def gravity 9.8)
(defn circle-area [r] (* pi (* r r)) : (λ [Float] Float)
(defn id [x] x) : (λ [a] a)
(def gravity 9.8) : Double
鲮 (type println)
=> IO.println : (λ [(Ref String)] ())
An idea stolen from Idris.
(defn id-for-strings-only [x]
(the String x))
鲮 (+ 1.0f ?w00t)
=> ?w00t : Float
(let [s (get-line)]
(println "OK")
<here>)
get-line : (λ [] String)
(let [s (get-line)]
(validate-string s))
(let [s (get-line)]
s)
validate-string : (λ [String] Bool)
(let [s (get-line)]
(do (validate s)
(validate s)
(validate s)))
=> Using a given-away value 's'
(let [s (get-line)]
(do (println (ref s))
(println (ref s))
(println (ref s))))
s : String
println : (λ [(Ref String)] ())
A reader macro.
(let [s (get-line)]
(do (println &s)
(println &s)
(println &s)))
(println "Hi!")
Would lead to dangling pointers.
(defn invalid []
(let [s (get-line)]
&s
<delete s here>))
invalid : (λ [] (Ref String))
The 'copy' functions take Ref:s and return non-Ref:s.
(defn name []
(copy "John McCarthy"))
name : (λ [] String)
String.copy : (λ [(Ref String)] String)
(defn name []
@"John McCarthy")
- Allow sharing of names
- Clarify which function or value that is used in the code
(defmodule Goods
(defn cost [] (random-between 100 200))
(def amount 75600))
(defn total-cost []
(* (Goods.cost) Goods.amount))
;; stuff.carp
(defmodule A
(defn f [] ...)
(defn g [] ...))
(defmodule B
(defn f [] ...)
(defn g [] ...)
(defn h [] ...))
(defmodule A
(defn f [] ...))
(defmodule A
(defn g [] ...))
(use Int)
(defn twice [x] (+ x x))
twice : (λ [Int] Int)
(use Int)
(use Double)
(use Float)
(defn inc [x] (+ x 1))
1 : Int
inc : (λ [Int] Int)
'+' resolves to 'Int.+'
(defmodule Ur
(defn f [x]
(foo x)))
(defmodule A
(defn foo [x]
(+ x 1)))
(defmodule B
(defn foo [x]
(+ x 1.0f)))
(defn tester []
(Ur.f 42))
(definterface foo (λ [a] a))
(defmodule Ur
(defn f [x]
(foo x)))
(defmodule A
(defn foo [x]
(+ x 1)))
(defmodule B
(defn foo [x]
(+ x 1.0f)))
(defn tester []
(Ur.f 42))
copy : (λ [&a] a)
str : (λ [a] String)
= : (λ [a, a] Bool)
鲮 (type Double)
Double : Module = {
* : (λ [Double Double] Double)
+ : (λ [Double Double] Double)
- : (λ [Double Double] Double)
/ : (λ [Double Double] Double)
cos : (λ [Double] Double)
from-int : (λ [Int] Double)
sin : (λ [Double] Double)
str : (λ [Double] String)
to-int : (λ [Double] Int)
pi : Double
}
(deftype Point
[x Int
y Int])
(deftype Point
[x Int
y Int])
Point : Module = {
init : (λ [Int Int] Point)
new : (λ [Int Int] (Ptr Point))
copy : (λ [(Ref Point)] Point)
delete : (λ [Point] ())
str : (λ [(Ref Point)] String)
x : (λ [(Ref Point)] Int)
y : (λ [(Ref Point)] Int)
set-x : (λ [Point Int] Point)
set-y : (λ [Point Int] Point)
update-x : (λ [Point (λ [Int] Int)] Point)
update-y : (λ [Point (λ [Int] Int)] Point)
}
(deftype Vec2
[x Int
y Int])
(deftype Vec3
[x Int
y Int
z Int])
(let [v (Vec2.init 11 35)]
(Vec2.x &v))
(let [v (Vec3.init 300 400 500)]
(Vec3.set-y v 0))
- Tagged unions
- Generic data types
[1 2 3 4 5]
Array.range : (λ [t t t] (Array t))
Array.repeat : (λ [Int (λ [] t)] (Array t))
Array.replicate : (λ [Int (Ref t)] (Array t))
Yes, the 't' in 'range' is too general.
Will allocate new memory and leave the old data as-is.
(let [xs [1 2 3 4 5]]
(copy-map Int.str &xs))
copy-map : (λ [(λ [&a] b), &(Array a)] (Array b))
(let [xs [1 2 3 4 5]]
(endo-map square xs))
Ownership of 'xs' is passed to the 'endo-map' function, which will mutate the array and return it.
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Haskell 23 607 330 4350
-------------------------------------------------------------------------------
SUM: 23 607 330 4350
-------------------------------------------------------------------------------