1
1
import functools
2
2
import threading
3
- from typing import Callable , Iterable , Iterator , Optional , TypeVar , overload
3
+ from typing import Callable , Iterable , Optional , TypeVar , overload
4
4
5
5
from basilisp .lang .interfaces import (
6
6
IPersistentMap ,
@@ -60,7 +60,7 @@ class Cons(ISeq[T], ISequential, IWithMeta):
60
60
61
61
def __init__ (
62
62
self ,
63
- first ,
63
+ first : T ,
64
64
seq : Optional [ISeq [T ]] = None ,
65
65
meta : Optional [IPersistentMap ] = None ,
66
66
) -> None :
@@ -91,57 +91,6 @@ def with_meta(self, meta: Optional[IPersistentMap]) -> "Cons[T]":
91
91
return Cons (self ._first , seq = self ._rest , meta = meta )
92
92
93
93
94
- class _Sequence (IWithMeta , ISequential , ISeq [T ]):
95
- """Sequences are a thin wrapper over Python Iterable values so they can
96
- satisfy the Basilisp `ISeq` interface.
97
-
98
- Sequences are singly linked lists which lazily traverse the input Iterable.
99
-
100
- Do not directly instantiate a Sequence. Instead use the `sequence` function
101
- below."""
102
-
103
- __slots__ = ("_first" , "_seq" , "_rest" , "_meta" )
104
-
105
- def __init__ (
106
- self , s : Iterator [T ], first : T , * , meta : Optional [IPersistentMap ] = None
107
- ) -> None :
108
- self ._seq = s
109
- self ._first = first
110
- self ._rest : Optional [ISeq ] = None
111
- self ._meta = meta
112
-
113
- @property
114
- def meta (self ) -> Optional [IPersistentMap ]:
115
- return self ._meta
116
-
117
- def with_meta (self , meta : Optional [IPersistentMap ]) -> "_Sequence[T]" :
118
- return _Sequence (self ._seq , self ._first , meta = meta )
119
-
120
- @property
121
- def is_empty (self ) -> bool :
122
- return False
123
-
124
- @property
125
- def first (self ) -> Optional [T ]:
126
- return self ._first
127
-
128
- @property
129
- def rest (self ) -> "ISeq[T]" :
130
- if self ._rest :
131
- return self ._rest
132
-
133
- try :
134
- n = next (self ._seq )
135
- self ._rest = _Sequence (self ._seq , n )
136
- except StopIteration :
137
- self ._rest = EMPTY
138
-
139
- return self ._rest
140
-
141
- def cons (self , elem ):
142
- return Cons (elem , self )
143
-
144
-
145
94
LazySeqGenerator = Callable [[], Optional [ISeq [T ]]]
146
95
147
96
@@ -150,21 +99,20 @@ class LazySeq(IWithMeta, ISequential, ISeq[T]):
150
99
with a function that can either return None or a Seq. If a Seq is returned,
151
100
the LazySeq is a proxy to that Seq.
152
101
153
- Callers should never provide the `obj` or ` seq` arguments -- these are provided
154
- only to support `with_meta` returning a new LazySeq instance."""
102
+ Callers should never provide the `seq` argument -- this is provided only to
103
+ support `with_meta` returning a new LazySeq instance."""
155
104
156
105
__slots__ = ("_gen" , "_obj" , "_seq" , "_lock" , "_meta" )
157
106
158
107
def __init__ (
159
108
self ,
160
109
gen : Optional [LazySeqGenerator ],
161
- obj : Optional [ISeq [T ]] = None ,
162
110
seq : Optional [ISeq [T ]] = None ,
163
111
* ,
164
112
meta : Optional [IPersistentMap ] = None ,
165
113
) -> None :
166
114
self ._gen : Optional [LazySeqGenerator ] = gen
167
- self ._obj : Optional [ISeq [T ]] = obj
115
+ self ._obj : Optional [ISeq [T ]] = None
168
116
self ._seq : Optional [ISeq [T ]] = seq
169
117
self ._lock = threading .RLock ()
170
118
self ._meta = meta
@@ -174,7 +122,7 @@ def meta(self) -> Optional[IPersistentMap]:
174
122
return self ._meta
175
123
176
124
def with_meta (self , meta : Optional [IPersistentMap ]) -> "LazySeq[T]" :
177
- return LazySeq (self . _gen , obj = self . _obj , seq = self ._seq , meta = meta )
125
+ return LazySeq (None , seq = self .seq () , meta = meta )
178
126
179
127
# LazySeqs have a fairly complex inner state, in spite of the simple interface.
180
128
# Calls from Basilisp code should be providing the only generator seed function.
@@ -255,11 +203,17 @@ def is_realized(self):
255
203
256
204
def sequence (s : Iterable [T ]) -> ISeq [T ]:
257
205
"""Create a Sequence from Iterable s."""
258
- try :
259
- i = iter (s )
260
- return _Sequence (i , next (i ))
261
- except StopIteration :
262
- return EMPTY
206
+ i = iter (s )
207
+
208
+ def _next_elem () -> ISeq [T ]:
209
+ try :
210
+ e = next (i )
211
+ except StopIteration :
212
+ return EMPTY
213
+ else :
214
+ return Cons (e , LazySeq (_next_elem ))
215
+
216
+ return LazySeq (_next_elem )
263
217
264
218
265
219
@overload
0 commit comments