1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-28 19:19:53 +00:00

Add lazyseqs code back.

This commit is contained in:
Calvin Rose 2018-09-22 14:17:47 -04:00
parent 16ac7ba1a1
commit 95b46cfc46

View File

@ -1,41 +1,107 @@
# Ansi terminal colors # An example implementation of functional, lazy
# sequences, as in clojure. The lazy seq is essentially
# A lazy linked list, where the next value is a function
# that must be called (realizing it), and the memoized.
# Use with (import "./path/to/this/file" :prefix "seq.")
(def- colormap (defmacro delay [& forms]
{:black 30 "Lazily evaluate a series of expressions. Returns a function that
:bg-black 40 returns the result of the last expression. Will only evaluate the
:red 31 body once, and then memoizes the result."
:bg-red 41 (def $state (gensym))
:green 32 (def $loaded (gensym))
:bg-green 42 (tuple 'do
:yellow 33 (tuple 'var $state nil)
:bg-yellow 43 (tuple 'var $loaded nil)
:blue 34 (tuple 'fn (array)
:bg-blue 44 (tuple 'if $loaded
:magenta 35 $state
:bg-magenta 45 (tuple 'do
:cyan 36 (tuple ':= $loaded true)
:bg-cyan 46 (tuple ':= $state (tuple.prepend forms 'do)))))))
:white 37
:bg-white 47
:bright-black 90 # Use tuples instead of structs to save memory
:bg-bright-black 100 (def HEAD :private 0)
:bright-red 91 (def TAIL :private 1)
:bg-bright-red 101
:bright-green 92
:bg-bright-green 102
:bright-yellow 93
:bg-bright-yellow 103
:bright-blue 94
:bg-bright-blue 104
:bright-magenta 95
:bg-bright-magenta 105
:bright-cyan 96
:bg-bright-cyan 106
:bright-white 97
:bg-bright-white 107})
(loop [[name color] :in (pairs colormap)] (defn empty-seq
(defglobal (string.slice name 1) "The empty sequence."
(fn color-wrapper [& pieces] [] nil)
(string "\e[" color "m" (apply1 string pieces) "\e[0m"))))
(defmacro cons
"Create a new sequence by prepending a value to the original sequence."
[h t]
(def x (tuple h t))
(fn [] x))
(defn empty?
"Check if a sequence is empty."
[s]
(not (s)))
(defn head
"Get the next value of the sequence."
[s]
(get (s) HEAD))
(defn tail
"Get the rest of a sequence"
[s]
(get (s) TAIL))
(defn range2
"Return a sequence of integers [start, end)."
[start end]
(if (< start end)
(delay (tuple start (range2 (+ 1 start) end)))
empty-seq))
(defn range
"Return a sequence of integers [0, end)."
[end]
(range2 0 end))
(defn map
"Return a sequence that is the result of applying f to each value in s."
[f s]
(delay
(def x (s))
(if x (tuple (f (get x HEAD)) (map f (get x TAIL))))))
(defn realize
"Force evaluation of a lazy sequence."
[s]
(when (s) (realize (tail s))))
(defn realize-map [f s]
"Evaluate f on each member of the sequence. Forces evaluation."
(when (s) (f (head s)) (realize-map f (tail s))))
(defn drop
"Ignores the first n values of the sequence and returns the rest."
[n s]
(delay
(def x (s))
(if (and x (pos? n)) ((drop (- n 1) (get x TAIL))))))
(defn take
"Returns at most the first n values of s."
[n s]
(delay
(def x (s))
(if (and x (pos? n))
(tuple (get x HEAD) (take (- n 1) (get x TAIL))))))
(defn randseq
"Return a sequence of random numbers."
[]
(delay (tuple (random) (randseq))))
(defn take-while
"Returns a sequence of values until the predicate is false."
[pred s]
(delay
(def x (s))
(when x
(def thehead (get HEAD x))
(if thehead (tuple thehead (take-while pred (get TAIL x)))))))