+# retains metadata
+def conj(args):
+ lst, args = args[0], args.rest()
+ new_lst = None
+ if types._list_Q(lst):
+ vals = args.values[:]
+ vals.reverse()
+ new_lst = MalList(vals + lst.values)
+ elif types._vector_Q(lst):
+ new_lst = MalVector(lst.values + list(args.values))
+ else:
+ throw_str("conj on non-list/non-vector")
+ new_lst.meta = lst.meta
+ return new_lst
+
+def seq(args):
+ a0 = args[0]
+ if isinstance(a0, MalVector):
+ if len(a0) == 0: return nil
+ return MalList(a0.values)
+ elif isinstance(a0, MalList):
+ if len(a0) == 0: return nil
+ return a0
+ elif types._string_Q(a0):
+ assert isinstance(a0, MalStr)
+ if len(a0) == 0: return nil
+ return MalList([MalStr(unicode(c)) for c in a0.value])
+ elif a0 is nil:
+ return nil
+ else:
+ throw_str("seq: called on non-sequence")