Last active
January 12, 2017 18:37
-
-
Save patrickgombert/9b840fd4adcba9f2d8373122cc8432df to your computer and use it in GitHub Desktop.
concepts from clj in py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lazyseq.py | |
class LazySeq(object): | |
def __init__(self, f): | |
self.f = f | |
self.seq = [] | |
def next(self): | |
res = self.f(self.seq) | |
self.seq.append(res) | |
return res | |
def iter(self): | |
return self | |
def contains(self, el): | |
try: | |
if el in self.seq: | |
return True | |
else: | |
while True: | |
if el == self.next(): | |
return True | |
except StopIteration: | |
return False | |
__next__ = next | |
__iter__ = iter | |
__contains__ = contains | |
def next_int(ints): | |
if len(ints) == 0: | |
return 0 | |
else: | |
return ints[-1] + 1 | |
positive_integers = LazySeq(next_int) | |
# fns.py | |
def lmap(f, lazy_seq): | |
i = iter(lazy_seq) | |
return LazySeq(lambda x: f(next(i))) | |
class FilterSeq(object): | |
def __init__(self, predicate, input_seq): | |
self.predicate = predicate | |
self.input_seq = iter(input_seq) | |
def next(self): | |
n = next(self.input_seq) | |
while not self.predicate(n): | |
n = next(self.input_seq) | |
return n | |
def iter(self): | |
return self | |
def contains(self, el): | |
try: | |
while True: | |
if el == self.next(): | |
return True | |
except StopIteration: | |
return False | |
__next__ = next | |
__iter__ = iter | |
__contains__ = contains | |
def lfilter(f, lazy_seq): | |
return FilterSeq(f, lazy_seq) | |
def take(n, lazy_seq): | |
res = [] | |
i = iter(lazy_seq) | |
while len(res) < n: | |
try: | |
res.append(next(i)) | |
except StopIteration: | |
break | |
return res | |
def range(start, end): | |
def next_int(ints): | |
if len(ints) == 0: | |
return start | |
elif ints[-1] == end: | |
raise StopIteration() | |
else: | |
return ints[-1] + 1 | |
return LazySeq(next_int) | |
def repeatedly(v): | |
return LazySeq(lambda _: v) | |
# llist.py | |
class LinkedListNode(object): | |
def __init__(self, contained, next): | |
self.contained = contained | |
self.next = next | |
def first(self): | |
return self.contained | |
def rest(self): | |
return self.next | |
class EmptyListNode(object): | |
def first(self): | |
return None | |
def rest(self): | |
return self | |
def first(s): | |
return s.first() | |
def rest(s): | |
return s.rest() | |
def linked_list(*args): | |
if len(args) == 0: | |
return EmptyListNode() | |
else: | |
first = LinkedListNode(args[0], None) | |
previous = first | |
for arg in args[1:len(args)]: | |
nxt = LinkedListNode(arg, None) | |
previous.next = nxt | |
previous = nxt | |
previous.next = EmptyListNode() | |
return first | |
def cons(s, el): | |
return LinkedListNode(el, s) | |
# interpreter.py | |
def eval(lst): | |
if (isinstance(lst, EmptyListNode) or isinstance(lst, LinkedListNode)) and callable(first(lst)): | |
return first(lst)(*map(eval, _llist_to_list(rest(lst)))) | |
else: | |
return lst | |
# helper to use python callables | |
def _llist_to_list(llist): | |
lst = [] | |
while not empty(llist): | |
lst.append(first(llist)) | |
llist = rest(llist) | |
return lst |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment