What I would like to say is that if your application needs lambda, filter or map, your code is getting bejond report or presentation generation (for which DTML is intended) and in the realm of data manipulation and business rules. In this case your code would be much better placed in some form of Method object, be that an External, Python, or when ready, Perl Method, or even as a disk based Product.
1: This is simply not true, and a very poor excuse for handicapping the language.
Nope. Lamba, filter, reduce, and map should IMHO not be part of DTML. Actually, exprs probably shouldn't be in there in the first place. People are trying to use DTML as a way to process non-UI elements. This is a slippery slope, and leads to something like PHP or ASP. My opinion is this: Generate and format your HTML with DTML, and do everything else in Python. This gives you the added benefit that you can change the return values of functions by changing the Python code without having to muck with DTML, which is painful any way you look at it. People are right when they say DTML is beginning to get worse than Perl, and IMHO, adding these functions could make it even worse than it is now. This sort of processing was not meant to happen in an expr under Zope. Python lets you do it, but it's sort of hard for somebody else to understand after you've completed it, even if they know Python well. Functional constructs are handy, but not the most clear thing on the planet.
A common example is:
<dtml-in "_.map (lambda item: Catalog.getobject (item.data_record_id_), Catalog (REQUEST)">
How could someone understand this when you're finished with it? I looked at it three times before figuring out what you were trying to do. What if you didn't write it and you needed to answer somebody asking a question about it on this mailing list? Isn't this much more understandable as an external method explicitly? def return_cataloged_objects(self): obs = [] catalog = self.Catalog request = self.REQUEST for r in catalog(request): d_rid = r.data_record_id_ ob = catalog.getobject(d_rid) obs.append(ob) return obs then: <dtml-in return_cataloged_objects> ... </dtml-in> It *might* be slighly slower, but someone maintaining your code will eventually thank you for this. Eventually it will cost you less money somewhere that you might be able to buy a faster server with.
I know fetching the actual records from a ZCatalog introduces a performance penalty, but sometimes it's necessary; there are times you need to be absolutely sure everything is pushed on the namespace, including user-defined properties and sub-objects. This is the case in Hack&Roll, and I have to use a very ugly Python Method there (and as PythonMethods don't have map either, I have to build a list from scratch using for, which introduces additional penalties as I'm basically bypassing Python's optimizations).
Sometimes. Sometimes not. Read http://www.python.org/doc/essays/list2str.html . As I understand it, by using expr syntax to begin with, you're defeating some of Zope's caching mechanisms, actually slowing things down in reality.
2: If I should be using a Python Method, then Python Methods should have these forms, and they don't.
Maybe they should... it would be nice. I'm not sure why they're not in Python Methods, other than Evan tried to make the security inherent in Python methods as close to DTML as he could. I use map a lot. I don't use lambda unless I really, really have to. Reduce and filter.. eh. I dunno. They're sort of on the periphery of usefulness.
3: In short, these excuses are just the fallback (or should I say Acquired?) excuses used mostly by people who don't know how to use these very cool features of Python.
I would hardly say Martijn is one of those. :-)