This repository has been archived by the owner on Jan 2, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
parameterised.clj
180 lines (149 loc) · 4.03 KB
/
parameterised.clj
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
; nil is an ISeq
; seq returns an ISeq (includes nil)
; nil <: (Seqable Unit)
; nil <: (ISeq Unit)
(+T clojure.core/seq [(U nil (Seqable A)) -> (ISeq A)])
Nil -
Nothing - bottom value
# Advantages of Nil <: Null
- Distinguish between nil and null
- null is not an ISeq (but nil is ...)
# Advantages of just Nil
- nil is still null
- no special cases for void
- hides details of null, void in type system
when they aren't needed
nil <!: java.lang.Void
nil <!: java.lang.Void/TYPE
nil <!: Null
nil <: Seq[Nothing]
nil <: IMeta
nil <: IObj
nil <: Counted
nil <: ILookup
nil <: Associative
(+T clojure.core/first [(U (Seqable A) nil) -> A])
; # Should we type methods of clojure.lang.* interfaces?
;
; - We could type check definitions of clojure.core functions
; - But it seems advantageous to abstract over clojure.core
; - eg. pretend clojure.lang.ISeq/seq is the same as clojure.core/seq
; - but there is a mismatch
; - eg. (iseq? nil) => false
; - but the type system says otherwise
;
; # Should we abstract over ISeq?
;
; - (seq x) is really [(U Seqable nil Iterable ...) -> (U nil ISeq)]
; - Would rather [Seqable -> ISeq]
; - We could introduce a new type
; - (def-type-alias SeqableI (A) (U (Seqable A) (Iterable A) (Array A) ...))
; - (def-type-alias SeqableOrNil (A) (U nil (SeqableI A)))
; - (def-type-alias SeqOrNil (A) (U nil (ISeq A)))
; - seq :- [(SeqableOrNil A) -> (SeqOrNil A)]
; - count :- [(SeqableOrNil A) -> (SeqOrNil A)]
(def-typed-interface Seqable (+A)
:methods
[(seq [this])])
(def-typed-interface IPersistentCollection (+A)
:extends-interface
[(Seqable A)]
:methods
[(count [this])
(cons [this o])
(empty [this])
(equiv [this o])])
(def-typed-interface ISeq (+A)
:extends-interface
[(IPersistentCollection A)]
:methods
[(first [this])])
(def-typed-interface IPersistentVector (+A)
:extends-interface
[(Associative Long A)
(Sequential A)
(IPersistentStack A)
Reversible
Indexed]
:methods
[(assocN [this i va])
(cons [this o])])
(def-typed-abstract APersistentVector (+A)
:extends-abstract
[(AFn ...)] ;TODO
:implements-interface
[(IPersistentVector A)
(Iterable A)
(List A)
RandomAccess
Comparable
Seriablizable
IHashEq])
(def-typed-class PersistentVector (+A)
:extends-abstract
[(APersistentVector A)]
:implements-interface
[IObj
IEditableCollection])
(def-typed-interface IMeta ()
:methods
[(meta [this])]
)
(def-typed-interface IObj ()
:extends-interface
[IMeta]
:methods
[(with-meta [this meta])]
)
(def-typed-interface IEditableInterface ()
:methods
[(asTransient [this])])
(def-typed-interface IHashEq ()
:methods
[(hashEq [this])])
(def-typed-interface MapEntry
)
(defprotocol ISeq (+A)
(-first [this] ...))
(definterface Iterable ()
)
(defprotocol IMeta ()
)
PersistentVector[X] extends APersistentVector[X] implements IObj[X], IEditableCollection[X]
APersistentVector[X] extends AFn[Long -> X] implements IPersistentVector[X], Iterable[X]
List[X], RandomAccess[X], Comparable[X],
Serializable[X], IHashEq[X]
; Fn types? have infinite domain..
; See scala's function1..function20..function?
AFn
(defn symbol? [a :- Any]
:filters
[a :- Symbol
a !:- Symbol])
(defn identity (A) [a :- A] A
:filters
[a !:- (U nil false)
a :- (U nil false)]
a)
(defn every? (A)
[f :- [A -> B]
coll :- (Seqable A)]
boolean
:filter
[coll :- (Seqable (then-filter f))
coll :- (Seqable (U (then-filter f)
(else-filter f)))]
)
(let [x (long-or-nil-seq)] ; (Seq (U Long nil))
(when (every? identity x)
; x :- (Seqable (U Long nil))
; with proposition x :- (Seqable !:- (U nil false))
; update (Seqable (U Long nil)
; (Seqable !:- (U nil false))
; => x :- (Seqable Long)
(apply + x)))
(let [x (some-seq)] ; (Seq Any)
(if (symbol? (first x))
; x :- (Seq Any)
; and (first x) :- Symbol
(str (namespace (first x)) (name (first x)))))