<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>joshu’s blog</title>
  <link>https://joshu.dreamwidth.org/</link>
  <description>joshu’s blog - Dreamwidth Studios</description>
  <lastBuildDate>Wed, 28 Jan 2015 06:50:04 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>joshu</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <image>
    <url>https://v2.dreamwidth.org/9508663/2362380</url>
    <title>joshu’s blog</title>
    <link>https://joshu.dreamwidth.org/</link>
    <width>100</width>
    <height>100</height>
  </image>

<item>
  <guid isPermaLink='true'>https://joshu.dreamwidth.org/386.html</guid>
  <pubDate>Wed, 28 Jan 2015 06:50:04 GMT</pubDate>
  <title>Decorators, Closures, and Partial Application</title>
  <link>https://joshu.dreamwidth.org/2015/01/27/fpp-1.html</link>
  <description>&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(&quot;%A, %B %e %Y&quot;)
print &quot;The unix epoch began on %s&quot; % pretty_date(0)
# The unix epoch began on Thursday, January  1 1970
print &quot;Beyoncé was born on %s&quot; % 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=&quot;https://en.wikipedia.org/wiki/ISO_8601&quot;&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(&quot;%Y-%m-%dT%H:%M:%S%z&quot;)
print &quot;The unix epoch began on %s&quot; % 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=&quot;https://docs.python.org/2/library/functools.html#functools.partial&quot;&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=&quot;https://www.dreamwidth.org/tools/commentcount?user=joshu&amp;ditemid=386&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://joshu.dreamwidth.org/2015/01/27/fpp-1.html</comments>
  <category>python</category>
  <category>programming</category>
  <category>fpp</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
</channel>
</rss>
