Skip to content

Instantly share code, notes, and snippets.

@gilch
Last active January 24, 2017 17:34
Show Gist options
  • Save gilch/2ea93c4852f2e16819fcaae020183b72 to your computer and use it in GitHub Desktop.
Save gilch/2ea93c4852f2e16819fcaae020183b72 to your computer and use it in GitHub Desktop.
# A quick proof-of-concept. There is some room for improvement.
# Note also that Clojure's macros have no loss of performance compared to writing their expansion (i.e. nested calls) in the first place.
# This, on the other hand, creates a new object per nesting. Python is very flexible, but it's not fast.
class Thead:
"""
Thread-Head class. Like Clojure's -> (thread-first) macro.
>>> import operator as op
>>> Thead(5)(op.sub, 3)(op.mul, 10).result
20
>>> Thead('XY')(op.add, 'a')(op.mul, 2)(op.add, 'b').result
'XYaXYab'
"""
# see also, Drython's DoTo. Method calls could also be threaded in Thead using __getattribute__
def __init__(self, result):
self.result = result
def __call__(self, func, *args, **kwargs):
return Thead(func(self.result, *args, **kwargs))
class Thail:
"""
Thread-Tail class. Like Clojure's ->> (thread-last) macro.
>>> import operator as op
>>> Thail(5)(op.sub, 3)(op.mul, 10).result
-20
>>> Thail('XY')(op.add, 'a')(op.mul, 2)(op.add, 'b').result
'baXYaXY'
"""
def __init__(self, result):
self.result = result
def __call__(self, func, *args, **kwargs):
return Thail(func(*args, self.result, **kwargs))
import doctest
doctest.testmod()
@dswhite11
Copy link

should the Thread-Tail class be called TTail?

@gilch
Copy link
Author

gilch commented Jan 24, 2017

Maybe they should just be Thead and Thail, since I intended it to be a Portmanteau of "Thread-head" and "Thread-tail". The words need to be short and easy to type, since Clojure's -> and ->> are even shorter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment