Re: [Python-Dev] Re: anonymous blocks

2005-04-21 Thread Paul Moore
On 4/20/05, Samuele Pedroni <[EMAIL PROTECTED]> wrote:
> 
> >
> >
> >def do():
> >print "setup"
> >try:
> >yield None
> >finally:
> >print "tear down"
> >
> > doesn't quite work (if it did, all you would need is syntactic sugar
> > for "for
> > dummy in").
> >
> PEP325 is about that

And, of course, PEP 310 is all about encapsulating before/after
(acquire/release) actions.

Paul.
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: switch statement

2005-04-21 Thread Michael Hudson
Shannon -jj Behrens <[EMAIL PROTECTED]> writes:

> On 4/20/05, M.-A. Lemburg <[EMAIL PROTECTED]> wrote:
>
>> My use case for switch is that of a parser switching on tokens.
>> 
>> mxTextTools applications would greatly benefit from being able
>> to branch on tokens quickly. Currently, there's only callbacks,
>> dict-to-method branching or long if-elif-elif-...-elif-else.
>
> I think "match" from Ocaml would be a much nicer addition to Python
> than "switch" from C.

Can you post a quick summary of how you think this would work?

Cheers,
mwh

-- 
  We did requirements and task analysis, iterative design, and user
  testing. You'd almost think programming languages were an interface
  between people and computers.-- Steven Pemberton
  (one of the designers of Python's direct ancestor ABC)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Re: anonymous blocks

2005-04-21 Thread Fredrik Lundh
Glyph Lefkowitz wrote:

> Despite being guilty of propagating this style for years myself, I have to 
> disagree.  Consider the 
> following network-conversation using Twisted style (which, I might add, would 
> be generalizable to 
> other Twisted-like systems if they existed ;-)):
>
> def strawman(self):
> def sayGoodbye(mingleResult):
> def goAway(goodbyeResult):
> self.loseConnection()
> self.send("goodbye").addCallback(goAway)
> def mingle(helloResult):
> self.send("nice weather we're having").addCallback(sayGoodbye)
> self.send("hello").addCallback(mingle)

def iterman(self):
yield "hello"
yield "nice weather we're having"
yield "goodbye"

 



___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: switch statement

2005-04-21 Thread Andrew McGregor
I can post an alternative, inspired by this bit of Haskell (I've  
deliberately left out the Haskell type annotation for this):

zoneOpts argv =
   case getOpt Permute options argv of
  (o,n,[]) -> return (o,n)
  (_,_,errs) -> error errs
which could, in a future Python, look something like:
def zoneOpts(argv):
case i of getopt(argv, options, longoptions):
i[2]:
raise OptionError(i[2])
True:
return i[:2]
The intent is that within the case, the bit before each : is a boolean  
expression, they're evaluated in order, and the following block is  
executed for the first one that evaluates to be True.  I know we have  
exceptions for this specific example, but it's just an example.  I'm  
also assuming for the time being that getopt returns a 3-tuple  
(options, arguments, errors) like the Haskell version does, just for  
the sake of argument, and there's an OptionError constructor that will  
do something with that error list..

Yes, that is very different semantics from a Haskell case expression,  
but it kind of looks like a related idea.  A more closely related idea  
would be to borrow the Haskell patterns:

def zoneOpts(argv):
case getopt(argv, options, longoptions):
(o,n,[]):
return o,n
(_,_,errs):
raise OptionError(errs)
where _ matches anything, a presently unbound name is bound for the  
following block by mentioning it, a bound name would match whatever  
value it referred to, and a literal matches only itself.  The first  
matching block gets executed.

Come to think of it, it should be possible to do both.
Not knowing Ocaml, I'd have to presume that 'match' is somewhat similar.
Andrew
On 21/04/2005, at 9:30 PM, Michael Hudson wrote:
Shannon -jj Behrens <[EMAIL PROTECTED]> writes:
On 4/20/05, M.-A. Lemburg <[EMAIL PROTECTED]> wrote:
My use case for switch is that of a parser switching on tokens.
mxTextTools applications would greatly benefit from being able
to branch on tokens quickly. Currently, there's only callbacks,
dict-to-method branching or long if-elif-elif-...-elif-else.
I think "match" from Ocaml would be a much nicer addition to Python
than "switch" from C.
Can you post a quick summary of how you think this would work?
Cheers,
mwh
--  
  We did requirements and task analysis, iterative design, and user
  testing. You'd almost think programming languages were an interface
  between people and computers.-- Steven Pemberton
  (one of the designers of Python's direct ancestor ABC)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:  
http://mail.python.org/mailman/options/python-dev/ 
andrew%40indranet.co.nz


___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Re: Re: anonymous blocks

2005-04-21 Thread Fredrik Lundh
Josiah Carlson wrote:

> > for my purposes, I've found that the #1 callback killer in contemporary 
> > Python
> > is for-in:s support for the iterator protocol:
> ...
> > and get shorter code that runs faster.  (see cElementTree's iterparse for
> > an excellent example.  for typical use cases, it's nearly three times faster
> > than pyexpat, which is the fastest callback-based XML parser we have)
>
> It seems as though you are saying that because callbacks are so slow,
> that blocks are a non-starter for you because of how slow it would be to
> call them.

Not really -- I see the for-in loop body as the block.

The increased speed is just a bonus.

> I'm thinking that if people get correct code easier, that speed will not be 
> as much
> of a concern (that's why I use Python already).

(Slightly OT, but speed is always a concern.  I no longer buy the "it's python,
it has to be slow" line of reasoning; when done correctly, Python code is often
faster than anything else.

cElementTree is one such example; people have reported that cElementTree
plus Python code can be a lot faster than dedicated XPath/XSLT engines; the
Python bytecode engine is extremely fast, also compared to domain-specific
interpreters...

And in this case, you get improved usability *and* improved speed at the
same time.  That's the way it should be.)

> With that said, both blocks and iterators makes /writing/ such things
> easier to understand, but neither really makes /reading/ much easier.
> Sure, it is far more terse, but that doesn't mean it is easier to read
> and understand what is going on.

Well, I was talking about reading here: with the for-in pattern, you loop over
the "callback source", and the "callback" itself is inlined.  You don't have to
think in "here is the callback, here I configure the callback source" terms; 
just
make a function call and loop over the result.

> Regardless, I believe that solving generator finalization (calling all
> enclosing finally blocks in the generator) is a worthwhile problem to
> solve.  Whether that be by PEP 325, 288, 325+288, etc., that should be
> discussed.  Whether people use it as a pseudo-block, or decide that
> blocks are further worthwhile, I suppose we could wait and see.

Agreed.

 



___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: anonymous blocks

2005-04-21 Thread Bob Ippolito
On Apr 21, 2005, at 6:28 AM, Fredrik Lundh wrote:
Glyph Lefkowitz wrote:
Despite being guilty of propagating this style for years myself, I 
have to disagree.  Consider the
following network-conversation using Twisted style (which, I might 
add, would be generalizable to
other Twisted-like systems if they existed ;-)):

def strawman(self):
def sayGoodbye(mingleResult):
def goAway(goodbyeResult):
self.loseConnection()
self.send("goodbye").addCallback(goAway)
def mingle(helloResult):
self.send("nice weather we're having").addCallback(sayGoodbye)
self.send("hello").addCallback(mingle)
def iterman(self):
yield "hello"
yield "nice weather we're having"
yield "goodbye"
Which, more or less works, for a literal translation of the straw-man 
above.  However, you're missing the point.  These deferred operations 
actually return results.  Generators offer no sane way to pass results 
back in.  If they did, then this use case could be mostly served by 
generators.

-bob
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Re: anonymous blocks

2005-04-21 Thread Steve Holden
Guido van Rossum wrote:
IMO this is clearer, and even shorter!
But it clutters the namespace with objects you don't need.

Why do people care about cluttering namespaces so much? I thought
thats' what namespaces were for -- to put stuff you want to remember
for a bit. A function's local namespace in particular seems a
perfectly fine place for temporaries.
Indeed. The way people bang on about "cluttering namespaces" you'd be 
forgiven for thinking that they are like attics, permanently attached to 
the house and liable to become cluttered over years.

Most function namespaces are in fact extremely short-lived, and there is 
little point worrying about clutter as long as there's no chance of 
confusion.

regards
 Steve
--
Steve Holden+1 703 861 4237  +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
Python Web Programming  http://pydish.holdenweb.com/
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] Re: switch statement

2005-04-21 Thread Michael Chermside
Andrew McGregor writes:
> I can post an alternative, inspired by this bit of Haskell
[...]
> The intent is that within the case, the bit before each : is a boolean
> expression, they're evaluated in order, and the following block is
> executed for the first one that evaluates to be True.

If we're going to be evaluating a series of booleans, then the One Proper
Format in Python is:

 if :
 
 elif :
 
 elif :
 
 else:
 

When people speak of introducing a "switch" statement they are speaking
of a construct in which the decision of which branch to take requires
time proportional to something LESS than a linear function of the number
of branches (it's not O(n) in the number of branches).

Now the pattern matching is more interesting, but again, I'd need to
see a proposed syntax for Python before I could begin to consider it.
If I understand it properly, pattern matching in Haskell relies
primarily on Haskell's excellent typing system, which is absent in
Python.

-- Michael Chermside

___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Reference counting when entering and exiting scopes

2005-04-21 Thread Matthew F. Barnes
On Wed, 2005-04-20 at 18:59 -0700, Brett C. wrote:
> So no leak.  Yes, there should be more explicit refcounting to be proper, but
> the compiler cheats in a couple of places for various reasons.  But basically
> everything is fine since st->st_cur and st->st_stack are only played with
> refcount-wise by either symtable_enter_scope() and symtable_exit_scope() and
> they are always called in pairs in the end.

... except for the "global" scope, for which symtable_exit_scope() is
never called.  But the last reference to *that* scope (st->st_cur) gets
cleaned up in PySymtable_Free().  Correct?

So the two things I thought were glitches are actually cancelling each
other out.  Very good.  Thanks for your help.

Matthew Barnes
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: switch statement

2005-04-21 Thread Nick Coghlan
Michael Chermside wrote:
Now the pattern matching is more interesting, but again, I'd need to
see a proposed syntax for Python before I could begin to consider it.
If I understand it properly, pattern matching in Haskell relies
primarily on Haskell's excellent typing system, which is absent in
Python.
There's no real need for special syntax in Python - an appropriate tuple 
subclass will do the trick quite nicely:

class pattern(tuple):
  ignore = object()
  def __new__(cls, *args):
return tuple.__new__(cls, args)
  def __hash__(self):
raise NotImplementedError
  def __eq__(self, other):
if len(self) != len(other):
return False
for item, other_item in zip(self, other):
  if item is pattern.ignore:
continue
  if item != other_item:
return False
return True
Py> x = (1, 2, 3)
Py> print x == pattern(1, 2, 3)
True
Py> print x == pattern(1, pattern.ignore, pattern.ignore)
True
Py> print x == pattern(1, pattern.ignore, 3)
True
Py> print x == pattern(2, pattern.ignore, pattern.ignore)
False
Py> print x == pattern(1)
False
It's not usable in a dict-based switch statement, obviously, but it's perfectly 
compatible with the current if/elif idiom.

Cheers,
Nick.
--
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---
http://boredomandlaziness.skystorm.net
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: switch statement

2005-04-21 Thread Michael Walter
On 4/21/05, Nick Coghlan <[EMAIL PROTECTED]> wrote:
> Michael Chermside wrote:
> > Now the pattern matching is more interesting, but again, I'd need to
> > see a proposed syntax for Python before I could begin to consider it.
> > If I understand it properly, pattern matching in Haskell relies
> > primarily on Haskell's excellent typing system, which is absent in
> > Python.
> 
> There's no real need for special syntax in Python - an appropriate tuple
> subclass will do the trick quite nicely:

You are missing the more interesting part of pattern matching, namely
that it is used for deconstructing values/binding subvalues. Ex.:

case lalala of
  Foo f -> f
  Bar (Baz brz) _ meep -> (brz, meep)

or Python-ish:

match doThis() with:
  Foo as f: return f
  (_,* as bar,_): return bar
  Baz(boink as brzzz, meep=10): return brzzz

"* as bar" is Not Very Nice (tm) :/

Michael
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Re: Re: anonymous blocks

2005-04-21 Thread Fredrik Lundh
Bob Ippolito wrote:

>>> def strawman(self):
>>> def sayGoodbye(mingleResult):
>>> def goAway(goodbyeResult):
>>> self.loseConnection()
>>> self.send("goodbye").addCallback(goAway)
>>> def mingle(helloResult):
>>> self.send("nice weather we're having").addCallback(sayGoodbye)
>>> self.send("hello").addCallback(mingle)
>>
>> def iterman(self):
>> yield "hello"
>> yield "nice weather we're having"
>> yield "goodbye"
>
> Which, more or less works, for a literal translation of the straw-man above.  
> However, you're 
> missing the point.  These deferred operations actually return results.  
> Generators offer no sane 
> way to pass results back in.

that's why you need a context object (=self, in this case).

def iterman(self):
yield "hello"
print self.data
yield "nice weather we're having"
print self.data
yield "goodbye"

also see:

http://effbot.org/zone/asyncore-generators.htm

> If they did, then this use case could be mostly served by generators.

exactly.

 



___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: switch statement

2005-04-21 Thread Samuele Pedroni
Michael Hudson wrote:
Shannon -jj Behrens <[EMAIL PROTECTED]> writes:
 

On 4/20/05, M.-A. Lemburg <[EMAIL PROTECTED]> wrote:
   

My use case for switch is that of a parser switching on tokens.
mxTextTools applications would greatly benefit from being able
to branch on tokens quickly. Currently, there's only callbacks,
dict-to-method branching or long if-elif-elif-...-elif-else.
 

I think "match" from Ocaml would be a much nicer addition to Python
than "switch" from C.
   

Can you post a quick summary of how you think this would work?
 

Well, Python lists are used more imperatively and are not made up with 
cons cells,
we have dictionaries which because of ordering issues are not trivial to 
match,
and  no general ordered records with labels. We have objects and not 
algebraic
data types. Literature on the topic usually indicates the visitor 
pattern as the
moral equivalent of pattern matching in an OO-context vs. algebraic data 
types/functional
one. I agree with that point of view and Python has idioms for the 
visitor pattern.

Interestingly even in the context of objects one can leverage the 
infrastructure that is
there for generalized copying/pickling to allow generalized pattern 
matching of
nested object data structures. Whether it is practical I don't know.

>>> class Pt:
...   def __init__(self, x,y):
... self.x = x
... self.y = y
...
>>> p(lambda _: Pt(1, _()) ).match(Pt(1,3))
(3,)
>>> p(lambda _: Pt(1, Pt(_(),_(.match(Pt(1,Pt(Pt(5,6),3)))
(<__main__.Pt instance at 0x40200b4c>, 3)
http://codespeak.net/svn/user/pedronis/match.py is an experiment in that 
direction (preceding this discussion
and inspired while reading a book that was using OCaml for its examples).

Notice that this is quite grossly subclassing pickling infrastracture  
(the innocent bystander should probably not try that), a cleaner 
approach redoing that logic with matching in mind is possible and would 
be preferable.






___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Reference counting when entering and exiting scopes

2005-04-21 Thread Guido van Rossum
> So the two things I thought were glitches are actually cancelling each
> other out.  Very good.  Thanks for your help.

Though I wonder why it was written so delicately. Would explicit
INCREF/DECREF really have hurt the performance that much? This is only
the bytecode compiler, which isn't on the critical path.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: Re: anonymous blocks

2005-04-21 Thread Guido van Rossum
[Brian Sabbey]
> >> If suites were commonly used as above to define properties, event handlers
> >> and other callbacks, then I think most people would be able to comprehend
> >> what the first example above is doing much more quickly than the second.

[Fredrik]
> > wonderful logic, there.  good luck with your future adventures in language
> > design.

[Brian again]
> I'm just trying to help python improve.  Maybe I'm not doing a very good
> job, I don't know.  Either way, there's no need to be rude.
> 
> If I've broken some sort of unspoken code of behavior for this list, then
> maybe it would be easier if you just 'spoke' it (perhaps in a private
> email or in the description of this list on python.org).

In his own inimitable way, Fredrik is pointing out that your argument
is a tautology (or very close to one): rephrased, it sounds like "if X
were commonly used, you'd recognize it easily", which isn't a
sufficient argument for anything.

While I've used similar arguments occasionally to shut up folks whose
only remaining argument against a new feature was "but nobody will
understand it the first time they encounter it" (which is true of
*everything* you see for the first time), such reasoning isn't strong
enough to support favoring one thing over another.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Guido van Rossum
> So while:
> fooble(arg)
> is pretty nasty, documentation that tells me that 'arg' is a string is
> probably enough to set me on the right track.  But if the
> documentation tells me that arg is a thunk/block, that's almost
> certainly not enough to get me going.  I also need to know how that
> thunk/block will be called.

This argument against thunks sounds bogus to me. The signature of any
callable arguments is recursively part of the signature of the
function you're documenting. Just like the element type of any
sequence arguments is part of the argument type.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Guido van Rossum
[Greg Ewing]
> My current thought is that it should look like this:
> 
>with_file(filename) as f:
>  do_something_with(f)
> 
> The success of this hinges on how many use cases can
> be arranged so that the word 'as' makes sense in that
> position.
[...]
> This way, the syntax is just
> 
>expr ['as' assignment_target] ':' suite
> 
> and the expr is evaluated quite normally.

Perhaps it could be even simpler: 

[assignment_target '=']* expr ':' suite

This would just be an extension of the regular assignment statement.

(More in a longer post I'm composing off-line while picking cherries
off the thread.)

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: Re: anonymous blocks

2005-04-21 Thread Samuele Pedroni
Fredrik Lundh wrote:
Regardless, I believe that solving generator finalization (calling all
enclosing finally blocks in the generator) is a worthwhile problem to
solve.  Whether that be by PEP 325, 288, 325+288, etc., that should be
discussed.  Whether people use it as a pseudo-block, or decide that
blocks are further worthwhile, I suppose we could wait and see.
   

Agreed.
 

I agree, in fact I think that solving that issue is very important 
before/if ever introducing a generalized block statement because otherwise
things that would naturally be expressible with for and generators will 
use the block construct which allow more variety and
so possibly less immediate clarity just because generators are not good 
at resource handling.
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] Re: switch statement

2005-04-21 Thread Michael Chermside
I wrote:
> Now the pattern matching is more interesting, but again, I'd need to
> see a proposed syntax for Python before I could begin to consider it.
> If I understand it properly, pattern matching in Haskell relies
> primarily on Haskell's excellent typing system, which is absent in
> Python.

Nick Coghlan replies:
> There's no real need for special syntax in Python - an appropriate tuple
> subclass will do the trick quite nicely:
[... sample code matching tuples ...]

Aha, but now you've answered my question about syntax, and I can see
that your syntax lacks most of the power of Haskell's pattern matching.
First of all, it can only match tuples ... most things in Python are
NOT tuples. Secondly (as Michael Walter explained) it doesn't allow
name binding to parts of the pattern.

Honestly, while I understand that pattern matching is extremely powerful,
I don't see how to apply it in Python. We have powerful introspective
abilities, which seems to be helpful, but on the other hand we lack
types, which are typically a key feature of such matching. And then
there's the fact that many of the elegent uses of pattern matching use
recursion to traverse data structures... a no-no in a CPython that
lacks tail-recursion elimination.

There is one exception... matching strings. There we have a powerful
means of specifying patterns (regular expressions), and a multi-way
branch based on the content of a string is a common situation. A new
way to write this:

s = get_some_string_value()
if s == '':
continue;
elif re.match('#.*$', s):
handle_comment()
elif s == 'DEFINE':
handle_define()
elif s == 'UNDEF':
handle_undefine()
elif re.match('[A-Za-z][A-Za-z0-9]*$', s):
handle_identifier()
else:
syntax_error()

would be might be nice, but I can't figure out how to make it work
more efficiently than the simple if-elif-else structure, nor an
elegent syntax.

-- Michael Chermside

___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Re: Re: switch statement

2005-04-21 Thread Fredrik Lundh
Michael Chermside wrote:
There is one exception... matching strings. There we have a powerful
means of specifying patterns (regular expressions), and a multi-way
branch based on the content of a string is a common situation. A new
way to write this:
   s = get_some_string_value()
   if s == '':
   continue;
   elif re.match('#.*$', s):
   handle_comment()
   elif s == 'DEFINE':
   handle_define()
   elif s == 'UNDEF':
   handle_undefine()
   elif re.match('[A-Za-z][A-Za-z0-9]*$', s):
   handle_identifier()
   else:
   syntax_error()
would be might be nice, but I can't figure out how to make it work
more efficiently than the simple if-elif-else structure, nor an
elegent syntax.
somewhat related:
http://mail.python.org/pipermail/python-dev/2003-April/035075.html

___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Steven Bethard
Guido van Rossum wrote:
> > So while:
> > fooble(arg)
> > is pretty nasty, documentation that tells me that 'arg' is a string is
> > probably enough to set me on the right track.  But if the
> > documentation tells me that arg is a thunk/block, that's almost
> > certainly not enough to get me going.  I also need to know how that
> > thunk/block will be called.
> 
> This argument against thunks sounds bogus to me. The signature of any
> callable arguments is recursively part of the signature of the
> function you're documenting. Just like the element type of any
> sequence arguments is part of the argument type.

It wasn't really an argument against thunks.  (See the disclaimer I
gave at the bottom of my previous email.)  Think of it as an early
documentation request for the thunks in the language reference -- I'd
like to see it remind users of thunks that part of the thunk-accepting
function interface is the parameters the thunk will be called with,
and that these should be documented.

In case my point about the difference between thunks and other
callables (specifically decorators) slipped by, consider the
documentation for staticmethod, which takes a callable.  All the
staticmethod documentation says about that callable's parameters is:
"A static method does not receive an implicit first argument"
Pretty simple I'd say.  Or classmethod:
"A class method receives the class as implicit first argument,
 just like an instance method receives the instance."
Again, pretty simple.  Why are these simple?  Because decorators
generally pass on pretty much the same arguments as the callables they
wrap.  My point was just that because thunks don't wrap other normal
callables, they can't make such abbreviations.

STeVe
-- 
You can wordify anything if you just verb it.
--- Bucky Katt, Get Fuzzy
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Guido van Rossum
> In case my point about the difference between thunks and other
> callables (specifically decorators) slipped by, consider the
> documentation for staticmethod, which takes a callable.  All the
> staticmethod documentation says about that callable's parameters is:
> "A static method does not receive an implicit first argument"
> Pretty simple I'd say.  Or classmethod:
> "A class method receives the class as implicit first argument,
>  just like an instance method receives the instance."
> Again, pretty simple.  Why are these simple?  Because decorators
> generally pass on pretty much the same arguments as the callables they
> wrap.  My point was just that because thunks don't wrap other normal
> callables, they can't make such abbreviations.

You've got the special-casing backwards. It's not thinks that are
special, but staticmethod (and decorators in general) because they
take *any* callable. That's unusual -- most callable arguments have a
definite signature, think of map(), filter(), sort() and Button
callbacks.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Steven Bethard
James Y Knight wrote:
> If it was possible to assign to a variable to a variable bound outside
> your function, but still in your lexical scope, I think it would fix
> this issue. That's always something I've thought should be possible,
> anyways. I propose to make it possible via a declaration similar to
> 'global'.
> 
> E.g. (stupid example, but it demonstrates the syntax):
> def f():
>count = 0
>def addCount():
>  lexical count
>  count += 1
>assert count == 0
>addCount()
>assert count == 1

It strikes me that with something like this lexical declaration, we
could abuse decorators as per Carl Banks's recipe[1] to get the
equivalent of thunks:

def withfile(filename, mode='r'):
def _(func):
f = open(filename, mode)
try:
func(f)
finally:
f.close()
return _

and used like:

line = None
@withfile("readme.txt")
def print_readme(fileobj):
lexical line
for line in fileobj:
print line
print "last line:" line

As the recipe notes, the main difference between print_readme and a
real "code block" is that print_readme doesn't have access to the
lexical scope.  Something like James's suggestion would solve this
problem.

One advantage I see of this route (i.e. using defs + lexical scoping
instead of new syntactic support) is that because we're using a normal
function, the parameter list is not an issue -- arguments to the
"thunk" are bound to names just as they are in any other function.

The big disadvantage I see is that my normal expectations for
decorators are wrong here -- after the decorator is applied
print_readme is set to None, not a new callable object.

Guess I'm still riding the fence. ;-)

STeVe

[1]http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/391199
-- 
You can wordify anything if you just verb it.
--- Bucky Katt, Get Fuzzy
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Steven Bethard
Guido van Rossum <[EMAIL PROTECTED]> wrote:
> > In case my point about the difference between thunks and other
> > callables (specifically decorators) slipped by, consider the
> > documentation for staticmethod, which takes a callable.  All the
> > staticmethod documentation says about that callable's parameters is:
> > "A static method does not receive an implicit first argument"
> > Pretty simple I'd say.  Or classmethod:
> > "A class method receives the class as implicit first argument,
> >  just like an instance method receives the instance."
> > Again, pretty simple.  Why are these simple?  Because decorators
> > generally pass on pretty much the same arguments as the callables they
> > wrap.  My point was just that because thunks don't wrap other normal
> > callables, they can't make such abbreviations.
> 
> You've got the special-casing backwards. It's not thinks that are
> special, but staticmethod (and decorators in general) because they
> take *any* callable. That's unusual -- most callable arguments have a
> definite signature, think of map(), filter(), sort() and Button
> callbacks.

Yeah, that was why I footnoted that most of my use for callables
taking callables was decorators.  But while I don't use map, filter or
Button callbacks, I am guilty of using sort and helping to add a key=
argument to min and max, so I guess I can't be too serious about only
using decorators. ;-)

STeVe
-- 
You can wordify anything if you just verb it.
--- Bucky Katt, Get Fuzzy
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Guido van Rossum
> It strikes me that with something like this lexical declaration, we
> could abuse decorators as per Carl Banks's recipe[1] to get the
> equivalent of thunks:

"abuse" being the operative word.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Steven Bethard
On 4/21/05, Guido van Rossum <[EMAIL PROTECTED]> wrote:
> > It strikes me that with something like this lexical declaration, we
> > could abuse decorators as per Carl Banks's recipe[1] to get the
> > equivalent of thunks:
> 
> "abuse" being the operative word.

Yup.  I was just drawing the parallel between:

@withfile("readme.txt")
def thunk(fileobj):
for line in fileobj:
print line

and

@withfile("readme.txt"):
# called by withfile as thunk(fileobj=)
for line in fileobj:
print line

STeVe
-- 
You can wordify anything if you just verb it.
--- Bucky Katt, Get Fuzzy
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: switch statement

2005-04-21 Thread Michael Hudson
Samuele Pedroni <[EMAIL PROTECTED]> writes:

> Michael Hudson wrote:

[pattern matching]

>>Can you post a quick summary of how you think this would work?
>>
>>  
> Well, Python lists are used more imperatively and are not made up
> with cons cells, we have dictionaries which because of ordering
> issues are not trivial to match, and no general ordered records with
> labels.

That's a better way of putting it than "pattern matching and python
don't really seem to fit together", for sure :)

(I'd quite like records with labels, tangentially, but am not so wild
about ordering)

> We have objects and not algebraic data types. Literature on the
> topic usually indicates the visitor pattern as the moral equivalent
> of pattern matching in an OO-context vs. algebraic data
> types/functional one. I agree with that point of view and Python has
> idioms for the visitor pattern.

But the visitor pattern is pretty grim, really.  It would be nice (tm)
to have something like:

  match node in:
Assign(lhs=Var(_), rhs=_):
   # lhs, rhs bound in here
Assign(lhs=Subscr(_,_), rhs=_):
   # ditto
Assign(lhs=Slice(*_), rhs=_):
   # ditto
Assign(lhs=_, rhs=_):
   raise SyntaxError
 
in Lib/compiler.

Vyper had something like this, I think.

>
> Interestingly even in the context of objects one can leverage the
> infrastructure that is there for generalized copying/pickling to
> allow generalized pattern matching of nested object data
> structures. Whether it is practical I don't know.
>
>  >>> class Pt:
> ...   def __init__(self, x,y):
> ... self.x = x
> ... self.y = y
> ...
>  >>> p(lambda _: Pt(1, _()) ).match(Pt(1,3))
> (3,)
>  >>> p(lambda _: Pt(1, Pt(_(),_(.match(Pt(1,Pt(Pt(5,6),3)))
> (<__main__.Pt instance at 0x40200b4c>, 3)
>
> http://codespeak.net/svn/user/pedronis/match.py is an experiment in
> that direction (preceding this discussion
> and inspired while reading a book that was using OCaml for its examples).

Yikes!

> Notice that this is quite grossly subclassing pickling infrastracture
> (the innocent bystander should probably not try that), a cleaner
> approach redoing that logic with matching in mind is possible and
> would be preferable.

Also, the syntax is disgusting.  But that's a separate issue, I guess.

Cheers,
mwh

-- 
  /* I'd just like to take this moment to point out that C has all
 the expressive power of two dixie cups and a string.
   */   -- Jamie Zawinski from the xkeycaps source
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] marshal / unmarshal

2005-04-21 Thread Michael Hudson
Scott David Daniels <[EMAIL PROTECTED]> writes:

> What should marshal / unmarshal do with floating point NaNs (the case we
> are worrying about is Infinity) ?  The current behavior is not perfect.

So, after a fair bit of hacking, I think I have most of a solution to
this, in two patches:

   make float packing copy bytes when they can
   http://python.org/sf/1181301
   binary formats for marshalling floats
   http://python.org/sf/1180995

I'd like to check them both in pretty soon, but would really
appreciate a review, especially of the first one as it's gotten a
little hairy, mainly so I could then write some detailed tests.

That said, if there are no objections I'm going to check them in
anyway, so if they turn out to suck, it'll be YOUR fault for not
reviewing the patches :)

Cheers,
mwh

-- 
 (Of course SML does have its weaknesses, but by comparison, a
  discussion of C++'s strengths and flaws always sounds like an
  argument about whether one should face north or east when one
  is sacrificing one's goat to the rain god.) -- Thant Tessman
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: switch statement

2005-04-21 Thread Shannon -jj Behrens
On 4/21/05, Michael Hudson <[EMAIL PROTECTED]> wrote:
> Shannon -jj Behrens <[EMAIL PROTECTED]> writes:
> 
> > On 4/20/05, M.-A. Lemburg <[EMAIL PROTECTED]> wrote:
> >
> >> My use case for switch is that of a parser switching on tokens.
> >>
> >> mxTextTools applications would greatly benefit from being able
> >> to branch on tokens quickly. Currently, there's only callbacks,
> >> dict-to-method branching or long if-elif-elif-...-elif-else.
> >
> > I think "match" from Ocaml would be a much nicer addition to Python
> > than "switch" from C.
> 
> Can you post a quick summary of how you think this would work?

Sure.  

Now that I'm actually trying to come up with an example, I'm noticing
that Ocaml is very different than Python because Python distinguishes
statements and expressions, unlike say, Scheme.  Furthermore, it's
important to minimize the number of new keywords and avoid excessive
punctuation (which Ocaml is full of).  Hence, I propose something
like:

def handle_token(token):
match token:
NUMBER:
return number / a
WHITESPACE if token.value == "\n":
return NEWLINE
(a, b):
return a / b
else:
return token

Hence, the syntax is something like (in pseudo EBNF):

'match' expr ':'
{match_expression ':'
block}*
'else' ':' 
block

match_expr ::= lvalue | constant_expression

Sematically, the above example translates into:

def handle_token(token):
if token == NUMBER:
return number / a
elif token == WHITESPACE and token.value == "\n":
return NEWLINE
elif "setting (a, b) = token succeeds":
return a / b
else:
return token

However, unlike the code above, you can more easily and more
aggressively optimize.

Best Regards,
-jj

-- 
I have decided to switch to Gmail, but messages to my Yahoo account will
still get through.
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Brian Sabbey
Greg Ewing wrote:
I also have a thought concerning whether the block
argument to the function should come first or last or
whatever. My solution is that the function should take
exactly *one* argument, which is the block. Any other
arguments are dealt with by currying. In other words,
with_file above would be defined as
 def with_file(filename):
   def func(block):
 f = open(filename)
 try:
   block(f)
 finally:
   f.close()
   return func
This would also make implementation much easier. The
parser isn't going to know that it's dealing with anything
other than a normal expression statement until it gets to
the 'as' or ':', by which time going back and radically
re-interpreting a previous function call could be awkward.
I made an example implementation, and this wasn't an issue.  It took some 
code to stick the thunk into the argument list, but it was pretty 
straightforward.  The syntax that is actually used by the parser can be 
the same regardless of whether or not argument list augmentation is done, 
so the parser will not find one more awkward than the other.

This way, the syntax is just
 expr ['as' assignment_target] ':' suite
and the expr is evaluated quite normally.
Requiring arguments other than the block to be dealt with by currying can 
lead to problems.  I won't claim these problems are serious, but they will 
be annoying.  Say, for example, you create a block-accepting function that 
takes no arguments.  Naturally, you would define it like this:

def f(block):
do_something_with_block
Now, say you want to add to this function an optional argument, so you 
wrap another function around it like in your 'with_file' example above. 
Unfortunately, now you need to go find every call of this function and add 
empty parentheses.  This is annoying.  Remember the first time you added 
optional arguments to a function and what a relief it was not to have to 
go find every call to that function and stick in the extra argument? 
Those days are over!  (well, in this case anyway.)

Some people, aware of this problem of adding optional arguments, will 
define *all* of their block-accepting functions so that they are wrapped 
in another function, even if that function takes no arguments (and wars, 
annoying ones, will be fought over whether this is the "right" way to do 
it or not!):

def f():
def real_func(block):
pass
return real_func
Now the documentation gets confusing.  Just saying that the function 
doesn't take any non-block arguments isn't enough.  You would need very 
specific language, which many library authors will not provide.

And there will always be that extra step in thought: do I need the stupid 
parentheses or not?  There will inevitably be people (including me) who 
get the parentheses wrong because of absentmindedness or carelessness. 
This will be an extra little speed bump.

Now, you may say that all these arguments apply to function decorators, so 
why have none of these problems appeared?  The difference is that defining 
a function takes a long time, so a little speed bump when decorating it 
isn't a big deal.  But blocks can be defined almost instantly.  Much of 
their purpose has to do with making things quicker.  Speed bumps are 
therefore a bigger deal.

This will also be an issue for beginners who use python.  A beginner won't 
necessarily have a good understanding of a function that returns a 
function.  But such an understanding would be required simply to *use* 
block-accepting functions.  Otherwise it would be completely mysterious 
why sometimes one sees this

f(a,b,c) as i:
pass
and sometimes this
g as i:
pass
even though both of these cases just seem to call the function that 
appears next to 'as' (imagine you don't have the source of 'f' and 'g'). 
Even worse, imagine finally learning the rule that parentheses are not 
allowed if there are zero arguments, and then seeing:

h() as i:
pass
Now it would just seem arbitrary whether or not parentheses are required 
or disallowed.  Such an issue may seem trivial to an experienced 
programmer, but can be very off-putting for a beginner.

Another set of question arose for me when Barry started musing over the 
combination of blocks and decorators.  What are blocks?  Well, obviously 
they are callable.  What do they return?  The local namespace they 
created/modified?
I think the return value of a block should be None.
In constructs like with_file, the block is being used for
its side effect, not to compute a value for consumption
by the block function. I don't see a great need for blocks
to be able to return values.
If you google "filetype:rb yield", you can see many the uses of yield in 
ruby.  By looking for the uses in which yield's return value is used, you 
can find blocks that return values.  For example, "t = yield()" or "unless 
yield()" indicate that a block is returning a value.  It is true that most 
of the time blocks do not return value

[Python-Dev] anonymous blocks

2005-04-21 Thread Guido van Rossum
I've been thinking about this a lot, but haven't made much
progess. Here's a brain dump.

I've been thinking about integrating PEP 325 (Resource-Release Support
for Generators) into the for-loop code, so that you could replace

the_lock.acquire()
try:
BODY
finally:
the_lock.release()

with

for dummy in synchronized(the_lock):
BODY

or perhaps even (making "for VAR" optional in the for-loop syntax)
with

in synchronized(the_lock):
BODY

Then synchronized() could be written cleanly as follows:

def synchronized(lock):
lock.acquire()
try:
yield None
finally:
lock.release()

But then every for-loop would have to contain an extra try-finally
clause; the translation of

for VAR in EXPR:
BODY

would become

__it = iter(EXPR)
try:
while True:
try:
VAR = __it.next()
except StopIteration:
break
BODY
finally:
if hasattr(__it, "close"):
__it.close()

which I don't particularly like: most for-loops DON'T need this, since
they don't use a generator but some other form of iterator, or even if
they use a generator, not all generators have a try/finally loop.  But
the bytecode compiler can't know that, so it will always have to
generate this code.  It also changes the semantics of using a
generator in a for-loop slightly: if you break out of the for-loop
before the generator is exhausted you will still get the close() call.

It's also a bit funny to see this approach used with the only other
use case for try/finally we've looked at, which requires passing a
variable into the block: the "with_file" use case.  We now can write
with_file as a nice and clean generator:

def with_file(filename):
f = open(filename)
try:
yield f
finally:
f.close()

but the use looks very odd because it is syntactically a for-loop but
there's only one iteration:

for f in with_file("/etc/passwd"):
for line in f:
print line[:line.find(":")]

Seeing this example makes me cringe -- why two nested for loops to
loop over the lines of one file???

So I think that this is probably not the right thing to pursue, and we
might be better off with something along the lines of PEP 310.  The
authors of PEP 310 agree; under Open Issues they wrote:

There are some simiralities in concept between 'with ...' blocks
and generators, which have led to proposals that for loops could
implement the with block functionality[3].  While neat on some
levels, we think that for loops should stick to being loops.

(Footnote [3] references the tread that originated PEP 325.)

Perhaps the most important lesson we've learned in this thread is that
the 'with' keyword proposed in PEP 310 is redundant -- the syntax
could just be

[VAR '=']* EXPR ':'
BODY

IOW the regular assignment / expression statement gets an optional
colon-plus-suite at the end.

So now let's assume we accept PEP 310 with this change.  Does this
leave any use cases for anonymous blocks uncovered?  Ruby's each()
pattern is covered by generators; personally I prefer Python's

for var in seq: ...

over Ruby's much-touted

seq.each() {|var| ...}

The try/finally use case is covered by PEP 310. (If you want to
combine this with a for-loop in a single operation, you'll need PEP
325.)

The use cases where the block actually returns a value are probably
callbacks for things like sort() or map(); I have to admit that I'd
rather keep lambda for these (and use named functions for longer
blocks) than introduce an anonymous block syntax that can return
values!  I also note that if you *already* have a comparison function,
Ruby's Array sort method doesn't let you pass it in as a function
argument; you have to give it a block that calls the comparison
function, because blocks are not the same as callables (and I'm not
sure that Ruby even *has* callables -- everything seems to be a
block).

My tentative conclusion remains: Python doesn't need Ruby blocks.
Brian Sabbey ought to come up with more examples rather than arguments
why his preferred syntax and semantics are best.

--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Ka-Ping Yee
On Thu, 21 Apr 2005, Guido van Rossum wrote:
> Perhaps it could be even simpler:
>
> [assignment_target '=']* expr ':' suite
>
> This would just be an extension of the regular assignment statement.

It sounds like you are very close to simply translating

expression... function_call(args):
suite

into

expression... function_call(args)(suitefunc)

If i understand what you proposed above, you're using assignment
as a special case to pass arguments to the inner suite, right?  So:

inner_args = function_call(outer_args):
suite

becomes:

def suitefunc(inner_args):
suite
function_call(outer_args)(suitefunc)

?

This could get a little hard to understand if the right-hand side
of the assignment is more complex than a single function call.
I think the meaning would be unambiguous, just non-obvious.  The
only interpretation i see for this:

x = spam('foo') + eggs('bar'):
suite

is this:

def suitefunc(x):
suite
spam('foo') + eggs('bar')(suitefunc)

but that could seem a little too mysterious.  Or you could (in a
later compiler pass) forbid more complex expressions on the RHS.

On another note, would there be any difference between

x = spam():
suite

and

x = spam:
suite

?


-- ?!ng
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Guido van Rossum
[Ping]
> It sounds like you are very close to simply translating
> 
> expression... function_call(args):
> suite
> 
> into
> 
> expression... function_call(args)(suitefunc)

Actually, I'm abandinging this interpretation; see my separate (long) post.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Reference counting when entering and exiting scopes

2005-04-21 Thread Brett C.
Guido van Rossum wrote:
>>So the two things I thought were glitches are actually cancelling each
>>other out.  Very good.  Thanks for your help.
> 
> 
> Though I wonder why it was written so delicately.

Don't know; Jeremy wrote those functions back in 2001 to add nested scopes.  If
he remembers he deserves a cookie for having such a good memory.

> Would explicit
> INCREF/DECREF really have hurt the performance that much? This is only
> the bytecode compiler, which isn't on the critical path.
> 

Probably not.  But at this point I doubt it is worth fixing since the AST
branch will replace it eventually (work is on-going, just slow since my thesis
is on the home stretch; initial draft is done and now I am editing to hand over
for final revision by my advisor).

-Brett
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Brett C.
Guido van Rossum wrote:
> I've been thinking about this a lot, but haven't made much
> progess. Here's a brain dump.
> 
> I've been thinking about integrating PEP 325 (Resource-Release Support
> for Generators) into the for-loop code, so that you could replace
> 

[SNIP - using 'for' syntax to delineate the block and resource]

> So I think that this is probably not the right thing to pursue,

I totally agree with your reasoning on this.

> and we
> might be better off with something along the lines of PEP 310.  The
> authors of PEP 310 agree; under Open Issues they wrote:
> 
> There are some simiralities in concept between 'with ...' blocks
> and generators, which have led to proposals that for loops could
> implement the with block functionality[3].  While neat on some
> levels, we think that for loops should stick to being loops.
> 
> (Footnote [3] references the tread that originated PEP 325.)
> 
> Perhaps the most important lesson we've learned in this thread is that
> the 'with' keyword proposed in PEP 310 is redundant -- the syntax
> could just be
> 
> [VAR '=']* EXPR ':'
> BODY
> 
> IOW the regular assignment / expression statement gets an optional
> colon-plus-suite at the end.
> 

Sure, but is the redundancy *that* bad?  You should be able to pick up visually
that something is an anonymous block from the indentation but I don't know how
obvious it would be.

Probably, in the end, this minimal syntax would be fine, but it just seems
almost too plain in terms of screaming at me that something special is going on
there (the '=' in an odd place just quite cut if for me for my meaning of
"special").

> So now let's assume we accept PEP 310 with this change.  Does this
> leave any use cases for anonymous blocks uncovered?  Ruby's each()
> pattern is covered by generators; personally I prefer Python's
> 
> for var in seq: ...
> 
> over Ruby's much-touted
> 
> seq.each() {|var| ...}
> 
> The try/finally use case is covered by PEP 310. (If you want to
> combine this with a for-loop in a single operation, you'll need PEP
> 325.)
> 
> The use cases where the block actually returns a value are probably
> callbacks for things like sort() or map(); I have to admit that I'd
> rather keep lambda for these (and use named functions for longer
> blocks) than introduce an anonymous block syntax that can return
> values!  I also note that if you *already* have a comparison function,
> Ruby's Array sort method doesn't let you pass it in as a function
> argument; you have to give it a block that calls the comparison
> function, because blocks are not the same as callables (and I'm not
> sure that Ruby even *has* callables -- everything seems to be a
> block).
> 
> My tentative conclusion remains: Python doesn't need Ruby blocks.
> Brian Sabbey ought to come up with more examples rather than arguments
> why his preferred syntax and semantics are best.
> 

I think I agree with Samuele that it would be more pertinent to put all of this
effort into trying to come up with some way to handle cleanup in a generator.

-Brett
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Guido van Rossum
[Brett]
> I think I agree with Samuele that it would be more pertinent to put all of 
> this
> effort into trying to come up with some way to handle cleanup in a generator.

I.e. PEP 325.

But (as I explained, and you agree) that still doesn't render PEP 310
unnecessary, because abusing the for-loop for implied cleanup
semantics is ugly and expensive, and would change generator semantics;
and it bugs me that the finally clause's reachability depends on the
destructor executing.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Ka-Ping Yee
On Thu, 21 Apr 2005, Guido van Rossum wrote:
> The use cases where the block actually returns a value are probably
> callbacks for things like sort() or map(); I have to admit that I'd
> rather keep lambda for these (and use named functions for longer
> blocks) than introduce an anonymous block syntax that can return
> values!

It seems to me that, in general, Python likes to use keywords for
statements and operators for expressions.

Maybe the reason lambda looks like such a wart is that it uses a
keyword in the middle of an expression.  It also uses the colon
*not* to introduce an indented suite, which is a strange thing to
the Pythonic eye.  This suggests that an operator might fit better.

A possible operator for lambda might be ->.

sort(items, key=x -> x.lower())

Anyway, just a thought.


-- ?!ng
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Samuele Pedroni
Guido van Rossum wrote:
[Brett]
I think I agree with Samuele that it would be more pertinent to put all of this
effort into trying to come up with some way to handle cleanup in a generator.

I.e. PEP 325.
But (as I explained, and you agree) that still doesn't render PEP 310
unnecessary, because abusing the for-loop for implied cleanup
semantics is ugly and expensive, and would change generator semantics;
and it bugs me that the finally clause's reachability depends on the
destructor executing.
yes, PEP325 would work in combination with PEP310, whether a combined 
thing (which cannot be the current for as dicussed) is desirable is a 
different issue: these anyway

f = file(...):
  for line in f:
...
vs.
it = gen():
  for val in it:
...
would be analogous in a PEP310+325 world.
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks (don't combine them with generator finalization)

2005-04-21 Thread Josiah Carlson

Guido van Rossum <[EMAIL PROTECTED]> wrote:
> 
> [Brett]
> > I think I agree with Samuele that it would be more pertinent to put all of 
> > this
> > effort into trying to come up with some way to handle cleanup in a 
> > generator.
> 
> I.e. PEP 325.
> 
> But (as I explained, and you agree) that still doesn't render PEP 310
> unnecessary, because abusing the for-loop for implied cleanup
> semantics is ugly and expensive, and would change generator semantics;
> and it bugs me that the finally clause's reachability depends on the
> destructor executing.

Yes and no.  PEP 325 offers a method to generators that handles cleanup
if necessary and calls it close().  Obviously calling it close is a
mistake.  Actually, calling it anything is a mistake, and trying to
combine try/finally handling in generators with __exit__/close (inside
or outside of generators) is also a mistake.


Start by saying, "If a non-finalized generator is garbage collected, it
will be finalized."  Whether this be by an exception or forcing a return,
so be it.

If this were to happen, we have generator finalization handled by the
garbage collector, and don't need to translate /any/ for loop.  As long
as the garbage collection requirement is documented, we are covered (yay!).


What about ...

i.__enter__()
try:
...
finally:
i.__exit__()

... types of things?  Well, you seem to have offered a syntax ...

[VAR '=']* EXPR:
BODY

... which seems to translate into ...

[VAR = ] __var = EXPR
try:
BODY
finally:
__var.__exit__()

... or something like that.  Great!  We've got a syntax for resource
allocation/freeing outside of generators, and a non-syntax for resource
allocation/freeing inside of generators.


 - Josiah

___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks (don't combine them with generator finalization)

2005-04-21 Thread Bob Ippolito
On Apr 21, 2005, at 8:59 PM, Josiah Carlson wrote:
Guido van Rossum <[EMAIL PROTECTED]> wrote:
[Brett]
I think I agree with Samuele that it would be more pertinent to put 
all of this
effort into trying to come up with some way to handle cleanup in a 
generator.
I.e. PEP 325.
But (as I explained, and you agree) that still doesn't render PEP 310
unnecessary, because abusing the for-loop for implied cleanup
semantics is ugly and expensive, and would change generator semantics;
and it bugs me that the finally clause's reachability depends on the
destructor executing.
Yes and no.  PEP 325 offers a method to generators that handles cleanup
if necessary and calls it close().  Obviously calling it close is a
mistake.  Actually, calling it anything is a mistake, and trying to
combine try/finally handling in generators with __exit__/close (inside
or outside of generators) is also a mistake.
Start by saying, "If a non-finalized generator is garbage collected, it
will be finalized."  Whether this be by an exception or forcing a 
return,
so be it.

If this were to happen, we have generator finalization handled by the
garbage collector, and don't need to translate /any/ for loop.  As long
as the garbage collection requirement is documented, we are covered 
(yay!).
Well, for the CPython implementation, couldn't you get away with using 
garbage collection to do everything?  Maybe I'm missing something..

import weakref
class ResourceHandle(object):
def __init__(self, acquire, release):
acquire()
# if I understand correctly, this is safer than __del__
self.ref = weakref.ref(self, lambda o:release())
class FakeLock(object):
def acquire(self):
print "acquired"
def release(self):
print "released"
def with_lock(lock):
r = ResourceHandle(lock.acquire, lock.release)
yield None
del r
>>> x = with_lock(FakeLock())
>>> del x
>>> with_lock(FakeLock()).next()
acquired
released
>>> for ignore in with_lock(FakeLock()):
... print ignore
...
acquired
None
released
I could imagine someone complaining about generators that are never 
used missing out on the acquire/release.  That could be solved with a 
trivial rewrite:

def with_lock(lock):
def _with_lock(r):
yield None
del r
return _with_lock(ResourceHandle(lock.acquire, lock.release))
>>> x = with_lock(FakeLock())
acquired
>>> del x
released
Of course, this just exaggerates Guido's "it bugs me that the finally 
clause's reachability depends on the destructor executing".. but it 
does work, in CPython.

It seems to me that this pattern would be painless enough to use 
without a syntax change...

-bob
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Aahz
On Thu, Apr 21, 2005, Guido van Rossum wrote:
>
> Perhaps the most important lesson we've learned in this thread is that
> the 'with' keyword proposed in PEP 310 is redundant -- the syntax
> could just be
> 
> [VAR '=']* EXPR ':'
> BODY
> 
> IOW the regular assignment / expression statement gets an optional
> colon-plus-suite at the end.

Yes, it could.  The question then becomes whether it should.  Because
it's easy to indent Python code when you're not using a block (consider
function calls with lots of args), my opinion is that like the "optional"
colon after ``for`` and ``if``, the resource block *should* have a
keyword.
-- 
Aahz ([EMAIL PROTECTED])   <*> http://www.pythoncraft.com/

"The joy of coding Python should be in seeing short, concise, readable
classes that express a lot of action in a small amount of clear code -- 
not in reams of trivial code that bores the reader to death."  --GvR
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Re: anonymous blocks

2005-04-21 Thread Terry Reedy
I do not know that I have ever needed 'anonymous blocks', and I have 
therefore not followed this discussion in detail, but I appreciate Python's 
beauty and want to see it maintained.  So I have three comments and 
yet-another syntax  proposal that I do not remember seeing (but could have 
missed).

1. Python's integration of for loops, iterators, and generators are, to me, 
a gem of program language design that distinguishes Python from other 
languages I have used.  Using them to not iterate but to do something else 
may be cute, but in a perverted sort of way.  I would rather have 
'something else' done some other way.

2. General-purpose passable block objects with parameters look a lot like 
general-purpose anonymous functions ('full lambdas').  I bet they would be 
used a such if at all possible.  This seems to me like the wrong direction.

3. The specific use-cases for Python not handled better by current syntax 
seem to be rather specialized: resource management around a block.  So I 
cautiously propose:

with  : 

with the exact semantics dependent on .  In particular:

with lock somelock:
codeblock

could abbreviate and mean

somelock.acquire()
try:
codeblock
finally:
somelock.release()

(Guido's example).

with file somefile:
codeblock

might translate to (the bytecode equivalent of)

if isinstance(somefile, basestring?):
somefile = open(somefile,defaults)
codeblock
somefile.close

The compound keywords could be 'underscored' but I presume they could be 
parsed as is, much like 'not in'.

Terry J. Reedy



___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Skip Montanaro

Guido> or perhaps even (making "for VAR" optional in the for-loop syntax)
Guido> with

Guido> in synchronized(the_lock):
Guido> BODY

This could be a new statement, so the problematic issue of implicit
try/finally in every for statement wouldn't be necessary.  That complication
would only be needed for the above form.

(Of course, if you've dispensed with this I am very likely missing something
fundamental.)

Skip
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Steven Bethard
Ka-Ping Yee wrote:
> It seems to me that, in general, Python likes to use keywords for
> statements and operators for expressions.

Probably worth noting that 'for', 'in' and 'if' in generator
expressions and list comprehensions blur this distinction somewhat...

Steve
-- 
You can wordify anything if you just verb it.
--- Bucky Katt, Get Fuzzy
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: switch statement

2005-04-21 Thread Phillip J. Eby
At 06:10 PM 04/21/2005 +0100, Michael Hudson wrote:
But the visitor pattern is pretty grim, really.  It would be nice (tm)
to have something like:
  match node in:
Assign(lhs=Var(_), rhs=_):
   # lhs, rhs bound in here
Assign(lhs=Subscr(_,_), rhs=_):
   # ditto
Assign(lhs=Slice(*_), rhs=_):
   # ditto
Assign(lhs=_, rhs=_):
   raise SyntaxError
in Lib/compiler.
FWIW, I do intend to add this sort of thing to PyProtocols' predicate 
dispatch system.  Actually, I can dispatch on rules like the above now, 
it's just that you have to spell out the cases as e.g.:

@do_it.when("isinstance(node, Assign) and isinstance(node.lhs, Subscr)")
def do_subscript_assign(node, ...):
...
I'd like to create a syntax sugar for pattern matching though, that would 
let you 1) use a less verbose way of saying the same thing, and 2) let you 
bind the intermediate values to variables that then become accessible in 
the function body as locals.

Anyway, the main holdup on this is deciding what sort of Python syntax 
abuse should represent variable bindings.  :)  Maybe something like this 
will be suitably horrific:

   @do_it.when("node in Assign.match(lhs=`lhs` in Subscr,rhs=`rhs`)")
   def do_subscript_assign((lhs,rhs), node, ...):
   ...
But I think maybe here the cure is worse than the disease.  :)  Pushed this 
far, it seems to beg for new syntax to accommodate in-expression variable 
bindings, something like 'var:=value'.  Really, though, the problem is 
probably just that inline variable binding is downright unpythonic.  The 
only time Python does anything vaguely similar is with the 'except 
type,var:' syntax.

___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Brett C.
Guido van Rossum wrote:
> [Brett]
> 
>>I think I agree with Samuele that it would be more pertinent to put all of 
>>this
>>effort into trying to come up with some way to handle cleanup in a generator.
> 
> 
> I.e. PEP 325.
> 
> But (as I explained, and you agree) that still doesn't render PEP 310
> unnecessary, because abusing the for-loop for implied cleanup
> semantics is ugly and expensive, and would change generator semantics;

Right, I'm not saying PEP 310 shouldn't also be considered.  It just seems like
we are beginning to pile a lot on this discussion by bringing in PEP 310 and
PEP 325 in at the same time since, as pointed out, there is no guarantee that
anything will be called in a generator and thus making PEP 310 work in
generators does not seem guaranteed to solve that problem (although I might
have missed something; just started really following the thread today).

At this point anonymous blocks just don't seem to be happening, at least not
like in Ruby.  Fine, I didn't want them anyway.  Now we are trying to simplify
resource cleanup and handling.  What I am trying to say is that generators
differ just enough as to possibly warrant a separate discussion from all of
this other resource handling "stuff".

So I am advocating a more focused generator discussion since resource handling
in generators is much more difficult than the general case in non-generator
situations.  I mean obviously in the general case all of this is handled
already in Python today with try/finally.  But with generators you have to jump
through some extra hoops to get similar support (passing in anything that needs
to be cleaned up, hoping that garbage collection will eventually handle things,
etc.).

> and it bugs me that the finally clause's reachability depends on the
> destructor executing.
> 

Yeah, I don't like it either.  I would rather see something like:

 def gen():
FILE = open("stuff.txt", 'rU')
for line in FILE:
yield line

cleanup:
FILE.close()

and have whatever is in the 'cleanup' block be either accessible from a method
in the generator or have it become the equivalent of a __del__ for the
generator, or maybe even both (which would remove contention that whatever
needs to be cleaned up is done too late thanks to gc not guaranteeing immediate
cleanup).  This way you get the guaranteed cleanup regardless and you don't
have to worry about creating everything outside of the generator, passing it
in, and then handling cleanup in a try/finally that contains the next() calls
to the generator (or any other contortion you might have to go through).

Anyway, my random Python suggestion for the day.

-Brett
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks (don't combine them with generator finalization)

2005-04-21 Thread Brett C.
Bob Ippolito wrote:
> 
> On Apr 21, 2005, at 8:59 PM, Josiah Carlson wrote:
> 
>> Guido van Rossum <[EMAIL PROTECTED]> wrote:
>>
>>>
>>> [Brett]
>>>
 I think I agree with Samuele that it would be more pertinent to put
 all of this
 effort into trying to come up with some way to handle cleanup in a
 generator.
>>>
>>>
>>> I.e. PEP 325.
>>>
>>> But (as I explained, and you agree) that still doesn't render PEP 310
>>> unnecessary, because abusing the for-loop for implied cleanup
>>> semantics is ugly and expensive, and would change generator semantics;
>>> and it bugs me that the finally clause's reachability depends on the
>>> destructor executing.
>>
>>
>> Yes and no.  PEP 325 offers a method to generators that handles cleanup
>> if necessary and calls it close().  Obviously calling it close is a
>> mistake.  Actually, calling it anything is a mistake, and trying to
>> combine try/finally handling in generators with __exit__/close (inside
>> or outside of generators) is also a mistake.
>>
>>
>> Start by saying, "If a non-finalized generator is garbage collected, it
>> will be finalized."  Whether this be by an exception or forcing a return,
>> so be it.
>>
>> If this were to happen, we have generator finalization handled by the
>> garbage collector, and don't need to translate /any/ for loop.  As long
>> as the garbage collection requirement is documented, we are covered
>> (yay!).
> 
> 
> Well, for the CPython implementation, couldn't you get away with using
> garbage collection to do everything?  Maybe I'm missing something..
> 

[SNIP]

Well, if you are missing something then so am I since your suggestion is
basically correct.  The only issue is that people will want more immediate
execution of the cleanup code which gc cannot guarantee.  That's why the
ability to call a method with the PEP 325 approach gets rid of that worry.

-Brett
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks (don't combine them with generator finalization)

2005-04-21 Thread Bob Ippolito
On Apr 22, 2005, at 12:28 AM, Brett C. wrote:
Bob Ippolito wrote:
On Apr 21, 2005, at 8:59 PM, Josiah Carlson wrote:
Guido van Rossum <[EMAIL PROTECTED]> wrote:
[Brett]
I think I agree with Samuele that it would be more pertinent to put
all of this
effort into trying to come up with some way to handle cleanup in a
generator.

I.e. PEP 325.
But (as I explained, and you agree) that still doesn't render PEP 
310
unnecessary, because abusing the for-loop for implied cleanup
semantics is ugly and expensive, and would change generator 
semantics;
and it bugs me that the finally clause's reachability depends on the
destructor executing.

Yes and no.  PEP 325 offers a method to generators that handles 
cleanup
if necessary and calls it close().  Obviously calling it close is a
mistake.  Actually, calling it anything is a mistake, and trying to
combine try/finally handling in generators with __exit__/close 
(inside
or outside of generators) is also a mistake.

Start by saying, "If a non-finalized generator is garbage collected, 
it
will be finalized."  Whether this be by an exception or forcing a 
return,
so be it.

If this were to happen, we have generator finalization handled by the
garbage collector, and don't need to translate /any/ for loop.  As 
long
as the garbage collection requirement is documented, we are covered
(yay!).

Well, for the CPython implementation, couldn't you get away with using
garbage collection to do everything?  Maybe I'm missing something..
[SNIP]
Well, if you are missing something then so am I since your suggestion 
is
basically correct.  The only issue is that people will want more 
immediate
execution of the cleanup code which gc cannot guarantee.  That's why 
the
ability to call a method with the PEP 325 approach gets rid of that 
worry.
Well in CPython, if you are never assigning the generator to any local 
or global, then you should be guaranteed that it gets cleaned up at the 
right time unless it's alive in a traceback somewhere (maybe you WANT 
it to be!) or some insane trace hook keeps too many references to 
frames around..

It seems *reasonably* certain that for reasonable uses this solution 
WILL clean it up optimistically.

-bob
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Proper place to put extra args for building

2005-04-21 Thread Brett C.
Martin v. LÃwis wrote:
> Brett C. wrote:
> 
>>Works for me.  If no one objects I will check in the change for CFLAGS to make
>>it ``$(BASECFLAGS) $(OPT) "$EXTRA_CFLAGS"`` soon (is quoting it enough to make
>>sure that it isn't evaluated by configure but left as a string to be evaluated
>>by the shell when the Makefile is running?).
> 
> 
> If you put it into Makefile.pre.in, the only thing to avoid that
> configure evaluates is is not to use @[EMAIL PROTECTED] OTOH, putting a $
> in front of it is not good enough for make: $EXTRA_CFLAGS evaluates
> the variable E, and then appends XTRA_CFLAGS.
> 

Yep, you're right.  I initially thought that the parentheses meant it was a
Makefile-only variable, but it actually goes to the environment for those
unknown values.

Before I check it in, though, should setup.py be tweaked to use it as well?  I
say yes.

-Brett
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Greg Ewing
Ka-Ping Yee wrote:
Can you explain what you meant by currying here?  I know what
the word "curry" means, but i am having a hard time seeing how
it applies to your example.
It's currying in the sense that instead of one function
which takes all the args at once, you have a function
that takes some of them (all except the thunk) and
returns another one that takes the rest (the thunk).
 Could you make up an example that uses more arguments?
  def with_file(filename, mode):
def func(block):
  f = open(filename, mode)
  try:
block(f)
  finally:
f.close()
return func
Usage example:
  with_file("foo.txt", "w") as f:
f.write("My hovercraft is full of parrots.")
Does that help?
--
Greg Ewing, Computer Science Dept, +--+
University of Canterbury,  | A citizen of NewZealandCorp, a   |
Christchurch, New Zealand  | wholly-owned subsidiary of USA Inc.  |
[EMAIL PROTECTED]  +--+
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Greg Ewing
Guido van Rossum wrote:
Perhaps it could be even simpler: 

[assignment_target '=']* expr ':' suite
I don't like that so much. It looks like you're
assigning the result of expr to assignment_target,
and then doing something else.
This would just be an extension of the regular assignment statement.
Syntactically, yes, but semantically it's more
complicated than just a "simple extension", to
my mind.
--
Greg Ewing, Computer Science Dept, +--+
University of Canterbury,  | A citizen of NewZealandCorp, a   |
Christchurch, New Zealand  | wholly-owned subsidiary of USA Inc.  |
[EMAIL PROTECTED]  +--+
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Greg Ewing
Steven Bethard wrote:
line = None
@withfile("readme.txt")
def print_readme(fileobj):
lexical line
for line in fileobj:
print line
print "last line:" line
Since the name of the function isn't important,
that could be reduced to
  @withfile("readme.txt")
  def _(fileobj):
...
(Disclaimer: This post should not be taken as
an endorsement of this abuse! I'd still much
rather have a proper language feature for it.)
--
Greg Ewing, Computer Science Dept, +--+
University of Canterbury,  | A citizen of NewZealandCorp, a   |
Christchurch, New Zealand  | wholly-owned subsidiary of USA Inc.  |
[EMAIL PROTECTED]  +--+
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-21 Thread Greg Ewing
Brian Sabbey wrote:
I made an example implementation, and this wasn't an issue.  It took 
some code to stick the thunk into the argument list, but it was pretty 
straightforward.
What does your implementation do with something like
  f() + g():
...
? (A syntax error, I would hope.)
While no doubt it can be done, I still don't like the
idea very much. It seems like a violation of modularity
in the grammar, so to speak. The syntax effectively
allowed for the expression is severely limited by the
fact that a block follows it, which is a kind of backward
effect that violates the predominantly LL-flavour of
the rest of the syntax. There's a backward effect in
the semantics, too -- you can't properly understand what
the otherwise-normal-looking function call is doing
without knowing what comes later.
An analogy has been made with the insertion of "self"
into the arguments of a method. But that is something quite
different. In x.meth(y), the rules are being followed
quite consistently: the result of x.meth is being
called with y (and only y!) as an argument; the insertion
of self happens later.
But here, insertion of the thunk would occur *before* any
call was made at all, with no clue from looking at the
call itself.
Requiring arguments other than the block to be dealt with by currying 
can lead to problems.  I won't claim these problems are serious, but 
they will be annoying.
You have some valid concerns there. You've given me
something to think about.
Here's another idea. Don't write the parameters in the form
of a call at all; instead, do this:
  with_file "foo.txt", "w" as f:
f.write("Spam!")
This would have the benefit of making it look more like
a control structure and less like a funny kind of call.
I can see some problems with that, though. Juxtaposing two
expressions doesn't really work, because the result can end up
looking like a function call or indexing operation. I
don't want to put a keyword in between because that would
mess up how it reads. Nor do I want to put some arbitrary
piece of punctuation in there.
The best I can think of right now is
  with_file {"foo.txt", "w"} as f:
f.write("Spam!")

If you google "filetype:rb yield", you can see many the uses of yield in 
ruby.
I'm sure that use cases can be found, but the pertinent question
is whether a substantial number of those use cases from Ruby fall
into the class of block-uses which aren't covered by other Python
facilities.
Also, I have a gut feeling that it's a bad idea to try to provide
for this. I think the reason is this: We're trying to create
something that feels like a user-defined control structure with
a suite, and there's currently no concept in Python of a suite
returning a value to be consumed by its containing control
structure. It would be something new, and it would require some
mental gymnastics to understand what it was doing. We already
have "return" and "yield"; this would be a third similar-yet-
different thing.
If it were considered important enough, it could easily be added
later, without disturbing anything. But I think it's best left
out of an initial specification.
--
Greg Ewing, Computer Science Dept, +--+
University of Canterbury,  | A citizen of NewZealandCorp, a   |
Christchurch, New Zealand  | wholly-owned subsidiary of USA Inc.  |
[EMAIL PROTECTED]  +--+
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com