forked from schani/clojurec
/
core.cljc
131 lines (105 loc) · 2.48 KB
/
core.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
;;; -*- clojure -*-
(ns cljc.core.List)
(def EMPTY nil)
(ns cljc.core)
(declare print)
(declare apply)
(defn ^boolean not
"Returns true if x is logical false, false otherwise."
[x] (if x false true))
(comment
(defprotocol IFn
(-invoke [& args]))
)
(defprotocol ASeq)
(defprotocol ISeq
(-first [coll])
(-rest [coll]))
(defprotocol INext
(-next [coll]))
(defprotocol ISeqable
(-seq [o]))
(deftype Cons [first rest]
ASeq
ISeq
(-first [coll] first)
(-rest [coll] (if (nil? rest) () rest))
INext
(-next [coll] (if (nil? rest) nil (-seq rest)))
ISeqable
(-seq [coll] coll))
(deftype EmptyList []
ISeq
(-first [coll] nil)
(-rest [coll] ())
INext
(-next [coll] nil)
ISeqable
(-seq [coll] nil))
(set! cljc.core.List/EMPTY (cljc.core/EmptyList))
(defn ^seq seq
"Returns a seq on the collection. If the collection is
empty, returns nil. (seq nil) returns nil. seq also works on
Strings."
[coll]
(when-not (nil? coll)
(if (satisfies? ASeq coll)
coll
(-seq coll))))
(defn first
"Returns the first item in the collection. Calls seq on its
argument. If coll is nil, returns nil."
[coll]
(when-not (nil? coll)
(if (satisfies? ISeq coll)
(-first coll)
(let [s (seq coll)]
(when-not (nil? s)
(-first s))))))
(defn ^seq rest
"Returns a possibly empty seq of the items after the first. Calls seq on its
argument."
[coll]
(if-not (nil? coll)
(if (satisfies? ISeq coll)
(-rest coll)
(let [s (seq coll)]
(if-not (nil? s)
(-rest s)
())))
()))
(defn ^seq next
"Returns a seq of the items after the first. Calls seq on its
argument. If there are no more items, returns nil"
[coll]
(when-not (nil? coll)
(if (satisfies? INext coll)
(-next coll)
(seq (rest coll)))))
(defn inc
"Returns a number one greater than num."
[x] (cljc.core/+ x 1))
(defn dec
"Returns a number one less than num."
[x] (- x 1))
(defn count
"Returns the number of items in the collection. (count nil) returns
0. Also works on strings, arrays, and Maps"
[coll]
(loop [s (seq coll)
acc 0]
(if s
(recur (next s) (inc acc))
acc)))
(defn cons
"Returns a new seq where x is the first element and seq is the rest."
[x coll]
(if (or (nil? coll)
(satisfies? ISeq coll))
(Cons x coll)
(Cons x (seq coll))))
(defn flatten-tail
[coll]
(if-let [n (next coll)]
(cons (first coll) (flatten-tail n))
(first coll)))