Re: [Python-Dev] Seeming unintended difference between list comprehensions and generator expressions...

2009-02-22 Thread Carl Johnson
Nick Coghlan wrote:
>
> Josiah Carlson wrote:
> >> Similarly, a 3.x list comprehension [i*i for i in x] is very roughly
> >> translated as:
> >>
> >>  def _lc(arg):
> >>result = []
> >>for i in arg:
> >>  result.append(i*i)
> >>return result
> >>
> >>   = _lc(x)
> >
> > I was under the impression that in 3.x, it was equivalent to
> > list() .  Which would explain the difference between 2.6 and
> > 3.0.
>
> Semantically, the two translations end up being the same.

Actually, they're not quite the same. list() will swallow any
StopIteration exceptions that end up getting thrown inside the
generator, but even in Python 3, list comprehensions will not catch
StopIteration. So for explanatory purposes, thinking of a list
comprehension as a function that returns a list is more useful than
thinking of it as list().

-- Carl
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 377 - allow __enter__() methods to skip the statement body

2009-03-15 Thread Carl Johnson
P.J. Eby wrote:

> Of course, at that point, what's the difference between:
>
>    with foo() as bar:
>        baz
>
> and...
>
>   �...@foo
>    def bar():
>       baz
>
> except for being slightly less verbose? (due to missing nonlocal statements,
> etc.)

That's not quite direct translation. Closer would be:

@foo()
def _(bar):
   baz
del _

since the "bar" of the with statement is injected into the namespace
of the block. (Obviously, the foo would have be implemented
differently in the two cases in order to have it operate the same
way.)

I have thought about suggesting adding control flow to the with
statement before, since I think if done properly, it might be able to
negate the desire people have for multi-line lambdas/Ruby-style
blocks, but I do wonder if it would be too confusing to have "with"
sometimes mean "abstracting error handling code" and other times mean
"abstracted control flow." But now it looks like there's no way around
using the with-statement for control flow, since sometimes the block
needs to be skipped anyway. So, I'm +.5 on the idea.

-- Carl
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] return from a generator [was:PEP 380 (yield from a subgenerator) comments]

2009-03-26 Thread Carl Johnson
>def g():
>yield 42
>return 43

I don't see how the allowing return values in generators can fail to
be confusing for people new to Python. Of course, there are limits to
the degree that we should let people who are bad at Python dictate our
code practices, but I really just feel like this is going to confuse
people endlessly. "Where did my 43 go? Why didn't it come up in my
loop?"

On the other hand, raising is a pretty well understood way of doing
control flow, if not value passing. But I can see why "raise
StopIteration(42)" might seem a bit obtuse. What if we just subclass
StopIteration and make something called "ReturnValue" or some-such.
Would a simple rename fix part of the problem:

def g():
yield 42
raise ReturnValue(43)


> Do you really think the intent of the code would be any clearer
> if all the returns were replaced by raising StopIteration?

Doesn't "ReturnValue(43)" pretty clearly indicate what's going on? I
think part of the appeal of using "return" is that return is what's
used in ordinary functions, but if you think about it, you already
have to make your cooperative multitasking mini-thread different from
an ordinary function anyway by sprinkling yields throughout it. If
you're going that far, is it really so bad to also change the "return"
to a "raise ReturnValue"?

-- Carl Johnson
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Decorator syntax

2009-09-02 Thread Carl Johnson
Crossposting to Python-ideas,

I asked for the same change to the grammar a couple months back on
python-ideas.

See http://mail.python.org/pipermail/python-ideas/2009-February/thread.html#2787

I'm all for it, but you'll have to convince Guido that this won't
result in confusing to read code. My own examples, unfortunately did
not advance your cause, as Guido explained, "My brain hurts trying to
understand all this. I don't think this bodes well as a use case for a
proposed feature." :-D The trouble is that I was using lambdas upon
lambdas to do all kinds of Ruby block-esque tricks. OTOH, if you come
up with some simple, clear use cases though, and I think he might
still be persuadable to make a simple change to the grammar.


— Carl Johnson

Rob Cliffe  wrote:

> Hi All,
> This is my first post to python-dev so I will briefly introduce myself:  My
> name is Rob Cliffe and I am a commercial programmer living in London, UK.  I
> have some 30 years of programming experience but have only been using Python
> for a couple of years.
> First I want to say what a fantastic language Python is.  It is THE best
> language for development in my opinion, and a joy to use.
>
> My specific issue:
> I eventually got my head round decorator syntax and realised that what came
> after the '@' was (basically) a function that took a function as argument
> and returned a function as result.
> However it seems to me unPythonesque (i.e. an exception to Python's normal
> consistency) that the syntax of what follows the '@' should be restricted to
> either a single (function) identifier or a single (function) identifier with
> an argument list.
> The example I tried, which seems not an unreasonable sort of thing to do,
> was along the lines of:
>
> def deco1(func):
>     
> def deco2(func):
>     
>
> DecoList = [deco1, deco2]
>
> @DecoList[0]    # NO - CAUSES SYNTAX ERROR
> def foo():
>     pass
>
> I am sure other guys have their own examples.
>
> I am of course not the first person to raise this issue, and I see that
> Guido has a "gut feeling" against allowing a general expression after the
> '@'.
>
> BUT - a general expression can be "smuggled in" very easily as a function
> argument:
>
> def Identity(x): return x
>
> @Identity(DecoList[0])    # THIS WORKS
> def foo():
>     pass
>
> So - the syntax restriction seems not only inconsistent, but pointless; it
> doesn't forbid anything, but merely means we have to do it in a slightly
> convoluted (unPythonesque) way.  So please, Guido, will you reconsider?
>
> Best wishes
> Rob Cliffe
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Incorrect documentation (and possibly implementation) for rlcompleter.Completer?

2009-01-25 Thread Carl Johnson
The documentation at http://docs.python.org/library/rlcompleter.html  
claims that



Completer.complete(text, state)¶

Return the state*th completion for *text.

If called for text that doesn’t include a period character  
('.'), it will complete from names currently defined in __main__,  
__builtin__ and keywords (as defined by the keyword module).


If called for a dotted name, it will try to evaluate anything  
without obvious side-effects (functions will not be evaluated, but  
it can generate calls to __getattr__()) up to the last part, and  
find matches for the rest via the dir() function. Any exception  
raised during the evaluation of the expression is caught, silenced  
and None is returned.


In other words, it claims to use dir(obj) as part of the tab  
completion process. This is not true (using Python 2.6.1 on OS X):


>>> class B(object):
...  def __dir__(self): return dir(u"") #Makes B objects look like  
strings

...
>>> b = B()
>>> dir(b)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',  
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',  
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',  
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__',  
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__',  
'__rmul__', '__setattr__', '__sizeof__', '__str__',  
'__subclasshook__', '_formatter_field_name_split',  
'_formatter_parser', 'capitalize', 'center', 'count', 'decode',  
'encode', 'endswith', 'expandtabs', 'find', 'format', 'index',  
'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'islower', 'isnumeric',  
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',  
'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition',  
'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip',  
'swapcase', 'title', 'translate', 'upper', 'zfill']

>>> c = rlcompleter.Completer()
>>> c.complete("b.", 0) #Notice that it does NOT return __add__
u'b.__class__('
>>> c.matches #Notice that this list is completely different from the  
list given by dir(b)
[u'b.__class__(', u'b.__delattr__(', u'b.__doc__', u'b.__format__(',  
u'b.__getattribute__(', u'b.__hash__(', u'b.__init__(', u'b.__new__(',  
u'b.__reduce__(', u'b.__reduce_ex__(', u'b.__repr__(',  
u'b.__setattr__(', u'b.__sizeof__(', u'b.__str__(',  
u'b.__subclasshook__(', u'b.__class__(', u'b.__class__(',  
u'b.__delattr__(', u'b.__dict__', u'b.__dir__(', u'b.__doc__',  
u'b.__format__(', u'b.__getattribute__(', u'b.__hash__(',  
u'b.__init__(', u'b.__module__', u'b.__new__(', u'b.__reduce__(',  
u'b.__reduce_ex__(', u'b.__repr__(', u'b.__setattr__(',  
u'b.__sizeof__(', u'b.__str__(', u'b.__subclasshook__(',  
u'b.__weakref__', u'b.__class__(', u'b.__delattr__(', u'b.__doc__',  
u'b.__format__(', u'b.__getattribute__(', u'b.__hash__(',  
u'b.__init__(', u'b.__new__(', u'b.__reduce__(', u'b.__reduce_ex__(',  
u'b.__repr__(', u'b.__setattr__(', u'b.__sizeof__(', u'b.__str__(',  
u'b.__subclasshook__(']


As I see it, there are two ways to fix the problem: Change the  
documentation or change rlcompleter.Complete. I think the latter  
option is preferable (although it might have to wait for Python  
2.7/3.1), but I thought I would ask other people if I'm missing  
something and if not which fix is preferred. If other people agree  
that it's a bug, I'll file it.


-- Carl Johnson
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Incorrect documentation (and possibly implementation) for rlcompleter.Completer?

2009-01-25 Thread Carl Johnson

On 2009/01/25, at 3:22 pm, Nick Coghlan wrote:


It needs to go on the tracker regardless of whether the problem is in
the documentation or in the implementation, so file away.


Issue #5062: http://bugs.python.org/issue5062

-- Carl Johnson
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com