Skip to content

Commit b54a652

Browse files
authored
Core seq function should return nil for empty seq (#98)
1 parent 6945a04 commit b54a652

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

basilisp/lang/runtime.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -392,20 +392,30 @@ def cons(o, seq) -> lseq.Seq:
392392
return to_seq(seq).cons(o) # type: ignore
393393

394394

395+
def _seq_or_nil(s: lseq.Seq) -> Optional[lseq.Seq]:
396+
"""Return None if a Seq is empty, the Seq otherwise."""
397+
if s.first is None and s.rest == lseq.empty():
398+
return None
399+
return s
400+
401+
395402
def to_seq(o) -> Optional[lseq.Seq]:
396403
"""Coerce the argument o to a Seq. If o is None, return None."""
397404
if o is None:
398405
return None
399406
if isinstance(o, lseq.Seq):
400-
return o
407+
return _seq_or_nil(o)
401408
if isinstance(o, lseq.Seqable):
402-
return o.seq()
403-
return lseq.sequence(o)
409+
return _seq_or_nil(o.seq())
410+
return _seq_or_nil(lseq.sequence(o))
404411

405412

406413
def concat(*seqs) -> lseq.Seq:
407414
"""Concatenate the sequences given by seqs into a single Seq."""
408-
return lseq.sequence(itertools.chain(*filter(None, map(to_seq, seqs))))
415+
allseqs = lseq.sequence(itertools.chain(*filter(None, map(to_seq, seqs))))
416+
if allseqs is None:
417+
return lseq.empty()
418+
return allseqs
409419

410420

411421
def apply(f, args):
@@ -418,7 +428,10 @@ def apply(f, args):
418428
(apply max [1 2 3]) ;=> 3
419429
(apply max 4 [1 2 3]) ;=> 4"""
420430
final = list(args[:-1])
421-
final.extend(to_seq(args[-1]))
431+
try:
432+
final.extend(to_seq(args[-1]))
433+
except TypeError:
434+
pass
422435
return f(*final)
423436

424437

tests/runtime_test.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import basilisp.lang.keyword as keyword
22
import basilisp.lang.list as llist
3+
import basilisp.lang.map as lmap
34
import basilisp.lang.runtime as runtime
45
import basilisp.lang.seq as lseq
6+
import basilisp.lang.set as lset
57
import basilisp.lang.vector as vec
68

79

@@ -46,9 +48,17 @@ def test_cons():
4648

4749
def test_to_seq():
4850
assert None is runtime.to_seq(None)
49-
50-
empty_list = llist.List.empty()
51-
assert empty_list == runtime.to_seq(empty_list)
51+
assert None is runtime.to_seq(llist.List.empty())
52+
assert None is runtime.to_seq(vec.Vector.empty())
53+
assert None is runtime.to_seq(lmap.Map.empty())
54+
assert None is runtime.to_seq(lset.Set.empty())
55+
assert None is runtime.to_seq("")
56+
57+
assert None is not runtime.to_seq(llist.l(1))
58+
assert None is not runtime.to_seq(vec.v(1))
59+
assert None is not runtime.to_seq(lmap.map({"a": 1}))
60+
assert None is not runtime.to_seq(lset.s(1))
61+
assert None is not runtime.to_seq("string")
5262

5363
one_elem = llist.l(keyword.keyword('kw'))
5464
assert one_elem == runtime.to_seq(one_elem)

0 commit comments

Comments
 (0)