I sing the praises of lambda, my friend and savior!

Jeff Shannon jeff at ccvcorp.com
Mon Oct 11 22:47:43 EDT 2004


Robert Brewer wrote:

>Jeff Shannon wrote:
>  
>
>>Maybe I'm just ignorant or behind the times, but I still 
>>haven't seen a 
>>real argument as to *why* lambdas are so useful.  There's some 
>>assertions about how avoiding giving something a name makes things 
>>clearer, which I disagree with.  ('Explicit is better than 
>>implicit.'  I 
>>don't see how 'no name' makes the purpose of a code segment 
>>clearer than 
>>'some meaningfully descriptive name', no matter how many times it's 
>>asserted.)  There's complaints that it takes a whole two 
>>extra lines to 
>>type a proper function def, as opposed to being able to use lambdas 
>>inline... but again, I'd claim that with a properly named 
>>function, the 
>>intent at point-of-use will be quite clear and the cost of two extra 
>>lines of code is minimal.
>>    
>>
>
>All I can say is, "sometimes it's not minimal". Adapters are a great
>example:
>
>xforms = {dejavu.icontains: lambda x, y: x + " Like '%" + y[1:-1] +
>"%'",
>          dejavu.icontainedby: icontainedby,
>          dejavu.istartswith: lambda x, y: x + " Like '" + y[1:-1] +
>"%'",
>          dejavu.iendswith: lambda x, y: x + " Like '%" + y[1:-1] + "'",
>          dejavu.ieq: lambda x, y: x + " = " + y,
>          dejavu.now: lambda: "Now()",
>          dejavu.today: lambda: "DateValue(Now())",
>          dejavu.year: lambda x: "Year(" + x + ")",
>          }
>
>Conciseness is a continuum. I understand (and agree with) your
>contention that many lambdas wouldn't suffer from a full function
>definition. Writing the above with full functions, however, would take
>us to the other extreme end of the continuum, which is boilerplate for
>boilerplate's sake. (If I ever write another unnecessary Java
>getter/setter pair, shoot me. ;)
>  
>

Well, all I can say is that I had to sit down and work through some 
examples to figure out what each of those lambdas would do.  It looks 
like a tangled mess of punctuation and x's and y's to me.  Maybe this 
just means I'm stupid, but... ::shrug::

I'm also not sure what the point is of defining a callable that returns 
a literal string, but I suppose you're just following a protocol 
established elsewhere.

Personally, I'd be likely to solve this particular issue by defining a 
make_formatter() function:

def make_formatter(format):
    def formatter(*args):
        return format % tuple(args)
    return formatter

xforms = {dejavu.icontains: make_formatter("%s Like '%%%s%%'"),
          dejavu.icontainedby: icontainedby,
          dejavu.istartswith: make_formatter("%s Like '%s%%'"),
          dejavu.iendswith: make_formatter("%s Like '%%%s'"),
          dejavu.ieq: make_formatter("%s = %s"),
          dejavu.now: make_formatter("Now()"),
          dejavu.today: make_formatter("DateValue(Now())"),
          dejavu.year: make_formatter("Year(%s)")
          }

# [...]
xforms[dejavu.icontains](x, y[1:-1])

I'm not sure that this is much clearer than your example, but I 
certainly don't think it's worse.  (Admittedly, much of the gain in my 
eyes comes from using string interpolation rather than addition, which 
looks clunky and ugly to me, but I suppose that tastes may vary...)

I suppose that the fact that all of these methods just happen to be 
building strings may be an artifact of the specific example, rather than 
a general case.  I haven't really needed to use adapters, so I can't 
really say how often a general transformation along these lines might be 
applicable...

Jeff Shannon
Technician/Programmer
Credit International




More information about the Python-list mailing list