Re: [Python-Dev] any support for a methodcaller HOF?
Giovanni Bajo wrote:
Alex Martelli <aleaxit@gmail.com> wrote:
I understand your worry re the syntax issue. So what about Michael Hudson's "placeholder class" idea, where X[1] returns the callable that will do x[1] when called, etc? Looks elegant to me...
Depends on how the final API looks like. "deffered(x)[1]" isn't that bad, but "def x: x[1]" still looks clearer as the 'def' keyword immediatly makes clear you're DEFining a DEFerred function <g> :) Of course we can paint our bikeshed of whatever color we like, but I'm happy enough if we agree with the general idea of keeping the same syntax in both deferred and immediate execution.
I don't agree with that "general idea" at all. Sorry. ;) I think the semantic emphasis should not be on "execution", but rather on "expression". The word "execution" to me implies "statements", and although some functions somewhere are called behind the scenes to evaluate any expression, the lambda (and its potential successors) differ from "def" by not allowing statements. They may be used to "defer execution" but to me, their value lies in being static expressions--object instances which are portable and introspectable. This is where LINQ [1] is taking off: expressions are declared with "var" (in C#). I used Expression() in Dejavu [2] for the same reasons (before LINQ came along ;), and am using it to build SQL from Python lambdas. I had to use lambda because that's Python's only builtin support for expressions-as-objects at the moment, but I'd like to see Python grow a syntax like: e = expr(x: x + 1) ...where expr() does early binding like dejavu.logic does. [Looking back over my logic module, I'm noticing it requires boolean return values, but it would not be difficult to extend to return abitrary values--even easier if it were rewritten as builtin functionality. Guess I need to write myself another ticket. ;)] Robert Brewer System Architect Amor Ministries fumanchu@amor.org [1] http://msdn.microsoft.com/netframework/future/linq/ [2] http://projects.amor.org/dejavu/browser/trunk/logic.py
Robert Brewer <fumanchu@amor.org> wrote:
The word "execution" to me implies "statements", and although some functions somewhere are called behind the scenes to evaluate any expression, the lambda (and its potential successors) differ from "def" by not allowing statements. They may be used to "defer execution" but to me, their value lies in being static expressions--object instances which are portable and introspectable.
This is where LINQ [1] is taking off: expressions are declared with "var" (in C#). I used Expression() in Dejavu [2] for the same reasons (before LINQ came along ;), and am using it to build SQL from Python lambdas. I had to use lambda because that's Python's only builtin support for expressions-as-objects at the moment, but I'd like to see Python grow a syntax like:
e = expr(x: x + 1)
I see what you mean, but in a way you're still agreeing with me :) Your expression-as-objects proposal is very clever, but to me (and as far as this thread is concerned) it still allows to write a "decorated" piece of code (expression), pass it around, and execute (evaluate) it later. This is what I (and others) mainly use lambda for, and your expr() thing would still serve me well. Instead, itemgetter() and friends are going to a different direction (the expression which is later evaluated is not clearly expressed in familiar Python terms), and that's what I find inconvenient. -- Giovanni Bajo
On 2/3/06, Robert Brewer <fumanchu@amor.org> wrote:
Giovanni Bajo wrote:
Alex Martelli <aleaxit@gmail.com> wrote:
I understand your worry re the syntax issue. So what about Michael Hudson's "placeholder class" idea, where X[1] returns the callable that will do x[1] when called, etc? Looks elegant to me...
Depends on how the final API looks like. "deffered(x)[1]" isn't that bad, but "def x: x[1]" still looks clearer as the 'def' keyword immediatly makes clear you're DEFining a DEFerred function <g> :) Of course we can paint our bikeshed of whatever color we like, but I'm happy enough if we agree with the general idea of keeping the same syntax in both deferred and immediate execution.
I don't agree with that "general idea" at all. Sorry. ;) I think the semantic emphasis should not be on "execution", but rather on "expression". The word "execution" to me implies "statements", and although some functions somewhere are called behind the scenes to evaluate any expression, the lambda (and its potential successors) differ from "def" by not allowing statements. They may be used to "defer execution" but to me, their value lies in being static expressions--object instances which are portable and introspectable.
This is where LINQ [1] is taking off: expressions are declared with "var" (in C#). I used Expression() in Dejavu [2] for the same reasons (before LINQ came along ;), and am using it to build SQL from Python lambdas. I had to use lambda because that's Python's only builtin support for expressions-as-objects at the moment, but I'd like to see Python grow a syntax like:
e = expr(x: x + 1)
...where expr() does early binding like dejavu.logic does. [Looking back over my logic module, I'm noticing it requires boolean return values, but it would not be difficult to extend to return abitrary values--even easier if it were rewritten as builtin functionality. Guess I need to write myself another ticket. ;)]
Well, maybe what we really want is lambda but under a different name. ``expr x: x + 1`` seems fine to me and it doesn't have the issue of portraying Python has having a crippled lambda expression. I do think that a general solution can be found that can allow us to do away with itemgetter, itergetter, and Alex's methodcaller (something like Michael's Placeholder class). The problem is when we want deferred arguments to a function call. We have functional.partial, but it can't do something like ``lambda x: func(1, 2, x, 4, 5)`` unless everything is turned to keyword arguments but that doesn't work when something only take positional arguments. This does not seem to have a good solution outside of lambda in terms of non-function definition. But then again small functions can be defined for those situations. So I think that functional.partial along with some deferred object implementation should deal with most uses of lambda and then allow us to use custom functions to handle all the other cases of when we would want lambda. -Brett
participants (3)
-
Brett Cannon
-
Giovanni Bajo
-
Robert Brewer