mirror of
https://github.com/carp-lang/Carp.git
synced 2024-11-04 01:25:04 +03:00
core: initial documentation work
This commit is contained in:
parent
7755cd8e1f
commit
b2c57e16d3
@ -1,5 +1,6 @@
|
||||
(defmodule Array
|
||||
|
||||
(doc reduce "Reduce an array, using the function f.")
|
||||
(defn reduce [f x xs]
|
||||
(let [total x]
|
||||
(do
|
||||
@ -7,12 +8,15 @@
|
||||
(set! total (f &total (nth xs i))))
|
||||
total)))
|
||||
|
||||
(doc first "Take the first element of an array.")
|
||||
(defn first [a]
|
||||
@(Array.nth a 0))
|
||||
|
||||
(doc last "Take the last element of an array.")
|
||||
(defn last [a]
|
||||
@(Array.nth a (Int.dec (Array.count a))))
|
||||
|
||||
(defn = "Compare two arrays.")
|
||||
(defn = [a b]
|
||||
(if (/= (count a) (count b))
|
||||
false
|
||||
@ -24,6 +28,7 @@
|
||||
(break))))
|
||||
eq)))
|
||||
|
||||
(doc maximum "Get the maximum in an array (elements must support <).")
|
||||
(defn maximum [xs]
|
||||
(let [result (first xs)
|
||||
n (count xs)]
|
||||
@ -35,6 +40,7 @@
|
||||
())))
|
||||
result)))
|
||||
|
||||
(doc minimum "Get the maximum in an array (elements must support >).")
|
||||
(defn minimum [xs]
|
||||
(let [result (first xs)
|
||||
n (count xs)]
|
||||
@ -46,9 +52,11 @@
|
||||
())))
|
||||
result)))
|
||||
|
||||
(doc minimum "Sum an array (elements must support + and zero).")
|
||||
(defn sum [xs]
|
||||
(Array.reduce add-ref (zero) xs))
|
||||
|
||||
(doc subarray "Get subarray from start-index to end-index.")
|
||||
(defn subarray [xs start-index end-index]
|
||||
(let [result []]
|
||||
(do
|
||||
@ -56,12 +64,15 @@
|
||||
(set! result (push-back result @(nth xs i))))
|
||||
result)))
|
||||
|
||||
(doc prefix-array "Get prefix-array to end-index.")
|
||||
(defn prefix-array [xs end-index]
|
||||
(subarray xs 0 end-index))
|
||||
|
||||
(doc suffix-array "Get subarray from start-index.")
|
||||
(defn suffix-array [xs start-index]
|
||||
(subarray xs start-index (count xs)))
|
||||
|
||||
(doc reverse "Reverse an array.")
|
||||
(defn reverse [a]
|
||||
(let-do [i 0
|
||||
j (Int.dec (count &a))]
|
||||
@ -73,6 +84,7 @@
|
||||
(set! j (Int.dec j))))
|
||||
a))
|
||||
|
||||
(doc index-of "Get the index of element e in an array.")
|
||||
(defn index-of [a e]
|
||||
(let-do [idx -1]
|
||||
(for [i 0 (count a)]
|
||||
@ -82,24 +94,29 @@
|
||||
(break))))
|
||||
idx))
|
||||
|
||||
(doc element-count "Count occurrences of element e in an array.")
|
||||
(defn element-count [a e]
|
||||
(let-do [c 0]
|
||||
(for [i 0 (count a)]
|
||||
(when (= e (nth a i)) (set! c (Int.inc c))))
|
||||
c))
|
||||
|
||||
(doc aupdate "Transmute the element at index i of array a using function f.")
|
||||
(defn aupdate [a i f]
|
||||
(let [new-value (f (nth &a i))]
|
||||
(aset a i new-value)))
|
||||
|
||||
(doc aupdate "Transmute the element at index i of array a using function f in place.")
|
||||
(defn aupdate! [a i f]
|
||||
(aset! a i (f (nth a i))))
|
||||
|
||||
(doc aupdate "Swap indices i and j of array a.")
|
||||
(defn swap [a i j]
|
||||
(let [x @(nth &a i)
|
||||
y @(nth &a j)]
|
||||
(aset (aset a i y) j x)))
|
||||
|
||||
(doc aupdate "Swap indices i and j of array a in place.")
|
||||
(defn swap! [a i j]
|
||||
(let-do [x @(nth a i)
|
||||
y @(nth a j)]
|
||||
@ -107,6 +124,7 @@
|
||||
(aset! a j x)))
|
||||
|
||||
; cannot use for, because we want also be able to go downwards
|
||||
(doc range "Create an array from start to end with step between them (the elements must support <, <=, and >=).")
|
||||
(defn range [start end step]
|
||||
(let-do [x (allocate (Int.inc (Int.abs (/ (- end start) step))))
|
||||
e start
|
||||
@ -119,24 +137,29 @@
|
||||
(set! e (+ e step))))
|
||||
x))
|
||||
|
||||
(doc sort "Sort an array (the elements must support cmp).")
|
||||
(defn sort [a]
|
||||
(sort-with a cmp))
|
||||
|
||||
(doc repeat "Repeat function f n times and store the results in an array.")
|
||||
(defn repeat [n f]
|
||||
(let-do [a (allocate n)]
|
||||
(for [i 0 n] (aset-uninitialized! &a i (f)))
|
||||
a))
|
||||
|
||||
(doc repeat-indexed "Repeat function f n times and store the results in an array (will be supplied with the index).")
|
||||
(defn repeat-indexed [n f]
|
||||
(let-do [a (allocate n)]
|
||||
(for [i 0 n] (aset-uninitialized! &a i (f i)))
|
||||
a))
|
||||
|
||||
(doc replicate "Repeat element e n times and store the results in an array.")
|
||||
(defn replicate [n e]
|
||||
(let-do [a (allocate n)]
|
||||
(for [i 0 n] (aset-uninitialized! &a i @e))
|
||||
a))
|
||||
|
||||
(doc copy-map "Map over array a using function f (copies the array).")
|
||||
(defn copy-map [f a]
|
||||
(let-do [na (allocate (count a))]
|
||||
(for [i 0 (count a)]
|
||||
|
@ -5,12 +5,17 @@
|
||||
|
||||
(defmodule Bench
|
||||
(def min-runs 50)
|
||||
(private min-runs)
|
||||
(hidden min-runs)
|
||||
|
||||
(doc set-min-runs! "Set the minimum number of runs. If your functions takes a large amount of time, experimenting with this might make sense.")
|
||||
(defn set-min-runs! [n]
|
||||
; / 2 because we run it twice per benchmarking run,
|
||||
; but this is an implementation detail
|
||||
(set! min-runs (/ n 2)))
|
||||
|
||||
(private get-unit)
|
||||
(hidden get-unit)
|
||||
(defn get-unit [n]
|
||||
(cond
|
||||
(< n 1000.0) (String.append (Double.str n) @"ns")
|
||||
@ -18,18 +23,24 @@
|
||||
(< n 1000000000.0) (String.append (Double.str (/ n 1000000.0)) @"ms")
|
||||
(String.append (Double.str (/ n 1000000000.0)) @"s")))
|
||||
|
||||
(private print)
|
||||
(hidden print)
|
||||
(defn print [title n]
|
||||
(let [unit (get-unit n)]
|
||||
(do
|
||||
(IO.print title)
|
||||
(IO.println &unit))))
|
||||
|
||||
(private ns-iter-inner)
|
||||
(hidden ns-iter-inner)
|
||||
(defn ns-iter-inner [f n]
|
||||
(let [start (get-time-elapsed)]
|
||||
(do
|
||||
(for [i 0 n] (ignore (f)))
|
||||
(Double.- (get-time-elapsed) start))))
|
||||
|
||||
(private print-bench-results)
|
||||
(hidden print-bench-results)
|
||||
(defn print-bench-results [res total]
|
||||
(do
|
||||
(print "Total time elapsed: " total)
|
||||
@ -37,6 +48,8 @@
|
||||
(print "Worst case: " @(Statistics.Summary.max res))
|
||||
(print "Standard deviation: " @(Statistics.Summary.stdev res))))
|
||||
|
||||
(private get-samples)
|
||||
(hidden get-samples)
|
||||
(defn get-samples [f n]
|
||||
(let [zero 0.0
|
||||
samples (Array.replicate min-runs &zero)]
|
||||
@ -45,11 +58,14 @@
|
||||
(Array.aset! &samples i (Double./ (ns-iter-inner f (Double.to-int n)) n)))
|
||||
(Statistics.summary &(Statistics.winsorize &samples 5.0)))))
|
||||
|
||||
(private min-one)
|
||||
(hidden min-one)
|
||||
(defn min-one [n]
|
||||
(if (> 1.0 n) n 1.0))
|
||||
|
||||
; it is actually possible to make this run forever by supplying a _really_
|
||||
; long-running function, where long-running is everything over 30ms.
|
||||
(doc bench "Benchmark function f and print the results.")
|
||||
(defn bench [f]
|
||||
(let [ns (ns-iter-inner f 1)
|
||||
ns-target-total 1000000.0
|
||||
|
@ -6,6 +6,7 @@
|
||||
(register from-int (Fn [Int] Char))
|
||||
(register copy (Fn [&Char] Char))
|
||||
|
||||
(doc meaning "Convert a numerical char into the appropriate number.")
|
||||
(defn meaning [char-ref]
|
||||
(cond
|
||||
(= @char-ref \0) 0
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
(defmodule Debug
|
||||
|
||||
(doc sanitize-addresses "Instruct the compiler to sanitize addresses.")
|
||||
(defdynamic sanitize-addresses []
|
||||
(add-cflag "-fsanitize=address"))
|
||||
|
||||
@ -9,14 +10,14 @@
|
||||
(register reset-memory-balance! (Fn [] ()))
|
||||
(register log-memory-balance! (Fn [Bool] ()))
|
||||
|
||||
;; The calls inside the form will be logged to stdout. Requires compiling with --log-memory.
|
||||
(doc memory-logged "Log all calls to memory allocation within te form. Requires compiling with --log-memory.")
|
||||
(defmacro memory-logged [form]
|
||||
(list 'do
|
||||
'(Debug.log-memory-balance! true)
|
||||
form
|
||||
'(Debug.log-memory-balance! false)))
|
||||
|
||||
;; Raises an error if the memory balance (nr of alloc:s minus nr of free:s) isn't 0. Requires compiling with --log-memory.
|
||||
(doc assert-balanced "Raises an error if the memory balance (numberr of alloc:s - number of free:s) isn't 0. Requires compiling with --log-memory.")
|
||||
(defmacro assert-balanced [form]
|
||||
(list 'let '[balance (Debug.memory-balance)]
|
||||
(list 'do
|
||||
@ -28,16 +29,17 @@
|
||||
(System.exit 1)))
|
||||
())))
|
||||
|
||||
;; Print the value of an expression to stdout, then return its value.
|
||||
(doc trace "Print the value of an expression to stdout, then return its value.")
|
||||
(defn trace [x]
|
||||
(do
|
||||
(IO.println &(str &x))
|
||||
x))
|
||||
|
||||
;; Leak some memory. Useful for testing tools that detect leaks.
|
||||
(doc leak-array "Leak some memory. Useful for testing tools that detect leaks.")
|
||||
(register leak-array (Fn [a] ()) "Debug_leak_MINUS_array")
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
;; HACK! This silences compiler errors about 'source-location' and 'source-path' being undefined.
|
||||
;; Actual calls to these special forms will be handled directly in the dynamic evaluator, see 'Eval.hs'.
|
||||
|
Loading…
Reference in New Issue
Block a user