diff options
author | Ben Sima <ben@bsima.me> | 2020-04-15 09:54:10 -0700 |
---|---|---|
committer | Ben Sima <ben@bsima.me> | 2020-04-15 10:06:56 -0700 |
commit | f4b8c0df041b063c0b47d2ec6c818a9c202fd833 (patch) | |
tree | 01ad246a83fda29c079847b3397ca6509a7f6106 /Alpha/Core.scm | |
parent | 6ed475ca94209ce92e75f48764cb9d361029ea26 (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.scm | 158 |
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>))) |