<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dw="https://www.dreamwidth.org">
  <id>tag:dreamwidth.org,2015-01-11:2362380</id>
  <title>joshu’s blog</title>
  <subtitle>joshu</subtitle>
  <author>
    <name>joshu</name>
  </author>
  <link rel="alternate" type="text/html" href="https://joshu.dreamwidth.org/"/>
  <link rel="self" type="text/xml" href="https://joshu.dreamwidth.org/data/atom"/>
  <updated>2015-01-29T04:23:41Z</updated>
  <dw:journal username="joshu" type="personal"/>
  <entry>
    <id>tag:dreamwidth.org,2015-01-11:2362380:386</id>
    <link rel="alternate" type="text/html" href="https://joshu.dreamwidth.org/386.html"/>
    <link rel="self" type="text/xml" href="https://joshu.dreamwidth.org/data/atom/?itemid=386"/>
    <title>Decorators, Closures, and Partial Application</title>
    <published>2015-01-28T06:50:04Z</published>
    <updated>2015-01-29T04:23:41Z</updated>
    <category term="fpp"/>
    <category term="programming"/>
    <category term="python"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;p&gt;I really like Python decorators. They provide a useful way to manipulate functions in a language that treats functions as first-class objects (i.e., a language that can pass around a function in the same way that you can pass around a string or an integer). They also provide a useful road into talking about some topics in computer science, namely closures and partial application!&lt;/p&gt;
&lt;p&gt;But let’s start with the concrete, shall we?&lt;/p&gt;
&lt;p&gt;Say that I’m working on an application that uses a database connection, and I find myself writing code that looks like this, using a global db variable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def do_a_query(query):
    db.connect()
    result = db.query(query)
    db.close()
    return result

def execute_an_insert(obj):
    db.connect()
    db.insert(obj)
    db.close()
    return True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you’ve got an eye for patterns, you’ll likely notice that I’ve re-used the same code in two places and will probably re-use it in more: opening and closing a database connection acts like a set of parentheses around my other code, and it seems tedious to write it again and again.&lt;/p&gt;
&lt;p&gt;But here come decorators to the rescue! I can, instead, write:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def with_db(f):
    def _f_with_db(*args, **kwargs):
        db.connect()
        result = f(*args, **kwargs)
        db.disconnect()
        return result
    return _f_with_db

@with_db
def do_a_query(query):
    return db.query(query)

@with_db
def execute_an_insert(obj):
    db.insert(obj)
    return True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it clears up a lot of the boilerplate. Fantastic! (Ignore for a moment those &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt;; we can come back to what they mean later. Suffice it to say, for now, that they pass along the arguments untouched.) I could even do something fancy, like extend my &lt;code&gt;with_db&lt;/code&gt; function to re-use existing open connections:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def with_db(f):
    def _f_with_db(*args, **kwargs):
        try:
            result = _f_with_db(*args, **kwargs)
        except DBConnectionError:
            db.connect()
            result = f(*args, **kwargs)
    return _f_with_db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the functions decorated with it shouldn’t care: it provides them with an active db connection that they can rely on, and that’s all they need to know.&lt;/p&gt;
&lt;h2&gt;Closures&lt;/h2&gt;
&lt;p&gt;So, let’s talk for a moment about closures. A closure, simply put, is a function – or a reference to a function – with some additional state attached. In Python, this generally looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def make_a_closure(seed_variable):
    state = something_generates_state_with(seed_variable)
    def _closure(other_arg):
        return do_some_things_with(state, other_arg)
    return _closure
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We would then call &lt;code&gt;make_a_closure(some_seed)&lt;/code&gt; to get a closure function seeded with &lt;code&gt;some_seed&lt;/code&gt;. For example, imagine that we wanted to make a function that, given a Unix Epoch timestamp, would return some predetermined format of date:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def make_a_strftime_closure(format_string):
    def _strftime_closure(epoch_timestamp):
        return time.strftime(format_string, time.gmtime(epoch_timestamp))
    return _strftime_closure

pretty_date = make_a_strftime_closure("%A, %B %e %Y")
print "The unix epoch began on %s" % pretty_date(0)
# The unix epoch began on Thursday, January  1 1970
print "Beyoncé was born on %s" % pretty_date(368434800)
# Beyoncé was born on Friday, September  4 1981
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Suppose, though, we want &lt;a href="https://en.wikipedia.org/wiki/ISO_8601"&gt;a standardized format of time&lt;/a&gt; for our logs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;iso_date = make_a_strftime_closure("%Y-%m-%dT%H:%M:%S%z")
print "The unix epoch began on %s" % iso_date(0)
# The unix epoch began on 1970-01-01T00:00:S+0000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To tie this back to decorators: if you notice, a decorator function is just a closure with &lt;em&gt;the decorated function&lt;/em&gt; as its bound state:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def decorate_a_function(f):
    def _decorated(*args, **kwargs):
        return f(*args, **kwargs)
    return _decorated
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Partially Applied Functions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Partially applied functions&lt;/strong&gt; sounds kind of gnarly and complicated but describes a pretty straightforward concept: applying some arguments to a function ahead of time.&lt;/p&gt;
&lt;p&gt;Imagine, if you will, our original example with &lt;code&gt;do_a_query&lt;/code&gt; and &lt;code&gt;execute_an_insert&lt;/code&gt;, but this time without a global DB object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def do_a_query_with_db(db, query):
    db.connect()
    result = db.query(query)
    db.close()
    return result
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you find yourself writing a lot of functions with a shared argument (e.g. &lt;code&gt;db&lt;/code&gt;), you could use a partial application to supply the &lt;code&gt;db&lt;/code&gt; argument ahead of time, using &lt;code&gt;functools.partial&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;do_a_query = partial(do_a_query_with_db, global_db)
do_a_query(some_query) # equivalent to do_a_query_with_db(global_db, some_query)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Python’s own documentation &lt;a href="https://docs.python.org/2/library/functools.html#functools.partial"&gt;calls out that partial() is a pretty simple decorator&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Roughly equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;So there you have it: Python’s decorators not only provide a neat way to manipulate and use functions, they &lt;em&gt;also&lt;/em&gt; provide us a foot in the door for some pretty neat CS concepts!&lt;/p&gt;
&lt;p&gt;Tune in next time for a choice of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Functional Python II: Decorators and Wacky Hidden Functions&lt;/li&gt;
&lt;li&gt;Functional Programming II: Folding and Currying&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=joshu&amp;ditemid=386" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
</feed>
