Skip to content

Instantly share code, notes, and snippets.

@maxfischer2781
Created June 16, 2018 19:02
Show Gist options
  • Save maxfischer2781/990494a8eefb9d616b85cb058a1a983f to your computer and use it in GitHub Desktop.
Save maxfischer2781/990494a8eefb9d616b85cb058a1a983f to your computer and use it in GitHub Desktop.
relative map based on abstract operations
#!/usr/bin/python3
"""
Draft for a relative ``map`` based on abstract operations
.. function:: map(function, iterable, ...)
.. function:: reify(operation, iterable)
Apply the relative ``operation`` to every element of ``iterable``.
For example, ``reify(relative[0], [(1, 2, 3), range(5), "foobar"])`` returns ``[1, 0, 'f']``.
"""
class Abstract(object):
def __getattribute__(self, item):
if item in {'__parent__', '__resolve__', '__content__'}:
return super().__getattribute__(item)
return Attribute(self, item)
def __call__(self, *args, **kwargs):
return Call(self, (args, kwargs))
def __getitem__(self, item):
return Item(self, item)
@staticmethod
def __resolve__(concrete):
return concrete
def __str__(self):
return '?'
def __repr__(self):
return '<abstract %s>' % self
class ChildNode(object):
def __init__(self, parent: Abstract, content):
self.__parent__ = parent
self.__content__ = content
class Attribute(ChildNode, Abstract):
def __resolve__(self, concrete):
concrete = self.__parent__.__resolve__(concrete)
return getattr(concrete, self.__content__)
def __str__(self):
return '%s.%s' % (self.__parent__, self.__content__)
class Call(ChildNode, Abstract):
def __resolve__(self, concrete):
concrete = self.__parent__.__resolve__(concrete)
args, kwargs = self.__content__
return concrete(*args, **kwargs)
def __str__(self):
signature = ''
args, kwargs = self.__content__
if args:
signature += ', '.join(args)
if kwargs:
signature += ', '.join('%s=%s' % (name, value) for name, value in kwargs.items())
return '%s(%s)' % (self.__parent__, signature)
class Item(ChildNode, Abstract):
def __resolve__(self, concrete):
concrete = self.__parent__.__resolve__(concrete)
return concrete[self.__content__]
def __str__(self):
return '%s[%s]' % (self.__parent__, self.__content__)
def reify(operation: Abstract, what):
return [operation.__resolve__(obj) for obj in what]
relative = Abstract()
if __name__ == '__main__':
abstraction = relative.__str__()[0]
print(abstraction)
print(reify(abstraction, (1, 2, 3.0)))
print(reify(relative[0], [(1, 2, 3), range(5), "foobar"]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment