On Thu, May 14, 2009 at 3:20 PM, Steven D'Aprano <steve@pearwood.info> wrote:
On Thu, 14 May 2009 12:41:17 pm Bruce Leban wrote:

> Explicit is better than implicit. There's a thunk getting created
> here, right? Don't you want that to be obvious? I do.

No, I don't want it to be obvious. I don't care about thunks, I care
that x gets bound at runtime. I don't care what the implementation is:
whether it is a thunk, eval(), voodoo or something else, just so long
as it works.

As for your argument that it is better to be explicit, when you want to
add two numbers and compare them with a third, do you write:

(1 .__add__(1)).__eq__(2)

instead of

1+1 == 2?

Absolutely not. This is a false analogy. The anology would be having an implicit multiplication operator and writing (a b c) instead of (a * b * c).
 

<snip> The syntax shouldn't depend on the
implementation.

lambda is already disliked by many people, including Guido. I don't
think any suggestion that we make lambda more confusing by giving it
two very different meanings ("create a thunk" inside function parameter
lists, and "create a function" everywhere else) will be very popular on
python-dev.

I'm *not* suggesting a new meaning for lambda! This is the same meaning that it has right now. The new meaning is the decorator attached to the default assignment that says evaluate that lambda.

I'll use an @dynamic decorator-like syntax to illustrate. These would be valid:

def foo(a, b = @dynamic lambda: []):
def foo(a, b = @dynamic lambda: list()):
def foo(a, b = @dynamic list):
def foo(a, b = @dynamic random.random):

and this would not:

def foo(a, b = @dynamic [])
def foo(a, b = @dynamic 5)

because @dynamic says that the thing that follows is called to generate a dynamic default parameter value and you can't call [] or 5.

My point about creating a thunk is *not* an implementation detail. The point here is that if you use one of the forms above with a lambda, it's the lambda creating a thunk/closure/voodoo thing at this point in the program, *not* the @dynamic decorator. The scope of that lambda is exactly what it looks like it is with or without the @dynamic decorator. Likewise, in the random.random, example, it's the value of random.random at the time the function is defined, not some later value that might be assigned to that name.

If you use some other syntax that doesn't look like a lambda, I have to learn the scoping rules for that syntax. I already know the rules for lambda.

--- Bruce