Functional programming

Marko Rauhamaa marko at pacujo.net
Tue Mar 4 21:50:30 CET 2014


Chris Angelico <rosuav at gmail.com>:

> On Wed, Mar 5, 2014 at 6:49 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
>> public ConnectionPool(int maxConnections, String url) throws SQLException {
>>     try {
>>         super(() -> {
>>             try {
>>                 return DriverManager.getConnection(url);
>>             } catch ( SQLException ex ) {
>>                 throw new WrappedSqlException(ex);
>>             }
>>         }, maxConnections);
>>     } catch (WrappedSqlException wse) {
>>         throw wse.getSqlException();
>>     }
>> }
>>
>> ===JAVA END=============================================================
>
> You're not doing the same thing, though. The Java rigmarole is to
> ensure that an SQLException thrown in getConnection will propagate up,
> despite (presumably) something inside the equivalent of
> super().__init__ that swallows SQLExceptions. Of course it looks
> tidier when you don't do the messy bit.

See <URL: http://stackoverflow.com/questions/14039995/
java-8-mandatory-checked-exceptions-handling-in-lambd
a-expressions-for-standard>.

The "rigmarole" is trying to get around Java's mandatory exception
handling limitations, which Python doesn't have.

You are not allowed to pass a lambda to the super constructor that
throws an SQLException. To get around the limitation, a RuntimeException
wrapper is created to smuggle the SQLException through the compiler's
defenses. Any code is free to throw a RuntimeException.

I don't know, though, if this is that good of an example. I don't know
if the lambda gets called within the constructor or, as I would guess,
whenever a new connection is needed. The whole wrapping exercise would
be for nothing, then.

Here's a more prosaic example (probably contains errors):

===JAVA BEGIN===========================================================

private Map<TaxpayerIdNumber, Map<FormId, Form>> filings =
    new TreeMap<TaxpayerIdNumber, Map<FormId, Form>>();

class FormFiling {
    public FormFiling(TaxpayerIdNumber taxpayerId, Form form) {
        this.taxpayerId = taxpayerId;
        this.form = form;
    }

    public TaxpayerIdNumber getTaxpayerId() { return taxpayerId; }
    public Form getForm() { return form; }

    private TaxpayerIdNumber taxpayerId;
    private Form form;
};

List<FormFiling> getForms(FormId formId)
{
    List<FormFiling> forms = new LinkedList<FormFiling>();
    for (Map.Entry<TaxpayerIdNumber, Map<FormId, Form>> payerEntry :
         filings.entrySet()) {
        TaxpayerIdNumber taxpayerId = payerEntry.getKey();
        Map<FormId, Form> filing = payerEntry.getValue();
        if (filing.containsKey(formId))
            forms.add(new FormFiling(taxpayerId, filing.get(formId)))
    }
    return forms;
}

===JAVA END=============================================================

===PYTHON BEGIN=========================================================

filings = {}

def getForms(formId):
    forms = []
    for taxpayerId, filing in filings.iteritems():
         if formId in filing:
             forms.append((taxpayerId, filing[formId]))
    return forms

===PYTHON END===========================================================

or:

===PYTHON BEGIN=========================================================

filings = {}

def getForms(formId):
    return ((taxpayerId, filing[formId])
            for (taxpayerId, filing) in filings.iteritems()
            if formId in filing)

===PYTHON END===========================================================


Marko



More information about the Python-list mailing list