summaryrefslogtreecommitdiff
path: root/Alpha/Core.scm
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2020-04-15 09:54:10 -0700
committerBen Sima <ben@bsima.me>2020-04-15 10:06:56 -0700
commitf4b8c0df041b063c0b47d2ec6c818a9c202fd833 (patch)
tree01ad246a83fda29c079847b3397ca6509a7f6106 /Alpha/Core.scm
parent6ed475ca94209ce92e75f48764cb9d361029ea26 (diff)
Re-namespacing
Moving away from the DNS-driven namespacing toward more condensed names, mostly because I don't like typing so much.
Diffstat (limited to 'Alpha/Core.scm')
-rw-r--r--Alpha/Core.scm158
1 files changed, 158 insertions, 0 deletions
diff --git a/Alpha/Core.scm b/Alpha/Core.scm
new file mode 100644
index 0000000..3a5ac6e
--- /dev/null
+++ b/Alpha/Core.scm
@@ -0,0 +1,158 @@
+(define-module (Alpha Core)
+ #:use-module ((ice-9 format))
+ #:export (
+ ;; simple printing
+ fmt printf pr prn
+
+ ;; navigating data
+ first next second rest
+
+ ;; booleans
+ true? false? nil nil?
+
+ ;; dev helpers
+ comment
+ ))
+
+(define (flip f) (lambda (x y) (f y x)))
+(define (curry f a) (lambda (b) (apply f (cons a (list b)))))
+(define pos?
+ (curry < 0))
+
+(define neg?
+ (curry > 0))
+
+(define (foldr f end lst)
+ (if (null? lst)
+ end
+ (f (car lst) (foldr f end (cdr lst)))))
+
+(define (foldl f acc lst)
+ (if (null? lst)
+ acc
+ (foldl f (f acc (car lst)) (cdr lst))))
+
+(define fold foldl)
+
+(define (unfold f init pred)
+ (if (pred init)
+ (cons init '())
+ (cons init (unfold f (f init) pred))))
+
+(define (sum lst) (fold + 0 lst))
+(define (produce lst) (fold * 1 lst))
+
+(define count length)
+
+
+;;
+;; clojure-like stuff
+;;
+
+(define (pr . a)
+ (for-each display a))
+
+(define (prn . a) (apply pr a) (newline))
+
+(define (first a)
+ "Return the first item in the collection."
+ (car a))
+
+(define (rest a)
+ "Returns a list of the items after the first."
+ (cdr a))
+
+(define (next a)
+ "Returns the next item after the first."
+ (cadr a))
+
+;; same thing, easier to remember/read
+(define second next)
+
+(define (ffirst a)
+ (first (first a)))
+
+(define (nnext a)
+ (next (next a)))
+
+(define (last coll)
+ "Return the last time in coll, in linear time."
+ (if (next coll)
+ (last coll)
+ (first coll)))
+
+(define (butlast ls)
+ "Return everthing execpt the last element in ls."
+ (let ((len (length ls)))
+ (list-head ls (- len 1))))
+
+(define (false? x)
+ (eq? #f x))
+
+(define (true? x)
+ (eq? #t x))
+
+(define nil #nil)
+
+(define (nil? x)
+ (eq? nil x))
+
+;; Ignores body, returns nil.
+(define-syntax comment
+ (syntax-rules ()
+ ((_ ...) nil)))
+
+(comment
+ ;; nil is different from null. nil is supposed to be more like
+ ;; 'Nothing' in Haskell, it is the absence of any value or type;
+ ;; whereas null is specifically the empty list, which still has a type
+ ;; of 'list'.
+ (null? '()) ;; => #t
+ (nil? '()) ;; => #f
+ )
+
+(define (some pred coll)
+ (or (pred (first coll))
+ (some pred (next coll))))
+
+(define comp compose)
+
+(define (not-any? pred coll)
+ (comp not some))
+
+(define (printf . args)
+ (display (apply format args)))
+
+(define-syntax fmt
+ (syntax-rules ()
+ ((_ s args ...)
+ (format #f s args ...))))
+
+;; If I implement ML-like interface abstractions in scheme, what would it look like?
+
+;;
+;; ;; seq
+
+;; (define-class <seq> () (_first))
+
+;;
+;; ;; Functor
+
+;; (define-class <functor> ())
+
+;; (define-method (fmap (f <procedure>) (coll <functor>)))
+
+;;
+;; ;; Applicative
+
+;; ;; a -> f a
+;; (define-method (pure (a <any>)))
+
+;; ;; f (a -> b) -> f a -> f b
+;; (define-method (<*> (f <procedure>) (a <applicative>) (b <applicative>)))
+
+;; ;; f a -> f b -> f b
+;; (define-method (*> (a <applicative>) (b <applicative>)))
+
+;; ;; f a -> f b -> f a
+;; (define-method (<* (a <applicative>) (b <applicative>)))