From bjourne at gmail.com  Tue May  1 01:24:25 2007
From: bjourne at gmail.com (=?ISO-8859-1?Q?BJ=F6rn_Lindqvist?=)
Date: Mon, 30 Apr 2007 23:24:25 +0000
Subject: [Python-ideas] ordered dict
In-Reply-To: <20070426090200.6427.JCARLSON@uci.edu>
References: <20070421112051.63AB.JCARLSON@uci.edu>
	<740c3aec0704260622m46dfd3aav56025918408e3935@mail.gmail.com>
	<20070426090200.6427.JCARLSON@uci.edu>
Message-ID: <740c3aec0704301624x60226147x7bb4c1def423441e@mail.gmail.com>

On 4/26/07, Josiah Carlson <jcarlson at uci.edu> wrote:
> > Similar fuck ups are possible when using dicts. In practice this is
> > not a problem. An ordered dict doesn't need any more safeguards than
> > Python's already existing data structures. Using the natural order of
> > its items are just fine and when you need something more fancy,
> > override the __eq__ method or give the collections sort method a
> > comparator function argument.
>
> Except this series of posts is about a "sorted dict", with a key,value
> mapping in which the equivalent .items() are sorted() as an ordering
> (rather than more or less dependant on hash value as in a standard
> dictionary).  But as I, and others have stated before, which you should
> read once again because you don't seem to get it:
> THE EXISTANCE OF A TOTAL ORDERING ON VALUES IN PYTHON TODAY IS A LIE.
> IN FUTURE PYTHONS WE ARE REMOVING THE LIE BECAUSE IT DOESN'T HELP ANYONE.
> IF YOU DON'T LIKE IT; TOUGH COOKIES.  STANDARD PYTHON DICTIONARIES
> WILL WORK THE WAY THEY ALWAYS HAVE.  ONLY PEOPLE WHO BELIEVE THAT
> INCOMPATIBLE TYPES SHOULD BE ORDERED IN A PARTICULAR WAY IN THINGS LIKE
> lst.sort() WILL BE AFFECTED.
>
> If you want an actual reference, please see PEP 3100 which says,
> "Comparisons other than == and != between disparate types will raise an
> exception unless explicitly supported by the type"
> ... and references:
>     http://mail.python.org/pipermail/python-dev/2004-June/045111.html
>
> If you don't understand this, please ask again without profanity or
> accusing the Python developers of removing the "consenting adults"
> requirement.  Python is getting smarter.  Maybe you just don't
> understand why this is the case.

I really do not understand what you are talking about. Maybe you have
misunderstood something?

Lets talk about Java for a moment. Java contains a class called
TreeMap which has all the features that the original poster asked
for. The Python equivalent to TreeMap would be a "sorted dictionary."

Java, just like Python 3k will, forbids comparisions between disparate
Comparable types. It follows that Java does not enforce any "total
ordering" on disparate types either. The absence of a total ordering
does not mean that Java's TreeMap class' constructor needs to be
supplied with a list of "allowed key types" as you and Terry Reedy
suggested that Python's hypothetical sorted dictionary would need.

Try the following Java code:

TreeMap tm = new TreeMap();
tm.put(new Integer(3), "moo");
tm.put(new Double(7), "moo");

Java is definitely not designed according to the "we are all
consenting adults" philosophy, but it has no problem whatsoever
accepting this code. Note that you did NOT have to specify the
"allowed key types" and that Integer and Double are incomparable. But
when you run it:

Exception in thread "main" java.lang.ClassCastException
        at java.lang.Double.compareTo(Double.java:642)
        at java.util.TreeMap.compare(TreeMap.java:1085)
        at java.util.TreeMap.put(TreeMap.java:463)
        at comp.main(comp.java:9)

Which is exactly how I am suggesting that the hypothetical sorted dict
class should work too (in py3k). You can read more about these Java
classes and interfaces here
http://java.sun.com/j2se/1.4.2/docs/api/java/util/TreeMap.html and
here http://java.sun.com/j2se/1.4.2/docs/api/java/util/SortedMap.html.

I hope you understand now why having to specify or restrict the
allowed "key types" is superfluous and why a sorted dict "doesn't need
any more safeguards than Python's already existing data structures."

-- 
mvh Bj?rn


From jcarlson at uci.edu  Tue May  1 05:27:51 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Mon, 30 Apr 2007 20:27:51 -0700
Subject: [Python-ideas] ordered dict
In-Reply-To: <740c3aec0704301624x60226147x7bb4c1def423441e@mail.gmail.com>
References: <20070426090200.6427.JCARLSON@uci.edu>
	<740c3aec0704301624x60226147x7bb4c1def423441e@mail.gmail.com>
Message-ID: <20070430194655.6448.JCARLSON@uci.edu>


"BJ?rn Lindqvist" <bjourne at gmail.com> wrote:
> On 4/26/07, Josiah Carlson <jcarlson at uci.edu> wrote:
> > > Similar fuck ups are possible when using dicts. In practice this is
> > > not a problem. An ordered dict doesn't need any more safeguards than
> > > Python's already existing data structures. Using the natural order of
> > > its items are just fine and when you need something more fancy,
> > > override the __eq__ method or give the collections sort method a
> > > comparator function argument.
[snip]
> I really do not understand what you are talking about. Maybe you have
> misunderstood something?

In your post with Message-Id:
    <740c3aec0704202128g6537c5bfv94c0f60a5d883d76 at mail.gmail.com>

you state...

> >>> l = [(), "moo", 123, []]
> >>> l.sort()
> >>> l
> [123, [], 'moo', ()]
> 
> If it is not a problem for lists it is not a problem for ordered dictionaries.

I pointed out in a reply to that message that it would be a problem
because the sort will fail in Python 3.x .

In your post with Message-Id:
    <740c3aec0704210817m3e11a9e5lb3325523e2490348 at mail.gmail.com>

you offer...

> Alternatively, you could require a comparator function to be specified
> at creation time.

Now you offer Java TreeMap as an example of semantics that you would
like to duplicate, from which I now understand the context of offering a
'comparator function'. Your current desired semantics are possible in
Python 3.x, as it no longer relies on a total ordering, but merely a
"natural ordering" (which should be defined for all a,b pairs both of
type c), which list.sort() will rely on in 3.x as well.

The question at this point is whether or not we want the equivalent of a
Java TreeMap in Python.  I'm leaning towards no, as I have found very
few uses of such things in my own code.

There's also the fact that Daniel Stutzbach's BList implementation
(which may make it into Python's collections module), would allow for a
more or less equivalent implementation of your desired semantics using
bisect, though each operation would suffer an O(logn) slowdown for
overall O(nlog^2n) sorting and O(log^2n) insertion/deletion/search per
item (O(logn) queries, O(logn) per query*).  Would that be sufficient?


 - Josiah

* The BList is at worst log base 64 (at beast 128), so if you are
emulating a TreeMap using BList and bisect, then in the worst case of 1
billion items in your TreeMap, you are running at around 1/5 the speed
of an equivalent Red-Black tree (1/4 at 16 million, 1/3 at 256k, 1/2 at
4k).



From tjreedy at udel.edu  Tue May  1 06:08:07 2007
From: tjreedy at udel.edu (Terry Reedy)
Date: Tue, 1 May 2007 00:08:07 -0400
Subject: [Python-ideas] ordered dict
References: <20070421112051.63AB.JCARLSON@uci.edu><740c3aec0704260622m46dfd3aav56025918408e3935@mail.gmail.com><20070426090200.6427.JCARLSON@uci.edu>
	<740c3aec0704301624x60226147x7bb4c1def423441e@mail.gmail.com>
Message-ID: <f16ef7$pjl$1@sea.gmane.org>


"BJ?rn Lindqvist" <bjourne at gmail.com> wrote 
in message 
news:740c3aec0704301624x60226147x7bb4c1def423441e at mail.gmail.com...

>Java, just like Python 3k will, forbids comparisions between disparate
>Comparable types. It follows that Java does not enforce any "total
>ordering" on disparate types either. The absence of a total ordering
>does not mean that Java's TreeMap class' constructor needs to be
>supplied with a list of "allowed key types" as you and Terry Reedy
>suggested that Python's hypothetical sorted dictionary would need.

I don't believe I said 'needs' and I already agreed that such a list would 
be less helpful than I had suggested.  But one would help give better 
messages from __str__ and exceptions.  Also, the first item added does not 
get compared to anything, so without such a list, it effectively determines 
the key type.

That said, propose what you want and see if it gets enough usage to justify 
addition to the collections module.  Anyone who wants a sorted dict with 
keytype attibute could get one by subclassing one without.

Terry Jan Reedy






From jjb5 at cornell.edu  Wed May  2 19:55:07 2007
From: jjb5 at cornell.edu (Joel Bender)
Date: Wed, 02 May 2007 13:55:07 -0400
Subject: [Python-ideas] fixing mutable default argument values
In-Reply-To: <91ad5bf80701181239p1aa710afv4401861257d2eb4f@mail.gmail.com>
References: <76fd5acf0701172010j554fa420q38f09151d46883af@mail.gmail.com>	<45AF79AC.9090509@cornell.edu>
	<20070118084035.5974.JCARLSON@uci.edu>	<fb6fbf560701181100q361c7098if6c60b9c8afbc603@mail.gmail.com>
	<91ad5bf80701181239p1aa710afv4401861257d2eb4f@mail.gmail.com>
Message-ID: <4638D07B.9060207@cornell.edu>

George Sakkis wrote:

>> Sure they have, and they've solved it (under different names) in
>> plenty of other languages.  In python, the only current solution seems
>> to be turning the function into a class (with self) or at least a
>> closure.  People have griped about this.
> 
> User-defined function attributes is another handy solution.
> 
>> For What Its Worth, my personal opinion is that having to create an
>> object instead of a function is annoying, but not so bad (or so
>> frequent) that it is worth special syntax.
> 
> Function attributes fit the bill really good if writing a class is too
> much overhead.

To follow up on this, here is a way to get something pretty close to 
what I wanted.  From this...

     def foo(x):
         local history = []
         history.append(x)

To this...

     def local(**locals):
         def _local(fn):
             fn.__dict__.update(locals)
             return fn
         return _local

     @local(history = [])
     def foo(x):
         foo.history.append(x)

I like this because it keeps history out of the parameter list, and 
while it's not part of the local namespace, it's readily accessible.


Joel


From jjb5 at cornell.edu  Wed May  2 21:37:43 2007
From: jjb5 at cornell.edu (Joel Bender)
Date: Wed, 02 May 2007 15:37:43 -0400
Subject: [Python-ideas] Should function attributes be properties?
Message-ID: <4638E887.4090600@cornell.edu>

I was expecting this to work:

     class myprop(property):
         def __get__(self, obj, cls): print "get", obj, cls
         def __set__(self, obj, value): print "set", obj, value

     def f(x):
         print 'f'
         f.p

     f.p = myprop()

So it comes out like this:

     >>> f(2)
     f
     get <function f at 0x61270> None

Is this a bug?  Or was it not in the scope of what properties would be 
used for?  Is this PEP material?


Joel



From guido at python.org  Wed May  2 22:22:06 2007
From: guido at python.org (Guido van Rossum)
Date: Wed, 2 May 2007 13:22:06 -0700
Subject: [Python-ideas] Should function attributes be properties?
In-Reply-To: <4638E887.4090600@cornell.edu>
References: <4638E887.4090600@cornell.edu>
Message-ID: <ca471dc20705021322v37c83e0ax452f136a8bf0eb7@mail.gmail.com>

You're misunderstanding descriptors. Descriptors only work when placed
in a class.

On 5/2/07, Joel Bender <jjb5 at cornell.edu> wrote:
> I was expecting this to work:
>
>      class myprop(property):
>          def __get__(self, obj, cls): print "get", obj, cls
>          def __set__(self, obj, value): print "set", obj, value
>
>      def f(x):
>          print 'f'
>          f.p
>
>      f.p = myprop()
>
> So it comes out like this:
>
>      >>> f(2)
>      f
>      get <function f at 0x61270> None
>
> Is this a bug?  Or was it not in the scope of what properties would be
> used for?  Is this PEP material?
>
>
> Joel
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>


-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


From jimjjewett at gmail.com  Thu May  3 00:00:10 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Wed, 2 May 2007 18:00:10 -0400
Subject: [Python-ideas] fixing mutable default argument values
In-Reply-To: <4638D07B.9060207@cornell.edu>
References: <76fd5acf0701172010j554fa420q38f09151d46883af@mail.gmail.com>
	<45AF79AC.9090509@cornell.edu> <20070118084035.5974.JCARLSON@uci.edu>
	<fb6fbf560701181100q361c7098if6c60b9c8afbc603@mail.gmail.com>
	<91ad5bf80701181239p1aa710afv4401861257d2eb4f@mail.gmail.com>
	<4638D07B.9060207@cornell.edu>
Message-ID: <fb6fbf560705021500k14b52de2rb97347329316ea4c@mail.gmail.com>

On 5/2/07, Joel Bender <jjb5 at cornell.edu> wrote:
>      @local(history = [])
>      def foo(x):
>          foo.history.append(x)

This assumes that the name "foo" won't be rebound underneath you.
That is usually, but not always, true.  __this_function__ from PEP
3130 would solve that gotcha.

> I like this because it keeps history out of the parameter list, and
> while it's not part of the local namespace, it's readily accessible.

Those are good things.

-jJ


From greg.ewing at canterbury.ac.nz  Thu May  3 02:56:43 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Thu, 03 May 2007 12:56:43 +1200
Subject: [Python-ideas] Should function attributes be properties?
In-Reply-To: <4638E887.4090600@cornell.edu>
References: <4638E887.4090600@cornell.edu>
Message-ID: <4639334B.3090502@canterbury.ac.nz>

Joel Bender wrote:

> Is this a bug?  Or was it not in the scope of what properties would be 
> used for?

The latter. To work, a property has to live in the
class of an object, not an attribute of the object
itself.

--
Greg


From grosser.meister.morti at gmx.net  Mon May  7 00:13:30 2007
From: grosser.meister.morti at gmx.net (=?ISO-8859-1?Q?Mathias_Panzenb=F6ck?=)
Date: Mon, 07 May 2007 00:13:30 +0200
Subject: [Python-ideas] PEP for executing a module in a package
 containing relative imports
In-Reply-To: <bbaeab100704192038v110b053eqfdcf49f613302f8@mail.gmail.com>
References: <bbaeab100704192038v110b053eqfdcf49f613302f8@mail.gmail.com>
Message-ID: <463E530A.8090200@gmx.net>

what about:

if __module__ is __main__:
	...

__module__ is a reference to "this module" and
__main__ is a reference to the module which stated execution

this would have the sideeffect that:

def f():
	__module__.x = 42

equals:

def f():
	global x
	x = 42

etc.


Off Topic:
a __func__ would also be nice:

def foo():
	print __func__.__name__

prints "foo"

def foo():
	x = 1
	
	def bar():
		__func__.parent.x += 1
		return __func__.parent.x
	
	return bar

print bar()

prints "2"

well, on second thought this is looks a bit cluttered.


From brett at python.org  Mon May  7 04:54:13 2007
From: brett at python.org (Brett Cannon)
Date: Sun, 6 May 2007 19:54:13 -0700
Subject: [Python-ideas] PEP for executing a module in a package
	containing relative imports
In-Reply-To: <463E530A.8090200@gmx.net>
References: <bbaeab100704192038v110b053eqfdcf49f613302f8@mail.gmail.com>
	<463E530A.8090200@gmx.net>
Message-ID: <bbaeab100705061954s2adf1755kbbee6dd0972a6b25@mail.gmail.com>

On 5/6/07, Mathias Panzenb?ck <grosser.meister.morti at gmx.net> wrote:
>
> what about:
>
> if __module__ is __main__:
>         ...
>
> __module__ is a reference to "this module" and
> __main__ is a reference to the module which stated execution
>
> this would have the sideeffect that:
>
> def f():
>         __module__.x = 42
>
> equals:
>
> def f():
>         global x
>         x = 42
>
> etc.



That's fine, but Guido has killed any attempt to fix this situation.


Off Topic:
> a __func__ would also be nice:
>
> def foo():
>         print __func__.__name__
>
> prints "foo"
>
> def foo():
>         x = 1
>
>         def bar():
>                 __func__.parent.x += 1
>                 return __func__.parent.x
>
>         return bar
>
> print bar()
>
> prints "2"



See PEP 3130.

-Brett
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070506/872517e4/attachment.html>

From castironpi at comcast.net  Wed May  9 04:22:00 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 8 May 2007 21:22:00 -0500
Subject: [Python-ideas] subclassing standard module
Message-ID: <20070509022203.E62BC1E4002@bag.python.org>

This on module inspect.

I'd like to subclass inspect.BlockFinder, but inspect.getblock uses it
directly.

Should we encapsulate this?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070508/f0c08e8a/attachment.html>

From tomerfiliba at gmail.com  Wed May  9 18:07:33 2007
From: tomerfiliba at gmail.com (tomer filiba)
Date: Wed, 9 May 2007 18:07:33 +0200
Subject: [Python-ideas] the future of the GIL
In-Reply-To: <1d85506f0705090147w155c15d3ka61f0f23b435b3a9@mail.gmail.com>
References: <1d85506f0705090147w155c15d3ka61f0f23b435b3a9@mail.gmail.com>
Message-ID: <1d85506f0705090907l735e007bk6a5f4aa6d4ad7701@mail.gmail.com>

[ moved to python-ideas from python-3000 ]


On 5/8/07, Thomas Heller <theller at ctypes.org> wrote:
> Wouldn't multiple interpreters (assuming the problems with them would be fixed)
> in the same process give the same benefit?  A separate GIL for each one?

hmm, i find this idea quite interesting really:

* builtin immutable objects such as None, small ints, non-heap types,
and builtin functions, would become uncollectible by the GC. after all,
we can't reclaim their memory anyway, so keeping the accounting
info is just a waste of time. the PyObject_HEAD struct would grow
an "ob_collectible" field, which would tell the GC to ignore these
objects altogether. for efficiency reasons, Py_INCREF/DECREF
would still change ob_refcount, only the GC will ignore it for
uncollectible objects.

* each thread would have a separate interpreter, and all APIs should
grow an additional parameter that specifies the interpreter state
to use.

* for compatibility reasons, we can also have a dict-like object mapping
between thread-ids to interpreter states. when you invoke an API,
it would get the interpreter state from the currently executing thread id.
maybe that could be defined as a macro over the real API function.

* the builtin immutable objects would be shared between all instances
of the interpreter. other then those, all other objects would be local
to the interpreter that created them

* extension modules would have to be changed to support
per-interpreter initialization.

* in order to communicate between interpreters, we would use some
kind of IPC mechanism, to serialize access to objects. of course it
would be much more efficient, as no context switches are required
in the same process. this would make each thread basically as
protected as a OS process, so no locks would be required.

* in order to support the IPC, a new builtin type, Proxy, would be added
to the language. it would be the only object that can hold a cross-reference
to objects in different interpreters -- much like today's RPC libs -- only
that wouldn't have to work over a socket.

* if python would ever have a tracing GC, that would greatly simplify
things. also, moving to an atomic incref/decref library could also
help.

of course i'm not talking about adding that to py3k. it's too immature
even for a pre-pep. but continuing to develop that idea more could
be the means to removing the GIL, and finally having really parallel
python scripts.


-tomer


From santagada at gmail.com  Wed May  9 15:16:26 2007
From: santagada at gmail.com (Leonardo Santagada)
Date: Wed, 9 May 2007 10:16:26 -0300
Subject: [Python-ideas] [Python-3000] the future of the GIL
In-Reply-To: <9F3AFD78-7C73-4C9F-8CA6-3D10A1468939@fuhm.net>
References: <1d85506f0705050629k35ebdf6aj285e8f10489d21d5@mail.gmail.com>
	<ca471dc20705071058n25a21acfvaca8e4979edfa404@mail.gmail.com>
	<9F3AFD78-7C73-4C9F-8CA6-3D10A1468939@fuhm.net>
Message-ID: <15D34974-A1F6-488F-8422-6E0DCAE7BDD3@gmail.com>


Em 09/05/2007, ?s 04:26, James Y Knight escreveu:

> On May 7, 2007, at 1:58 PM, Guido van Rossum wrote:
>> As C doesn't have an atomic increment nor an atomic
>> decrement-and-test, the INCREF and DECREF macros sprinkled throughout
>> the code (many thousands of them) must be protected by some lock.
>
> I've been intently ignoring the rest of the thread (and will continue
> to do so), but, to respond to this one particular point...
>
> This just isn't true. Python can do an atomic increment in a fast
> platform specific way. It need not restrict itself to what's
> available in C. (after all, *threads* aren't available in C....)
>
> Two implementations of note:
>
> 1) gcc 4.1 has atomic operation builtins:
> http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-
> Builtins.html#Atomic-Builtins
>
> 2) There's a pretty damn portable library which provides these
> functions for what looks to me like pretty much all CPUs anyone would
> use, under Linux, Windows, HP/UX, Solaris, and OSX, and has a
> fallback to using pthreads mutexes:
>
> http://www.hpl.hp.com/research/linux/atomic_ops/index.php4
> http://packages.debian.org/stable/libdevel/libatomic-ops-dev
>
>
> It's quite possible the overhead of GIL-less INCREF/DECREF is still
> too high even with atomic increment/decrement primitives, but AFAICT
> nobody has actually tried it. So saying GIL-less operation for sure
> has too high of an overhead unless the refcounting GC is replaced
> seems a bit premature.
>
> James
This seems like a good idea... how about moving this discussion to  
python-ideas?


--
Leonardo Santagada
santagada at gmail.com





From santagada at gmail.com  Wed May  9 15:20:15 2007
From: santagada at gmail.com (Leonardo Santagada)
Date: Wed, 9 May 2007 10:20:15 -0300
Subject: [Python-ideas] [Python-3000] the future of the GIL
In-Reply-To: <f1s312$489$1@sea.gmane.org>
References: <f1l97g$5cm$1@sea.gmane.org> <463E4645.5000503@acm.org>
	<20070506222840.25B2.JCARLSON@uci.edu> <f1s312$489$1@sea.gmane.org>
Message-ID: <ED1B29FC-CB8E-4043-9847-EAA603477335@gmail.com>


Em 09/05/2007, ?s 06:07, Giovanni Bajo escreveu:

> On 07/05/2007 7.36, Josiah Carlson wrote:
>
>> By going multi-process rather than multi-threaded, one generally  
>> removes
>> shared memory from the equasion.  Note that this has the same  
>> effect as
>> using queues with threads, which is generally seen as the only way of
>> making threads "easy".  If one *needs* shared memory, we can  
>> certainly
>> create an mmap-based shared memory subsystem with fine-grained object
>> locking, or emulate it via a server process as the processing package
>> has done.
>>
>> Seriously, give the processing package a try.  It's much faster  
>> than one
>> would expect.
>
> I'm fully +1 with you on everything.
>
> And part of the fact that we have to advocate this is because  
> Python has
> always had pretty good threading libraries, but not processing  
> libraries;
> actually, Python does have problems at spawning processes: the whole
> popen/popen2/subprocess mess isn't even fully solved yet.
>
> One thing to be said, though, is that using multiple processes  
> cause some
> headaches with frozen distributions (PyInstaller, py2exe, etc.),  
> like those
> usually found on Windows, specifically because Windows does not  
> have fork().
>
> The processing module, for instance, doesn't take this problem into  
> account at
> all, making it worthless for many of my real-world use cases.
> -- 
> Giovanni Bajo

Another problem is that althought people like the idea of processing  
more, the only module on python stdlib is thread and Threading... So  
why not include processing in stdlib and in both thread and Threading  
give pointers to its use? This would probably diminish the problem  
with newcomers on the language that hate the GIL because they don't  
know better (and also because threading is supported out of the box  
on python). Yes I know there is fork, but still it is not as useable  
and pythonic as processing.


--
Leonardo Santagada
santagada at gmail.com





From castironpi at comcast.net  Wed May  9 22:22:40 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Wed, 9 May 2007 15:22:40 -0500
Subject: [Python-ideas] parameter omit
Message-ID: <20070509202544.CC7471E4002@bag.python.org>

Is it possible to signal to a parameter to use its default?

 

def f( a, b=None, c='' ):...

 

f( 123, <def>, 'abc' )

f( 123, ObjA, <def> )

 

Did I miss something, plus did you cover it before?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070509/a32dac3b/attachment.html>

From steven.bethard at gmail.com  Wed May  9 22:45:14 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Wed, 9 May 2007 14:45:14 -0600
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070509202544.CC7471E4002@bag.python.org>
References: <20070509202544.CC7471E4002@bag.python.org>
Message-ID: <d11dcfba0705091345n44c71933q8003b715bcc47bfa@mail.gmail.com>

On 5/9/07, Aaron Brady <castironpi at comcast.net> wrote:
> Is it possible to signal to a parameter to use its default?
>
> def f( a, b=None, c='' ):...
>
> f( 123, <def>, 'abc' )
> f( 123, ObjA, <def> )

In this case, it's pretty easy::

    f(123, c='abc')
    f(123, ObjA)

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From castironpi at comcast.net  Wed May  9 23:42:35 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Wed, 9 May 2007 16:42:35 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <d11dcfba0705091345n44c71933q8003b715bcc47bfa@mail.gmail.com>
Message-ID: <20070509214244.086DF1E4009@bag.python.org>

Actually, I wanted a uniform way to call f.  f(a,b,c) for both cases if b
can equal <def>.

-----Original Message-----
From: Steven Bethard [mailto:steven.bethard at gmail.com] 
Sent: Wednesday, May 09, 2007 3:45 PM
To: Aaron Brady
Cc: python-ideas at python.org
Subject: Re: [Python-ideas] parameter omit

On 5/9/07, Aaron Brady <castironpi at comcast.net> wrote:
> Is it possible to signal to a parameter to use its default?
>
> def f( a, b=None, c='' ):...
>
> f( 123, <def>, 'abc' )
> f( 123, ObjA, <def> )

In this case, it's pretty easy::

    f(123, c='abc')
    f(123, ObjA)

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy



From jcarlson at uci.edu  Wed May  9 23:50:44 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Wed, 09 May 2007 14:50:44 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070509214244.086DF1E4009@bag.python.org>
References: <d11dcfba0705091345n44c71933q8003b715bcc47bfa@mail.gmail.com>
	<20070509214244.086DF1E4009@bag.python.org>
Message-ID: <20070509145008.25EB.JCARLSON@uci.edu>


"Aaron Brady" <castironpi at comcast.net> wrote:
> 
> Actually, I wanted a uniform way to call f.  f(a,b,c) for both cases if b
> can equal <def>.

f(a, b=...) #default c
f(a, c=...) #default b


 - Josiah

> -----Original Message-----
> From: Steven Bethard [mailto:steven.bethard at gmail.com] 
> Sent: Wednesday, May 09, 2007 3:45 PM
> To: Aaron Brady
> Cc: python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> On 5/9/07, Aaron Brady <castironpi at comcast.net> wrote:
> > Is it possible to signal to a parameter to use its default?
> >
> > def f( a, b=None, c='' ):...
> >
> > f( 123, <def>, 'abc' )
> > f( 123, ObjA, <def> )
> 
> In this case, it's pretty easy::
> 
>     f(123, c='abc')
>     f(123, ObjA)
> 
> STeVe
> -- 
> I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
> tiny blip on the distant coast of sanity.
>         --- Bucky Katt, Get Fuzzy
> 
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas



From castironpi at comcast.net  Wed May  9 23:50:10 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Wed, 9 May 2007 16:50:10 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070509145008.25EB.JCARLSON@uci.edu>
Message-ID: <20070509215017.B047C1E4004@bag.python.org>

No, still not uniform.  Cases might be rare, even syntactic sugar maybe.
if something huge:
	b=<def>
more huge
if something else:
	b=mything
still more
f(a,b,c).

-----Original Message-----
From: Josiah Carlson [mailto:jcarlson at uci.edu] 
Sent: Wednesday, May 09, 2007 4:51 PM
To: Aaron Brady; python-ideas at python.org
Subject: Re: [Python-ideas] parameter omit


"Aaron Brady" <castironpi at comcast.net> wrote:
> 
> Actually, I wanted a uniform way to call f.  f(a,b,c) for both cases if b
> can equal <def>.

f(a, b=...) #default c
f(a, c=...) #default b


 - Josiah

> -----Original Message-----
> From: Steven Bethard [mailto:steven.bethard at gmail.com] 
> Sent: Wednesday, May 09, 2007 3:45 PM
> To: Aaron Brady
> Cc: python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> On 5/9/07, Aaron Brady <castironpi at comcast.net> wrote:
> > Is it possible to signal to a parameter to use its default?
> >
> > def f( a, b=None, c='' ):...
> >
> > f( 123, <def>, 'abc' )
> > f( 123, ObjA, <def> )
> 
> In this case, it's pretty easy::
> 
>     f(123, c='abc')
>     f(123, ObjA)
> 
> STeVe
> -- 
> I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
> tiny blip on the distant coast of sanity.
>         --- Bucky Katt, Get Fuzzy
> 
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas



From castironpi at comcast.net  Wed May  9 23:55:33 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Wed, 9 May 2007 16:55:33 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070509215017.B047C1E4004@bag.python.org>
Message-ID: <20070509215540.9025E1E4002@bag.python.org>

You can almost do,
	b=f.func_defaults[1],
but you still have to know where the defaults start.  Very small what I'm
missing.

-----Original Message-----
From: python-ideas-bounces at python.org
[mailto:python-ideas-bounces at python.org] On Behalf Of Aaron Brady
Sent: Wednesday, May 09, 2007 4:50 PM
To: 'Josiah Carlson'; python-ideas at python.org
Subject: Re: [Python-ideas] parameter omit

No, still not uniform.  Cases might be rare, even syntactic sugar maybe.
if something huge:
	b=<def>
more huge
if something else:
	b=mything
still more
f(a,b,c).

-----Original Message-----
From: Josiah Carlson [mailto:jcarlson at uci.edu] 
Sent: Wednesday, May 09, 2007 4:51 PM
To: Aaron Brady; python-ideas at python.org
Subject: Re: [Python-ideas] parameter omit


"Aaron Brady" <castironpi at comcast.net> wrote:
> 
> Actually, I wanted a uniform way to call f.  f(a,b,c) for both cases if b
> can equal <def>.

f(a, b=...) #default c
f(a, c=...) #default b


 - Josiah

> -----Original Message-----
> From: Steven Bethard [mailto:steven.bethard at gmail.com] 
> Sent: Wednesday, May 09, 2007 3:45 PM
> To: Aaron Brady
> Cc: python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> On 5/9/07, Aaron Brady <castironpi at comcast.net> wrote:
> > Is it possible to signal to a parameter to use its default?
> >
> > def f( a, b=None, c='' ):...
> >
> > f( 123, <def>, 'abc' )
> > f( 123, ObjA, <def> )
> 
> In this case, it's pretty easy::
> 
>     f(123, c='abc')
>     f(123, ObjA)
> 
> STeVe
> -- 
> I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
> tiny blip on the distant coast of sanity.
>         --- Bucky Katt, Get Fuzzy
> 
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas

_______________________________________________
Python-ideas mailing list
Python-ideas at python.org
http://mail.python.org/mailman/listinfo/python-ideas



From castironpi at comcast.net  Thu May 10 00:35:24 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Wed, 9 May 2007 17:35:24 -0500
Subject: [Python-ideas] parameter omit
Message-ID: <20070509223534.D58C11E4002@bag.python.org>

Could easily incorporate, as shown here.
#sample function with default args
def f( a,b=None,c='abc' ):
   print a,b,c

#customizer
default= object()
def call_wrapper( callable, *args, **kwargs ):
   args=list(args)
   for i,j in enumerate( args ):
      if j is default:
         offset= callable.func_code.co_argcount-\
            len(callable.func_defaults)
         args[i]= callable.func_defaults[i-offset]
   return callable( *args,**kwargs )

#the uniform calls
call_wrapper( f,0,default,'def' )
call_wrapper( f,0,'somebody',default )

-----Original Message-----
From: Aaron Brady [mailto:castironpi at comcast.net] 
Sent: Wednesday, May 09, 2007 4:56 PM
To: 'Aaron Brady'; 'Josiah Carlson'; 'python-ideas at python.org'
Subject: RE: [Python-ideas] parameter omit

You can almost do,
	b=f.func_defaults[1],
but you still have to know where the defaults start.  Very small what I'm
missing.

-----Original Message-----
From: python-ideas-bounces at python.org
[mailto:python-ideas-bounces at python.org] On Behalf Of Aaron Brady
Sent: Wednesday, May 09, 2007 4:50 PM
To: 'Josiah Carlson'; python-ideas at python.org
Subject: Re: [Python-ideas] parameter omit

No, still not uniform.  Cases might be rare, even syntactic sugar maybe.
if something huge:
	b=<def>
more huge
if something else:
	b=mything
still more
f(a,b,c).

-----Original Message-----
From: Josiah Carlson [mailto:jcarlson at uci.edu] 
Sent: Wednesday, May 09, 2007 4:51 PM
To: Aaron Brady; python-ideas at python.org
Subject: Re: [Python-ideas] parameter omit


"Aaron Brady" <castironpi at comcast.net> wrote:
> 
> Actually, I wanted a uniform way to call f.  f(a,b,c) for both cases if b
> can equal <def>.

f(a, b=...) #default c
f(a, c=...) #default b


 - Josiah

> -----Original Message-----
> From: Steven Bethard [mailto:steven.bethard at gmail.com] 
> Sent: Wednesday, May 09, 2007 3:45 PM
> To: Aaron Brady
> Cc: python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> On 5/9/07, Aaron Brady <castironpi at comcast.net> wrote:
> > Is it possible to signal to a parameter to use its default?
> >
> > def f( a, b=None, c='' ):...
> >
> > f( 123, <def>, 'abc' )
> > f( 123, ObjA, <def> )
> 
> In this case, it's pretty easy::
> 
>     f(123, c='abc')
>     f(123, ObjA)
> 
> STeVe
> -- 
> I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
> tiny blip on the distant coast of sanity.
>         --- Bucky Katt, Get Fuzzy
> 
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas

_______________________________________________
Python-ideas mailing list
Python-ideas at python.org
http://mail.python.org/mailman/listinfo/python-ideas



From scott+python-ideas at scottdial.com  Thu May 10 00:15:42 2007
From: scott+python-ideas at scottdial.com (Scott Dial)
Date: Wed, 09 May 2007 18:15:42 -0400
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070509215540.9025E1E4002@bag.python.org>
References: <20070509215540.9025E1E4002@bag.python.org>
Message-ID: <4642480E.9070006@scottdial.com>

Aaron Brady wrote:
> You can almost do,
> 	b=f.func_defaults[1],
> but you still have to know where the defaults start.  Very small what I'm
> missing.
> 
> -----Original Message-----
> From: python-ideas-bounces at python.org
> [mailto:python-ideas-bounces at python.org] On Behalf Of Aaron Brady
> Sent: Wednesday, May 09, 2007 4:50 PM
> To: 'Josiah Carlson'; python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> No, still not uniform.  Cases might be rare, even syntactic sugar maybe.
> if something huge:
> 	b=<def>
> more huge
> if something else:
> 	b=mything
> still more
> f(a,b,c).
> 

I've never wanted to do this in my life..

args = {}
if foo:
     args['b'] = b
if bar:
     args['c'] = c
f(a, **kwargs)

-Scott

-- 
Scott Dial
scott at scottdial.com
scodial at cs.indiana.edu


From castironpi at comcast.net  Thu May 10 23:34:40 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 16:34:40 -0500
Subject: [Python-ideas] parser in stdlib
Message-ID: <20070510213449.099CC1E4003@bag.python.org>

Is it possible to get `profile' into the stdlib?  Currently just tinkering,
and it might not be advisable either, subject to abuse, per GvR:

 

"Programmable syntax is not in Python's

future -- or at least it's not for Python 3000. The problem IMO is

that everybody will abuse it to define their own language. And the

problem with that is that it will fracture the Python community

because nobody can read each other's code any more."

- http://mail.python.org/pipermail/python-3000/2006-April/000286.html

 

What do you think?  Same reason apply?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070510/89e46b99/attachment.html>

From adam at atlas.st  Thu May 10 23:45:36 2007
From: adam at atlas.st (Adam Atlas)
Date: Thu, 10 May 2007 17:45:36 -0400
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070510213449.099CC1E4003@bag.python.org>
References: <20070510213449.099CC1E4003@bag.python.org>
Message-ID: <311252E3-C7A0-4D03-BA14-310F84635D00@atlas.st>


On 10 May 2007, at 17.34, Aaron Brady wrote:
> Is it possible to get `profile? into the stdlib?  Currently just  
> tinkering, and it might not be advisable either, subject to abuse,  
> per GvR:

What are you referring to here as `profile`? You're obviously (I  
think?) not talking about the existing stdlib module called `profile`.

From castironpi at comcast.net  Fri May 11 00:26:01 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 17:26:01 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <311252E3-C7A0-4D03-BA14-310F84635D00@atlas.st>
Message-ID: <20070510222612.4322C1E4003@bag.python.org>

>From: Adam Atlas [mailto:adam at atlas.st] 
>Sent: Thursday, May 10, 2007 4:46 PM
>
>On 10 May 2007, at 17.34, Aaron Brady wrote:
>> Is it possible to get `profile' into the stdlib?  Currently just  
>> tinkering, and it might not be advisable either, subject to abuse,  
>> per GvR:
>
>What are you referring to here as `profile`? You're obviously (I  
>think?) not talking about the existing stdlib module called `profile`.=

Right.  Pretend I said `parser' instead.



From collinw at gmail.com  Fri May 11 00:38:46 2007
From: collinw at gmail.com (Collin Winter)
Date: Thu, 10 May 2007 15:38:46 -0700
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070510222612.4322C1E4003@bag.python.org>
References: <311252E3-C7A0-4D03-BA14-310F84635D00@atlas.st>
	<20070510222612.4322C1E4003@bag.python.org>
Message-ID: <43aa6ff70705101538j62ad47a3oc650dd7b2393a520@mail.gmail.com>

On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> >From: Adam Atlas [mailto:adam at atlas.st]
> >Sent: Thursday, May 10, 2007 4:46 PM
> >
> >On 10 May 2007, at 17.34, Aaron Brady wrote:
> >> Is it possible to get `profile' into the stdlib?  Currently just
> >> tinkering, and it might not be advisable either, subject to abuse,
> >> per GvR:
> >
> >What are you referring to here as `profile`? You're obviously (I
> >think?) not talking about the existing stdlib module called `profile`.=
>
> Right.  Pretend I said `parser' instead.

Your request still doesn't make any sense:
http://docs.python.org/lib/module-parser.html

Collin Winter


From castironpi at comcast.net  Fri May 11 00:39:20 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 17:39:20 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <d11dcfba0705101531n53fb5c96se73dd6a1f5c5e648@mail.gmail.com>
Message-ID: <20070510223928.60CCB1E4003@bag.python.org>


> -----Original Message-----
> From: Steven Bethard [mailto:steven.bethard at gmail.com] 
> Sent: Thursday, May 10, 2007 5:32 PM
> 
> On 10 May 2007, at 17.34, Aaron Brady wrote:
> > Is it possible to get `profile' into the stdlib?
> 
> From: Adam Atlas [mailto:adam at atlas.st]
> > What are you referring to here as `profile`? You're obviously (I
> > think?) not talking about the existing stdlib module called `profile`.=
> 
> On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > Right.  Pretend I said `parser' instead.
> 
> I'm afraid that's not any clearer. There's also already a parser module:
> 
> >>> import parser
> >>> parser.__doc__
> "This is an interface to Python's internal parser."
> 
> STeVe
> -- 
> I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
> tiny blip on the distant coast of sanity.
>         --- Bucky Katt, Get Fuzzy
>

There is, but I want access to it.
>>> import parser
>>> parser.__file__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__file__'




From castironpi at comcast.net  Fri May 11 00:45:41 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 17:45:41 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <43aa6ff70705101538j62ad47a3oc650dd7b2393a520@mail.gmail.com>
Message-ID: <20070510224549.4C18E1E4003@bag.python.org>

> -----Original Message-----
> From: Collin Winter [mailto:collinw at gmail.com]
> Sent: Thursday, May 10, 2007 5:39 PM
> 
> On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > >From: Adam Atlas [mailto:adam at atlas.st]
> > >Sent: Thursday, May 10, 2007 4:46 PM
> > >
> > >On 10 May 2007, at 17.34, Aaron Brady wrote:
> > >> Is it possible to get `profile' into the stdlib?  Currently just
> > >> tinkering, and it might not be advisable either, subject to abuse,
> > >> per GvR:
> > >
> > >What are you referring to here as `profile`? You're obviously (I
> > >think?) not talking about the existing stdlib module called `profile`.=
> >
> > Right.  Pretend I said `parser' instead.
> 
> Your request still doesn't make any sense:
> http://docs.python.org/lib/module-parser.html
> 
> Collin Winter

Very well; I wasn't close to clear.

I want to do a custom compile, say by overriding one of the methods in
`parser'.  Where are they?

C:\Python25\Lib>dir p*.py
 Volume in drive C is C Local Disk
 Volume Serial Number is E849-EE50

 Directory of C:\Python25\Lib

04/04/2007  06:17 PM            43,532 pdb.py
10/28/2005  08:07 PM            46,183 pickle.py

parser.py is not to be found.




From adam at atlas.st  Fri May 11 00:47:01 2007
From: adam at atlas.st (Adam Atlas)
Date: Thu, 10 May 2007 18:47:01 -0400
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <D84A596C-456E-4CEF-A531-DF96418C831A@atlas.st>
References: <20070510223928.60CCB1E4003@bag.python.org>
	<D84A596C-456E-4CEF-A531-DF96418C831A@atlas.st>
Message-ID: <194B3690-3D8F-4D45-9D07-D1E537F292EF@atlas.st>


On 10 May 2007, at 18.39, Aaron Brady wrote:
> There is, but I want access to it.
>>>> import parser
>>>> parser.__file__
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> AttributeError: 'module' object has no attribute '__file__'

That's because it's a builtin module, written in C. It's Python/ 
parsermodule.c in the source distributions.

What exactly are you suggesting should be possible? Are you trying to  
programmatically change the parser?



From castironpi at comcast.net  Fri May 11 00:50:28 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 17:50:28 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <194B3690-3D8F-4D45-9D07-D1E537F292EF@atlas.st>
Message-ID: <20070510225036.52FA81E400C@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Adam Atlas
> Sent: Thursday, May 10, 2007 5:47 PM
> 
> On 10 May 2007, at 18.39, Aaron Brady wrote:
> > There is, but I want access to it.
> >>>> import parser
> >>>> parser.__file__
> > Traceback (most recent call last):
> >   File "<stdin>", line 1, in <module>
> > AttributeError: 'module' object has no attribute '__file__'
> 
> That's because it's a builtin module, written in C. It's Python/
> parsermodule.c in the source distributions.
> 
> What exactly are you suggesting should be possible? Are you trying to
> programmatically change the parser?

Yes.  The relevant code snippet:

class Transformer:
    <snip>
    def parsesuite(self, text):
        """Return a modified parse tree for the given suite text."""
        return self.transform(parser.suite(text))

Hence to allusion to Van Rossum's note, for the record.



From collinw at gmail.com  Fri May 11 00:56:30 2007
From: collinw at gmail.com (Collin Winter)
Date: Thu, 10 May 2007 15:56:30 -0700
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070510225036.52FA81E400C@bag.python.org>
References: <194B3690-3D8F-4D45-9D07-D1E537F292EF@atlas.st>
	<20070510225036.52FA81E400C@bag.python.org>
Message-ID: <43aa6ff70705101556q5ec76666geb7984978ceef3b1@mail.gmail.com>

On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > -----Original Message-----
> > From: python-ideas-bounces at python.org [mailto:python-ideas-
> > bounces at python.org] On Behalf Of Adam Atlas
> > Sent: Thursday, May 10, 2007 5:47 PM
> >
> > On 10 May 2007, at 18.39, Aaron Brady wrote:
> > > There is, but I want access to it.
> > >>>> import parser
> > >>>> parser.__file__
> > > Traceback (most recent call last):
> > >   File "<stdin>", line 1, in <module>
> > > AttributeError: 'module' object has no attribute '__file__'
> >
> > That's because it's a builtin module, written in C. It's Python/
> > parsermodule.c in the source distributions.
> >
> > What exactly are you suggesting should be possible? Are you trying to
> > programmatically change the parser?
>
> Yes.  The relevant code snippet:
>
> class Transformer:
>     <snip>
>     def parsesuite(self, text):
>         """Return a modified parse tree for the given suite text."""
>         return self.transform(parser.suite(text))
>
> Hence to allusion to Van Rossum's note, for the record.

That is not and will not be possible using Python's built-in parser.

Collin Winter


From castironpi at comcast.net  Fri May 11 01:00:42 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 18:00:42 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <43aa6ff70705101556q5ec76666geb7984978ceef3b1@mail.gmail.com>
Message-ID: <20070510230051.3B4ED1E4003@bag.python.org>

> -----Original Message-----
> From: Collin Winter [mailto:collinw at gmail.com]
> Sent: Thursday, May 10, 2007 5:57 PM
> 
> On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > -----Original Message-----
> > > From: python-ideas-bounces at python.org [mailto:python-ideas-
> > > bounces at python.org] On Behalf Of Adam Atlas
> > > Sent: Thursday, May 10, 2007 5:47 PM
> > >
> > > On 10 May 2007, at 18.39, Aaron Brady wrote:
> > > > There is, but I want access to it.
> > > >>>> import parser
> > > >>>> parser.__file__
> > > > Traceback (most recent call last):
> > > >   File "<stdin>", line 1, in <module>
> > > > AttributeError: 'module' object has no attribute '__file__'
> > >
> > > That's because it's a builtin module, written in C. It's Python/
> > > parsermodule.c in the source distributions.
> > >
> > > What exactly are you suggesting should be possible? Are you trying to
> > > programmatically change the parser?
> >
> > Yes.  The relevant code snippet:
> >
> > class Transformer:
> >     <snip>
> >     def parsesuite(self, text):
> >         """Return a modified parse tree for the given suite text."""
> >         return self.transform(parser.suite(text))
> >
> > Hence to allusion to Van Rossum's note, for the record.
> 
> That is not and will not be possible using Python's built-in parser.
> 
> Collin Winter

I'm 25, FTR, heavy experience.  Why not?  PEP or FAQ if there is one.

Aaron Brady



From collinw at gmail.com  Fri May 11 01:07:56 2007
From: collinw at gmail.com (Collin Winter)
Date: Thu, 10 May 2007 16:07:56 -0700
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <4643a431.03d79cb4.6461.fffff2ccSMTPIN_ADDED@mx.google.com>
References: <43aa6ff70705101556q5ec76666geb7984978ceef3b1@mail.gmail.com>
	<4643a431.03d79cb4.6461.fffff2ccSMTPIN_ADDED@mx.google.com>
Message-ID: <43aa6ff70705101607p266dcee3o4c79214ac0fdf937@mail.gmail.com>

On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > -----Original Message-----
> > From: Collin Winter [mailto:collinw at gmail.com]
> > Sent: Thursday, May 10, 2007 5:57 PM
> >
> > On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > > -----Original Message-----
> > > > From: python-ideas-bounces at python.org [mailto:python-ideas-
> > > > bounces at python.org] On Behalf Of Adam Atlas
> > > > Sent: Thursday, May 10, 2007 5:47 PM
> > > >
> > > > On 10 May 2007, at 18.39, Aaron Brady wrote:
> > > > > There is, but I want access to it.
> > > > >>>> import parser
> > > > >>>> parser.__file__
> > > > > Traceback (most recent call last):
> > > > >   File "<stdin>", line 1, in <module>
> > > > > AttributeError: 'module' object has no attribute '__file__'
> > > >
> > > > That's because it's a builtin module, written in C. It's Python/
> > > > parsermodule.c in the source distributions.
> > > >
> > > > What exactly are you suggesting should be possible? Are you trying to
> > > > programmatically change the parser?
> > >
> > > Yes.  The relevant code snippet:
> > >
> > > class Transformer:
> > >     <snip>
> > >     def parsesuite(self, text):
> > >         """Return a modified parse tree for the given suite text."""
> > >         return self.transform(parser.suite(text))
> > >
> > > Hence to allusion to Van Rossum's note, for the record.
> >
> > That is not and will not be possible using Python's built-in parser.
> >
> > Collin Winter
>
> I'm 25, FTR, heavy experience.

I have no idea why that's relevant.

> Why not?  PEP or FAQ if there is one.

Because programmable syntax isn't something we want in Python; you
yourself quoted an email from Guido explaining why. If you like the
idea of allowing every module to define its own syntactic constructs
-- at runtime or otherwise -- Perl 6, Haskell and others are more than
happy to help you.

Collin Winter


From castironpi at comcast.net  Fri May 11 01:11:47 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 18:11:47 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070510230051.3B4ED1E4003@bag.python.org>
Message-ID: <20070510231155.2EAAE1E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Aaron Brady
> Sent: Thursday, May 10, 2007 6:01 PM
> 
> > -----Original Message-----
> > From: Collin Winter [mailto:collinw at gmail.com]
> > Sent: Thursday, May 10, 2007 5:57 PM
> >
> > On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > > -----Original Message-----
> > > > From: python-ideas-bounces at python.org [mailto:python-ideas-
> > > > bounces at python.org] On Behalf Of Adam Atlas
> > > > Sent: Thursday, May 10, 2007 5:47 PM
> > > >
> > > > On 10 May 2007, at 18.39, Aaron Brady wrote:
> > > > > There is, but I want access to it.
> > > > >>>> import parser
> > > > >>>> parser.__file__
> > > > > Traceback (most recent call last):
> > > > >   File "<stdin>", line 1, in <module>
> > > > > AttributeError: 'module' object has no attribute '__file__'
> > > >
> > > > That's because it's a builtin module, written in C. It's Python/
> > > > parsermodule.c in the source distributions.
> > > >
> > > > What exactly are you suggesting should be possible? Are you trying
> to
> > > > programmatically change the parser?
> > >
> > > Yes.  The relevant code snippet:
> > >
> > > class Transformer:
> > >     <snip>
> > >     def parsesuite(self, text):
> > >         """Return a modified parse tree for the given suite text."""
> > >         return self.transform(parser.suite(text))
> > >
> > > Hence to allusion to Van Rossum's note, for the record.
> >
> > That is not and will not be possible using Python's built-in parser.
> >
> > Collin Winter
> 
> I'm 25, FTR, heavy experience.  Why not?  PEP or FAQ if there is one.
> 
> Aaron Brady
> 
I'd also like to get an attribute in class objects containing the first line
number, and can't see why not.  Code objects have them; new.code() requires
them.  I've treated dynamic creation on the newsgroup, and
inspect.findsource(object):

    if isclass(object):
        name = object.__name__
        pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
        # make some effort to find the best matching class definition:
        # use the one with the least indentation, which is the one
        # that's most probably not inside a function definition.
        candidates = []

cleans up quite a bit.

Aaron Brady



From castironpi at comcast.net  Fri May 11 01:14:11 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 18:14:11 -0500
Subject: [Python-ideas] parameter omit
Message-ID: <20070510231419.2DC891E4003@bag.python.org>

> -----Original Message-----
> From: Aaron Brady [mailto:castironpi at comcast.net]
> Sent: Wednesday, May 09, 2007 5:35 PM
> 
> Could easily incorporate, as shown here.
> #sample function with default args
> def f( a,b=None,c='abc' ):
>    print a,b,c
> 
> #customizer
> default= object()
> def call_wrapper( callable, *args, **kwargs ):
>    args=list(args)
>    for i,j in enumerate( args ):
>       if j is default:
>          offset= callable.func_code.co_argcount-\
>             len(callable.func_defaults)
>          args[i]= callable.func_defaults[i-offset]
>    return callable( *args,**kwargs )
> 
> #the uniform calls
> call_wrapper( f,0,default,'def' )
> call_wrapper( f,0,'somebody',default )
> 
> -----Original Message-----
> From: Aaron Brady [mailto:castironpi at comcast.net]
> Sent: Wednesday, May 09, 2007 4:56 PM
> To: 'Aaron Brady'; 'Josiah Carlson'; 'python-ideas at python.org'
> Subject: RE: [Python-ideas] parameter omit
> 
> You can almost do,
> 	b=f.func_defaults[1],
> but you still have to know where the defaults start.  Very small what I'm
> missing.
> 
> -----Original Message-----
> From: python-ideas-bounces at python.org
> [mailto:python-ideas-bounces at python.org] On Behalf Of Aaron Brady
> Sent: Wednesday, May 09, 2007 4:50 PM
> To: 'Josiah Carlson'; python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> No, still not uniform.  Cases might be rare, even syntactic sugar maybe.
> if something huge:
> 	b=<def>
> more huge
> if something else:
> 	b=mything
> still more
> f(a,b,c).
> 
> -----Original Message-----
> From: Josiah Carlson [mailto:jcarlson at uci.edu]
> Sent: Wednesday, May 09, 2007 4:51 PM
> To: Aaron Brady; python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> 
> "Aaron Brady" <castironpi at comcast.net> wrote:
> >
> > Actually, I wanted a uniform way to call f.  f(a,b,c) for both cases if
> b
> > can equal <def>.
> 
> f(a, b=...) #default c
> f(a, c=...) #default b
> 
> 
>  - Josiah
> 
> > -----Original Message-----
> > From: Steven Bethard [mailto:steven.bethard at gmail.com]
> > Sent: Wednesday, May 09, 2007 3:45 PM
> > To: Aaron Brady
> > Cc: python-ideas at python.org
> > Subject: Re: [Python-ideas] parameter omit
> >
> > On 5/9/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > Is it possible to signal to a parameter to use its default?
> > >
> > > def f( a, b=None, c='' ):...
> > >
> > > f( 123, <def>, 'abc' )
> > > f( 123, ObjA, <def> )
> >
> > In this case, it's pretty easy::
> >
> >     f(123, c='abc')
> >     f(123, ObjA)
> >
> > STeVe
> > --
> > I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
> > tiny blip on the distant coast of sanity.
> >         --- Bucky Katt, Get Fuzzy

Also, any follow-up on this?  (I posted at top.)



From castironpi at comcast.net  Fri May 11 01:23:50 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 18:23:50 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <43aa6ff70705101607p266dcee3o4c79214ac0fdf937@mail.gmail.com>
Message-ID: <20070510232357.9A2071E4003@bag.python.org>

> -----Original Message-----
> From: Collin Winter [mailto:collinw at gmail.com]
> Sent: Thursday, May 10, 2007 6:08 PM
> 
> On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > -----Original Message-----
> > > From: Collin Winter [mailto:collinw at gmail.com]
> > > Sent: Thursday, May 10, 2007 5:57 PM
> > >
> > > On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > > > -----Original Message-----
> > > > > From: python-ideas-bounces at python.org [mailto:python-ideas-
> > > > > bounces at python.org] On Behalf Of Adam Atlas
> > > > > Sent: Thursday, May 10, 2007 5:47 PM
> > > > >
> > > > > On 10 May 2007, at 18.39, Aaron Brady wrote:
> > > > > > There is, but I want access to it.
> > > > > >>>> import parser
> > > > > >>>> parser.__file__
> > > > > > Traceback (most recent call last):
> > > > > >   File "<stdin>", line 1, in <module>
> > > > > > AttributeError: 'module' object has no attribute '__file__'
> > > > >
> > > > > That's because it's a builtin module, written in C. It's Python/
> > > > > parsermodule.c in the source distributions.
> > > > >
> > > > > What exactly are you suggesting should be possible? Are you trying
> to
> > > > > programmatically change the parser?
> > > >
> > > > Yes.  The relevant code snippet:
> > > >
> > > > class Transformer:
> > > >     <snip>
> > > >     def parsesuite(self, text):
> > > >         """Return a modified parse tree for the given suite text."""
> > > >         return self.transform(parser.suite(text))
> > > >
> > > > Hence to allusion to Van Rossum's note, for the record.
> > >
> > > That is not and will not be possible using Python's built-in parser.
> > >
> > > Collin Winter
> >
> > I'm 25, FTR, heavy experience.
> 
> I have no idea why that's relevant.
> 
> > Why not?  PEP or FAQ if there is one.
> 
> Because programmable syntax isn't something we want in Python; you
> yourself quoted an email from Guido explaining why. If you like the
> idea of allowing every module to define its own syntactic constructs
> -- at runtime or otherwise -- Perl 6, Haskell and others are more than
> happy to help you.
> 
> Collin Winter

Huge bag of worms, I see now.  I was tinkering for hobby Python use.  I
hadn't proposed a syntax change, not there yet.  I was wanting to intercept
parser somewhere after it's started parsing source, but before it gets to
the rules.  The particular change I'm tinkering with was replacing an equal
sign with a natural word.

1, 2 to a, c
-and-
to a, c 1, 2

map to:

a, c = 1, 2

Like I said, trivial, but I was hoping a small change to parser would work.
(It's not always unambiguous either.)  But here's the idea.



From jcarlson at uci.edu  Fri May 11 02:59:39 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Thu, 10 May 2007 17:59:39 -0700
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070510232357.9A2071E4003@bag.python.org>
References: <43aa6ff70705101607p266dcee3o4c79214ac0fdf937@mail.gmail.com>
	<20070510232357.9A2071E4003@bag.python.org>
Message-ID: <20070510175916.2606.JCARLSON@uci.edu>


"Aaron Brady" <castironpi at comcast.net> wrote:
> Huge bag of worms, I see now.  I was tinkering for hobby Python use.  I
> hadn't proposed a syntax change, not there yet.  I was wanting to intercept
> parser somewhere after it's started parsing source, but before it gets to
> the rules.  The particular change I'm tinkering with was replacing an equal
> sign with a natural word.

Use Logix: http://www.livelogix.net/logix/

 - Josiah



From jcarlson at uci.edu  Fri May 11 03:03:35 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Thu, 10 May 2007 18:03:35 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <200705102321.l4ANLgaV021115@mx3.service.uci.edu>
References: <200705102321.l4ANLgaV021115@mx3.service.uci.edu>
Message-ID: <20070510175956.2609.JCARLSON@uci.edu>


"Aaron Brady" <castironpi at comcast.net> wrote:
> Also, any follow-up on this?  (I posted at top.)

I don't like it.  The current calling semantics are sufficient for the
vast majority of cases.  For those cases that are not covered by the
current calling semantics, there is a PEP for allowing variations in
optional arguments, keyword arguments, etc.  I can't remember the number,
but the PEP index has it.

As for signaling "use the default", there is a standard method: omit the
argument.  If you want the argument to always be required to be a
keyword argument, you can use...

    def foo(arg1, **kwargs):
        arg2 = kwargs.get('arg2', 1.2325)
        arg3 = kwargs.get('arg3', 'hello')
        ...

 - Josiah



From terry at jon.es  Fri May 11 03:00:32 2007
From: terry at jon.es (Terry Jones)
Date: Fri, 11 May 2007 03:00:32 +0200
Subject: [Python-ideas] parser in stdlib
In-Reply-To: Your message at 17:59:39 on Thursday, 10 May 2007
References: <43aa6ff70705101607p266dcee3o4c79214ac0fdf937@mail.gmail.com>
	<20070510232357.9A2071E4003@bag.python.org>
	<20070510175916.2606.JCARLSON@uci.edu>
Message-ID: <17987.49200.291234.235644@terry-jones-computer.local>

>>>>> "Josiah" == Josiah Carlson <jcarlson at uci.edu> writes:
Josiah> "Aaron Brady" <castironpi at comcast.net> wrote:
>> Huge bag of worms, I see now.  I was tinkering for hobby Python use.  I
>> hadn't proposed a syntax change, not there yet.  I was wanting to intercept
>> parser somewhere after it's started parsing source, but before it gets to
>> the rules.  The particular change I'm tinkering with was replacing an equal
>> sign with a natural word.

Josiah> Use Logix: http://www.livelogix.net/logix/

Use sed: http://www.gnu.org/software/sed/   :-)

Terry


From castironpi at comcast.net  Fri May 11 04:11:40 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 21:11:40 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070510175956.2609.JCARLSON@uci.edu>
Message-ID: <20070511021148.F22EB1E4003@bag.python.org>

> -----Original Message-----
> From: Josiah Carlson [mailto:jcarlson at uci.edu]
> Sent: Thursday, May 10, 2007 8:04 PM
> 
> "Aaron Brady" <castironpi at comcast.net> wrote:
> > Also, any follow-up on this?  (I posted at top.)
> 
> I don't like it.  The current calling semantics are sufficient for the
> vast majority of cases.  For those cases that are not covered by the
> current calling semantics, there is a PEP for allowing variations in
> optional arguments, keyword arguments, etc.  I can't remember the number,
> but the PEP index has it.
> 
> As for signaling "use the default", there is a standard method: omit the
> argument.  If you want the argument to always be required to be a
> keyword argument, you can use...
> 
>     def foo(arg1, **kwargs):
>         arg2 = kwargs.get('arg2', 1.2325)
>         arg3 = kwargs.get('arg3', 'hello')
>         ...
> 
>  - Josiah

I don't like it.  Cobol is sufficient.  Python is very cool.

>     def foo(arg1, **kwargs):
>         arg2 = kwargs.get('arg2', 1.2325)
>         arg3 = kwargs.get('arg3', 'hello')
>         ...

Library functions have many parameters, and huge if statements are hard to
read.  My solution costs only a single built-in object, not even a keyword
or syntax modification.  Your solution takes a three-line function
definition.  Compare to mine:

     def foo(arg1, argFoo=1.2325, argBree='hello'):
         ...

Specific and concise.  Clearly better, by all measures I read.



From jcarlson at uci.edu  Fri May 11 04:35:58 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Thu, 10 May 2007 19:35:58 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <200705110211.l4B2BpRk023341@mx2.service.uci.edu>
References: <20070510175956.2609.JCARLSON@uci.edu>
	<200705110211.l4B2BpRk023341@mx2.service.uci.edu>
Message-ID: <20070510193316.260F.JCARLSON@uci.edu>


"Aaron Brady" <castironpi at comcast.net> wrote:
> Library functions have many parameters, and huge if statements are hard to
> read.  My solution costs only a single built-in object, not even a keyword
> or syntax modification.  Your solution takes a three-line function
> definition.  Compare to mine:
> 
>      def foo(arg1, argFoo=1.2325, argBree='hello'):
>          ...
> 
> Specific and concise.  Clearly better, by all measures I read.

Except that it has no support from anyone with any pull.  Feel free to
wait for it, and/or keep pestering people to offer their opinions.

Note that not everyone has the desire for such (arguably unnecessary)
consistency as you seem to.


 - Josiah



From castironpi at comcast.net  Fri May 11 04:35:29 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 21:35:29 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070510193316.260F.JCARLSON@uci.edu>
Message-ID: <20070511023536.EB37C1E4003@bag.python.org>

> -----Original Message-----
> From: Josiah Carlson [mailto:jcarlson at uci.edu]
> Sent: Thursday, May 10, 2007 9:36 PM
> 
> 
> "Aaron Brady" <castironpi at comcast.net> wrote:
> > Library functions have many parameters, and huge if statements are hard
> to
> > read.  My solution costs only a single built-in object, not even a
> keyword
> > or syntax modification.  Your solution takes a three-line function
> > definition.  Compare to mine:
> >
> >      def foo(arg1, argFoo=1.2325, argBree='hello'):
> >          ...
> >
> > Specific and concise.  Clearly better, by all measures I read.
> 
> Except that it has no support from anyone with any pull.  Feel free to
> wait for it, and/or keep pestering people to offer their opinions.
> 
> Note that not everyone has the desire for such (arguably unnecessary)
> consistency as you seem to.
> 
> 
>  - Josiah

Copy Houston.  Have to be someone to be right.  It's a good idea and I'll
wait if it suits to.  I'll quote Guido in the future.



From castironpi at comcast.net  Fri May 11 05:47:10 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 22:47:10 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <91ad5bf80705102036l436e0cbewc32a2eb4b9edbabb@mail.gmail.com>
Message-ID: <20070511034722.0E65F1E4003@bag.python.org>

> -----Original Message-----
> From: george.sakkis at gmail.com [mailto:george.sakkis at gmail.com] On Behalf
> Of George Sakkis
> Sent: Thursday, May 10, 2007 10:36 PM
> To: Aaron Brady
> Subject: Re: [Python-ideas] parser in stdlib
> 
> On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> 
> > Huge bag of worms, I see now.  I was tinkering for hobby Python use.  I
> > hadn't proposed a syntax change, not there yet.  I was wanting to
> intercept
> > parser somewhere after it's started parsing source, but before it gets
> to
> > the rules.  The particular change I'm tinkering with was replacing an
> equal
> > sign with a natural word.
> >
> > 1, 2 to a, c
> > -and-
> > to a, c 1, 2
> >
> > map to:
> >
> > a, c = 1, 2
> 
> A perfect example of why programmable syntax is out of question for
> Python.
> 
> George

Hence the quote.  First thing I said was, "...it might not be advisable
either, subject to abuse, per GvR...."

But that doesn't preclude exposing `parser'.  It is the extent of my
question, no more.  Can we expose the module?

Do I take the powers that be to have said, "No, that would open too many
doors and give the programmers too much freedom?"  If so, that's
straight-forward and honest, and presents the next problem for solutions.
Can we expose that and still keep programs up to standard?



From castironpi at comcast.net  Fri May 11 05:51:48 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 22:51:48 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511023536.EB37C1E4003@bag.python.org>
Message-ID: <20070511035157.388981E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Aaron Brady
> Sent: Thursday, May 10, 2007 9:35 PM
> To: 'Josiah Carlson'; python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> > -----Original Message-----
> > From: Josiah Carlson [mailto:jcarlson at uci.edu]
> > Sent: Thursday, May 10, 2007 9:36 PM
> >
> >
> > "Aaron Brady" <castironpi at comcast.net> wrote:
> > > Library functions have many parameters, and huge if statements are
> hard
> > to
> > > read.  My solution costs only a single built-in object, not even a
> > keyword
> > > or syntax modification.  Your solution takes a three-line function
> > > definition.  Compare to mine:
> > >
> > >      def foo(arg1, argFoo=1.2325, argBree='hello'):
> > >          ...
> > >
> > > Specific and concise.  Clearly better, by all measures I read.
> >
> > Except that it has no support from anyone with any pull.  Feel free to
> > wait for it, and/or keep pestering people to offer their opinions.
> >
> > Note that not everyone has the desire for such (arguably unnecessary)
> > consistency as you seem to.
> >
> >
> >  - Josiah
> 
> Copy Houston.  Have to be someone to be right.  It's a good idea and I'll
> wait if it suits to.  I'll quote Guido in the future.

To finish up, I, the newcomer, have a solution that encompasses more
situations at very small cost.  No compatibility issues either.  What should
I expect?



From tjreedy at udel.edu  Fri May 11 06:02:22 2007
From: tjreedy at udel.edu (Terry Reedy)
Date: Fri, 11 May 2007 00:02:22 -0400
Subject: [Python-ideas] parser in stdlib
References: <194B3690-3D8F-4D45-9D07-D1E537F292EF@atlas.st><20070510225036.52FA81E400C@bag.python.org>
	<43aa6ff70705101556q5ec76666geb7984978ceef3b1@mail.gmail.com>
Message-ID: <f20pse$fgl$1@sea.gmane.org>


"Collin Winter" <collinw at gmail.com> | That is 
not and will not be possible using Python's built-in parser.

One can manipulate the AST that the parser produces.  (This is how the 2to3 
converter tool will work.)  Perhaps this will at least partially meet the 
OP's needs.  Beats head-butting a wall.

tjr





From jcarlson at uci.edu  Fri May 11 06:26:50 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Thu, 10 May 2007 21:26:50 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <200705110245.l4B2jeYq008970@mx1.service.uci.edu>
References: <20070510193316.260F.JCARLSON@uci.edu>
	<200705110245.l4B2jeYq008970@mx1.service.uci.edu>
Message-ID: <20070510205525.2612.JCARLSON@uci.edu>


Adding python-ideas in as a CC, because I'm a jerk.

"Aaron Brady" <castironpi at comcast.net> wrote:
> On a personal note, Josiah, you strike first.  "Pestering" is pejorative.
> My statements do not merit it.  Keep it off the newsgroup.  You insult me
> without grounds; and in fact -after- my abilities are demonstrated.  Quote
> me instead, as I do, to disagree.
> 
> The discussion reads as follows.  "Better except that it has no support."
> So support it.  Who's to blame: myself, or those with pull?
> 
> I have a good idea by newsgroup standards.  You reveal bias to summarily
> dismiss.  I urge you to reconsider; practice diplomacy here.

Post what you want.  If people aren't offering +1 or -1, it could be for
any number of reasons; from being busy (it is in the middle of the week),
to just not caring enough either way, believing that their opinions and
interests are already being expressed, etc.

But when you post something, then 24 hours and 40 minutes later you ask,
"Also, any follow-up on this?  (I posted at top.)" at the bottom of a 95
line quote of your own last post without cutting out the unimportant
parts, it is pestering, and a very low signal to noise ratio 1:95. Never
mind that you only recently seemed to learn that we don't top post in
Python mailing lists, but you still haven't realized that we trim
unimportant parts of quoted posts.  Had you top posted or failed to trim
either in python-list (or the equivalent comp.lang.python), any number
of people would have told you as much.

But hey, you are being such the good usenet poster, you couldn't have
made a mistake, of course not.  Get over yourself.


With that said, I don't particularly like the addition of syntax for
something that can already be done other ways (TOOWTDI), or the addition
of a new builtin to signal something that I've never heard *anyone* ask
about before.  Really, the only *reasonable* name is 'default', which is
used at least 146 times in the Python standard library (according to my
regular expression of default\s*=), and I'm sure thousands of times in 3rd
party code.  It would necessitate a huge change for a feature that no
one (but you) as asked for so that you can use...

    foo(a, b=default, c=1234)
    foo(a, b=253463, c=default)

rather than...

    foo(a, c=1234)
    foo(a, b=253463)

Personally, I find the latter more consistant (only pass arguments that
you care to change).  If you don't, that's fine.  The burdon of proof
isn't on me, or anyone else in python-ideas to prove to you that your
idea sucks; it's on you to prove to everyone else that your idea
*doesn't* suck.  Good luck on that.


Local jerk,
 - Josiah



From castironpi at comcast.net  Fri May 11 06:25:11 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 23:25:11 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <f20pse$fgl$1@sea.gmane.org>
Message-ID: <20070511042520.19A5E1E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Terry Reedy
> Sent: Thursday, May 10, 2007 11:02 PM
> 
> "Collin Winter" <collinw at gmail.com> | That is
> not and will not be possible using Python's built-in parser.
> 
> One can manipulate the AST that the parser produces.  (This is how the
> 2to3
> converter tool will work.)  Perhaps this will at least partially meet the
> OP's needs.  Beats head-butting a wall.
> 
> tjr

I've very much looked into it.  In fact, it gave rise to the follow-up idea
of attaching a `firstlineno' attribute to class objects.  (18:12 American
Central Time.)  Rather costly, 50% of the attributes, but stepping through
the InteractiveCodeGenerator class hasn't failed yet.



From gsakkis at rutgers.edu  Fri May 11 06:26:13 2007
From: gsakkis at rutgers.edu (George Sakkis)
Date: Fri, 11 May 2007 00:26:13 -0400
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070511034722.0E65F1E4003@bag.python.org>
References: <91ad5bf80705102036l436e0cbewc32a2eb4b9edbabb@mail.gmail.com>
	<20070511034722.0E65F1E4003@bag.python.org>
Message-ID: <91ad5bf80705102126we788898i4211797869e80192@mail.gmail.com>

On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:

> > -----Original Message-----
> > From: george.sakkis at gmail.com [mailto:george.sakkis at gmail.com] On Behalf
> > Of George Sakkis
> > Sent: Thursday, May 10, 2007 10:36 PM
> > To: Aaron Brady
> > Subject: Re: [Python-ideas] parser in stdlib
> >
> > On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> >
> > > Huge bag of worms, I see now.  I was tinkering for hobby Python use.  I
> > > hadn't proposed a syntax change, not there yet.  I was wanting to
> > intercept
> > > parser somewhere after it's started parsing source, but before it gets
> > to
> > > the rules.  The particular change I'm tinkering with was replacing an
> > equal
> > > sign with a natural word.
> > >
> > > 1, 2 to a, c
> > > -and-
> > > to a, c 1, 2
> > >
> > > map to:
> > >
> > > a, c = 1, 2
> >
> > A perfect example of why programmable syntax is out of question for
> > Python.
> >
> > George
>
> Hence the quote.  First thing I said was, "...it might not be advisable
> either, subject to abuse, per GvR...."
>
> But that doesn't preclude exposing `parser'.  It is the extent of my
> question, no more.  Can we expose the module?
>
> Do I take the powers that be to have said, "No, that would open too many
> doors and give the programmers too much freedom?"  If so, that's
> straight-forward and honest, and presents the next problem for solutions.
> Can we expose that and still keep programs up to standard?

There is no universally accepted answer to this question. Each
language positions itself (deliberately or by accident) somewhere in
the spectrum between total bondage and total freedom. Static typing
proponents find that dynamic typing is already "too much freedom", let
alone programmable syntax. Those that don't believe there is such a
thing as "too much freedom" tend to climb their way up in the language
ecosystem, until they discover Lisp and reach nirvana. Python keeps a
happy medium by accepting that programmers are neither clueless drones
that need a static compiler to babysit them all the time, nor
omnipotent gods; they are just humans.

George


-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."


From jcarlson at uci.edu  Fri May 11 06:37:02 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Thu, 10 May 2007 21:37:02 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <200705110352.l4B3q3ta004354@mx1.service.uci.edu>
References: <20070511023536.EB37C1E4003@bag.python.org>
	<200705110352.l4B3q3ta004354@mx1.service.uci.edu>
Message-ID: <20070510212720.2615.JCARLSON@uci.edu>


"Aaron Brady" <castironpi at comcast.net> wrote:
> To finish up, I, the newcomer, have a solution that encompasses more
> situations at very small cost.  No compatibility issues either.  What should
> I expect?

Is this the same idea or something different?  If it's the same, wait a
few days for responses.

If it is something different, post the current situation, what's wrong
with the current situation, and what you think would be better.  When
people disagree with you (there is always at least one :) ), don't reply
with "but that doesn't do *exactly* what I want".  Instead understand
that no matter how much you post, no matter how much people like your
idea, no matter how much Guido likes your idea, or even if you have a
working implementation, it can be tossed in the trash (see the February
"New syntax for 'dynamic' attribute access" postings here and the
related python-dev thread for an example).


 - Josiah



From castironpi at comcast.net  Fri May 11 06:55:52 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Thu, 10 May 2007 23:55:52 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070510205525.2612.JCARLSON@uci.edu>
Message-ID: <20070511045600.95C791E4003@bag.python.org>


> -----Original Message-----
> From: Josiah Carlson [mailto:jcarlson at uci.edu]
> Sent: Thursday, May 10, 2007 11:27 PM
> 
> "Aaron Brady" <castironpi at comcast.net> wrote:
> 
> Post what you want.  If people aren't offering +1 or -1, it could be for
> any number of reasons; from being busy (it is in the middle of the week),
> to just not caring enough either way, believing that their opinions and
> interests are already being expressed, etc.
> 
> But when you post something, then 24 hours and 40 minutes later you ask,
> "Also, any follow-up on this?  (I posted at top.)" at the bottom of a 95
> line quote of your own last post without cutting out the unimportant
> parts, it is pestering, and a very low signal to noise ratio 1:95. Never
> mind that you only recently seemed to learn that we don't top post in
> Python mailing lists, but you still haven't realized that we trim
> unimportant parts of quoted posts.  Had you top posted or failed to trim
> either in python-list (or the equivalent comp.lang.python), any number
> of people would have told you as much.
> 
> But hey, you are being such the good usenet poster, you couldn't have
> made a mistake, of course not.  Get over yourself.
> 
> 
> With that said, I don't particularly like the addition of syntax for
> something that can already be done other ways (TOOWTDI), or the addition
> of a new builtin to signal something that I've never heard *anyone* ask
> about before.  Really, the only *reasonable* name is 'default', which is
> used at least 146 times in the Python standard library (according to my
> regular expression of default\s*=), and I'm sure thousands of times in 3rd
> party code.  It would necessitate a huge change for a feature that no
> one (but you) as asked for so that you can use...
> 
>     foo(a, b=default, c=1234)
>     foo(a, b=253463, c=default)
> 
> rather than...
> 
>     foo(a, c=1234)
>     foo(a, b=253463)
> 
> Personally, I find the latter more consistant (only pass arguments that
> you care to change).  If you don't, that's fine.  The burdon of proof
> isn't on me, or anyone else in python-ideas to prove to you that your
> idea sucks; it's on you to prove to everyone else that your idea
> *doesn't* suck.  Good luck on that.
> 
> Local jerk,
>  - Josiah

Correct, signal to noise, content to form.  My idea came in a slightly
unconventional format.  Not posting in Hebrew or something.  Besides, that
problem cleared itself up on its own.  I noticed I wasn't blending in.

Within a full 24 hours, I expect an, "I like this, may be good.  Here's my
personal e-mail address, get back to me in a week if you haven't heard
anything."  No elaboration is necessary at this point.  It only takes one
day to write this.  But that's just where I come from.  So instead, I pursue
and follow-up on my own initiative.  Does need a reply of some sort or
another.

Lastly, most importantly, you misunderstand the issue.  The example says it
all, but I'm willing to explain, just for the asking.  Don't misquote me,
but the trade-off follows.

Three-line function definition [Carlson 19:59 American Central Time] versus
one.  More than three lines if you have more than three parameters: one line
per parameter.  Cobol is another way to do it, so be careful with acronyms.
No new syntax in this one.

The old ways:

[code to assign my_b and my_c]
if use_default_b and use_defualt_c:
	foo(a)
elif use_default_b:
	foo(a, c=my_c)
elif use_default_c:
	foo(a, my_b)

-or-

def foo(arg1, **kwargs):
	arg2 = kwargs.get('arg2', 1.2325)
	arg3 = kwargs.get('arg3', 'hello')

The new way:

my_b, my_c= paramdefault, paramdefault
[code to assign my_b and my_c]
foo(a, my_b, my_c)

And don't get me started on `d'.  ParamDefault is like True, False, and
None.  Not traditional, in truth, Pythonic.  Looking far into the future,
however, I suppose it could start to get abused, like putting None in
dictionaries, for example.  Perhaps it was None's original intent.

Fellow jerk,
- Aaron

[p.s. { 'akey': ParamDefault }, ha]



From steven.bethard at gmail.com  Fri May 11 07:13:24 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Thu, 10 May 2007 23:13:24 -0600
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511045600.95C791E4003@bag.python.org>
References: <20070510205525.2612.JCARLSON@uci.edu>
	<20070511045600.95C791E4003@bag.python.org>
Message-ID: <d11dcfba0705102213u837668y3d2260b168484bd9@mail.gmail.com>

On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> The old ways:
>
> [code to assign my_b and my_c]
> if use_default_b and use_defualt_c:
>         foo(a)
> elif use_default_b:
>         foo(a, c=my_c)
> elif use_default_c:
>         foo(a, my_b)
[snip]
> The new way:
>
> my_b, my_c= paramdefault, paramdefault
> [code to assign my_b and my_c]
> foo(a, my_b, my_c)

As another poster mentioned, the normal way to write this is::

    kwargs = {}
    if use_default_b:
        kwargs['b'] = my_b
    if use_default_c:
        kwargs['c'] = my_c
    foo(a, **kwargs)

It is so extremely uncommon to need to do such a thing that I'm firmly
against adding any additional syntax. Syntax should only be introduced
for common things that many people need.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From castironpi at comcast.net  Fri May 11 07:22:55 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 00:22:55 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <d11dcfba0705102213u837668y3d2260b168484bd9@mail.gmail.com>
Message-ID: <20070511052310.1F2B71E4003@bag.python.org>

> -----Original Message-----
> From: Steven Bethard [mailto:steven.bethard at gmail.com]
> Sent: Friday, May 11, 2007 12:13 AM
> 
> On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > The old ways:
> >
> > [code to assign my_b and my_c]
> > if use_default_b and use_defualt_c:
> >         foo(a)
> > elif use_default_b:
> >         foo(a, c=my_c)
> > elif use_default_c:
> >         foo(a, my_b)
> [snip]
> > The new way:
> >
> > my_b, my_c= paramdefault, paramdefault
> > [code to assign my_b and my_c]
> > foo(a, my_b, my_c)
> 
> As another poster mentioned, the normal way to write this is::
> 
>     kwargs = {}
>     if use_default_b:
>         kwargs['b'] = my_b
>     if use_default_c:
>         kwargs['c'] = my_c
>     foo(a, **kwargs)
> 
> It is so extremely uncommon to need to do such a thing that I'm firmly
> against adding any additional syntax. Syntax should only be introduced
> for common things that many people need.
> 
> STeVe

Mr. Bethard, I am not adding syntax.  Don't put words in my mouth.  This is
another one- observe the subject line.  Tell me you always make a call with
the same parameters, every time you make the call.  My thinking can't be
that backwards.  A use case could take some time, but sure.

> > Cobol is another way to do it, so be careful with acronyms.
> > No new syntax in this one.
> > 
> > The old ways: ...



From talin at acm.org  Fri May 11 07:38:39 2007
From: talin at acm.org (Talin)
Date: Thu, 10 May 2007 22:38:39 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511021148.F22EB1E4003@bag.python.org>
References: <20070511021148.F22EB1E4003@bag.python.org>
Message-ID: <4644015F.80100@acm.org>

Aaron Brady wrote:
>> -----Original Message-----
>> From: Josiah Carlson [mailto:jcarlson at uci.edu]
>> Sent: Thursday, May 10, 2007 8:04 PM
>>
>> "Aaron Brady" <castironpi at comcast.net> wrote:
>>> Also, any follow-up on this?  (I posted at top.)
>> I don't like it.  The current calling semantics are sufficient for the
>> vast majority of cases.  For those cases that are not covered by the
>> current calling semantics, there is a PEP for allowing variations in
>> optional arguments, keyword arguments, etc.  I can't remember the number,
>> but the PEP index has it.
>>
>> As for signaling "use the default", there is a standard method: omit the
>> argument.  If you want the argument to always be required to be a
>> keyword argument, you can use...
>>
>>     def foo(arg1, **kwargs):
>>         arg2 = kwargs.get('arg2', 1.2325)
>>         arg3 = kwargs.get('arg3', 'hello')
>>         ...
>>
>>  - Josiah
> 
> I don't like it.  Cobol is sufficient.  Python is very cool.
> 
>>     def foo(arg1, **kwargs):
>>         arg2 = kwargs.get('arg2', 1.2325)
>>         arg3 = kwargs.get('arg3', 'hello')
>>         ...
> 
> Library functions have many parameters, and huge if statements are hard to
> read.  My solution costs only a single built-in object, not even a keyword
> or syntax modification.  Your solution takes a three-line function
> definition.  Compare to mine:
> 
>      def foo(arg1, argFoo=1.2325, argBree='hello'):
>          ...
> 
> Specific and concise.  Clearly better, by all measures I read.

With PEP 3102 in place you don't even need the **kwargs:

http://www.python.org/dev/peps/pep-3102/

-- Talin



From steven.bethard at gmail.com  Fri May 11 07:41:51 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Thu, 10 May 2007 23:41:51 -0600
Subject: [Python-ideas] parameter omit
In-Reply-To: <4643fdbb.6d47eccd.14ef.ffffbc16SMTPIN_ADDED@mx.google.com>
References: <d11dcfba0705102213u837668y3d2260b168484bd9@mail.gmail.com>
	<4643fdbb.6d47eccd.14ef.ffffbc16SMTPIN_ADDED@mx.google.com>
Message-ID: <d11dcfba0705102241w25783034xec370b22152c80a6@mail.gmail.com>

On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> From: Steven Bethard [mailto:steven.bethard at gmail.com]
> > On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > The new way:
> > >
> > > my_b, my_c= paramdefault, paramdefault
> > > [code to assign my_b and my_c]
> > > foo(a, my_b, my_c)
[snip]
> > It is so extremely uncommon to need to do such a thing that I'm firmly
> > against adding any additional syntax. Syntax should only be introduced
> > for common things that many people need.
>
> Mr. Bethard, I am not adding syntax.  Don't put words in my mouth.  This is
> another one- observe the subject line.  Tell me you always make a call with
> the same parameters, every time you make the call.  My thinking can't be
> that backwards.  A use case could take some time, but sure.

Hmm...  If ``paramdefault`` isn't syntax, then how are you proposing
to implement it?

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From castironpi at comcast.net  Fri May 11 07:51:32 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 00:51:32 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <4644015F.80100@acm.org>
Message-ID: <20070511055143.091031E4003@bag.python.org>

> -----Original Message-----
> From: Talin [mailto:talin at acm.org]
> Sent: Friday, May 11, 2007 12:39 AM
> 
> Aaron Brady wrote:
> >> -----Original Message-----
> >> From: Josiah Carlson [mailto:jcarlson at uci.edu]
> >> Sent: Thursday, May 10, 2007 8:04 PM
> >>
> >> "Aaron Brady" <castironpi at comcast.net> wrote:
> >> [snip]
> > I don't like it.  Cobol is sufficient.  Python is very cool.
> >
> >>     def foo(arg1, **kwargs):
> >>         arg2 = kwargs.get('arg2', 1.2325)
> >>         arg3 = kwargs.get('arg3', 'hello')
> >>         ...
> >
> > Library functions have many parameters, and huge if statements are hard
> to
> > read.  My solution costs only a single built-in object, not even a
> keyword
> > or syntax modification.  Your solution takes a three-line function
> > definition.  Compare to mine:
> >
> >      def foo(arg1, argFoo=1.2325, argBree='hello'):
> >          ...
> >
> > Specific and concise.  Clearly better, by all measures I read.
> 
> With PEP 3102 in place you don't even need the **kwargs:
> 
> http://www.python.org/dev/peps/pep-3102/
> 
> -- Talin

I'm not adding restrictions.  I'm simplifying.  The subject solution is
general.  Less code in all cases, meaning still as clear or clearer.




From castironpi at comcast.net  Fri May 11 07:59:16 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 00:59:16 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <91ad5bf80705102126we788898i4211797869e80192@mail.gmail.com>
Message-ID: <20070511055925.77C861E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of George Sakkis
> Sent: Thursday, May 10, 2007 11:26 PM
> 
> On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> 
> > > -----Original Message-----
> > > From: george.sakkis at gmail.com [mailto:george.sakkis at gmail.com] On
> Behalf
> > > Of George Sakkis
> > > Sent: Thursday, May 10, 2007 10:36 PM
> > > To: Aaron Brady
> > > Subject: Re: [Python-ideas] parser in stdlib
> > >
> > > On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > >
> > > > [snip]
> > > A perfect example of why programmable syntax is out of question for
> > > Python.
> > >
> > > George
> >
> > Hence the quote.  First thing I said was, "...it might not be advisable
> > either, subject to abuse, per GvR...."
> >
> > But that doesn't preclude exposing `parser'.  It is the extent of my
> > question, no more.  Can we expose the module?
> >
> > Do I take the powers that be to have said, "No, that would open too many
> > doors and give the programmers too much freedom?"  If so, that's
> > straight-forward and honest, and presents the next problem for
> solutions.
> > Can we expose that and still keep programs up to standard?
> 
> There is no universally accepted answer to this question. Each
> language positions itself (deliberately or by accident) somewhere in
> the spectrum between total bondage and total freedom. Static typing
> proponents find that dynamic typing is already "too much freedom", let
> alone programmable syntax. Those that don't believe there is such a
> thing as "too much freedom" tend to climb their way up in the language
> ecosystem, until they discover Lisp and reach nirvana. Python keeps a
> happy medium by accepting that programmers are neither clueless drones
> that need a static compiler to babysit them all the time, nor
> omnipotent gods; they are just humans.
> 
> George

You mean static like ML?  Python's very acceptable.  It's why I continue to
choose it (and Logix does!).  Free form yet structured.  It strikes very
good balances.

The problem is, white-space doesn't mean anything.  I addressed M. Santagada
about it.  I was trying to, but hit the absence of parser.  So what do we
make it mean?

Can't do this:
	if exists fname...
Because of that:
	loptosize self.graphic

They must both map to:
	if fname.exists() #wrong
and
	self.graphic.loptosize()

-or-

	if exists( fname )
and
	loptosize( self.graphic ) #wrong instead

I'm shooting for:
	if exists( fname )
and
	self.graphic.loptosize()

Can't have both.  Possibilities, silliest first:
- Rule that functions that end in `s' are predicates not imperatives (-is-
this not -do- this).  No.
- Rule that functions in Boolean expressions are the former form, and
otherwise the latter.  It sort of works, but unfortunately, loptosize()
might return a value, and you get:
	if loptosize self.graphic:
	-mapping to-
	if loptosize( self.graphic ), which is not what you mean.
- Only permit mapping on one, not both.
		if fname exists:
		-map to-
		if exists( fname ):
	-or-
		loptosize self.graphic
		-map to-
		self.graphic.loptosize()
	In other words, take whitespace to mean -either- membership
retrievals -or- global function references; and don't permit the other.

Last but not least,
- Actively check which interpretation is "valid," and if uniquely
determined, use that.  This takes us well past the realm of syntax, however,
into semantics.  (Language does too, after all.)
	In the case where fname has an exists() attribute -and- the user
does `from os.path import exist', raise an AmbiguityException at run-time.
The fully-qualified call is still available to writer; this is an optional
change of scenery, good for the eyes and fingers.  Don't use it if it's
ambiguous.  Don't use it if you have too much to keep track of, either.
	Even still, we need not delay evaluation until run-time completely.
Rather, parse to AmbiguousStmt( Tok1, Tok2 ), check for colliding tokens
later, and have both FuncCall objects ready in bytecode.

While languages move away from ambiguity [1], let's meet them half way and
begin to accomodate it.  It's what we speak.
acb

[1] The Lojban language.
http://www.lojban.org/tiki/tiki-index.php?page=Home+Page&bl



From talin at acm.org  Fri May 11 08:24:32 2007
From: talin at acm.org (Talin)
Date: Thu, 10 May 2007 23:24:32 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <E1HmO2X-0002gD-Ui@box115.bluehost.com>
References: <E1HmO2X-0002gD-Ui@box115.bluehost.com>
Message-ID: <46440C20.2010101@acm.org>

Aaron Brady wrote:
>>> Specific and concise.  Clearly better, by all measures I read.
>> With PEP 3102 in place you don't even need the **kwargs:
>>
>> http://www.python.org/dev/peps/pep-3102/
>>
>> -- Talin
> 
> I'm not adding restrictions.  I'm simplifying.  The subject solution is
> general.  Less code in all cases, meaning still as clear or clearer.

Non-sequitur? How does that relate to what I said?

Let me state in different words what others have already stated: There 
are already ways to accomplish most what you are trying to do.

In Python, any argument will have its default value if you omit it from 
the argument list when calling the function. There's no need to 
explicitly tell it to use the default value, it just does this naturally.

Now, the only case where this might be a problem is a fairly rare and 
odd case where you are specifying arguments positionally and not by 
keyword, where you want to specify the value of argument N+1 but want 
argument N to be its default.

But the language should not make a special cases to support this 
particular case, for 3 reasons:

1) The case is rare.

2) There are easy ways around it: Simply supply the value of argument 
N+1 by keyword instead of by position.

3) If your function has lots of positional arguments, each of which has 
a different meaning, then your function probably needs to be refactored 
anyway. Using keywords is much safer in such cases, and if you use 
keywords, then the whole problem you raise goes away.

-- Talin


From castironpi at comcast.net  Fri May 11 08:28:59 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 01:28:59 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511052310.1F2B71E4003@bag.python.org>
Message-ID: <20070511062909.7D1A01E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Aaron Brady
> Sent: Friday, May 11, 2007 12:23 AM
> 
> > -----Original Message-----
> > From: Steven Bethard [mailto:steven.bethard at gmail.com]
> > Sent: Friday, May 11, 2007 12:13 AM
> >
> > On 5/10/07, Aaron Brady <castironpi at comcast.net> wrote:
> > [snip]
> > > The new way:
> > >
> > > my_b, my_c= paramdefault, paramdefault
> > > [code to assign my_b and my_c]
> > > foo(a, my_b, my_c)
> >
> > As another poster mentioned, the normal way to write this is::
> >
> >     kwargs = {}
> >     if use_default_b:
> >         kwargs['b'] = my_b
> >     if use_default_c:
> >         kwargs['c'] = my_c
> >     foo(a, **kwargs)
> >
> > It is so extremely uncommon to need to do such a thing that I'm firmly
> > against adding any additional syntax. Syntax should only be introduced
> > for common things that many people need.
> >
> > STeVe

Steve,

Take a shot at this one.

class WebRetrieveElement:
	def netretrieveOld( self ):
		if hasattr( self,'hook' ) and self.filename:
			urlretrieve( self.url, self.filename, self.hook )
		elif hashook:
			urlretrieve( self.url, reporthook= self.hook )
		else:
			urlretrieve( self.url, self.filename )

	def netretrieveNew( self ):
		filename= self.filename or ParamDefault
		hook= hasattr( self,'hook' ) and self.hook or ParamDefault
		urlretrieve( self.url, filename, hook )

What is the default parameter for the function?  Problem is, the docs don't
say what it is.  Does it pick its own filename to use for empty inputs?





From castironpi at comcast.net  Fri May 11 08:33:25 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 01:33:25 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <46440C20.2010101@acm.org>
Message-ID: <20070511063334.68C741E4003@bag.python.org>



> -----Original Message-----
> From: Talin [mailto:talin at acm.org]
> Sent: Friday, May 11, 2007 1:25 AM
> 
> Aaron Brady wrote:
> [snip]
> Non-sequitur? How does that relate to what I said?
> 
> Let me state in different words what others have already stated: There
> are already ways to accomplish most what you are trying to do.
> 
> In Python, any argument will have its default value if you omit it from
> the argument list when calling the function. There's no need to
> explicitly tell it to use the default value, it just does this naturally.
> 
> Now, the only case where this might be a problem is a fairly rare and
> odd case where you are specifying arguments positionally and not by
> keyword, where you want to specify the value of argument N+1 but want
> argument N to be its default.
> 
> But the language should not make a special cases to support this
> particular case, for 3 reasons:
> 
> 1) The case is rare.
> 
> 2) There are easy ways around it: Simply supply the value of argument
> N+1 by keyword instead of by position.
> 
> 3) If your function has lots of positional arguments, each of which has
> a different meaning, then your function probably needs to be refactored
> anyway. Using keywords is much safer in such cases, and if you use
> keywords, then the whole problem you raise goes away.
> 
> -- Talin

Alert me if my post [Brady 01:25 U.S. Central] doesn't illuminate your
concerns, and I will treat them.




From jcarlson at uci.edu  Fri May 11 08:46:27 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Thu, 10 May 2007 23:46:27 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511062909.7D1A01E4003@bag.python.org>
References: <20070511052310.1F2B71E4003@bag.python.org>
	<20070511062909.7D1A01E4003@bag.python.org>
Message-ID: <20070510234449.2618.JCARLSON@uci.edu>


"Aaron Brady" <castironpi at comcast.net> wrote:
> What is the default parameter for the function?  Problem is, the docs don't
> say what it is.  Does it pick its own filename to use for empty inputs?

    >>> import urllib
    >>> help(urllib.urlretrieve)
    Help on function urlretrieve in module urllib:

    urlretrieve(url, filename=None, reporthook=None, data=None)

    >>>


 - Josiah



From castironpi at comcast.net  Fri May 11 08:46:14 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 01:46:14 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070510234449.2618.JCARLSON@uci.edu>
Message-ID: <20070511064622.D8FA51E4003@bag.python.org>


> -----Original Message-----
> From: Josiah Carlson [mailto:jcarlson at uci.edu]
> Sent: Friday, May 11, 2007 1:46 AM
> To: Aaron Brady; python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> 
> "Aaron Brady" <castironpi at comcast.net> wrote:
> > What is the default parameter for the function?  Problem is, the docs
> don't
> > say what it is.  Does it pick its own filename to use for empty inputs?
> 
>     >>> import urllib
>     >>> help(urllib.urlretrieve)
>     Help on function urlretrieve in module urllib:
> 
>     urlretrieve(url, filename=None, reporthook=None, data=None)
> 
>     >>>
> 
> 
>  - Josiah

No nitpicking, Mr. Carlson.  These pieces of information are -not- always
available.



From steven.bethard at gmail.com  Fri May 11 08:50:08 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Fri, 11 May 2007 00:50:08 -0600
Subject: [Python-ideas] parameter omit
In-Reply-To: <46440d38.4521e763.55c9.4ab6SMTPIN_ADDED@mx.google.com>
References: <20070511052310.1F2B71E4003@bag.python.org>
	<46440d38.4521e763.55c9.4ab6SMTPIN_ADDED@mx.google.com>
Message-ID: <d11dcfba0705102350t540d3e05he249ea822bd9cece@mail.gmail.com>

On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> Take a shot at this one.
>
> class WebRetrieveElement:
>         def netretrieveOld( self ):
>                 if hasattr( self,'hook' ) and self.filename:
>                         urlretrieve( self.url, self.filename, self.hook )
>                 elif hashook:
>                         urlretrieve( self.url, reporthook= self.hook )
>                 else:
>                         urlretrieve( self.url, self.filename )

def netretrieve(self):
    kwargs = {}
    if self.filename:
        kwargs['filename'] = self.filename
    if hasattr(self, 'hook'):
        kwargs['reporthook'] = self.hook
    urlretrieve(self.url, **kwargs)


STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From castironpi at comcast.net  Fri May 11 08:57:43 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 01:57:43 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <d11dcfba0705102350t540d3e05he249ea822bd9cece@mail.gmail.com>
Message-ID: <20070511065752.6C9B71E4003@bag.python.org>

> -----Original Message-----
> From: Steven Bethard [mailto:steven.bethard at gmail.com]
> Sent: Friday, May 11, 2007 1:50 AM
> 
> On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> > Take a shot at this one.
> >
> > class WebRetrieveElement:
> >         def netretrieveOld( self ):
> >                 if hasattr( self,'hook' ) and self.filename:
> >                         urlretrieve( self.url, self.filename, self.hook
> )
> >                 elif hashook:
> >                         urlretrieve( self.url, reporthook= self.hook )
> >                 else:
> >                         urlretrieve( self.url, self.filename )
> 
> def netretrieve(self):
>     kwargs = {}
>     if self.filename:
>         kwargs['filename'] = self.filename
>     if hasattr(self, 'hook'):
>         kwargs['reporthook'] = self.hook
>     urlretrieve(self.url, **kwargs)

Right.  That's the alternative, -as- I keep bringing up.

Now let's compare, and judge if X is worth Y.

My solution, 3 lines.  Yours, 6.

X = 50% profit, -plus- the attention you save.  Y = a built-in, unobtrusive
variable, a trivial cost.  `None' doesn't get in your way, does it?

As you can see, X -is- worth Y.  Therefore, my proposal is better.




From steven.bethard at gmail.com  Fri May 11 09:06:23 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Fri, 11 May 2007 01:06:23 -0600
Subject: [Python-ideas] parameter omit
In-Reply-To: <46441517.798dd6a1.4277.5638SMTPIN_ADDED@mx.google.com>
References: <d11dcfba0705102345v4da6c71fj5fd1474e782a2b13@mail.gmail.com>
	<46441517.798dd6a1.4277.5638SMTPIN_ADDED@mx.google.com>
Message-ID: <d11dcfba0705110006k6c75cda6vead2c85d263c0e02@mail.gmail.com>

Steven Bethard [mailto:steven.bethard at gmail.com]
> Can you show me code that would make your new "morpheme" work?  All
> the implementations I can imagine involve making it some sort of
> special keyword.

On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> Nope, routine object.  I defined it earlier:
>
> paramdefault= object()

Yes, but how is it going to *work*?  Say I wrote the function::

    def foo(bar=1, baz=2):
        print bar, baz

Now if I call that like::

    foo(bar=paramdefault, baz=paramdefault)

I'm going to see something like::

    <object object at 0x009A0468> <object object at 0x009A0468>

Is that really what you want?  I thought you wanted this to work for
all functions...

STeve
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From steven.bethard at gmail.com  Fri May 11 09:11:01 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Fri, 11 May 2007 01:11:01 -0600
Subject: [Python-ideas] parameter omit
In-Reply-To: <464413ef.4faba5d4.7bd2.1544SMTPIN_ADDED@mx.google.com>
References: <d11dcfba0705102350t540d3e05he249ea822bd9cece@mail.gmail.com>
	<464413ef.4faba5d4.7bd2.1544SMTPIN_ADDED@mx.google.com>
Message-ID: <d11dcfba0705110011w7fc53406v8ed3d8519d0ba100@mail.gmail.com>

On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> > -----Original Message-----
> > From: Steven Bethard [mailto:steven.bethard at gmail.com]
> > Sent: Friday, May 11, 2007 1:50 AM
> >
> > On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > Take a shot at this one.
> > >
> > > class WebRetrieveElement:
> > >         def netretrieveOld( self ):
> > >                 if hasattr( self,'hook' ) and self.filename:
> > >                         urlretrieve( self.url, self.filename, self.hook
> > )
> > >                 elif hashook:
> > >                         urlretrieve( self.url, reporthook= self.hook )
> > >                 else:
> > >                         urlretrieve( self.url, self.filename )
> >
> > def netretrieve(self):
> >     kwargs = {}
> >     if self.filename:
> >         kwargs['filename'] = self.filename
> >     if hasattr(self, 'hook'):
> >         kwargs['reporthook'] = self.hook
> >     urlretrieve(self.url, **kwargs)
>
> Right.  That's the alternative, -as- I keep bringing up.
>
> Now let's compare, and judge if X is worth Y.
>
> My solution, 3 lines.  Yours, 6.

If you really care about lines and characters, you can write::

    k = {}
    if self.filename: k['filename'] = self.filename
    if hasattr(self, 'hook'): k['reporthook'] = self.hook
    urlretrieve(self.url, **k)

That's 4 lines, 132 characters, compared to your 3 lines, 133 characters.

But the fact that you're drawing the "lets count lines of code" card
suggests that there's no point discussing this any further.

Good luck with your proposal.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From castironpi at comcast.net  Fri May 11 09:15:37 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 02:15:37 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <d11dcfba0705110006k6c75cda6vead2c85d263c0e02@mail.gmail.com>
Message-ID: <20070511071546.76D421E4003@bag.python.org>

> -----Original Message-----
> From: Steven Bethard [mailto:steven.bethard at gmail.com]
> Sent: Friday, May 11, 2007 2:06 AM
> 
> Steven Bethard [mailto:steven.bethard at gmail.com]
> > Can you show me code that would make your new "morpheme" work?  All
> > the implementations I can imagine involve making it some sort of
> > special keyword.
> 
> On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> > Nope, routine object.  I defined it earlier:
> >
> > paramdefault= object()
> 
> Yes, but how is it going to *work*?  Say I wrote the function::
> 
>     def foo(bar=1, baz=2):
>         print bar, baz
> 
> Now if I call that like::
> 
>     foo(bar=paramdefault, baz=paramdefault)
> 
> I'm going to see something like::
> 
>     <object object at 0x009A0468> <object object at 0x009A0468>
> 
> Is that really what you want?  I thought you wanted this to work for
> all functions...
> 
> STeve

You want to see the worked example again.  Voila.

def f( a,b=None,c='abc' ):
   print a,b,c

default= object()
def call_wrapper( callable, *args, **kwargs ):
   args=list(args)
   for i,j in enumerate( args ):
      if j is default:
         offset= callable.func_code.co_argcount-\
				len(callable.func_defaults)
         args[i]= callable.func_defaults[i-offset]
   return callable( *args,**kwargs )

call_wrapper( f,0,default,'def' )
call_wrapper( f,0,'somebody',default )

#and output is:
0 None def
0 somebody abc





From castironpi at comcast.net  Fri May 11 09:16:46 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 02:16:46 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <d11dcfba0705110011w7fc53406v8ed3d8519d0ba100@mail.gmail.com>
Message-ID: <20070511071654.969D81E4003@bag.python.org>

> -----Original Message-----
> From: Steven Bethard [mailto:steven.bethard at gmail.com]
> Sent: Friday, May 11, 2007 2:11 AM
> 
> On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > -----Original Message-----
> > > From: Steven Bethard [mailto:steven.bethard at gmail.com]
> > > Sent: Friday, May 11, 2007 1:50 AM
> > >
> > > On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> > > > [snip]
> > >
> > > def netretrieve(self):
> > >     kwargs = {}
> > >     if self.filename:
> > >         kwargs['filename'] = self.filename
> > >     if hasattr(self, 'hook'):
> > >         kwargs['reporthook'] = self.hook
> > >     urlretrieve(self.url, **kwargs)
> >
> > Right.  That's the alternative, -as- I keep bringing up.
> >
> > Now let's compare, and judge if X is worth Y.
> >
> > My solution, 3 lines.  Yours, 6.
> 
> If you really care about lines and characters, you can write::
> 
>     k = {}
>     if self.filename: k['filename'] = self.filename
>     if hasattr(self, 'hook'): k['reporthook'] = self.hook
>     urlretrieve(self.url, **k)
> 
> That's 4 lines, 132 characters, compared to your 3 lines, 133 characters.
> 
> But the fact that you're drawing the "lets count lines of code" card
> suggests that there's no point discussing this any further.
> 
> Good luck with your proposal.
> 
> STeVe

Fine.  No dice on lines of code alone.  We talk readability.  Tell me yours
is easier to read, compressed or no.





From g.brandl at gmx.net  Fri May 11 09:24:57 2007
From: g.brandl at gmx.net (Georg Brandl)
Date: Fri, 11 May 2007 09:24:57 +0200
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511071546.76D421E4003@bag.python.org>
References: <d11dcfba0705110006k6c75cda6vead2c85d263c0e02@mail.gmail.com>
	<20070511071546.76D421E4003@bag.python.org>
Message-ID: <f215oa$jvl$1@sea.gmane.org>

Aaron Brady schrieb:

>> Is that really what you want?  I thought you wanted this to work for
>> all functions...
>> 
>> STeve
> 
> You want to see the worked example again.  Voila.
> 
> def f( a,b=None,c='abc' ):
>    print a,b,c
> 
> default= object()
> def call_wrapper( callable, *args, **kwargs ):
>    args=list(args)
>    for i,j in enumerate( args ):
>       if j is default:
>          offset= callable.func_code.co_argcount-\
> 				len(callable.func_defaults)
>          args[i]= callable.func_defaults[i-offset]
>    return callable( *args,**kwargs )
> 
> call_wrapper( f,0,default,'def' )
> call_wrapper( f,0,'somebody',default )
> 
> #and output is:
> 0 None def
> 0 somebody abc

Fine, and now go ahead and patch this into the interpreter. I fear that
if you don't, nobody will.

IMHO this proposal is not completely bad, and as we can see there are
cases where it can help (albeit rare cases -- try to find one in the
standard library). But to assign a special meaning to a regular object
in this way (you can use it all the way you want, but once you call
something with it, it will be magically replaced) is a precedent in
Python, and I wouldn't have much hope for it.

But let this not hinder you to write a patch and bring it up on python-dev.

Georg



From g.brandl at gmx.net  Fri May 11 09:29:22 2007
From: g.brandl at gmx.net (Georg Brandl)
Date: Fri, 11 May 2007 09:29:22 +0200
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070511034722.0E65F1E4003@bag.python.org>
References: <91ad5bf80705102036l436e0cbewc32a2eb4b9edbabb@mail.gmail.com>
	<20070511034722.0E65F1E4003@bag.python.org>
Message-ID: <f2160j$jvl$2@sea.gmane.org>

Aaron Brady schrieb:

>> A perfect example of why programmable syntax is out of question for
>> Python.
>> 
>> George
> 
> Hence the quote.  First thing I said was, "...it might not be advisable
> either, subject to abuse, per GvR...."
> 
> But that doesn't preclude exposing `parser'.  It is the extent of my
> question, no more.  Can we expose the module?

If you tell us what you mean with "expose"... the module is written in C
and is not much more than a wrapper around Python's own parser, which
is written in C too.

If you are looking for a Python parser written in Python, you may want
to look at the PyPy project's implementation.

Georg



From jcarlson at uci.edu  Fri May 11 09:59:35 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Fri, 11 May 2007 00:59:35 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <200705110646.l4B6kQ2Z014168@mx2.service.uci.edu>
References: <20070510234449.2618.JCARLSON@uci.edu>
	<200705110646.l4B6kQ2Z014168@mx2.service.uci.edu>
Message-ID: <20070511001240.261B.JCARLSON@uci.edu>


"Aaron Brady" <castironpi at comcast.net> wrote:
> > From: Josiah Carlson [mailto:jcarlson at uci.edu]
> > "Aaron Brady" <castironpi at comcast.net> wrote:
> > > What is the default parameter for the function?  Problem is, the docs
> > don't
> > > say what it is.  Does it pick its own filename to use for empty inputs?
> > 
> >     >>> import urllib
> >     >>> help(urllib.urlretrieve)
> >     Help on function urlretrieve in module urllib:
> > 
> >     urlretrieve(url, filename=None, reporthook=None, data=None)
> > 
> >     >>>
> 
> No nitpicking, Mr. Carlson.  These pieces of information are -not- always
> available.

Should I send you my 486 laptop so that you can have access to a Python
interpreter?  Because I really can't see how you being ignorant of the
arguments to a standard library function in any way supports your case.

Further, if you always use 'None' as the default for functions being
called, then you can get things like this...

class WebRetrieveElement:
    hook = None
    filename = None

    def netretrieveNew( self ):
        filename= self.filename or ParamDefault
        hook= hasattr( self,'hook' ) and self.hook or ParamDefault
        urlretrieve( self.url, filename, hook )

    def netretrieveBest(self):
        urlretrieve(self.url, self.filename, self.hook)

And look at that.  I define two class level variables and all of a
sudden the implementation of netretrieveBest gets a trivial
implementation (though it breaks netretrieveNew, which uses a generally
frowned upon mechanism that fails when filename and hook are None).

But no, lets add a completely useless instance of object so that people
can pass silly default arguments like ParamDefault that is a bazillion
times more confusing than what Python users have been using for 15
years; None.

 - Josiah



From castironpi at comcast.net  Fri May 11 10:20:27 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 03:20:27 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511001240.261B.JCARLSON@uci.edu>
Message-ID: <20070511082036.EFDB91E4004@bag.python.org>

> -----Original Message-----
> From: Josiah Carlson [mailto:jcarlson at uci.edu]
> 
> "Aaron Brady" <castironpi at comcast.net> wrote:
> > [snip]
> >
> 
> Should I send you my 486 laptop so that you can have access to a Python
> interpreter?  Because I really can't see how you being ignorant of the
> arguments to a standard library function in any way supports your case.
> 
> Further, if you always use 'None' as the default for functions being
> called, then you can get things like this...
> 
> class WebRetrieveElement:
>     hook = None
>     filename = None
> 
>     def netretrieveNew( self ):
>         filename= self.filename or ParamDefault
>         hook= hasattr( self,'hook' ) and self.hook or ParamDefault
>         urlretrieve( self.url, filename, hook )
> 
>     def netretrieveBest(self):
>         urlretrieve(self.url, self.filename, self.hook)
> 
> And look at that.  I define two class level variables and all of a
> sudden the implementation of netretrieveBest gets a trivial
> implementation (though it breaks netretrieveNew, which uses a generally
> frowned upon mechanism that fails when filename and hook are None).
> 
> But no, lets add a completely useless instance of object so that people
> can pass silly default arguments like ParamDefault that is a bazillion
> times more confusing than what Python users have been using for 15
> years; None.
> 
>  - Josiah

No thank you.  Your example is sufficient.  Well-crafted at that.  Good
example.

Imagine with me if you will.

Say I -am- "ignorant of the arguments to a standard library function".  But
say they aren't published in help().  Then that breaks yours and we have two
broken examples.  Great lot of good that did you.

Say the default is not None; but a class callback.  Say it is a default
string for a join delimiter somewhere.

Fine examples are imaginary numbers, the function string.split,
file([bufsize]), int([radix]), list.sort([cmp]), etc.  Pretty much anywhere
you see the [] brackets in the documentation.  These default values are
obvious, and further, None is always a good guess.  Answer this one
carefully: Have you asserted that defaults are -always- available and
published, in the standard library as well as elsewhere?  Could one extra
value in __builtins__ already be worth all our third-parties' time who could
relax and get along?  It'll bring world peace.

But sure.  Send your laptop on over.  I'll pay on delivery.

Sincerely,
That Newsgroup Jerk



From castironpi at comcast.net  Fri May 11 10:43:18 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 03:43:18 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511082036.EFDB91E4004@bag.python.org>
Message-ID: <20070511084328.14F781E4004@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Aaron Brady
> 
> > [snip]

Your stewardship is remarkable.  But in the case I mention, the costs aren't
worth mention.  It's an outstanding case, for clear, cost-free, net benefit.
Say the parameter is required to be callable.  `None' will not suffice.  The
strongest case against me is that I enable lazy programmers to make
assignments in the function declaration.  That's worth bringing up.  OTOH,
what if None is the wrong default?

2.4 Built-in Constants 
A small number of constants live in the built-in namespace. They are: 

False - The false value of the bool type. New in version 2.3. 

True - The true value of the bool type. New in version 2.3. 

None - The sole value of types.NoneType. None is frequently used to
represent the absence of a value, as when default arguments are not passed
to a function. 

NotImplemented - Special value which can be returned by the ``rich
comparison'' special methods (__eq__(), __lt__(), and friends), to indicate
that the comparison is not implemented with respect to the other type. 

Ellipsis - Special value used in conjunction with extended slicing syntax.

DefaultArgument - Special value used in remaining cases of default arguments
where None is not what is intended.

Does one complain about Ellipsis?  No, it's useful.  Comes in handy at just
the right times.

And furthermore, this proposal isn't entirely without precedent.



From santagada at gmail.com  Fri May 11 12:14:48 2007
From: santagada at gmail.com (Leonardo Santagada)
Date: Fri, 11 May 2007 07:14:48 -0300
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511084328.14F781E4004@bag.python.org>
References: <20070511084328.14F781E4004@bag.python.org>
Message-ID: <450DAC26-940F-4BCD-834F-4AC48DAEDAB2@gmail.com>


Em 11/05/2007, ?s 05:43, Aaron Brady escreveu:

>
> And furthermore, this proposal isn't entirely without precedent.

Ok, we got the idea so let's start voting then :)
i'm like -1000 on it... or

def vote(who, value=-1000):
	...

i'm like:
vote(santagada at gmail.com)

:)

--
Leonardo Santagada
santagada at gmail.com





From aurelien.campeas at logilab.fr  Fri May 11 12:57:23 2007
From: aurelien.campeas at logilab.fr (=?iso-8859-1?Q?Aur=E9lien_Camp=E9as?=)
Date: Fri, 11 May 2007 12:57:23 +0200
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <f2160j$jvl$2@sea.gmane.org>
References: <91ad5bf80705102036l436e0cbewc32a2eb4b9edbabb@mail.gmail.com>
	<20070511034722.0E65F1E4003@bag.python.org>
	<f2160j$jvl$2@sea.gmane.org>
Message-ID: <20070511105723.GB24761@crater.logilab.fr>

On Fri, May 11, 2007 at 09:29:22AM +0200, Georg Brandl wrote:
> Aaron Brady schrieb:
> 
> >> A perfect example of why programmable syntax is out of question for
> >> Python.
> >> 
> >> George
> > 
> > Hence the quote.  First thing I said was, "...it might not be advisable
> > either, subject to abuse, per GvR...."
> > 
> > But that doesn't preclude exposing `parser'.  It is the extent of my
> > question, no more.  Can we expose the module?
> 
> If you tell us what you mean with "expose"... the module is written in C
> and is not much more than a wrapper around Python's own parser, which
> is written in C too.
> 
> If you are looking for a Python parser written in Python, you may want
> to look at the PyPy project's implementation.

or this : http://www.fiber-space.de/EasyExtend/doc/EE.html

> 
> Georg
> 
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas


From jan.kanis at phil.uu.nl  Fri May 11 13:58:56 2007
From: jan.kanis at phil.uu.nl (Jan Kanis)
Date: Fri, 11 May 2007 13:58:56 +0200
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511084328.14F781E4004@bag.python.org>
References: <20070511084328.14F781E4004@bag.python.org>
Message-ID: <op.tr5vkisvd64u53@jan-laptop>

On Fri, 11 May 2007 10:43:18 +0200, Aaron Brady <castironpi at comcast.net>  
wrote:

>> -----Original Message-----
>> From: python-ideas-bounces at python.org [mailto:python-ideas-
>> bounces at python.org] On Behalf Of Aaron Brady
>>
>> > [snip]
>
> Your stewardship is remarkable.  But in the case I mention, the costs  
> aren't
> worth mention.  It's an outstanding case, for clear, cost-free, net  
> benefit.
> Say the parameter is required to be callable.  `None' will not suffice.   
> The
> strongest case against me is that I enable lazy programmers to make
> assignments in the function declaration.  That's worth bringing up.   
> OTOH,
> what if None is the wrong default?
>
> 2.4 Built-in Constants
> A small number of constants live in the built-in namespace. They are:
>
> False - The false value of the bool type. New in version 2.3.
>
> True - The true value of the bool type. New in version 2.3.
>
> None - The sole value of types.NoneType. None is frequently used to
> represent the absence of a value, as when default arguments are not  
> passed
> to a function.
>
> NotImplemented - Special value which can be returned by the ``rich
> comparison'' special methods (__eq__(), __lt__(), and friends), to  
> indicate
> that the comparison is not implemented with respect to the other type.
>
> Ellipsis - Special value used in conjunction with extended slicing  
> syntax.
>
> DefaultArgument - Special value used in remaining cases of default  
> arguments
> where None is not what is intended.
>
> Does one complain about Ellipsis?  No, it's useful.  Comes in handy at  
> just
> the right times.
>
> And furthermore, this proposal isn't entirely without precedent.
>

There are some hidden costs you haven't mentioned yet:
1) It's another paragraph in the manual.
2) If DefaultArgument is just a normal object in the builtin namespace,  
without any interpreter magic every function using default values would  
have to use some logic to recognize DefaultArgument and do the right  
thing. If there is interpreter magic that'll be more magic, and another  
section in the manual to explain that. (apart from magic in itself being  
bad)

A small manual addition wouldn't be a problem on its own, but proposals  
that easily fix some use case with just a single paragraph manual addition  
pass by every other week. If they'd all be accepted we'd be saving  
ourselves a lot of trouble by switching to Perl immediately. More manual  
means more language complexity, another little step for people learning  
python, and another page of brain cell usage for anyone using Python.

In short, any new addition has to have a *lot* of utility to be  
acceptable, or else it wil lead to the way of the Perl side.

- Jan

Oh, and having jerks around is an unfortunate & unintended side effect of  
having people in the mailing list. I'd be interested if you had any ideas  
to diminish the problem, though. <wink>


From jimjjewett at gmail.com  Fri May 11 17:00:18 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Fri, 11 May 2007 11:00:18 -0400
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511082036.EFDB91E4004@bag.python.org>
References: <20070511001240.261B.JCARLSON@uci.edu>
	<20070511082036.EFDB91E4004@bag.python.org>
Message-ID: <fb6fbf560705110800u4a972e18v436c8162e0ac25c6@mail.gmail.com>

On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:

> carefully: Have you asserted that defaults are -always- available and
> published, in the standard library as well as elsewhere?

Of course not.

Sometimes the real default value doesn't really exist yet, because it
is constructed after the function gets called with 'None'.  Your
proposal doesn't change this.

When the default should be introspectable and isn't, this is usually
because the function was written in C, and the author wasn't careful
to add the proper docstring tagging.  If they aren't supporting
docstrings yet, they won't bother to support your new object either --
so it has to be done either at the interpreter level or with a wrapper
function.

The costs in the interpreter would be significant, both in complexity
(a special case) and in speed (that particular loop is tight enough
that any change can have unexpected results by changing cache
performance).

The wrapper solution seems good enough to me; it doesn't slow things
down unless you use it.  You can even automate it with monkey-patching
if you like.

> Within a full 24 hours, I expect an, "I like this, may be good.  Here's my
> personal e-mail address, get back to me in a week if you haven't heard
> anything."

I am pleasantly surprised to get 24 hour response from a vendor, even
when I (or, rather, my employer) has paid for that support.

But in this case, you actually did get a fairly quick response; it
just wasn't what you wanted, because the responders did *not* think it
was likely to be a good idea, and you weren't willing to listen to the
alternative solutions they proposed.

> Could one extra value in __builtins__ already be worth all our third-parties'
> time who could relax and get along?

If you compile your own local copy, then sure.  If you want it in the
worldwide distribution, then probably not; backwards compatibility
means that it will change only at a bureaucratic pace.

As a point of comparison, your proposal would actually be a larger
change than decorators, for a less frequent use case.

Decorators were agreed to in theory for 2.3 (around 2002/2003), but
concerns about how to do it right kept them out until 2.4.  Class
decorators were still not included (despite a working implementation
which was actually a bit simpler) because there was a chance they
wouldn't be needed, and adding things is easier than taking them back
out.  Class decorators have now been approved for Python 2.6, which
will probably be available some time next year.

-jJ


From castironpi at comcast.net  Fri May 11 20:09:39 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 13:09:39 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <op.tr5vkisvd64u53@jan-laptop>
Message-ID: <20070511180950.AA6391E4005@bag.python.org>

> -----Original Message-----
> From: Jan Kanis [mailto:jan.kanis at phil.uu.nl]
> Sent: Friday, May 11, 2007 6:59 AM
> 
> On Fri, 11 May 2007 10:43:18 +0200, Aaron Brady <castironpi at comcast.net>
> wrote:
> 
> >> -----Original Message-----
> >> From: python-ideas-bounces at python.org [mailto:python-ideas-
> >> bounces at python.org] On Behalf Of Aaron Brady
> >>
> >> > [snip]
> >
> > Your stewardship is remarkable.  But in the case I mention, the costs
> > aren't
> > worth mention.  It's an outstanding case, for clear, cost-free, net
> > benefit.
> > Say the parameter is required to be callable.  `None' will not suffice.
> > The
> > strongest case against me is that I enable lazy programmers to make
> > assignments in the function declaration.  That's worth bringing up.
> > OTOH,
> > what if None is the wrong default?
> >
> > 2.4 Built-in Constants
> > A small number of constants live in the built-in namespace. They are:
> >
> > False - The false value of the bool type. New in version 2.3.
> >
> > True - The true value of the bool type. New in version 2.3.
> >
> > None - The sole value of types.NoneType. None is frequently used to
> > represent the absence of a value, as when default arguments are not
> > passed
> > to a function.
> >
> > NotImplemented - Special value which can be returned by the ``rich
> > comparison'' special methods (__eq__(), __lt__(), and friends), to
> > indicate
> > that the comparison is not implemented with respect to the other type.
> >
> > Ellipsis - Special value used in conjunction with extended slicing
> > syntax.
> >
> > DefaultArgument - Special value used in remaining cases of default
> > arguments
> > where None is not what is intended.
> >
> > Does one complain about Ellipsis?  No, it's useful.  Comes in handy at
> > just
> > the right times.
> >
> > And furthermore, this proposal isn't entirely without precedent.
> >
> 
> There are some hidden costs you haven't mentioned yet:
> 1) It's another paragraph in the manual.
> 2) If DefaultArgument is just a normal object in the builtin namespace,
> without any interpreter magic every function using default values would
> have to use some logic to recognize DefaultArgument and do the right
> thing. If there is interpreter magic that'll be more magic, and another
> section in the manual to explain that. (apart from magic in itself being
> bad)
> 
> A small manual addition wouldn't be a problem on its own, but proposals
> that easily fix some use case with just a single paragraph manual addition
> pass by every other week. If they'd all be accepted we'd be saving
> ourselves a lot of trouble by switching to Perl immediately. More manual
> means more language complexity, another little step for people learning
> python, and another page of brain cell usage for anyone using Python.
> 
> In short, any new addition has to have a *lot* of utility to be
> acceptable, or else it wil lead to the way of the Perl side.
> 
> - Jan
> 
> Oh, and having jerks around is an unfortunate & unintended side effect of
> having people in the mailing list. I'd be interested if you had any ideas
> to diminish the problem, though. <wink>

Not only does the OP's proposal (me) exonerate programmers who have screwed
up before, those who have neglected to use None for defaults, and who chose
meaningful ones instead, but encourages them to continue to choose it, and
frees them from checking the parameter later.

> From: Leonardo Santagada
> i'm like -1000 on it... or
> 
> def vote(who, value=-1000):
-1000: well within expected parameters.  <Snick>

Note DefaultArg needs never get referenced literally in declarations, only
in calls.

def ghi( j=None, k=None, l=None ):
	if j is None: j= Something
	if k is None: k= Something2
	if l is None: l= Something3

No.  Here, I do it all at once.
def ghi( j=Something, k=Something2, l=Something3 ):

Calls like ghi( MyThing ) still work, as does:
ghi( MyThing, l=MyThing3 ).

Everybody's on board so far and nothing's changed.  Omissions, positional,
and keyword arguments still work as we've grown to know and love.

What we can do, is always know the parameter.  The change is to know the
default value in every situation.  It's always DefaultArg.

ghi( MyThing, DefaultArg, Mything3 )
as well as
ghi( DefaultArg, MyThing2 )

Nothing breaks; everything that used to work still does.  There's no magic
in my proposal, no more than defaults create in the first place.  Functions
get the assignments done for them; they take no extra logic on their own.

It's completely backwards compatible.  No question there!  But you get new
abilities too, for the price of something that's unobtrusive and blends
right in.

To address Jewett, default arguments -are- built into bytecode.  The wrapper
takes a single memory address comparison on a per-argument basis.  It could
get expensive, but at least compare it to looking up values in dictionaries,
which is quite common.

> > DefaultArgument - Special value used in remaining cases of default
> > arguments
> > where None is otherwise meaningful.  New in version 2.6.

If they're not defined, as in C code, then they're always last, or couldn't
be called like you guys want to anyway.  Raise the usual exception anyway.

> In short, any new addition has to have a *lot* of utility to be
> acceptable, or else it wil lead to the way of the Perl side.

Agreed entirely.  You mean, like this?

Who brings up the manual?  Good.  Document something.

Your names in lights, I can see it now.  I'll write the PEP, but first stop
pointing out drawbacks and motivate me.  Wink( DefaultArg ).

P.S.
> Oh, and having jerks around is an unfortunate & unintended side effect of
> having people in the mailing list. I'd be interested if you had any ideas
> to diminish the problem, though. <wink>
Nonsense.  I'll have my people call my people immediately re: mailing list
people.  A little louder and stronger could suffice.  "Let me hear it son.
Costs and benefits.  Bottom line.  Assets or liabilities?"  Then put your
feet up.



From taleinat at gmail.com  Fri May 11 22:02:27 2007
From: taleinat at gmail.com (Tal Einat)
Date: Fri, 11 May 2007 23:02:27 +0300
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511180950.AA6391E4005@bag.python.org>
References: <op.tr5vkisvd64u53@jan-laptop>
	<20070511180950.AA6391E4005@bag.python.org>
Message-ID: <7afdee2f0705111302r26afeef5h4f688889adcaa095@mail.gmail.com>

On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
>
> Note DefaultArg needs never get referenced literally in declarations, only
> in calls.
>
> def ghi( j=None, k=None, l=None ):
>         if j is None: j= Something
>         if k is None: k= Something2
>         if l is None: l= Something3
>
> No.  Here, I do it all at once.
> def ghi( j=Something, k=Something2, l=Something3 ):


Maybe I'm missing something here... But why would someone not use the latter
syntax unless the value must be calculated when the function is called, as
opposed to when the function is defined? In such cases, None fits the bill.
(Default arguments are evaluated at function definition.)

Calls like ghi( MyThing ) still work, as does:
> ghi( MyThing, l=MyThing3 ).
>
> Everybody's on board so far and nothing's changed.  Omissions, positional,
> and keyword arguments still work as we've grown to know and love.
>
> What we can do, is always know the parameter.  The change is to know the
> default value in every situation.  It's always DefaultArg.
>
> ghi( MyThing, DefaultArg, Mything3 )
> as well as
> ghi( DefaultArg, MyThing2 )


IMHO this is far less readable than using keyword arguments and omitting
those arguments for which you'd like to use the default value. I personally
like the "keyword-only arguments" PEP (3102) because it could help make
function calls more readable.


Perhaps we could learn from experience?

I've recently had to automate Excel with Python and used the COM interface.
In COM, there is a value called "Missing" which is passed to functions when
no value should be passed for an argument - similar to your DefaultArg. This
leads to code like this (C# code examples):

http://msdn2.microsoft.com/en-us/library/aa168343(office.11).aspx  (straight
from the online MSDN)

MenuBarItem = MainMenuBar.Controls.Add(
    Office.MsoControlType.msoControlPopup,
    Type.Missing, Type.Missing, Type.Missing, true);


And that was not a far-fetched example - here is an extreme example:

http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-unformatted-excel-sheets-into-sql-server-2000-using-net-part-i-7501

Excel.Application excelApp = new Excel.ApplicationClass();
Excel.Workbook thisWorkbook = excelApp.Workbooks.Open(strFileName,
Type.Missing, Type.Missing,
Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing,
Type.Missing,Type.Missing, Type.Missing, Type.Missing,
Type.Missing,Type.Missing, Type.Missing);


IMO this is horrendous. Horrible. Eye-gouging.

I'd rather write machine code in hex.

- Tal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070511/329fef12/attachment.html>

From castironpi at comcast.net  Fri May 11 22:26:27 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 15:26:27 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <7afdee2f0705111302r26afeef5h4f688889adcaa095@mail.gmail.com>
Message-ID: <20070511202639.13B871E4005@bag.python.org>

 

  _____  

From: Tal Einat [mailto:taleinat at gmail.com] 
Sent: Friday, May 11, 2007 3:02 PM
To: python-ideas at python.org
Cc: Aaron Brady
Subject: Re: [Python-ideas] parameter omit

 

On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:

Note DefaultArg needs never get referenced literally in declarations, only
in calls.

def ghi( j=None, k=None, l=None ):
        if j is None: j= Something
        if k is None: k= Something2
        if l is None: l= Something3 

No.  Here, I do it all at once.
def ghi( j=Something, k=Something2, l=Something3 ):


Maybe I'm missing something here... But why would someone not use the latter
syntax unless the value must be calculated when the function is called, as
opposed to when the function is defined? In such cases, None fits the bill.
(Default arguments are evaluated at function definition.) 

 

Calls like ghi( MyThing ) still work, as does:
ghi( MyThing, l=MyThing3 ).

Everybody's on board so far and nothing's changed.  Omissions, positional,
and keyword arguments still work as we've grown to know and love.

What we can do, is always know the parameter.  The change is to know the 
default value in every situation.  It's always DefaultArg.

ghi( MyThing, DefaultArg, Mything3 )
as well as
ghi( DefaultArg, MyThing2 )


IMHO this is far less readable than using keyword arguments and omitting
those arguments for which you'd like to use the default value. I personally
like the "keyword-only arguments" PEP (3102) because it could help make
function calls more readable. 


Perhaps we could learn from experience?

I've recently had to automate Excel with Python and used the COM interface.
In COM, there is a value called "Missing" which is passed to functions when
no value should be passed for an argument - similar to your DefaultArg. This
leads to code like this (C# code examples): 

http://msdn2.microsoft.com/en-us/library/aa168343(office.11).aspx  (straight
from the online MSDN)



 
MenuBarItem = MainMenuBar.Controls.Add(


    Office.MsoControlType.msoControlPopup, 


    Type.Missing, Type.Missing, Type.Missing, true);


And that was not a far-fetched example - here is an extreme example: 

http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-unformat
ted-excel-sheets-into-sql-server-2000-using-net-part-i-7501 

Excel.Application excelApp = new Excel.ApplicationClass(); 
Excel.Workbook thisWorkbook =
excelApp.Workbooks.Open(strFileName,Type.Missing, Type.Missing, 
Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, 
Type.Missing,Type.Missing, Type.Missing, Type.Missing, 
Type.Missing,Type.Missing, Type.Missing); 


IMO this is horrendous. Horrible. Eye-gouging.

I'd rather write machine code in hex.


- Tal

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070511/1ae1852c/attachment.html>

From castironpi at comcast.net  Fri May 11 22:40:46 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 15:40:46 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <7afdee2f0705111302r26afeef5h4f688889adcaa095@mail.gmail.com>
Message-ID: <20070511204058.840F61E400F@bag.python.org>



> -----Original Message-----
> From: Tal Einat [mailto:taleinat at gmail.com]
> Sent: Friday, May 11, 2007 3:02 PM
> 
> On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> 
> 	Note DefaultArg needs never get referenced literally in
> declarations, only
> 	in calls.
> 
> 	def ghi( j=None, k=None, l=None ):
> 	        if j is None: j= Something
> 	        if k is None: k= Something2
> 	        if l is None: l= Something3
> 
> 	No.  Here, I do it all at once.
> 	def ghi( j=Something, k=Something2, l=Something3 ):
> 
> 
> Maybe I'm missing something here... But why would someone not use the
> latter syntax unless the value must be calculated when the function is
> called, as opposed to when the function is defined? In such cases, None
> fits the bill. (Default arguments are evaluated at function definition.)
> 
> 
> 
> 	Calls like ghi( MyThing ) still work, as does:
> 	ghi( MyThing, l=MyThing3 ).
> 
> 	Everybody's on board so far and nothing's changed.  Omissions,
> positional,
> 	and keyword arguments still work as we've grown to know and love.
> 
> 	What we can do, is always know the parameter.  The change is to know
> the
> 	default value in every situation.  It's always DefaultArg.
> 
> 	ghi( MyThing, DefaultArg, Mything3 )
> 	as well as
> 	ghi( DefaultArg, MyThing2 )
> 
> 
> IMHO this is far less readable than using keyword arguments and omitting
> those arguments for which you'd like to use the default value. I
> personally like the "keyword-only arguments" PEP (3102) because it could
> help make function calls more readable.
> 
> 
> Perhaps we could learn from experience?
> 
> I've recently had to automate Excel with Python and used the COM
> interface. In COM, there is a value called "Missing" which is passed to
> functions when no value should be passed for an argument - similar to your
> DefaultArg. This leads to code like this (C# code examples):
> 
> http://msdn2.microsoft.com/en-us/library/aa168343(office.11).aspx
> (straight from the online MSDN)
> 
> MenuBarItem = MainMenuBar.Controls.Add(
>     Office.MsoControlType.msoControlPopup,
>     Type.Missing, Type.Missing, Type.Missing, true);
> 
> And that was not a far-fetched example - here is an extreme example:
> 
> http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-
> unformatted-excel-sheets-into-sql-server-2000-using-net-part-i-7501
> <http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-
> unformatted-excel-sheets-into-sql-server-2000-using-net-part-i-7501>
> 
> Excel.Application excelApp = new Excel.ApplicationClass();
> Excel.Workbook thisWorkbook =
> excelApp.Workbooks.Open(strFileName,Type.Missing, Type.Missing,
> Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing,
> Type.Missing,Type.Missing, Type.Missing, Type.Missing,
> Type.Missing,Type.Missing, Type.Missing);
> 
> 
> IMO this is horrendous. Horrible. Eye-gouging.
> 
> I'd rather write machine code in hex.
> 
> 
> - Tal

Ok, this isn't working to get my idea over.  There's something wrong with
somebody, and it's simplest to assume its me.  Probably inexperience in
posting.  Not to mention, I have no idea who I'm talking to, or what the
local dialect is.  (Sorry about the blank message too... wrong keystroke.)

Tal's examples don't contradict me.  In his, I call:

> MenuBarItem = MainMenuBar.Controls.Add(
>     Office.MsoControlType.msoControlPopup, thenamedarg= true);
and
> Excel.Workbook thisWorkbook = excelApp.Workbooks.Open(strFileName)

Traditional function call.  Calls still will work the way they do today.
You have -extra- flexibility, not less, sir.  I add zero requirements.
Please let me repeat.  Nothing breaks.



From rrr at ronadam.com  Fri May 11 22:54:35 2007
From: rrr at ronadam.com (Ron Adam)
Date: Fri, 11 May 2007 15:54:35 -0500
Subject: [Python-ideas] Alternate quote delimiters
Message-ID: <4644D80B.4080806@ronadam.com>


While watching the various issues about raw strings and quotes being 
discussed, I decided look into other ways to resolve string delimiter 
collisions that might also improve pythons string handling in general.

And I'd figure I'd let it get shot full of holes here first. ;-)



Here's a nice overview of the issue with various examples.

     http://en.wikipedia.org/wiki/String_literal


*Note: The wiki python raw string example has a trailing backslash which 
would cause an error.

     r"The Windows path is C:\Foo\Bar\Baz\"


In the case of raw strings, the escaped quotes are only needed in order for 
  tokenize.c to locate the end of the string.  The back slashes remain in 
the string. The end of the string is the first unescaped quote of the same 
type as the starting quote.

     >>> s = r"\"Hello World\""
     >>> print s
     \"Hello World\"


This allows you to enter, back-slash + quote, pairs into a string, but ...

- This doesn't help in entering only quotes.  You still need to either use 
a different quotes than what is in the string or not use raw strings.

- A minor side effect is that you can't have a raw string end with a single 
slash as in the incorrect wiki example above.  Other languages which use 
escape characters in raw strings have the same issue.

- If you have a long string with multiple quotes as you can in regular 
expressions the increased number of \ characters can make the regular 
expression more difficult to read and can add up to be more characters than 
needed.

- Another minor issue I've found is doctest that do test on quoted strings 
may have multiple nested doc strings which may require careful selection of 
quote characters.  The problem arises because the start and end delimiters 
are the same.  The start of the nested string ends the top level string. 
The current solution is to pick different quote characters or escape quote 
characters in the nested strings.


So how about a multiple quoting solution?  The examples of this in the wiki 
page are of the form...

    qq^I said, "Can you hear me?"^

    qq at I said, "Can you hear me?"@

    qq?I said, "Can you hear me?"?


But that doesn't fit well with pythons use of quotes.  But a variation of 
this would.  Add a 'q' string prefix similar to the 'u' and 'r' prefix's 
that takes the first character inside the quotes as an additional 
delimiter.  Then ending quote will then need to have that same character 
proceeding it.

    q"^I said, "Can you hear me?"^"

    q"""|I said, "Can you hear me?"|"""

The vertical bar is part of the quote here, not part of the string.


     rq"^The Windows path is C:\Foo\Bar\Baz\^"

This example will work as expected.


Because the beginning and ending of the strings are not identical, it's 
possible that they can allow nesting.

     rq"""^
         rq"""^
                   This is a nested string.
         ^"""
         """
                   Another nested string.
         """
     ^"""


The most useful feature of this would be in temporarily commenting out 
large blocks of python code.  Currently this doesn't work well if the block 
that contain triple quoted doc strings.


Another option might be to designate certain quote delimiters for special 
purposes.

     Dedented strings.

     q"""<
         This is a
         Dedented
         Paragraph.
     <"""


     Commented out source code.

     q"""#
     def foo(bar):
         """
            A bar checker.
         """
         return bar is True
     #"""


     ReST formatted strings.

     rq""":
         Bullet lists:

         - This is item 1
         - This is item 2

         - Bullets are "-", "*" or "+".
           Continuing text must be aligned
           after the bullet and whitespace.

         Note that a blank line is required
         before the first item and after the
         last, but is optional between items.
     :"""

This use would require some way to preserve it's quoting type so it can 
later be used to render the text. (Any ideas?)


Cheers,
    Ron






















From castironpi at comcast.net  Sat May 12 00:02:08 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 17:02:08 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511001240.261B.JCARLSON@uci.edu>
Message-ID: <20070511220225.216BE1E4006@bag.python.org>



> -----Original Message-----
> From: Josiah Carlson [mailto:jcarlson at uci.edu]
> Sent: Friday, May 11, 2007 3:00 AM
> 
> "Aaron Brady" <castironpi at comcast.net> wrote:
> [snip]
> 
> class WebRetrieveElement:
>     hook = None
>     filename = None
> 
>     def netretrieveNew( self ):
>         filename= self.filename or ParamDefault
>         hook= hasattr( self,'hook' ) and self.hook or ParamDefault
>         urlretrieve( self.url, filename, hook )
> 
>     def netretrieveBest(self):
>         urlretrieve(self.url, self.filename, self.hook)

class WebRetrieveElement:
	url= None
	filename= None
	hook= None

	def netretrieveOld( self ):
			urlretrieve( self.url, self.filename, self.hook )

	def netretrieveNew( self ):
			urlretrieve( self.url, self.filename, self.hook )




From castironpi at comcast.net  Sat May 12 00:15:11 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 17:15:11 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <f2160j$jvl$2@sea.gmane.org>
Message-ID: <20070511221523.D36331E4005@bag.python.org>

Hi, I see:
def parsesuite(self, text):
    """Return a modified parse tree for the given suite text."""
    return self.transform(parser.suite(text))

in
https://codespeak.net/viewvc/pypy/dist/lib-python/2.4.1/compiler/transformer
.py?revision=39456&view=markup

and

...future.py 	 39456
misc.py 	 39456
pyassem.py 	 39456
pycodegen.py 	 39456...

in https://codespeak.net/viewvc/pypy/dist/lib-python/2.4.1/compiler/

as well as

os.py 	 39456
os2emxpath.py 	 39456
pdb.doc 	 39456
pdb.py 	 39456

in https://codespeak.net/viewvc/pypy/dist/lib-python/2.4.1/ .

Where, exactly?

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Georg Brandl
> Sent: Friday, May 11, 2007 2:29 AM
> To: python-ideas at python.org
> Subject: Re: [Python-ideas] parser in stdlib
> 
> Aaron Brady schrieb:
> 
> >> A perfect example of why programmable syntax is out of question for
> >> Python.
> >>
> >> George
> >
> > Hence the quote.  First thing I said was, "...it might not be advisable
> > either, subject to abuse, per GvR...."
> >
> > But that doesn't preclude exposing `parser'.  It is the extent of my
> > question, no more.  Can we expose the module?
> 
> If you tell us what you mean with "expose"... the module is written in C
> and is not much more than a wrapper around Python's own parser, which
> is written in C too.
> 
> If you are looking for a Python parser written in Python, you may want
> to look at the PyPy project's implementation.
> 
> Georg
> 
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas



From cvrebert at gmail.com  Sat May 12 01:09:33 2007
From: cvrebert at gmail.com (Chris Rebert)
Date: Fri, 11 May 2007 16:09:33 -0700
Subject: [Python-ideas] Alternate quote delimiters
In-Reply-To: <4644D80B.4080806@ronadam.com>
References: <4644D80B.4080806@ronadam.com>
Message-ID: <47c890dc0705111609m490ef42cva79ba7d32a4182c7@mail.gmail.com>

On 5/11/07, Ron Adam <rrr at ronadam.com> wrote:
>
> While watching the various issues about raw strings and quotes being
> discussed, I decided look into other ways to resolve string delimiter
> collisions that might also improve pythons string handling in general.
>
> And I'd figure I'd let it get shot full of holes here first. ;-)

Here come the first shots. ;-)

> So how about a multiple quoting solution?  The examples of this in the wiki
> page are of the form...
>
>     qq^I said, "Can you hear me?"^
>
>     qq at I said, "Can you hear me?"@
>
>     qq?I said, "Can you hear me?"?
>
>
> But that doesn't fit well with pythons use of quotes.  But a variation of
> this would.  Add a 'q' string prefix similar to the 'u' and 'r' prefix's
> that takes the first character inside the quotes as an additional
> delimiter.  Then ending quote will then need to have that same character
> proceeding it.
>
>     q"^I said, "Can you hear me?"^"
>
>     q"""|I said, "Can you hear me?"|"""
>
> The vertical bar is part of the quote here, not part of the string.

Ick. This will make python code harder to parse (I wonder whether the
current parser even do what you propose), and isn't that much of an
improvement in ease of expression. Also, this seems way too perlish
for my tastes. There should be only one way to do quoting, but
practicality beat purity for quotes and regexes. However, allowing
arbitrary quoting characters seems like overkill.

> Because the beginning and ending of the strings are not identical, it's
> possible that they can allow nesting.
>
>      rq"""^
>          rq"""^
>                    This is a nested string.
>          ^"""
>          """
>                    Another nested string.
>          """
>      ^"""
>
>
> The most useful feature of this would be in temporarily commenting out
> large blocks of python code.  Currently this doesn't work well if the block
> that contain triple quoted doc strings.

A block commenting syntax may be useful, however I don't like this
proposal because of the previous point. Also, most python editors let
you block comment out stuff with a command to add the appropriate #s
pretty easily.

> Another option might be to designate certain quote delimiters for special
> purposes.
>
>      Dedented strings.
>
>      q"""<
>          This is a
>          Dedented
>          Paragraph.
>      <"""
>
>
>      Commented out source code.
>
>      q"""#
>      def foo(bar):
>          """
>             A bar checker.
>          """
>          return bar is True
>      #"""

I'm neutral on these.

>      ReST formatted strings.
>
>      rq""":
>          Bullet lists:
>
>          - This is item 1
>          - This is item 2
>
>          - Bullets are "-", "*" or "+".
>            Continuing text must be aligned
>            after the bullet and whitespace.
>
>          Note that a blank line is required
>          before the first item and after the
>          last, but is optional between items.
>      :"""

Seems like a little much to have syntax for ReST. Is it used
frequently enough to justify adding this?

- Chris Rebert

From scott+python-ideas at scottdial.com  Sat May 12 01:25:27 2007
From: scott+python-ideas at scottdial.com (Scott Dial)
Date: Fri, 11 May 2007 19:25:27 -0400
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070511221523.D36331E4005@bag.python.org>
References: <20070511221523.D36331E4005@bag.python.org>
Message-ID: <4644FB67.8080607@scottdial.com>

Aaron Brady wrote:
 > Georg Brandl wrote:
>> If you are looking for a Python parser written in Python, you may want
>> to look at the PyPy project's implementation.
>>
 > Where, exactly?
 >

First of all, stop top posting, it makes it hard to reply to you. Second 
of all, I doubt this will at all aide you in whatever quest you are on, 
but the place you are looking for is:

/pypy/interpreter/pyparser/pythonparse.py

I think the link to EasyExtend was the most logical one..

-Scott

-- 
Scott Dial
scott at scottdial.com
scodial at cs.indiana.edu


From greg.ewing at canterbury.ac.nz  Sat May 12 01:49:43 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Sat, 12 May 2007 11:49:43 +1200
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070511034722.0E65F1E4003@bag.python.org>
References: <20070511034722.0E65F1E4003@bag.python.org>
Message-ID: <46450117.40407@canterbury.ac.nz>

Aaron Brady wrote:

> But that doesn't preclude exposing `parser'.  It is the extent of my
> question, no more.  Can we expose the module?

I can understand there being reluctance to expose
what are currently internal details of this module,
thereby effectively freezing them.

--
Greg


From rrr at ronadam.com  Sat May 12 01:56:07 2007
From: rrr at ronadam.com (Ron Adam)
Date: Fri, 11 May 2007 18:56:07 -0500
Subject: [Python-ideas] Alternate quote delimiters
In-Reply-To: <47c890dc0705111609m490ef42cva79ba7d32a4182c7@mail.gmail.com>
References: <4644D80B.4080806@ronadam.com>
	<47c890dc0705111609m490ef42cva79ba7d32a4182c7@mail.gmail.com>
Message-ID: <46450297.3090307@ronadam.com>

Chris Rebert wrote:
> On 5/11/07, Ron Adam <rrr at ronadam.com> wrote:
>>
>> While watching the various issues about raw strings and quotes being
>> discussed, I decided look into other ways to resolve string delimiter
>> collisions that might also improve pythons string handling in general.
>>
>> And I'd figure I'd let it get shot full of holes here first. ;-)
> 
> Here come the first shots. ;-)

Great!  ;-)


>> So how about a multiple quoting solution?  The examples of this in the 
>> wiki
>> page are of the form...
>>
>>     qq^I said, "Can you hear me?"^
>>
>>     qq at I said, "Can you hear me?"@
>>
>>     qq?I said, "Can you hear me?"?
>>
>>
>> But that doesn't fit well with pythons use of quotes.  But a variation of
>> this would.  Add a 'q' string prefix similar to the 'u' and 'r' prefix's
>> that takes the first character inside the quotes as an additional
>> delimiter.  Then ending quote will then need to have that same character
>> proceeding it.
>>
>>     q"^I said, "Can you hear me?"^"
>>
>>     q"""|I said, "Can you hear me?"|"""
>>
>> The vertical bar is part of the quote here, not part of the string.
> 
> Ick. This will make python code harder to parse (I wonder whether the
> current parser even do what you propose), and isn't that much of an
> improvement in ease of expression.

The tokanizer can be modified to convert any of these to standard or raw
strings accordingly.  It just needs to find the beginning and the end. I
haven't looked into what will be needed to pass the delimiter to the
compiler yet.  So in it's simplest form, it's just a bit of preprocessing.


> Also, this seems way too perlish
> for my tastes. There should be only one way to do quoting, but
> practicality beat purity for quotes and regexes. However, allowing
> arbitrary quoting characters seems like overkill.

Then limit it to just a smaller set of characters.  Which ones do you suggest.

Perl uses the forms above I didn't choose.  Those don't even look like
strings to me, which is why id didn't even consider them.  Almost every
other solution has problems of some sort.  This is the only solution I
liked that did not have any problems.  Like anything new it may take a
little getting used to before it seems like python rather than something
tacked on.


>> Because the beginning and ending of the strings are not identical, it's
>> possible that they can allow nesting.
>>
>>      rq"""^
>>          rq"""^
>>                    This is a nested string.
>>          ^"""
>>          """
>>                    Another nested string.
>>          """
>>      ^"""
>>
>>
>> The most useful feature of this would be in temporarily commenting out
>> large blocks of python code.  Currently this doesn't work well if the 
>> block
>> that contain triple quoted doc strings.
> 
> A block commenting syntax may be useful, however I don't like this
> proposal because of the previous point. Also, most python editors let
> you block comment out stuff with a command to add the appropriate #s
> pretty easily.

True, and that is what I do.  However, most non-python editors need macros
programed into them if they have them, if they don't,  you must fall back
to manually adding #'s to each line.


>> Another option might be to designate certain quote delimiters for special
>> purposes.
>>
>>      Dedented strings.
>>
>>      q"""<
>>          This is a
>>          Dedented
>>          Paragraph.
>>      <"""
>>
>>
>>      Commented out source code.
>>
>>      q"""#
>>      def foo(bar):
>>          """
>>             A bar checker.
>>          """
>>          return bar is True
>>      #"""
> 
> I'm neutral on these.

The choices of delimiters in these cases need not be carved in stone.  It
can be an informal standard as well.


>>      ReST formatted strings.
>>
>>      rq""":
>>          Bullet lists:
>>
>>          - This is item 1
>>          - This is item 2
>>
>>          - Bullets are "-", "*" or "+".
>>            Continuing text must be aligned
>>            after the bullet and whitespace.
>>
>>          Note that a blank line is required
>>          before the first item and after the
>>          last, but is optional between items.
>>      :"""
> 
> Seems like a little much to have syntax for ReST. Is it used
> frequently enough to justify adding this?

It's not really syntax for reST in this case.  It's more of a very general
method to notate or tag a string.  There may be other uses for that as well.


> - Chris Rebert

Cheers,
    Ron







From castironpi at comcast.net  Sat May 12 02:17:25 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 19:17:25 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <46450117.40407@canterbury.ac.nz>
Message-ID: <20070512001737.BC6F31E4005@bag.python.org>

> -----Original Message-----
> From: Greg Ewing [mailto:greg.ewing at canterbury.ac.nz]
> Sent: Friday, May 11, 2007 6:50 PM
> 
> Aaron Brady wrote:
> 
> > But that doesn't preclude exposing `parser'.  It is the extent of my
> > question, no more.  Can we expose the module?
> 
> I can understand there being reluctance to expose
> what are currently internal details of this module,
> thereby effectively freezing them.
> 
> --
> Greg

I didn't realize they were changing so dynamically.  But then, plenty of the
modules have parallel Python and C implementations.

I suspect the true reason lies more with Sakkis' post [5/10 23:26 us
central].  A mimetic structure such as Python will sit somewhere between
restriction and liberty.  Best to be deliberate in choosing a place on the
continuum.  But where, exactly?

Discouraging customized syntax is one thing.  Prohibiting it altogether is
another extreme.  The current positioning lies with the latter.  Put
`parser' in to encourage the adventurous explorer, -while- keeping native
dynamic constructs disabled in order to keep up unity.

I do not hold that we lift all restrictions.  Rather, merely -reduce- the
number of hoops you must jump through to get at Python internals.

If you think that everybody will jump-to and create their own Python the
very first day you let a second ray of light shine in, you've underestimated
Python.  For one thing, we -want- to stick together, and will on our own.
Present the option, and you'll only get better suggestions, thenceforth.

The current state is too restrictive.



From taleinat at gmail.com  Sat May 12 02:14:33 2007
From: taleinat at gmail.com (Tal Einat)
Date: Sat, 12 May 2007 03:14:33 +0300
Subject: [Python-ideas] parameter omit
In-Reply-To: <4644d502.4a2a05fb.048d.ffffabfeSMTPIN_ADDED@mx.google.com>
References: <7afdee2f0705111302r26afeef5h4f688889adcaa095@mail.gmail.com>
	<4644d502.4a2a05fb.048d.ffffabfeSMTPIN_ADDED@mx.google.com>
Message-ID: <7afdee2f0705111714s60118d8cuc219765830b3f59f@mail.gmail.com>

On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
>
>
> > Perhaps we could learn from experience?
> >
> > I've recently had to automate Excel with Python and used the COM
> > interface. In COM, there is a value called "Missing" which is passed to
> > functions when no value should be passed for an argument - similar to
> your
> > DefaultArg. This leads to code like this (C# code examples):
> >
> > http://msdn2.microsoft.com/en-us/library/aa168343(office.11).aspx
> > (straight from the online MSDN)
> >
> > MenuBarItem = MainMenuBar.Controls.Add(
> >     Office.MsoControlType.msoControlPopup,
> >     Type.Missing, Type.Missing, Type.Missing, true);
> >
> > And that was not a far-fetched example - here is an extreme example:
> >
> > http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-
> > unformatted-excel-sheets-into-sql-server-2000-using-net-part-i-7501
> > <http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-
> > unformatted-excel-sheets-into-sql-server-2000-using-net-part-i-7501>
> >
> > Excel.Application excelApp = new Excel.ApplicationClass();
> > Excel.Workbook thisWorkbook =
> > excelApp.Workbooks.Open(strFileName,Type.Missing, Type.Missing,
> > Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing,
> > Type.Missing,Type.Missing, Type.Missing, Type.Missing,
> > Type.Missing,Type.Missing, Type.Missing);
> >
> >
> > IMO this is horrendous. Horrible. Eye-gouging.
> >
> > I'd rather write machine code in hex.
> >
> >
> > - Tal
>
> Ok, this isn't working to get my idea over.  There's something wrong with
> somebody, and it's simplest to assume its me.  Probably inexperience in
> posting.  Not to mention, I have no idea who I'm talking to, or what the
> local dialect is.  (Sorry about the blank message too... wrong keystroke.)
>
> Tal's examples don't contradict me.  In his, I call:
>
> > MenuBarItem = MainMenuBar.Controls.Add(
> >     Office.MsoControlType.msoControlPopup, thenamedarg= true);
> and
> > Excel.Workbook thisWorkbook = excelApp.Workbooks.Open(strFileName)
>
> Traditional function call.  Calls still will work the way they do today.
> You have -extra- flexibility, not less, sir.  I add zero requirements.
> Please let me repeat.  Nothing breaks.


These are simply the examples I could find with several minutes of Googling,
admittedly not great examples, as you pointed out. I was just trying to show
real world ugly code which was written as a result of an infrastructure
adopting a concept which is very similar to the one which you propose. The
point was to show that adopting your suggestion could result in even less
readable function calls.

Yes, nothing breaks. I really get it. I'm against this because it is, IMHO,
not Pythonic.

I'm not saying it won't be possible to write readable code. I'm saying it
-would- be possible to write even less readable code. Specifically, I might
be forced to write such ugly function calls when calling functions written
by others, therefore adopting this feature could lead to my being forced to
write uglier code. Not to mention reading others' uglier code...

- Tal

(P.S. in the first example, a keyword argument could not be used, because
all of the arguments were positional.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070512/77a4f3c2/attachment.html>

From castironpi at comcast.net  Sat May 12 02:56:03 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 11 May 2007 19:56:03 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511220225.216BE1E4006@bag.python.org>
Message-ID: <20070512005615.EB6681E4005@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Aaron Brady
> > -----Original Message-----
> > From: Josiah Carlson [mailto:jcarlson at uci.edu]
> > Sent: Friday, May 11, 2007 3:00 AM
> > [snip]
> 
> class WebRetrieveElement:
> 	url= None
> 	filename= None
> 	hook= None
> 
> 	def netretrieveOld( self ):
> 			urlretrieve( self.url, self.filename, self.hook )
> 
> 	def netretrieveNew( self ):
> 			urlretrieve( self.url, self.filename, self.hook )

And while I'm at it and thinking clearly, with cool weather and open doors,
the basic problem here, underlying and distilled, is that None is serving
double-duty.  I've had a feeling so since month two.

It's used to signal an absence of a value.  But there are two distinct
situations in which it's needed.  One for values, two for function calls.

You could always require all parameter defaults to equal `None'.  But since
they're not, take this.

DefaultArg = object()



From guido at python.org  Sat May 12 04:29:33 2007
From: guido at python.org (Guido van Rossum)
Date: Fri, 11 May 2007 19:29:33 -0700
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070512001737.BC6F31E4005@bag.python.org>
References: <46450117.40407@canterbury.ac.nz>
	<20070512001737.BC6F31E4005@bag.python.org>
Message-ID: <ca471dc20705111929i41248576l807a258394bee4ec@mail.gmail.com>

On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> I suspect the true reason lies more with Sakkis' post [5/10 23:26 us
> central].  A mimetic structure such as Python will sit somewhere between
> restriction and liberty.  Best to be deliberate in choosing a place on the
> continuum.  But where, exactly?

What on earth is a "mimetic structure"? Please keep the jargon
understandable for the rest of us, at least if you want to be heard.

> Discouraging customized syntax is one thing.  Prohibiting it altogether is
> another extreme.  The current positioning lies with the latter.  Put
> `parser' in to encourage the adventurous explorer, -while- keeping native
> dynamic constructs disabled in order to keep up unity.
>
> I do not hold that we lift all restrictions.  Rather, merely -reduce- the
> number of hoops you must jump through to get at Python internals.

Depends on which internals you're talking about. Most internals are
very close to the surface. Syntax happens to be hermetic though.
Perhaps you need to find a different language for what you want?

> If you think that everybody will jump-to and create their own Python the
> very first day you let a second ray of light shine in, you've underestimated
> Python.  For one thing, we -want- to stick together, and will on our own.
> Present the option, and you'll only get better suggestions, thenceforth.
>
> The current state is too restrictive.

That's easy for you to say. Have you tried (*seriously* tried) to
specify such a thing? (For Python, maintaining full backwards
compatibility.) In this community, code talks. Good understandable
specs are sometimes allowed to speak. Wild ideas, especially if they
involve "let others figure out how to design and implement my idea,
but I need it now" are shown the door.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


From jimjjewett at gmail.com  Sat May 12 18:11:02 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Sat, 12 May 2007 12:11:02 -0400
Subject: [Python-ideas] Alternate quote delimiters
In-Reply-To: <4644D80B.4080806@ronadam.com>
References: <4644D80B.4080806@ronadam.com>
Message-ID: <fb6fbf560705120911y53960a64j9940f8bc9bb7bb0a@mail.gmail.com>

> ... doctest that do test on quoted strings
> may have multiple nested doc strings ...

> ...  Add a 'q' string prefix similar to the 'u' and 'r' prefix's
> that takes the first character inside the quotes as an
> additional delimiter.  Then ending quote will then need to
> have that same character proceeding it.

>     q"^I said, "Can you hear me?"^"

>     q"""|I said, "Can you hear me?"|"""

> The vertical bar is part of the quote here, not part of
> the string.

This should work, but I can't help wondering if it is too complicated.
 What if the character were limited to the opening of a
bracketed-pair, such as {[(  Or is that just as bad, and less flexible
to  boot? }]}

>      rq"^The Windows path is C:\Foo\Bar\Baz\^"

> This example will work as expected.

How serious is this problem?

    r"The Windows path is C:\Foo\Bar\Baz\X"[:-1]

is awkward, but ... how much complexity do we want to incur avoiding it?

-jJ


From jimjjewett at gmail.com  Sat May 12 18:35:54 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Sat, 12 May 2007 12:35:54 -0400
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070512005615.EB6681E4005@bag.python.org>
References: <20070511220225.216BE1E4006@bag.python.org>
	<20070512005615.EB6681E4005@bag.python.org>
Message-ID: <fb6fbf560705120935y35407a55o892c928b7a75696f@mail.gmail.com>

On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:

> And while I'm at it and thinking clearly, with cool weather and open doors,
> the basic problem here, underlying and distilled, is that None is serving
> double-duty.

Yes.  When None appears in a parameter list (or an argument list, at
the calling site), it might really be a sentinel for something else,
and that is a wart.

> You could always require all parameter defaults to equal `None'.  But since
> they're not, take this.

> DefaultArg = object()

Yes; this is used when None actually is a valid and meaningful value.

I don't see a good way to *always* use this idiom though, because

(1)  If DefaultArg is a pre-existing object, then there will be times
when it is valid and meaningful data -- such as when introspecting.

(2)  Creating it afresh is a bit of boilerplate that we wouldn't want
to require when it isn't really needed.

    sentinel=object()
    def f(val=sentinel):
        if val is sentinel:

And note that the creation can't be inline, such as

     def f(val=object()):

or there wouldn't be any good way to test for it.  Adding a keyword to do that

    def f(val=object()):
        if defaulted val:

would probably be a good idea.  (I don't think it would get used often
enough to justify the costs of a change, but there would be a clear
benefit to include in the cost-benefit calculations.)

-jJ


From rrr at ronadam.com  Sat May 12 19:37:41 2007
From: rrr at ronadam.com (Ron Adam)
Date: Sat, 12 May 2007 12:37:41 -0500
Subject: [Python-ideas] Alternate quote delimiters
In-Reply-To: <fb6fbf560705120911y53960a64j9940f8bc9bb7bb0a@mail.gmail.com>
References: <4644D80B.4080806@ronadam.com>
	<fb6fbf560705120911y53960a64j9940f8bc9bb7bb0a@mail.gmail.com>
Message-ID: <4645FB65.6090809@ronadam.com>

Jim Jewett wrote:
>> ... doctest that do test on quoted strings
>> may have multiple nested doc strings ...
> 
>> ...  Add a 'q' string prefix similar to the 'u' and 'r' prefix's
>> that takes the first character inside the quotes as an
>> additional delimiter.  Then ending quote will then need to
>> have that same character proceeding it.
> 
>>     q"^I said, "Can you hear me?"^"
> 
>>     q"""|I said, "Can you hear me?"|"""
> 
>> The vertical bar is part of the quote here, not part of
>> the string.
> 
> This should work, but I can't help wondering if it is too complicated.
> What if the character were limited to the opening of a
> bracketed-pair, such as {[(  Or is that just as bad, and less flexible
> to  boot? }]}

If we are not concerned about meta uses, then we probably only need one. I 
prefer the non-directional symbols as they don't suggest the string is 
another container type.

Raymonds information attribute pep might fulfill the meta uses I had in 
mind.  (Don't know until we see it.)


>>      rq"^The Windows path is C:\Foo\Bar\Baz\^"
> 
>> This example will work as expected.
> 
> How serious is this problem?
> 
>    r"The Windows path is C:\Foo\Bar\Baz\X"[:-1]
> 
> is awkward, but ... how much complexity do we want to incur avoiding it?

Since Guido gave the nod to Martin for starting a pep to remove escapes 
from raw strings completely, this one may no longer be an issue.  ;-)



On another note, it may be useful to have or be able to use an alternative 
escape character.

    e&"The Windows path is C:\Foo\Bar\Baz\X\"   # '&' is escape, not '\'

    e&"I said, &"Can you hear me now?&""

The '&' is used much less frequently than the '\' is.

Raw strings wouldn't use it.  ;-)


The advantage in this is that many other languages use the '\' as an escape 
introducer. So being able to use a '&' can avoid escape character clashes 
if you are using python to generate code or scripts where the '\' is used 
frequently.

And then we can have the ('\' + chr) or ('&' + chr) pairs always be an 
escape character.  Currently '\' by it self isn't always an escape 
character and it's evaluated differently than for example how re evaluates 
it if the character following the '\' is not special.


Alternatively it might be good if python raised an error on an escape 
sequence it doesn't recognize just as it does with the percent character.

(Just looking for the little things that can be cleaned up a tiny bit, 
I'll leave the big Base Classes and Super issues to the experts. ;-)

Cheers,
    Ron









From castironpi at comcast.net  Sat May 12 20:40:58 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Sat, 12 May 2007 13:40:58 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <fb6fbf560705120935y35407a55o892c928b7a75696f@mail.gmail.com>
Message-ID: <20070512184112.75CFA1E4010@bag.python.org>

> -----Original Message-----
> From: Jim Jewett [mailto:jimjjewett at gmail.com]
> Sent: Saturday, May 12, 2007 11:36 AM
> 
> On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> 
> > And while I'm at it and thinking clearly, with cool weather and open
> doors,
> > the basic problem here, underlying and distilled, is that None is
> serving
> > double-duty.
> 
> Yes.  When None appears in a parameter list (or an argument list, at
> the calling site), it might really be a sentinel for something else,
> and that is a wart.
> 
> > You could always require all parameter defaults to equal `None'.  But
> since
> > they're not, take this.
> 
> > DefaultArg = object()
> 
> Yes; this is used when None actually is a valid and meaningful value.
> 
> I don't see a good way to *always* use this idiom though, because
> 
> (1)  If DefaultArg is a pre-existing object, then there will be times
> when it is valid and meaningful data -- such as when introspecting.
> 
> (2)  Creating it afresh is a bit of boilerplate that we wouldn't want
> to require when it isn't really needed.
> 
>     sentinel=object()
>     def f(val=sentinel):
>         if val is sentinel:
> 
> And note that the creation can't be inline, such as
> 
>      def f(val=object()):
> 
> or there wouldn't be any good way to test for it.  Adding a keyword to do
> that
> 
>     def f(val=object()):
>         if defaulted val:
> 
> would probably be a good idea.  (I don't think it would get used often
> enough to justify the costs of a change, but there would be a clear
> benefit to include in the cost-benefit calculations.)
> 
> -jJ

Can we do:

>     sentinel=object()
>     def f(val=sentinel):
>         if val is sentinel:

	sentinel=object()
	def f(val='utf-8'):
		if val is sentinel:
			pass
	f(sentinel)

?  How common are non-None default values?





From jimjjewett at gmail.com  Sat May 12 21:10:00 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Sat, 12 May 2007 15:10:00 -0400
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070512184112.75CFA1E4010@bag.python.org>
References: <fb6fbf560705120935y35407a55o892c928b7a75696f@mail.gmail.com>
	<20070512184112.75CFA1E4010@bag.python.org>
Message-ID: <fb6fbf560705121210y79d3a15fue4dc9c7a70682622@mail.gmail.com>

On 5/12/07, Aaron Brady <castironpi at comcast.net> wrote:
> Can we do:

>         sentinel=object()
>         def f(val='utf-8'):
>                 if val is sentinel:

Sure, but then people have to import sentinel before using it to call
your function.

> ?  How common are non-None default values?

Pretty common.  They are usually (but not always) a zero of some sort
(0, "", {}, []) which *could* be done with the None and type
annotations in Py3.

-jJ


From castironpi at comcast.net  Sun May 13 00:21:22 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Sat, 12 May 2007 17:21:22 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <fb6fbf560705121210y79d3a15fue4dc9c7a70682622@mail.gmail.com>
Message-ID: <20070512222132.0E4781E4005@bag.python.org>



> -----Original Message-----
> From: Jim Jewett [mailto:jimjjewett at gmail.com]
> Sent: Saturday, May 12, 2007 2:10 PM
> To: Aaron Brady
> Cc: python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> On 5/12/07, Aaron Brady <castironpi at comcast.net> wrote:
> > Can we do:
> 
> >         sentinel=object()
> >         def f(val='utf-8'):
> >                 if val is sentinel:
> 
> Sure, but then people have to import sentinel before using it to call
> your function.
> 
> > ?  How common are non-None default values?
> 
> Pretty common.  They are usually (but not always) a zero of some sort
> (0, "", {}, []) which *could* be done with the None and type
> annotations in Py3.
> 
> -jJ

I've gone through quite a few moods, attitudes, reading this.  If you do,
seek help; I am a miscreant by profession.

Ranging from audacity and awe, to indignance, I have found the newsgroup on
the whole to be reasonable yet stubborn.  Expect me to take the other side
soon.  Erratic, fickle, go for it.  Jewett's idea,

>         if defaulted val:

-is- very Pythonic, blending in much better than mine.

Mine isn't after all but I don't see why or how.  Too bad too; it's a beaut'
as ideas go.

> Sure, but then people have to import sentinel before using it to call
> your function.

Good.  Fine.  From constants import True, None, Sentinel.  I see in
contrast.

You know how many cigarettes I'd get for free if I saved all my C-Note
Camelbucks?

More later, if at all.



From cvrebert at gmail.com  Sun May 13 00:43:36 2007
From: cvrebert at gmail.com (Chris Rebert)
Date: Sat, 12 May 2007 15:43:36 -0700
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070512184112.75CFA1E4010@bag.python.org>
References: <20070512184112.75CFA1E4010@bag.python.org>
Message-ID: <46464318.4050204@gmail.com>

<snip>
> ?  How common are non-None default values?
</snip>

Quoting myself from 
http://mail.python.org/pipermail/python-3000/2007-February/005704.html 
([Python-3000] pre-PEP: Default Argument Expressions), when I generated 
statistics related to this subject:

 > A survey of the standard library for Python v2.5, produced via a
 > script [7], gave the following statistics for the standard library
 > (608 files, test suites were excluded):
 >
 >   total number of non-None immutable default arguments: 1585 (41.5%)
 >   total number of mutable default arguments: 186 (4.9%)
 >   total number of default arguments with a value of None: 1813 (47.4%)
 >   total number of default arguments with unknown mutability: 238 (6.2%)
 >   total number of comparisons to None: 940

So, I'd say that they're pretty frequent, with at least 41.5% of all std 
lib default values being non-None.

- Chris Rebert


From jan.kanis at phil.uu.nl  Sun May 13 01:13:48 2007
From: jan.kanis at phil.uu.nl (Jan Kanis)
Date: Sun, 13 May 2007 01:13:48 +0200
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070511180949.D387B2DC7@kleene.admin.phil.uu.nl>
References: <20070511180949.D387B2DC7@kleene.admin.phil.uu.nl>
Message-ID: <op.tr8lhaxxd64u53@jan-laptop>

On Fri, 11 May 2007 20:09:39 +0200, Aaron Brady <castironpi at comcast.net>  
wrote:

>> -----Original Message-----
>> From: Jan Kanis [mailto:jan.kanis at phil.uu.nl]
>> Sent: Friday, May 11, 2007 6:59 AM
>>
>> In short, any new addition has to have a *lot* of utility to be
>> acceptable, or else it wil lead to the way of the Perl side.
>
> Agreed entirely.  You mean, like this?
>
> Who brings up the manual?  Good.  Document something.

It isn't really about the manual, and I think I meant something like  
'language reference' (sorry, not native English). It's about the  
complexity of the language. The size of the language reference can be seen  
as a more or less objective way to measure language complexity. Your  
proposal adds a little bit more complexity, and most people here agree  
that the benefits, which are there, are not worth it.


From aahz at pythoncraft.com  Sun May 13 01:30:57 2007
From: aahz at pythoncraft.com (Aahz)
Date: Sat, 12 May 2007 16:30:57 -0700
Subject: [Python-ideas] the future of the GIL
In-Reply-To: <464281AE.7040903@acm.org>
References: <f1l97g$5cm$1@sea.gmane.org> <463E4645.5000503@acm.org>
	<20070506222840.25B2.JCARLSON@uci.edu> <f1s312$489$1@sea.gmane.org>
	<4642745C.1040702@canterbury.ac.nz> <464281AE.7040903@acm.org>
Message-ID: <20070512233057.GA16939@panix.com>

[excessive quoting ahead to move to python-ideas from python-3000, please
trim when you followup]

On Wed, May 09, 2007, Talin wrote:
> Greg Ewing wrote:
>> Giovanni Bajo wrote:
>>>
>>> using multiple processes cause some 
>>> headaches with frozen distributions (PyInstaller, py2exe, etc.),
>>> like those usually found on Windows, specifically because Windows
>>> does not have fork().
>>
>> Isn't that just a problem with Windows generally? I don't
>> see what the method of packaging has to do with it.
>> 
>> Also, I've seen it suggested that there may actually be
>> a way of doing something equivalent to a fork in Windows,
>> even though it doesn't have a fork() system call as such.
>> Does anyone know more about this?
> 
> I also wonder about embedded systems and game consoles. I don't know how 
> many embedded microprocessors support fork(), but I know that modern 
> consoles such as PS/3 and Xbox do not, since they have no support for 
> virtual memory at all.
> 
> Also remember that the PS/3 is supposed to be one of the poster children 
> for multiprocessing -- the whole 'cell processor' thing. You can't write 
> an efficient game on the PS/3 unless it uses multiple processors.
> 
> Admittedly, not many current console-based games use Python, but that 
> need not always be the case in the future, and a number of PC-based 
> games are using it already.
> 
> This much I agree: There's no point in talking about supporting multiple 
> processors using threads as long as we're living in a refcounting world.
> 
> Thought experiment: Suppose you were writing and brand-new dynamic 
> language today, designed to work efficiently on multi-processor systems. 
> Forget all of Python's legacy implementation details such as GILs and 
> refcounts and such. What would it look like, and how well would it 
> perform? (And I don't mean purely functional languages a la Erlang.)
> 
> For example, in a language that is based on continuations at a very deep 
> level, there need not be any "global interpreter" at all. Each separate 
> flow of execution is merely a pointer to a call frame, the evaluation of 
> which produces a pointer to another call frame (or perhaps the same 
> one). Yes, there would still be some shared state that would have to be 
> managed, but I wouldn't think that the performance penalty of managing 
> that would be horrible.

One of the primary goals of Python was/is to be an easy glue language
for C libraries.  How do you propose to handle the issue that many C
libraries use global state?
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"Look, it's your affair if you want to play with five people, but don't
go calling it doubles."  --John Cleese anticipates Usenet


From greg.ewing at canterbury.ac.nz  Sun May 13 02:58:59 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Sun, 13 May 2007 12:58:59 +1200
Subject: [Python-ideas] Alternate quote delimiters
In-Reply-To: <fb6fbf560705120911y53960a64j9940f8bc9bb7bb0a@mail.gmail.com>
References: <4644D80B.4080806@ronadam.com>
	<fb6fbf560705120911y53960a64j9940f8bc9bb7bb0a@mail.gmail.com>
Message-ID: <464662D3.9020406@canterbury.ac.nz>

Jim Jewett wrote:

>  What if the character were limited to the opening of a
> bracketed-pair, such as {[(  Or is that just as bad, and less flexible
> to  boot? }]}

This would be better, I think, as then nested occurrences
of the bracket chars could be skipped without having to
pick a different character for each level of quoting.

It could even be restricted to just one kind of bracket
if desired without losing anything.

> How serious is this problem?
> 
>     r"The Windows path is C:\Foo\Bar\Baz\X"[:-1]
> 
> is awkward, but ... how much complexity do we want to incur avoiding it?

If you use os.path.join and friends to manipulate your
paths (as you should!) you will hardly ever have to deal
with a path containing a trailing backslash in the first
place. So I wouldn't worry about it much.

--
Greg


From castironpi at comcast.net  Sun May 13 06:41:27 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Sat, 12 May 2007 23:41:27 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <ca471dc20705111929i41248576l807a258394bee4ec@mail.gmail.com>
Message-ID: <20070513044141.74BAE1E4006@bag.python.org>


> -----Original Message-----
> From: gvanrossum at gmail.com [mailto:gvanrossum at gmail.com] On Behalf Of
> Guido van Rossum
> Sent: Friday, May 11, 2007 9:30 PM
> 
> On 5/11/07, Aaron Brady <castironpi at comcast.net> wrote:
> > I suspect the true reason lies more with Sakkis' post [5/10 23:26 us
> > central].  A mimetic structure such as Python will sit somewhere between
> > restriction and liberty.  Best to be deliberate in choosing a place on
> the
> > continuum.  But where, exactly?
> 
> What on earth is a "mimetic structure"? Please keep the jargon
> understandable for the rest of us, at least if you want to be heard.
> 
> > [snip]
> > The current state is too restrictive.
> 
> That's easy for you to say. Have you tried (*seriously* tried) to
> specify such a thing? (For Python, maintaining full backwards
> compatibility.) In this community, code talks. Good understandable
> specs are sometimes allowed to speak. Wild ideas, especially if they
> involve "let others figure out how to design and implement my idea,
> but I need it now" are shown the door.
> 
> --
> --Guido van Rossum (home page: http://www.python.org/~guido/)

> What on earth is a "mimetic structure"? Please keep the jargon

Any kind of framework.  Policies, axioms, etc.  A bit of a stretch.

> Good understandable specs are sometimes allowed to speak.

Here is the potential seed of compromise.

>>> import compiler
>>> compiler.suite( 'tok1 id2' )
Module(None, Stmt([Name('a')), Name('b'))]))

The ASTVisitor raises a SyntaxError prior to execution.







From taleinat at gmail.com  Sun May 13 11:07:44 2007
From: taleinat at gmail.com (Tal Einat)
Date: Sun, 13 May 2007 12:07:44 +0300
Subject: [Python-ideas] Alternate quote delimiters
In-Reply-To: <464662D3.9020406@canterbury.ac.nz>
References: <4644D80B.4080806@ronadam.com>
	<fb6fbf560705120911y53960a64j9940f8bc9bb7bb0a@mail.gmail.com>
	<464662D3.9020406@canterbury.ac.nz>
Message-ID: <7afdee2f0705130207v144f033fm5468ad2ba432fe29@mail.gmail.com>

On 5/13/07, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
>
> Jim Jewett wrote:
>
> > How serious is this problem?
> >
> >     r"The Windows path is C:\Foo\Bar\Baz\X"[:-1]
> >
> > is awkward, but ... how much complexity do we want to incur avoiding it?
>
> If you use os.path.join and friends to manipulate your
> paths (as you should!) you will hardly ever have to deal
> with a path containing a trailing backslash in the first
> place. So I wouldn't worry about it much.


When learning Python, new users often get bitten by this. Simple learning
exercises often leave os.path for later, and use simpler hard-coded file
paths instead. When teaching Python, this is one more sharp edge I'm forced
to warn new users about.

I also hear people complaining about this when using Python for simple
automation scripts, where hard-coded paths are common, and using os.path can
easily double the amount of code and its complexity for no extra
functionality.

(Yes, the [:-1] hack works, but it's ugly, and Python should be beautiful.)

I'm sure the "completely remove escapes from raw strings" PEP will solve
this issue, and I'm looking forward to it.

- Tal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070513/8328c020/attachment.html>

From castironpi at comcast.net  Sun May 13 22:27:59 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Sun, 13 May 2007 15:27:59 -0500
Subject: [Python-ideas] parser in stdlib
In-Reply-To: <20070511042520.19A5E1E4003@bag.python.org>
Message-ID: <20070513202808.E6B011E4007@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces+castironpi=comcast.net at python.org
> [mailto:python-ideas-bounces+castironpi=comcast.net at python.org] On Behalf
> Of Aaron Brady
> 
> > -----Original Message-----
> > From: python-ideas-bounces at python.org [mailto:python-ideas-
> > bounces at python.org] On Behalf Of Terry Reedy
> > [snip]
> 
> I've very much looked into it.  In fact, it gave rise to the follow-up
> idea
> of attaching a `firstlineno' attribute to class objects.  (18:12 American
> Central Time.)  Rather costly, 50% of the attributes, but stepping through
> the InteractiveCodeGenerator class hasn't failed yet.

This is better.  Inspect.getsource( AClass ) can be wrong.  Raise exceptions
before that happens.

import inspect
class A:
	b=1

class A:
	b=2

B=A
print inspect.getsource(B)

Output is:

class A:
        b=1

Which is not what I asked it.  Return candidates maybe?




From castironpi at comcast.net  Sun May 13 23:37:09 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Sun, 13 May 2007 16:37:09 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <fb6fbf560705120935y35407a55o892c928b7a75696f@mail.gmail.com>
Message-ID: <20070513213716.B115F1E400D@bag.python.org>

> -----Original Message-----
> From: Jim Jewett [mailto:jimjjewett at gmail.com]
> Sent: Saturday, May 12, 2007 11:36 AM
> 
>     def f(val=object()):
>         if defaulted val:

Might this create a option to omit required parameters too?



From castironpi at comcast.net  Mon May 14 00:50:55 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Sun, 13 May 2007 17:50:55 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <7afdee2f0705111714s60118d8cuc219765830b3f59f@mail.gmail.com>
Message-ID: <20070513225103.BE04B1E400A@bag.python.org>



> -----Original Message-----
> From: Tal Einat [mailto:taleinat at gmail.com]
> Sent: Friday, May 11, 2007 7:15 PM
> >
> > MenuBarItem = MainMenuBar.Controls.Add(
> >     Office.MsoControlType.msoControlPopup,
> >     Type.Missing, Type.Missing, Type.Missing, true);

MenuBarItem = MainMenuBar.Controls.Add(
     *[Office.MsoControlType.msoControlPopup] +
     [Type.Missing]*3 + [true]);

> > Excel.Application excelApp = new Excel.ApplicationClass ();
> > Excel.Workbook thisWorkbook =
> > excelApp.Workbooks.Open(strFileName,Type.Missing, Type.Missing,
> > Type.Missing, Type.Missing,Type.Missing, Type.Missing,
> Type.Missing,
> > Type.Missing,Type.Missing , Type.Missing, Type.Missing,
> > Type.Missing,Type.Missing, Type.Missing);

Excel.Workbook thisWorkbook =
excelApp.Workbooks.Open( *[strFileName] + [Type.Missing]*14 );



From rrr at ronadam.com  Mon May 14 01:57:24 2007
From: rrr at ronadam.com (Ron Adam)
Date: Sun, 13 May 2007 18:57:24 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070509202544.CC7471E4002@bag.python.org>
References: <20070509202544.CC7471E4002@bag.python.org>
Message-ID: <4647A5E4.5070300@ronadam.com>

Aaron Brady wrote:
> Is it possible to signal to a parameter to use its default?
>  
> 
> def f( a, b=None, c=?? ):...
> 
> f( 123, <def>, ?abc? )
> 
> f( 123, ObjA, <def> )
> 
>   
> Did I miss something, plus did you cover it before?

You might be able to make a decorator that handles this the way you describe.


It might look something like the following.


class DefaultValue(object):
    """  An signal object. """
    pass
DfV = DefaultValue()    # Default value signal object


def defaults(*args):
    " a decorator that assigns and checks defaults values."
    ...


@defaults(None, None, '')
def f(a, b, c):
    return a, b, c


Then you could do as you wrote above and get something like...

 >>> f(123, DfV, 'abc')
123, None, 'abc'

 >>> f(123, ObjA, DfV)
123, <OjbA>, ''


I'll leave the actual implementation to you.


It might be useful in cases where you want the calling signature to look 
alike for a group of dispatched functions and the added overhead the 
decorator adds isn't a problem.  But you probably wouldn't want that 
overhead all the time, so having it as an optional decorator would be good.

Cheers,
    Ron










From castironpi at comcast.net  Mon May 14 02:32:08 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Sun, 13 May 2007 19:32:08 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <4647A5E4.5070300@ronadam.com>
Message-ID: <20070514003216.278961E4007@bag.python.org>

> -----Original Message-----
> From: Ron Adam [mailto:rrr at ronadam.com]
> Sent: Sunday, May 13, 2007 6:57 PM
> To: Aaron Brady; python-ideas at python.org
> Subject: Re: [Python-ideas] parameter omit
> 
> Aaron Brady wrote:
> [snip]
> 
> You might be able to make a decorator that handles this the way you
> describe.
> 
> 
> It might look something like the following.
> [snip]
> @defaults(None, None, '')
> def f(a, b, c):
>     return a, b, c

Great ideas.  It turned out really nicely.

class GuardDefault:
	Val= object()
	def __call__( self, *args, **kwargs ):
		args=list(args)
		for i,j in enumerate( args ):
			if j is GuardDefault.Val:
				offset=
self.callable.func_code.co_argcount-\
					len(self.callable.func_defaults)
				args[i]=
self.callable.func_defaults[i-offset]
		return self.callable( *args,**kwargs )
	def __init__( self,callable ):
		self.callable= callable

@GuardDefault
def f( a,b=None,c='abc' ):
   print a,b,c

f( 0,GuardDefault.Val,'def' )
f( 0,'somebody',GuardDefault.Val )

gives:

0 None def
0 somebody abc



From castironpi at comcast.net  Mon May 14 03:09:48 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Sun, 13 May 2007 20:09:48 -0500
Subject: [Python-ideas] python appreciation site
Message-ID: <20070514010956.2423B1E4007@bag.python.org>

This is a joke, for austerity.

http://home.comcast.net/~castironpi/pythonappr.html



From adam at atlas.st  Mon May 14 03:26:57 2007
From: adam at atlas.st (Adam Atlas)
Date: Sun, 13 May 2007 21:26:57 -0400
Subject: [Python-ideas] python appreciation site
In-Reply-To: <20070514010956.2423B1E4007@bag.python.org>
References: <20070514010956.2423B1E4007@bag.python.org>
Message-ID: <D07C9D13-4474-45EE-B6EF-E7FD82ED1133@atlas.st>


On 13 May 2007, at 21.09, Aaron Brady wrote:
> This is a joke, for austerity.
>
> http://home.comcast.net/~castironpi/pythonappr.html

Nice! I think that deserves to go on <http://www.python.org/doc/ 
Humor.html>.

My favourite is the Cobol one. :)


From castironpi at comcast.net  Mon May 14 04:28:23 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Sun, 13 May 2007 21:28:23 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070514003216.278961E4007@bag.python.org>
Message-ID: <20070514022832.0638E1E4007@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Aaron Brady
> 
> class GuardDefault:
> 	Val= object()
> 	def __call__( self, *args, **kwargs ):
> 		args=list(args)
> 		for i,j in enumerate( args ):
> 			if j is GuardDefault.Val:
> 				offset=
> self.callable.func_code.co_argcount-\
> 					len(self.callable.func_defaults)
> 				args[i]=
> self.callable.func_defaults[i-offset]
> 		return self.callable( *args,**kwargs )
> 	def __init__( self,callable ):
> 		self.callable= callable

Do you have any interest in pursuing this?



From castironpi at comcast.net  Mon May 14 08:19:36 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Mon, 14 May 2007 01:19:36 -0500
Subject: [Python-ideas] python appreciation site
In-Reply-To: <D07C9D13-4474-45EE-B6EF-E7FD82ED1133@atlas.st>
Message-ID: <20070514061945.DBAE41E4009@bag.python.org>


> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Adam Atlas
> Sent: Sunday, May 13, 2007 8:27 PM
> To: Python-Ideas
> Subject: Re: [Python-ideas] python appreciation site
> 
> 
> On 13 May 2007, at 21.09, Aaron Brady wrote:
> > This is a joke, for austerity.
> >
> > http://home.comcast.net/~castironpi/pythonappr.html
> 
> Nice! I think that deserves to go on <http://www.python.org/doc/
> Humor.html>.
> 
> My favourite is the Cobol one. :)
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
Put it up there!



From rajb at rice.edu  Mon May 14 18:53:11 2007
From: rajb at rice.edu (Raj B)
Date: Mon, 14 May 2007 11:53:11 -0500
Subject: [Python-ideas] Function/method call issues
Message-ID: <AAD8D5AB-96A1-4503-A90B-B037CAFA13EB@rice.edu>

Hello everyone,

First of all, I'll introduce myself. I've been working on a Python  
compiler written in OCaml for about a year now. Some of you might  
know me from my talk at Google. One of the list members suggested  
this mailing list as a good forum for discussion and bouncing ideas.

I think that one issue to consider are the complex semantics of  
functions and method calls. Whenever a function call is made, there  
is a lot of checking involved as to 'where' the function is called  
from: i.e. whether it's a user-defined function/method, a built-in  
function/method, a class function/method or an instance function/ 
method. Just reading the reference manual section on 'function  
objects' is enough to see how many different cases are there.

Of course, this provides tons of flexibility in reusing the same code  
for different ways. However, it increases the amount of book-keeping  
and pre-processing required for a call. For example, Consider an  
object that implements methods 'str' and 'append' (the list object,  
for instance). During retrieval of methods, the following default  
retrieval method is called (in OCaml syntax, a simplified version).

let list_getattr o attr =
	let v = get o.dict attr in (* lookup the attribute in the dictionary *)

	match attr with
	| String "append" | ... | ->
				v.instance = o; v (* set the method's instance to o
								   before returning it *)

	| _ -> v            (* else return the method object as is *)

So basically, I have to check for two cases based on the actual names  
of the methods being called. This seems like extra work for the runtime.

As a suggestion, I think that adopting a single calling convention  
(either 'x.foo()' or 'foo(x)') would have 2 advantages.

1) It would make it easier for users and make for more readable code.  
I still find myself having to refer to the docs to find out how a  
method needs to be called.
2) It would improve performance by reducing these checks shown above  
to one case.

What do y'all think? Would this sacrifice too much flexibility? If  
this topic has been discussed on this list before, please feel free  
to point me there.

Thank you
Raj


From tjreedy at udel.edu  Mon May 14 20:41:47 2007
From: tjreedy at udel.edu (Terry Reedy)
Date: Mon, 14 May 2007 14:41:47 -0400
Subject: [Python-ideas] Function/method call issues
References: <AAD8D5AB-96A1-4503-A90B-B037CAFA13EB@rice.edu>
Message-ID: <f2aah9$9s7$1@sea.gmane.org>


"Raj B" <rajb at rice.edu> wrote in message 
news:AAD8D5AB-96A1-4503-A90B-B037CAFA13EB at rice.edu...
| Hello everyone,
|
| First of all, I'll introduce myself. I've been working on a Python
| compiler written in OCaml for about a year now. Some of you might
| know me from my talk at Google. One of the list members suggested
| this mailing list as a good forum for discussion and bouncing ideas.
|
| I think that one issue to consider are the complex semantics of
| functions and method calls. Whenever a function call is made, there
| is a lot of checking involved as to 'where' the function is called
| from: i.e. whether it's a user-defined function/method, a built-in
| function/method, a class function/method or an instance function/
| method. Just reading the reference manual section on 'function
| objects' is enough to see how many different cases are there.
|
| Of course, this provides tons of flexibility in reusing the same code
| for different ways. However, it increases the amount of book-keeping
| and pre-processing required for a call. For example, Consider an
| object that implements methods 'str' and 'append' (the list object,
| for instance). During retrieval of methods, the following default
| retrieval method is called (in OCaml syntax, a simplified version).
|
| let list_getattr o attr =
| let v = get o.dict attr in (* lookup the attribute in the dictionary *)
|
| match attr with
| | String "append" | ... | ->
| v.instance = o; v (* set the method's instance to o
|    before returning it *)
|
| | _ -> v            (* else return the method object as is *)

I cannot understand above, even 'simplified'.

| So basically, I have to check for two cases based on the actual names
| of the methods being called. This seems like extra work for the runtime.
|
| As a suggestion, I think that adopting a single calling convention
| (either 'x.foo()' or 'foo(x)') would have 2 advantages.

If foo is an instance method, the latter has to be x.__class__.foo(x).
There is no way to disallow the latter; but the former is much easier.

| 1) It would make it easier for users and make for more readable code.
| I still find myself having to refer to the docs to find out how a
| method needs to be called.

I do not understand 'needs'.  Any instance method can be called either way, 
with the first much easier.  Knowing about the second is mainly needed to 
understand why instance methods all have a self parameter.

| 2) It would improve performance by reducing these checks shown above
| to one case.

tjr





From jcarlson at uci.edu  Mon May 14 20:53:11 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Mon, 14 May 2007 11:53:11 -0700
Subject: [Python-ideas] Function/method call issues
In-Reply-To: <AAD8D5AB-96A1-4503-A90B-B037CAFA13EB@rice.edu>
References: <AAD8D5AB-96A1-4503-A90B-B037CAFA13EB@rice.edu>
Message-ID: <20070514114644.855C.JCARLSON@uci.edu>


Raj B <rajb at rice.edu> wrote:
> 1) It would make it easier for users and make for more readable code.  
> I still find myself having to refer to the docs to find out how a  
> method needs to be called.
> 2) It would improve performance by reducing these checks shown above  
> to one case.

foo(x) means one thing.  x.foo() means another.  Trying to merge them
for the sake of "consistency" will only confuse everyone who has been
using method calling (x.foo()) to call methods on an object (making
every function call into a generic function that users don't know if it
is really just a generic function, or a method caller), or will give all
objects in which you want to call the function foo() on have a method
x.foo() (making every method call indistinguishable as to whether you
are calling the function foo with argument x, or method foo on object x).

While it may make it easier for you to implement in OCaml, it makes no
sense in terms of Python sementics that are understood by basically
everyone for at least 10 years.


 - Josiah



From rajb at rice.edu  Mon May 14 21:52:53 2007
From: rajb at rice.edu (Raj B)
Date: Mon, 14 May 2007 14:52:53 -0500
Subject: [Python-ideas] Function/method call issues
In-Reply-To: <20070514114644.855C.JCARLSON@uci.edu>
References: <AAD8D5AB-96A1-4503-A90B-B037CAFA13EB@rice.edu>
	<20070514114644.855C.JCARLSON@uci.edu>
Message-ID: <38D88956-0540-4EC1-87D3-E15736A2D312@rice.edu>


Well, this definitely makes no difference to me to implement in OCaml  
or any other language. I'm implementing exactly how Python behaves,  
so whether it's easy or difficult is not really the question.

Consider the list object (listobject.c). In CPython, the 'repr'  
method for integers is implemented by the 'list_repr' function  and  
the 'insert operation is implemented by 'listinsert', which in turn  
is part of the 'list_as_sequence' set of methods. So it both 'repr'  
and 'insert' are implemented as 'methods'. However, the Python  
convention is that 'repr' is called as repr(l) whereas insert would  
be l.insert(i,v), with l passed implicitly.

In both cases, they are performing almost the same amount of work in  
looking up a function in a PyObject structure (with two lookups for  
'repr' and three for 'insert'). Obviously there is a design/ 
implementation/philosophical decision that one is a generic function  
and the other is a method call. However, the implementation has to do  
2 different things based on the name of the function to be called,  
even though they are both part of the same object structure. I was  
wondering why it was necessary to do it that way.

Thanks
Raj


On May 14, 2007, at 1:53 PM, Josiah Carlson wrote:

>
> Raj B <rajb at rice.edu> wrote:
>> 1) It would make it easier for users and make for more readable code.
>> I still find myself having to refer to the docs to find out how a
>> method needs to be called.
>> 2) It would improve performance by reducing these checks shown above
>> to one case.
>
> foo(x) means one thing.  x.foo() means another.  Trying to merge them
> for the sake of "consistency" will only confuse everyone who has been
> using method calling (x.foo()) to call methods on an object (making
> every function call into a generic function that users don't know  
> if it
> is really just a generic function, or a method caller), or will  
> give all
> objects in which you want to call the function foo() on have a method
> x.foo() (making every method call indistinguishable as to whether you
> are calling the function foo with argument x, or method foo on  
> object x).
>
> While it may make it easier for you to implement in OCaml, it makes no
> sense in terms of Python sementics that are understood by basically
> everyone for at least 10 years.
>
>
>  - Josiah

--
When you are not cute, you've got to be clever
						-- David Sedaris






From jcarlson at uci.edu  Mon May 14 22:23:56 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Mon, 14 May 2007 13:23:56 -0700
Subject: [Python-ideas] Function/method call issues
In-Reply-To: <38D88956-0540-4EC1-87D3-E15736A2D312@rice.edu>
References: <20070514114644.855C.JCARLSON@uci.edu>
	<38D88956-0540-4EC1-87D3-E15736A2D312@rice.edu>
Message-ID: <20070514130706.8566.JCARLSON@uci.edu>


Please don't top post, it unnecessarily removes context for replies that
help in understanding (most people read top to bottom, not bottom to top).

Raj B <rajb at rice.edu> wrote:
> Well, this definitely makes no difference to me to implement in OCaml  
> or any other language. I'm implementing exactly how Python behaves,  
> so whether it's easy or difficult is not really the question.
> 
> Consider the list object (listobject.c). In CPython, the 'repr'  
> method for integers is implemented by the 'list_repr' function  and  

(repr(5) is implemented as int_repr() in intobject.c)

> the 'insert operation is implemented by 'listinsert', which in turn  
> is part of the 'list_as_sequence' set of methods. So it both 'repr'  
> and 'insert' are implemented as 'methods'. However, the Python  
> convention is that 'repr' is called as repr(l) whereas insert would  
> be l.insert(i,v), with l passed implicitly.

You are not going to change the oft-discussed, long-time established
__magic__ method and magic() builtins.  That is to say, certain builtin
functions (and some operations) result in a method invocation of
obj.__magic__() (sometimes with additional arguments).  This is not
going to change.  Please see the various Python 3.0 PEPs.  Among those
are len(), repr(), etc., as well as functions listed in operator module.

Why?  Generally, finding the length of an object has been defined to be
discovered by len(obj).  While it is internally translated into
obj.__len__(), this is to allow for user methods to take on names that
could otherwise clash with standard methods.


> In both cases, they are performing almost the same amount of work in  
> looking up a function in a PyObject structure (with two lookups for  
> 'repr' and three for 'insert'). Obviously there is a design/ 
> implementation/philosophical decision that one is a generic function  
> and the other is a method call. However, the implementation has to do  
> 2 different things based on the name of the function to be called,  
> even though they are both part of the same object structure. I was  
> wondering why it was necessary to do it that way.

Convenience, flexibility, established semantics, etc.  To change it
would be a major language overhaul for little (if any, if not negative)
Python user gains.


 - Josiah

> On May 14, 2007, at 1:53 PM, Josiah Carlson wrote:
> 
> >
> > Raj B <rajb at rice.edu> wrote:
> >> 1) It would make it easier for users and make for more readable code.
> >> I still find myself having to refer to the docs to find out how a
> >> method needs to be called.
> >> 2) It would improve performance by reducing these checks shown above
> >> to one case.
> >
> > foo(x) means one thing.  x.foo() means another.  Trying to merge them
> > for the sake of "consistency" will only confuse everyone who has been
> > using method calling (x.foo()) to call methods on an object (making
> > every function call into a generic function that users don't know  
> > if it
> > is really just a generic function, or a method caller), or will  
> > give all
> > objects in which you want to call the function foo() on have a method
> > x.foo() (making every method call indistinguishable as to whether you
> > are calling the function foo with argument x, or method foo on  
> > object x).
> >
> > While it may make it easier for you to implement in OCaml, it makes no
> > sense in terms of Python sementics that are understood by basically
> > everyone for at least 10 years.
> >
> >
> >  - Josiah
> 
> --
> When you are not cute, you've got to be clever
> 						-- David Sedaris
> 



From castironpi at comcast.net  Tue May 15 08:45:32 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 15 May 2007 01:45:32 -0500
Subject: [Python-ideas] parameter omit
Message-ID: <20070515064546.663581E4016@bag.python.org>

> -----Original Message-----
> From: Aaron Brady [mailto:castironpi at comcast.net]
> Sent: Sunday, May 13, 2007 9:28 PM
> 
> > -----Original Message-----
> > From: python-ideas-bounces at python.org [mailto:python-ideas-
> > bounces at python.org] On Behalf Of Aaron Brady
> >
> > class GuardDefault:
> > 	Val= object()
> > 	def __call__( self, *args, **kwargs ):
> > 		args=list(args)
> > 		for i,j in enumerate( args ):
> > 			if j is GuardDefault.Val:
> > 				offset=
> > self.callable.func_code.co_argcount-\
> > 					len(self.callable.func_defaults)
> > 				args[i]=
> > self.callable.func_defaults[i-offset]
> > 		return self.callable( *args,**kwargs )
> > 	def __init__( self,callable ):
> > 		self.callable= callable
> 
> Do you have any interest in pursuing this?

Actually not too bad for functools.  Does this take a proposal?  -I- am
God-awful at lengthy technical writing.



From steven.bethard at gmail.com  Tue May 15 08:53:46 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Tue, 15 May 2007 00:53:46 -0600
Subject: [Python-ideas] parameter omit
In-Reply-To: <20070515064546.663581E4016@bag.python.org>
References: <20070515064546.663581E4016@bag.python.org>
Message-ID: <d11dcfba0705142353w3d635434h16c91f320ee24f1b@mail.gmail.com>

On 5/15/07, Aaron Brady <castironpi at comcast.net> wrote:
> > -----Original Message-----
> > From: Aaron Brady [mailto:castironpi at comcast.net]
> > Sent: Sunday, May 13, 2007 9:28 PM
> >
> > > -----Original Message-----
> > > From: python-ideas-bounces at python.org [mailto:python-ideas-
> > > bounces at python.org] On Behalf Of Aaron Brady
> > >
> > > class GuardDefault:
> > >     Val= object()
> > >     def __call__( self, *args, **kwargs ):
> > >             args=list(args)
> > >             for i,j in enumerate( args ):
> > >                     if j is GuardDefault.Val:
> > >                             offset=
> > > self.callable.func_code.co_argcount-\
> > >                                     len(self.callable.func_defaults)
> > >                             args[i]=
> > > self.callable.func_defaults[i-offset]
> > >             return self.callable( *args,**kwargs )
> > >     def __init__( self,callable ):
> > >             self.callable= callable
> >
> > Do you have any interest in pursuing this?
>
> Actually not too bad for functools.  Does this take a proposal?  -I- am
> God-awful at lengthy technical writing.

You might be able to get away without a PEP, but you'll definitely
need to post an implementation patch to the bug tracker
(http://sourceforge.net/tracker/?group_id=5470&atid=105470).  Once
you've posted your implementation, you should send an email to
python-dev asking folks what they think about it.  Be sure to give
some code examples that using this decorator would simplify.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From rrr at ronadam.com  Tue May 15 14:39:22 2007
From: rrr at ronadam.com (Ron Adam)
Date: Tue, 15 May 2007 07:39:22 -0500
Subject: [Python-ideas] parameter omit
In-Reply-To: <200705142344234.SM01928@sccrmhc11.comcast.net>
References: <200705142344234.SM01928@sccrmhc11.comcast.net>
Message-ID: <4649A9FA.7030208@ronadam.com>

Aaron Brady wrote:
>> -----Original Message-----
>> From: Aaron Brady [mailto:castironpi at comcast.net]
>> Sent: Sunday, May 13, 2007 9:28 PM
>>
>>> -----Original Message-----
>>> From: python-ideas-bounces at python.org [mailto:python-ideas-
>>> bounces at python.org] On Behalf Of Aaron Brady
>>>
>>> class GuardDefault:
>>> 	Val= object()
>>> 	def __call__( self, *args, **kwargs ):
>>> 		args=list(args)
>>> 		for i,j in enumerate( args ):
>>> 			if j is GuardDefault.Val:
>>> 				offset=
>>> self.callable.func_code.co_argcount-\
>>> 					len(self.callable.func_defaults)
>>> 				args[i]=
>>> self.callable.func_defaults[i-offset]
>>> 		return self.callable( *args,**kwargs )
>>> 	def __init__( self,callable ):
>>> 		self.callable= callable
>> Do you have any interest in pursuing this?
> 
> Actually not too bad for functools.  Does this take a proposal?  -I- am
> God-awful at lengthy technical writing.

I suggest you post it on the python-list firsts and see what others think. 
      They may offer alternative ways of doing it that will make it better 
based on how they will used it.

Cheers,
    Ron



From ian.bollinger at gmail.com  Tue May 15 16:53:57 2007
From: ian.bollinger at gmail.com (Ian D. Bollinger)
Date: Tue, 15 May 2007 10:53:57 -0400
Subject: [Python-ideas] Have list/deque grow a copy() method
Message-ID: <4649C985.7050100@gmail.com>

It would be nice if containers had a more consistent interface. The
standard idiom for copying a list has been L[:], but this isn't
polymorphic and perhaps arcane. Also, deques can only be copied with the
copy module's copy function (or calling the __copy__ wrapper directly);
thus using copy.copy is the only polymorphic way to copy a mutable
container. Additionally, having a consistent interface for mutable
containers may dovetail with the ABC PEP.

An alternate proposal would be to move copy.copy (and perhaps
copy.deepcopy) into __builtins__. (Though this might be nice
regardless.)

As an aside, in addition to the copy method, list is the only mutable
container not to have a clear method. Of course, del L[:] is the
standard idiom for doing so, but this has the same problem of not being
polymorphic. Perhaps having both del L[:] and L.clear() would violate
the TOOWTDI principle, but L.reverse() can also be done with L = L[::-1]
(maybe not the best example since they have different semantics.)
Nevertheless, one is a lot easier to read.

As for a use case, one might be a class that generalizes how it stores
elements.  For instance...

class MutableUnorderedTree(AbstractTree):
    _storage_class = set

class MutableOrderedTree(AbstractTree):
    _storage_class = list

...the latter has to be adapted to ensure consistent interface for
methods like copy/clear.

Well, that's my crackpot idea for today.
- Ian D. Bolligner



From jcarlson at uci.edu  Tue May 15 17:11:58 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 15 May 2007 08:11:58 -0700
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <4649C985.7050100@gmail.com>
References: <4649C985.7050100@gmail.com>
Message-ID: <20070515080638.8569.JCARLSON@uci.edu>


"Ian D. Bollinger" <ian.bollinger at gmail.com> wrote:
> It would be nice if containers had a more consistent interface. The
> standard idiom for copying a list has been L[:], but this isn't

The standard way of copying a list (or producing a list from an
arbitrary sequence) is list(L).

> polymorphic and perhaps arcane. Also, deques can only be copied with the
> copy module's copy function (or calling the __copy__ wrapper directly);

No, you can use deque(D).

> As an aside, in addition to the copy method, list is the only mutable
> container not to have a clear method. Of course, del L[:] is the
> standard idiom for doing so, but this has the same problem of not being
> polymorphic. Perhaps having both del L[:] and L.clear() would violate
> the TOOWTDI principle, but L.reverse() can also be done with L = L[::-1]
> (maybe not the best example since they have different semantics.)
> Nevertheless, one is a lot easier to read.

I'm -0 on list.clear(), but can see why people would prefer it over del
L[:] .


Regarding your main proposal of inserting copy.copy into the builtins,
I'm -1.  Using the object constructors themselves as copying/creation
procedures is generally seen to be a good practice, as it also typically
allows users to pass *any* iterable and have it end up in a format that
the recipient of the data wants.


 - Josiah



From g.brandl at gmx.net  Tue May 15 17:10:35 2007
From: g.brandl at gmx.net (Georg Brandl)
Date: Tue, 15 May 2007 17:10:35 +0200
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <20070515080638.8569.JCARLSON@uci.edu>
References: <4649C985.7050100@gmail.com> <20070515080638.8569.JCARLSON@uci.edu>
Message-ID: <f2cihh$hu4$1@sea.gmane.org>

Josiah Carlson schrieb:
> "Ian D. Bollinger" <ian.bollinger at gmail.com> wrote:
>> It would be nice if containers had a more consistent interface. The
>> standard idiom for copying a list has been L[:], but this isn't
> 
> The standard way of copying a list (or producing a list from an
> arbitrary sequence) is list(L).

The first part is news to me. Who defined that standard?

Georg



From fdrake at acm.org  Tue May 15 17:21:44 2007
From: fdrake at acm.org (Fred L. Drake, Jr.)
Date: Tue, 15 May 2007 11:21:44 -0400
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <4649C985.7050100@gmail.com>
References: <4649C985.7050100@gmail.com>
Message-ID: <200705151121.45297.fdrake@acm.org>

On Tuesday 15 May 2007, Ian D. Bollinger wrote:
 > It would be nice if containers had a more consistent interface. The
 > standard idiom for copying a list has been L[:], but this isn't
 > polymorphic and perhaps arcane. Also, deques can only be copied with the
 > copy module's copy function (or calling the __copy__ wrapper directly);
 > thus using copy.copy is the only polymorphic way to copy a mutable
 > container. Additionally, having a consistent interface for mutable
 > containers may dovetail with the ABC PEP.

copy.copy() and copy.deepcopy() have always been the only polymorphic ways to 
create copies.  Is there any real motivation not to just use them?

I've not found that I need a way to copy arbitrary objects very often, and 
haven't found the occaissional import of the copy module to be an 
obstruction.  Are you needing to create lots of copies for some reason?


  -Fred

-- 
Fred L. Drake, Jr.   <fdrake at acm.org>


From steven.bethard at gmail.com  Tue May 15 17:48:13 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Tue, 15 May 2007 09:48:13 -0600
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <200705151121.45297.fdrake@acm.org>
References: <4649C985.7050100@gmail.com> <200705151121.45297.fdrake@acm.org>
Message-ID: <d11dcfba0705150848m70d982d4x63a45d6b4a9b6ad1@mail.gmail.com>

On 5/15/07, Fred L. Drake, Jr. <fdrake at acm.org> wrote:
> On Tuesday 15 May 2007, Ian D. Bollinger wrote:
>  > It would be nice if containers had a more consistent interface. The
>  > standard idiom for copying a list has been L[:], but this isn't
>  > polymorphic and perhaps arcane. Also, deques can only be copied with the
>  > copy module's copy function (or calling the __copy__ wrapper directly);
>  > thus using copy.copy is the only polymorphic way to copy a mutable
>  > container. Additionally, having a consistent interface for mutable
>  > containers may dovetail with the ABC PEP.
>
> copy.copy() and copy.deepcopy() have always been the only polymorphic ways to
> create copies.

For builtin container types (and many other container types as well):
    type(obj)(obj)
is another polymorphic way to create copies.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From fdrake at acm.org  Tue May 15 18:06:49 2007
From: fdrake at acm.org (Fred L. Drake, Jr.)
Date: Tue, 15 May 2007 12:06:49 -0400
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <d11dcfba0705150848m70d982d4x63a45d6b4a9b6ad1@mail.gmail.com>
References: <4649C985.7050100@gmail.com> <200705151121.45297.fdrake@acm.org>
	<d11dcfba0705150848m70d982d4x63a45d6b4a9b6ad1@mail.gmail.com>
Message-ID: <200705151206.50034.fdrake@acm.org>

On Tuesday 15 May 2007, Steven Bethard wrote:
 > For builtin container types (and many other container types as well):
 >     type(obj)(obj)
 > is another polymorphic way to create copies.

If you're willing to rely on the constructor signature, sure.  For many 
applications, the convention that the constructor can be used as a copier 
doesn't hold.


  -Fred

-- 
Fred L. Drake, Jr.   <fdrake at acm.org>


From jcarlson at uci.edu  Tue May 15 22:47:09 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 15 May 2007 13:47:09 -0700
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <200705151206.50034.fdrake@acm.org>
References: <d11dcfba0705150848m70d982d4x63a45d6b4a9b6ad1@mail.gmail.com>
	<200705151206.50034.fdrake@acm.org>
Message-ID: <20070515134615.8572.JCARLSON@uci.edu>


"Fred L. Drake, Jr." <fdrake at acm.org> wrote:
> 
> On Tuesday 15 May 2007, Steven Bethard wrote:
>  > For builtin container types (and many other container types as well):
>  >     type(obj)(obj)
>  > is another polymorphic way to create copies.
> 
> If you're willing to rely on the constructor signature, sure.  For many 
> applications, the convention that the constructor can be used as a copier 
> doesn't hold.

But for builtin types (which is the only objects we can reliably change),
using the base constructor to copy an object *does* work for all
container types (except for defaultdict).

 - Josiah



From jcarlson at uci.edu  Tue May 15 22:54:07 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 15 May 2007 13:54:07 -0700
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <f2cihh$hu4$1@sea.gmane.org>
References: <20070515080638.8569.JCARLSON@uci.edu> <f2cihh$hu4$1@sea.gmane.org>
Message-ID: <20070515134716.8575.JCARLSON@uci.edu>


Georg Brandl <g.brandl at gmx.net> wrote:
> Josiah Carlson schrieb:
> > "Ian D. Bollinger" <ian.bollinger at gmail.com> wrote:
> >> It would be nice if containers had a more consistent interface. The
> >> standard idiom for copying a list has been L[:], but this isn't
> > 
> > The standard way of copying a list (or producing a list from an
> > arbitrary sequence) is list(L).
> 
> The first part is news to me. Who defined that standard?

No one needs to define a standard for it to be the standard.  How would
you propose, generally, to convert some arbitrary sequence into a list?
Would you use a list comprehension: [i for i in seq] ?  Would you use a
generator expression passed to a list: list(i for i in seq) ?  Or would
you just use list(seq)?  Me, I prefer simplicity and the case that works
the way I usually need it to: list(seq).  Conveniently, this works for
list(dct), list(lst), list(deq), list(st), list(uni), list(tup),
list(ite), ...  To not use list(obj) when you can would seem to me to be
an anti-pattern, regardless of the minor opimization that can be had in
lst[:] copying.

This technique is also going to be used in the 2to3 conversion utility
to convert range() calls to list(range()) calls, and I am honestly
baffled by anyone asking, "how do I copy a list, deque, dictionary,...". 
How could one *not* look at the base constructors?

 - Josiah



From g.brandl at gmx.net  Tue May 15 22:54:41 2007
From: g.brandl at gmx.net (Georg Brandl)
Date: Tue, 15 May 2007 22:54:41 +0200
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <20070515134716.8575.JCARLSON@uci.edu>
References: <20070515080638.8569.JCARLSON@uci.edu> <f2cihh$hu4$1@sea.gmane.org>
	<20070515134716.8575.JCARLSON@uci.edu>
Message-ID: <f2d6mm$2ep$1@sea.gmane.org>

Josiah Carlson schrieb:
> Georg Brandl <g.brandl at gmx.net> wrote:
>> Josiah Carlson schrieb:
>> > "Ian D. Bollinger" <ian.bollinger at gmail.com> wrote:
>> >> It would be nice if containers had a more consistent interface. The
>> >> standard idiom for copying a list has been L[:], but this isn't
>> > 
>> > The standard way of copying a list (or producing a list from an
>> > arbitrary sequence) is list(L).
>> 
>> The first part is news to me. Who defined that standard?
> 
> No one needs to define a standard for it to be the standard.  How would
> you propose, generally, to convert some arbitrary sequence into a list?

No, I meant the "copying a list" part. Getting a list from an iterable is
easiest with list(), of course.

Georg



From jcarlson at uci.edu  Tue May 15 23:12:16 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 15 May 2007 14:12:16 -0700
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <f2d6mm$2ep$1@sea.gmane.org>
References: <20070515134716.8575.JCARLSON@uci.edu> <f2d6mm$2ep$1@sea.gmane.org>
Message-ID: <20070515140958.8578.JCARLSON@uci.edu>


Georg Brandl <g.brandl at gmx.net> wrote:
> Josiah Carlson schrieb:
> > Georg Brandl <g.brandl at gmx.net> wrote:
> >> Josiah Carlson schrieb:
> >> > "Ian D. Bollinger" <ian.bollinger at gmail.com> wrote:
> >> >> It would be nice if containers had a more consistent interface. The
> >> >> standard idiom for copying a list has been L[:], but this isn't
> >> > 
> >> > The standard way of copying a list (or producing a list from an
> >> > arbitrary sequence) is list(L).
> >> 
> >> The first part is news to me. Who defined that standard?
> > 
> > No one needs to define a standard for it to be the standard.  How would
> > you propose, generally, to convert some arbitrary sequence into a list?
> 
> No, I meant the "copying a list" part. Getting a list from an iterable is
> easiest with list(), of course.

I choose as standard what works in the most cases.  Since list() works
everywhere, using it on lists makes the most sense to me.

 - Josiah



From castironpi at comcast.net  Wed May 16 12:54:53 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Wed, 16 May 2007 05:54:53 -0500
Subject: [Python-ideas] dot bend spoon
Message-ID: <20070516105510.26D531E4002@bag.python.org>

Is the going semantic to carry a relation:

spoon.bend()

or

johnson.bend( spoon ) ?

How to phrase this.  How do -you- do it?  Weird.  Because spoon.bend() is a
misnomer; construed to mean spoon.getsbent().  More in the predicate vs.
controller category.  Haven't got model-view-controller yet but I know the
term.



From adam at atlas.st  Wed May 16 14:21:46 2007
From: adam at atlas.st (Adam Atlas)
Date: Wed, 16 May 2007 08:21:46 -0400
Subject: [Python-ideas] dot bend spoon
In-Reply-To: <20070516105510.26D531E4002@bag.python.org>
References: <20070516105510.26D531E4002@bag.python.org>
Message-ID: <98B0F0E9-A048-4BD3-B72B-5779F78500BB@atlas.st>


On 16 May 2007, at 06.54, Aaron Brady wrote:
> Is the going semantic to carry a relation:
>
> spoon.bend()
>
> or
>
> johnson.bend( spoon ) ?

This is probably more appropriate for the usual comp.lang.python  
group rather than Python-ideas, no?

In any case, this would probably be an easier question to answer with  
a more realistic example.



From george.sakkis at gmail.com  Wed May 16 16:50:40 2007
From: george.sakkis at gmail.com (George Sakkis)
Date: Wed, 16 May 2007 10:50:40 -0400
Subject: [Python-ideas] Positional only arguments
Message-ID: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>

This was posted on python-dev two weeks ago [1] but didn't get very
far; probably python-ideas is a more appropriate list if this is to be
taken any further.

In short, PEP 3102 enables the declaration of keyword-only arguments,
making it easier for an API to grow in a backwards compatible way. As
Benji York, I see the utility of positional-only arguments, not just
for the sake of symmetry but for pragmatic reasons; in fact the same
reasons that serve as rationale to the keywords-only PEP.

I don't have any concrete proposal (syntactic or otherwise) at this
point, but I'd like to see this feature in Py3K even if I dislike the
specific syntax or other machinery that implements it (just like
decorators). For now it's worth just getting an idea of whether the
feature itself is deemed useful enough or the current status quo is
adequate.

George


[1] http://mail.python.org/pipermail/python-dev/2006-May/064790.html



-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."

Unknown


From guido at python.org  Wed May 16 17:09:26 2007
From: guido at python.org (Guido van Rossum)
Date: Wed, 16 May 2007 08:09:26 -0700
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
Message-ID: <ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>

+1 for the concept.

Personally, when I really wanted this, I've given the arguments names
like __foo.

--Guido

On 5/16/07, George Sakkis <george.sakkis at gmail.com> wrote:
> This was posted on python-dev two weeks ago [1] but didn't get very
> far; probably python-ideas is a more appropriate list if this is to be
> taken any further.
>
> In short, PEP 3102 enables the declaration of keyword-only arguments,
> making it easier for an API to grow in a backwards compatible way. As
> Benji York, I see the utility of positional-only arguments, not just
> for the sake of symmetry but for pragmatic reasons; in fact the same
> reasons that serve as rationale to the keywords-only PEP.
>
> I don't have any concrete proposal (syntactic or otherwise) at this
> point, but I'd like to see this feature in Py3K even if I dislike the
> specific syntax or other machinery that implements it (just like
> decorators). For now it's worth just getting an idea of whether the
> feature itself is deemed useful enough or the current status quo is
> adequate.
>
> George
>
>
> [1] http://mail.python.org/pipermail/python-dev/2006-May/064790.html
>
>
>
> --
> "If I have been able to see further, it was only because I stood on
> the shoulders of million monkeys."
>
> Unknown
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>


-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


From george.sakkis at gmail.com  Wed May 16 18:25:05 2007
From: george.sakkis at gmail.com (George Sakkis)
Date: Wed, 16 May 2007 12:25:05 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <464B2114.9030601@zope.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
	<464B2114.9030601@zope.com>
Message-ID: <91ad5bf80705160925p158dd8dbiff7919c352b81349@mail.gmail.com>

On 5/16/07, Benji York <benji at zope.com> wrote:

> Guido van Rossum wrote:
> > Personally, when I really wanted this, I've given the arguments names
> > like __foo.
>
> That could be enshrined as the syntax, much like "private" attributes.

What's the future of "private" attributes in Py3K ? I remember Raymond
Hettinger bringing up a challenge on c.l.py about a decorator that
could replace the double underscore mangling and Michele Simionato
caming up with a bytecode hack that showed it is possible.

If they're staying though, +epsilon for blessing __args as
positional-only (for some positive epsilon ;-)).

George

-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."


From taleinat at gmail.com  Wed May 16 18:29:15 2007
From: taleinat at gmail.com (Tal Einat)
Date: Wed, 16 May 2007 19:29:15 +0300
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
Message-ID: <7afdee2f0705160929v60e82fbcja948b0bb9e0f02f6@mail.gmail.com>

On 5/16/07, George Sakkis <george.sakkis at gmail.com> wrote:
>
> This was posted on python-dev two weeks ago [1] but didn't get very
> far; probably python-ideas is a more appropriate list if this is to be
> taken any further.
>
> In short, PEP 3102 enables the declaration of keyword-only arguments,
> making it easier for an API to grow in a backwards compatible way. As
> Benji York, I see the utility of positional-only arguments, not just
> for the sake of symmetry but for pragmatic reasons; in fact the same
> reasons that serve as rationale to the keywords-only PEP.
>
> I don't have any concrete proposal (syntactic or otherwise) at this
> point, but I'd like to see this feature in Py3K even if I dislike the
> specific syntax or other machinery that implements it (just like
> decorators). For now it's worth just getting an idea of whether the
> feature itself is deemed useful enough or the current status quo is
> adequate.
>
> George
>
>
> [1] http://mail.python.org/pipermail/python-dev/2006-May/064790.html


Well, if the syntax currently suggested in PEP 3102 [1] is adopted:
def compare(a, b, *, key=None):

Then it could be decided that arguments before the asterisk are
positional-only, and those after the asterisk are keyword-only. This would
be backwards compatible, since functions defined without the asterisk could
work as they currently do.

Alternatively, we could decide that we don't like
positional-or-keyword-arguments at all any more, and do away with them
altogether. All arguments would be positional only by default, unless they
are declared keyword-only (by whatever syntax is adopted).

Now waiting for the big guys to knock this down :)

- Tal

[1] http://www.python.org/dev/peps/pep-3102/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070516/cfab9337/attachment.html>

From guido at python.org  Wed May 16 18:45:42 2007
From: guido at python.org (Guido van Rossum)
Date: Wed, 16 May 2007 09:45:42 -0700
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705160925p158dd8dbiff7919c352b81349@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
	<464B2114.9030601@zope.com>
	<91ad5bf80705160925p158dd8dbiff7919c352b81349@mail.gmail.com>
Message-ID: <ca471dc20705160945y7462e547p874569f92a883e99@mail.gmail.com>

On 5/16/07, George Sakkis <george.sakkis at gmail.com> wrote:
> What's the future of "private" attributes in Py3K ? I remember Raymond
> Hettinger bringing up a challenge on c.l.py about a decorator that
> could replace the double underscore mangling and Michele Simionato
> caming up with a bytecode hack that showed it is possible.
>
> If they're staying though, +epsilon for blessing __args as
> positional-only (for some positive epsilon ;-)).

Nobody submitted a PEP to remove them in time for any of the several
deadlines I gave, so they are staying. (I think that even if a PEP had
been submitted it would probably have been rejected, after a long
discussion.)

But I'd love to see better syntax for positional-only arguments. What
I would like to be able to do is somehow write a signature like this:

  def foo(abc, xyz=42): ...

where both arguments (if present) *must* be given using positional
notation, so that foo(42) and foo(42, 24) are legal, but foo(abc=42)
and foo(42, xyz=24) are illegal. (Alas, I don't have any clever
suggestions.)

This could be proposed as an addition for 2.6 and then we'd have to
slip it into 3.0.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


From steven.bethard at gmail.com  Wed May 16 19:17:30 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Wed, 16 May 2007 11:17:30 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <ca471dc20705160945y7462e547p874569f92a883e99@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
	<464B2114.9030601@zope.com>
	<91ad5bf80705160925p158dd8dbiff7919c352b81349@mail.gmail.com>
	<ca471dc20705160945y7462e547p874569f92a883e99@mail.gmail.com>
Message-ID: <d11dcfba0705161017j7e388805g8249f08c60891945@mail.gmail.com>

On 5/16/07, Guido van Rossum <guido at python.org> wrote:
> But I'd love to see better syntax for positional-only arguments. What
> I would like to be able to do is somehow write a signature like this:
>
>   def foo(abc, xyz=42): ...
>
> where both arguments (if present) *must* be given using positional
> notation, so that foo(42) and foo(42, 24) are legal, but foo(abc=42)
> and foo(42, xyz=24) are illegal. (Alas, I don't have any clever
> suggestions.)

I'd particularly like to see some way to do this because it would make
duplicating the dict() and dict.update() signatures easier.  Currently
you could write::

    class C(object):
        def __init__(self, obj=None, **kwargs):

but this breaks when you try something like::

    C(obj='foo', bar='baz')

and expect both keyword arguments to be caught in the **kwargs.  And
let's hope you never need to write something like::

    C(self=1, other=2)

where you'll get a::

    TypeError: __init__() got multiple values for keyword argument 'self'

The current correct version looks like::

    class C(object):
        def __init__(*args, **kwargs):
            self = args[0]
            if len(args) == 2:
                obj = args[1]
            elif len(args) == 1:
                obj = None
            else:
                raise TypeError()

Nasty.


STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From benji at benjiyork.com  Wed May 16 19:47:23 2007
From: benji at benjiyork.com (Benji York)
Date: Wed, 16 May 2007 13:47:23 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
Message-ID: <464B43AB.8030005@benjiyork.com>

Guido van Rossum wrote:
> Personally, when I really wanted this, I've given the arguments names
> like __foo.

That could be enshrined as the syntax, much like "private" attributes.
-- 
Benji York
http://benjiyork.com


From greg.ewing at canterbury.ac.nz  Thu May 17 02:45:33 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Thu, 17 May 2007 12:45:33 +1200
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
Message-ID: <464BA5AD.4050507@canterbury.ac.nz>

Guido van Rossum wrote:

> Personally, when I really wanted this, I've given the arguments names
> like __foo.

But that doesn't address all the reasons for wanting
keyword-only args. An important reason is when you
want to accept an arbitrary number of positional args,
plus some keyword args. You can only do that now by
manually unpacking things from **kwds.

--
Greg


From jimjjewett at gmail.com  Thu May 17 02:59:03 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Wed, 16 May 2007 20:59:03 -0400
Subject: [Python-ideas] dot bend spoon
In-Reply-To: <20070516105510.26D531E4002@bag.python.org>
References: <20070516105510.26D531E4002@bag.python.org>
Message-ID: <fb6fbf560705161759k16da1844hd6f3565efcaa69c3@mail.gmail.com>

On 5/16/07, Aaron Brady <castironpi at comcast.net> wrote:
> Is the going semantic to carry a relation:

Do you just mean, "What is the most common idiom?"

I'll answer on that assumption, though if I'm correct,
comp.lang.python would be the more appropriate list.

> spoon.bend()

Tell the spoon to bend itself.

There are probably other things you could tell the spoon, but no
reason to believe that other objects bend.

> or

> johnson.bend( spoon ) ?

Tell Johnson to bend a spoon.

You could have told him to bend a knife instead.

-jJ


From guido at python.org  Thu May 17 04:04:34 2007
From: guido at python.org (Guido van Rossum)
Date: Wed, 16 May 2007 19:04:34 -0700
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <464BA5AD.4050507@canterbury.ac.nz>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
	<464BA5AD.4050507@canterbury.ac.nz>
Message-ID: <ca471dc20705161904r48fe115ele010cbb1c0317731@mail.gmail.com>

On 5/16/07, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Guido van Rossum wrote:
>
> > Personally, when I really wanted this, I've given the arguments names
> > like __foo.
>
> But that doesn't address all the reasons for wanting
> keyword-only args. An important reason is when you
> want to accept an arbitrary number of positional args,
> plus some keyword args. You can only do that now by
> manually unpacking things from **kwds.

In Py3k, the syntax is extended to support this:

def f(*args, foo=1, bar=2): pass



-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


From greg.ewing at canterbury.ac.nz  Thu May 17 05:58:04 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Thu, 17 May 2007 15:58:04 +1200
Subject: [Python-ideas] dot bend spoon
In-Reply-To: <fb6fbf560705161759k16da1844hd6f3565efcaa69c3@mail.gmail.com>
References: <20070516105510.26D531E4002@bag.python.org>
	<fb6fbf560705161759k16da1844hd6f3565efcaa69c3@mail.gmail.com>
Message-ID: <464BD2CC.6000909@canterbury.ac.nz>

Jim Jewett wrote:

> > or
> 
> > johnson.bend( spoon ) ?
> 
> Tell Johnson to bend a spoon.

or

   uri_geller.bend(spoon)

which doesn't actually bend the spoon, but makes the
rest of the program think it has been. :-)

More seriously, you can't say that one of these is better
than the other out of context. It depends on how the rest
of the program is designed.

-- 
Greg Ewing, Computer Science Dept, +--------------------------------------+
University of Canterbury,	   | Carpe post meridiem!          	  |
Christchurch, New Zealand	   | (I'm not a morning person.)          |
greg.ewing at canterbury.ac.nz	   +--------------------------------------+


From greg.ewing at canterbury.ac.nz  Thu May 17 06:06:38 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Thu, 17 May 2007 16:06:38 +1200
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <464BA5AD.4050507@canterbury.ac.nz>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
	<464BA5AD.4050507@canterbury.ac.nz>
Message-ID: <464BD4CE.10203@canterbury.ac.nz>

I wrote:
> Guido van Rossum wrote:
> 
> > Personally, when I really wanted this, I've given the arguments names
> > like __foo.
> 
> But that doesn't address all the reasons for wanting
> keyword-only args.

Sorry, I got mixed up between the positional-only and
keyword-only threads going on at the same time. Please
disregard that comment.

Personally I don't care much about positional-only
args other than through *args. If an elegant way of
accommodating them can be found, that's fine, but
I wouldn't go out of my way to find one.

-- 
Greg Ewing, Computer Science Dept, +--------------------------------------+
University of Canterbury,	   | Carpe post meridiem!          	  |
Christchurch, New Zealand	   | (I'm not a morning person.)          |
greg.ewing at canterbury.ac.nz	   +--------------------------------------+


From rasky at develer.com  Fri May 18 01:58:31 2007
From: rasky at develer.com (Giovanni Bajo)
Date: Fri, 18 May 2007 01:58:31 +0200
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
Message-ID: <f2iq77$p83$1@sea.gmane.org>

On 16/05/2007 16.50, George Sakkis wrote:

> In short, PEP 3102 enables the declaration of keyword-only arguments,
> making it easier for an API to grow in a backwards compatible way. As
> Benji York, I see the utility of positional-only arguments, not just
> for the sake of symmetry but for pragmatic reasons; in fact the same
> reasons that serve as rationale to the keywords-only PEP.

I've needed this only a few times, and I have used something like:

def foo(*args):
    a,b,c = args

as a workaround. Doesn't look too clumsy after all.

For Py4k, the only thing that occurred to me is to reuse the parenthesis:

def foo((a, b, c, d), e, f, *, g, h):
    pass

- a,b,c,d are positional-only
- e,f can be either positional or keyword
- g,h are only keyword.

-- 
Giovanni Bajo



From gsakkis at rutgers.edu  Fri May 18 03:14:57 2007
From: gsakkis at rutgers.edu (George Sakkis)
Date: Thu, 17 May 2007 21:14:57 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <f2iq77$p83$1@sea.gmane.org>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<f2iq77$p83$1@sea.gmane.org>
Message-ID: <91ad5bf80705171814h2b6b3ce1k8ee58a2e3e3aa78a@mail.gmail.com>

On 5/17/07, Giovanni Bajo <rasky at develer.com> wrote:

> On 16/05/2007 16.50, George Sakkis wrote:
>
> > In short, PEP 3102 enables the declaration of keyword-only arguments,
> > making it easier for an API to grow in a backwards compatible way. As
> > Benji York, I see the utility of positional-only arguments, not just
> > for the sake of symmetry but for pragmatic reasons; in fact the same
> > reasons that serve as rationale to the keywords-only PEP.
>
> I've needed this only a few times, and I have used something like:
>
> def foo(*args):
>     a,b,c = args
>
> as a workaround. Doesn't look too clumsy after all.

Well, it's better than nothing but it's an abuse of the *varargs
syntax and not friendly to signature inspection tools.

> For Py4k, the only thing that occurred to me is to reuse the parenthesis:
>
> def foo((a, b, c, d), e, f, *, g, h):
>     pass
>
> - a,b,c,d are positional-only
> - e,f can be either positional or keyword
> - g,h are only keyword.

Not too bad, but the pair of parentheses is redundant; positional-only
args (if any) must start from index 0. Also this doesn't address
pos-only args with defaults like Guido's example foo(abc, xyz=42). A
single "delimiter" symbol (e.g. '%') between pos-only and pos-or-kw
would kill both birds with one stone, i.e. something like:

def foo(a, b=42,           # pos-only
             % ,                   # delimiter
             c=0, d=None, # pos-or-kw
             *args,              # varargs
             e=-1,z='',        # kw-only
             **kwds            # keyword dictionary
)

Pros:
- Backwards compatible: args are pos-or-kw by default as they are now;
only those before the new delimiter are positional.
- Easy to change the status of a parameter; just move it to the
appropriate section (at least if it has a default value).

Cons:
- Yet another magic symbol, smells like perl (reusing the single star
would be ambiguous).
- The presumably common cases of functions without pos-or-kw args is clumsy:
def foo(a, b, c=31, %):  # all pos-only
def bar(a, b=1, %, *, c=31, d=None):  # pos-only or kw-only

Overall, I still prefer the double underscores.

George

-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."


From rrr at ronadam.com  Fri May 18 04:10:05 2007
From: rrr at ronadam.com (Ron Adam)
Date: Thu, 17 May 2007 21:10:05 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
Message-ID: <464D0AFD.3080900@ronadam.com>

George Sakkis wrote:
> This was posted on python-dev two weeks ago [1] but didn't get very
> far; probably python-ideas is a more appropriate list if this is to be
> taken any further.
> 
> In short, PEP 3102 enables the declaration of keyword-only arguments,
> making it easier for an API to grow in a backwards compatible way. As
> Benji York, I see the utility of positional-only arguments, not just
> for the sake of symmetry but for pragmatic reasons; in fact the same
> reasons that serve as rationale to the keywords-only PEP.
> 
> I don't have any concrete proposal (syntactic or otherwise) at this
> point, but I'd like to see this feature in Py3K even if I dislike the
> specific syntax or other machinery that implements it (just like
> decorators). For now it's worth just getting an idea of whether the
> feature itself is deemed useful enough or the current status quo is
> adequate.
> 
> George
> 
> 
> [1] http://mail.python.org/pipermail/python-dev/2006-May/064790.html


It seems there is a growing menu of arguments options. I suppose that's a 
good thing.  As long as it doesn't get too confusing.


Another thing I've wished I had recently is a way to over specify an 
argument list by giving it a larger list of arguments (or keywords) than is 
needed.

For example if I'm dispatching a collection of functions that each have 
different set or number of arguments, I'd like to say on the calling end 
for the function to take what it needs from a list and/or dictionary, but 
ignore what it doesn't need.

In the case of positional only arguments, it could take them in order, and 
in the case of keywords only, by name.  The point is to be able to specify 
it from the calling end in a generic way instead of having to do it inside 
the function or by adding a decorator to each function.  It's kind of like 
an simplified or generic adapter in a way.

Cheers,
    Ron















From arno at marooned.org.uk  Fri May 18 08:35:06 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Fri, 18 May 2007 07:35:06 +0100 (BST)
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <ca471dc20705160945y7462e547p874569f92a883e99@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
	<464B2114.9030601@zope.com>
	<91ad5bf80705160925p158dd8dbiff7919c352b81349@mail.gmail.com>
	<ca471dc20705160945y7462e547p874569f92a883e99@mail.gmail.com>
Message-ID: <61393.80.195.169.49.1179470106.squirrel@webmail.marooned.org.uk>


On Wed, May 16, 2007 5:45 pm, Guido van Rossum wrote:
[...]
> But I'd love to see better syntax for positional-only arguments. What
> I would like to be able to do is somehow write a signature like this:
>
>   def foo(abc, xyz=42): ...
>
> where both arguments (if present) *must* be given using positional
> notation, so that foo(42) and foo(42, 24) are legal, but foo(abc=42)
> and foo(42, xyz=24) are illegal. (Alas, I don't have any clever
> suggestions.)

One could decorate foo with:

def posonly(f):
    def posf(*args, **kwargs): return f(*args, *kwargs)
    posf.__name__ = f.__name__
    return f

So:

@posonly
def foo(abc, xyz=42):...

would behave as you want.  Of course it doesn't have an interesting
signature.

By extension one could have the arglist element *(a, b, c) for
positional-only arguments and **(x, y, z) for keyword-only arguments:

def foo(*(abc, xyz=42)):...

def bar(a, b, **(x, y=2)):...
    # a and b are positional/keyword arguments
    # x is keyword-only and mandatory
    # y is keyword-only with a default value of 2

It sort of fits with the current use of * as when calling foo:

foo(my_abc, my_xyz)

is equivalent to

foo(*(my_abc, my_xyz))

-- 
Arnaud




From fdrake at acm.org  Fri May 18 14:51:20 2007
From: fdrake at acm.org (Fred L. Drake, Jr.)
Date: Fri, 18 May 2007 08:51:20 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705171814h2b6b3ce1k8ee58a2e3e3aa78a@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<f2iq77$p83$1@sea.gmane.org>
	<91ad5bf80705171814h2b6b3ce1k8ee58a2e3e3aa78a@mail.gmail.com>
Message-ID: <200705180851.20823.fdrake@acm.org>

On Thursday 17 May 2007, George Sakkis wrote:
 > single "delimiter" symbol (e.g. '%') between pos-only and pos-or-kw
 > would kill both birds with one stone, i.e. something like:

A delimeter that would be needed anyway would make this a little nicer:

  def myfunc(a, b, c=24; *, kw=42):
      pass

This example would have 3 positional-only arguments (a, b, c) and one 
keyword-only argument (kw).

Replacing the comma with a semicolon avoids the need for a syntax-only 
position (good, IMO), avoids introducing a new special character, and re-uses 
one that's rarely used anyway.


  -Fred

-- 
Fred L. Drake, Jr.   <fdrake at acm.org>


From guido at python.org  Fri May 18 16:40:08 2007
From: guido at python.org (Guido van Rossum)
Date: Fri, 18 May 2007 07:40:08 -0700
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <61393.80.195.169.49.1179470106.squirrel@webmail.marooned.org.uk>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
	<464B2114.9030601@zope.com>
	<91ad5bf80705160925p158dd8dbiff7919c352b81349@mail.gmail.com>
	<ca471dc20705160945y7462e547p874569f92a883e99@mail.gmail.com>
	<61393.80.195.169.49.1179470106.squirrel@webmail.marooned.org.uk>
Message-ID: <ca471dc20705180740n3674e551kc3df5e48bf1a7cdd@mail.gmail.com>

This decorator solution is the best I've seen so far! It is probably
possible to (a) copy signature info into the returned wrapper, and (b)
support keyword args (after the lone '*' or after *args).
--Guido

On 5/17/07, Arnaud Delobelle <arno at marooned.org.uk> wrote:
>
> On Wed, May 16, 2007 5:45 pm, Guido van Rossum wrote:
> [...]
> > But I'd love to see better syntax for positional-only arguments. What
> > I would like to be able to do is somehow write a signature like this:
> >
> >   def foo(abc, xyz=42): ...
> >
> > where both arguments (if present) *must* be given using positional
> > notation, so that foo(42) and foo(42, 24) are legal, but foo(abc=42)
> > and foo(42, xyz=24) are illegal. (Alas, I don't have any clever
> > suggestions.)
>
> One could decorate foo with:
>
> def posonly(f):
>     def posf(*args, **kwargs): return f(*args, *kwargs)
>     posf.__name__ = f.__name__
>     return f
>
> So:
>
> @posonly
> def foo(abc, xyz=42):...
>
> would behave as you want.  Of course it doesn't have an interesting
> signature.
>
> By extension one could have the arglist element *(a, b, c) for
> positional-only arguments and **(x, y, z) for keyword-only arguments:
>
> def foo(*(abc, xyz=42)):...
>
> def bar(a, b, **(x, y=2)):...
>     # a and b are positional/keyword arguments
>     # x is keyword-only and mandatory
>     # y is keyword-only with a default value of 2
>
> It sort of fits with the current use of * as when calling foo:
>
> foo(my_abc, my_xyz)
>
> is equivalent to
>
> foo(*(my_abc, my_xyz))
>
> --
> Arnaud
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>


-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


From rrr at ronadam.com  Fri May 18 17:14:42 2007
From: rrr at ronadam.com (Ron Adam)
Date: Fri, 18 May 2007 10:14:42 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <200705180851.20823.fdrake@acm.org>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>	<f2iq77$p83$1@sea.gmane.org>	<91ad5bf80705171814h2b6b3ce1k8ee58a2e3e3aa78a@mail.gmail.com>
	<200705180851.20823.fdrake@acm.org>
Message-ID: <464DC2E2.5000603@ronadam.com>

Fred L. Drake, Jr. wrote:
> On Thursday 17 May 2007, George Sakkis wrote:
>  > single "delimiter" symbol (e.g. '%') between pos-only and pos-or-kw
>  > would kill both birds with one stone, i.e. something like:
> 
> A delimeter that would be needed anyway would make this a little nicer:
> 
>   def myfunc(a, b, c=24; *, kw=42):
>       pass
> 
> This example would have 3 positional-only arguments (a, b, c) and one 
> keyword-only argument (kw).
> 
> Replacing the comma with a semicolon avoids the need for a syntax-only 
> position (good, IMO), avoids introducing a new special character, and re-uses 
> one that's rarely used anyway.


[A few thoughts]

     def foo([positonal_only_args][; [kwd_args][; kwds_only]]): ...

     def myfunct(a, b, c=42; e=99; kw=42): ...

     args = (1, 2, 3, 4)   # 'e' can be in either args or kwds,
     kwds = {'kw': 42}     # but not both.

     bar = foo(*args, **kwds)


How about signature objects that are similar to slice objects?

     sig = signature(*args, **kwds)      # Pre package signature.
     sig = signature(1, 2, 3, 4, kw=42)

Could something like this have performance benefit if the same exact 
signature is used over and over?  Possibly just passing a pre parsed name 
space to the function?

     bar = foo(sig)        # No need to unpack with * or **.

     bar = foo(@sig)       # Be lenient, extra args and kwds
                           # are consumed or ignored.
                           # But always error if something is missing.

The '@' sign is like a vortex which sucks up unused args.  ;-)

Ron











From rrr at ronadam.com  Fri May 18 17:41:48 2007
From: rrr at ronadam.com (Ron Adam)
Date: Fri, 18 May 2007 10:41:48 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <464DC2E2.5000603@ronadam.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>	<f2iq77$p83$1@sea.gmane.org>	<91ad5bf80705171814h2b6b3ce1k8ee58a2e3e3aa78a@mail.gmail.com>	<200705180851.20823.fdrake@acm.org>
	<464DC2E2.5000603@ronadam.com>
Message-ID: <464DC93C.3080304@ronadam.com>

Ron Adam wrote:
> Fred L. Drake, Jr. wrote:
>> On Thursday 17 May 2007, George Sakkis wrote:
>>  > single "delimiter" symbol (e.g. '%') between pos-only and pos-or-kw
>>  > would kill both birds with one stone, i.e. something like:
>>
>> A delimeter that would be needed anyway would make this a little nicer:
>>
>>   def myfunc(a, b, c=24; *, kw=42):
>>       pass
>>
>> This example would have 3 positional-only arguments (a, b, c) and one 
>> keyword-only argument (kw).
>>
>> Replacing the comma with a semicolon avoids the need for a syntax-only 
>> position (good, IMO), avoids introducing a new special character, and re-uses 
>> one that's rarely used anyway.
> 
> 
> [A few thoughts]
> 
>      def foo([positonal_only_args][; [kwd_args][; kwds_only]]): ...
 >
>      def myfunct(a, b, c=42; e=99; kw=42): ...

Hmmm, this has a problem if you use * or ** in the definition. :(

        def myfunc(*args;  ?  ; **kwds): ...


I think this would be an issue with some of the other ideas as well.


>      args = (1, 2, 3, 4)   # 'e' can be in either args or kwds,
>      kwds = {'kw': 42}     # but not both.
> 
>      bar = foo(*args, **kwds)
> 
> 
> How about signature objects that are similar to slice objects?
> 
>      sig = signature(*args, **kwds)      # Pre package signature.
>      sig = signature(1, 2, 3, 4, kw=42)
> 
> Could something like this have performance benefit if the same exact 
> signature is used over and over?  Possibly just passing a pre parsed name 
> space to the function?
> 
>      bar = foo(sig)        # No need to unpack with * or **.
> 
>      bar = foo(@sig)       # Be lenient, extra args and kwds
>                            # are consumed or ignored.
>                            # But always error if something is missing.
> 
> The '@' sign is like a vortex which sucks up unused args.  ;-)
> 
> Ron



From martin at ambric.com  Fri May 18 17:34:53 2007
From: martin at ambric.com (Rick Martin)
Date: Fri, 18 May 2007 08:34:53 -0700
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <ca471dc20705180740n3674e551kc3df5e48bf1a7cdd@mail.gmail.com>
Message-ID: <C291E7B53B30114EA3EF037D279CD0EA801BC7@ben.ambric.local>

Has anyone considered the Common Lisp argument list as a place to look
for ideas?

(var...
 &optional (var initform svar)...
 &rest var
 &key ((keyword var) initform svar)...
 &aux (var initform)...)

http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node64.html

Rick


From arno at marooned.org.uk  Fri May 18 19:42:13 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Fri, 18 May 2007 18:42:13 +0100 (BST)
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <61393.80.195.169.49.1179470106.squirrel@webmail.marooned.org.uk>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<ca471dc20705160809p4060bb59l2a16a810c0b1def3@mail.gmail.com>
	<464B2114.9030601@zope.com>
	<91ad5bf80705160925p158dd8dbiff7919c352b81349@mail.gmail.com>
	<ca471dc20705160945y7462e547p874569f92a883e99@mail.gmail.com>
	<61393.80.195.169.49.1179470106.squirrel@webmail.marooned.org.uk>
Message-ID: <61788.80.195.168.31.1179510133.squirrel@webmail.marooned.org.uk>


On Fri, May 18, 2007 7:35 am, Arnaud Delobelle wrote:
[...]
> def posonly(f):
>     def posf(*args, **kwargs): return f(*args, *kwargs)
>     posf.__name__ = f.__name__
>     return f

I wrote this just before going to work this morning, and of course I
didn't try it or probably even reread it...  So apart from the typos it
doesn't work with **kwargs.  I've got a working version:

def posonly(arg):
    def deco(f, nposargs):
        name = f.__name__
        posargnames = f.func_code.co_varnames[:nposargs]
        def posf(*args, **kwargs):
            for kw in kwargs:
                if kw in posargnames:
                    raise TypeError("%s() arg '%s' is posonly" % (name, kw))
            return f(*args, **kwargs)
        posf.__name__ = name
        return posf
    if isinstance(arg, int):
        return lambda f: deco(f, arg)
    else:
        return deco(arg, arg.func_code.co_argcount)

It works like this:

@posonly
def foo(x, y, z=10, t=100):
    # All arguments are positional only
    # foo(1, 2, 3) -> 106
    # foo(1, y=2) -> TypeError
    # foo(1, t=7) -> TypeError
    return x+y+z+t

@posonly(2)
def bar(x, y=1, z=10, t=100):
    # Only the first two arguments are posonly
    # bar(1, y=2) -> TypeError
    # bar(1, z=0) -> 102

Being a mere python end-user, I don't know if I'm using the func_code
attribute of functions correctly, so this might break in various ways!

-- 
Arnaud




From steven.bethard at gmail.com  Fri May 18 23:07:22 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Fri, 18 May 2007 15:07:22 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
Message-ID: <d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>

On 5/16/07, George Sakkis <george.sakkis at gmail.com> wrote:
> I see the utility of positional-only arguments, not just
> for the sake of symmetry but for pragmatic reasons; in fact the same
> reasons that serve as rationale to the keywords-only PEP.

In the hopes of keeping this discussion enough on track that we can
eventually come to a conclusion, I thought I'd just take a couple
minutes to summarize the proposals so far. I'm looking at the
following function as an example::

    def f(a, b=None, *, c=42, **kwargs)

where ``a`` and ``b`` should be positional-only and ``c`` should be
keyword-only. Here are the alternatives I've seen so far:

* Do nothing, e.g.::

    def (*args, c=42, **kwargs):
        if len(args) == 1:
            a = args[0]
            b = None
        elif len(args) == 2:
            a, b = args
        else:
            raise TypeError()

  Pro: backwards compatible, requires no new syntax
  Con: unfriendly to introspection, requires extra boiler-plate

* Enforce double-underscore names as being positional-only syntactically, e.g.::

    def f(__a, __b=None, *, c=42, **kwargs)

  Pro: requires no new syntax
  Con: slightly backwards incompatible (but who calls f(__a) anyway?)

* Use a decorator, e.g.::

    @posonly(2)
    def f(a, b=None, *, c=42, **kwargs)

  Pro: backwards compatible, requires no new syntax, could work with Python 2.5
  Con: moves some signature info out of the argument list

* Make the lone '*' force everything to the left to be positional-only
and everything to the right be keyword-only, e.g.::

    def f(a, b=None, *, c=42, **kwargs):

  Pro: backwards compatible (since lone '*' is not yet introduced),
requires no new syntax
  Con: disallows named arguments with keyword-only arguments,
disallows positional-only arguments with *args.

* Reuse syntax like what was removed for tuple arguments, e.g.::

    def f((a, b=None), *, c=42, **kwargs):

  Pro: ?
  Con: changes meaning of tuple argument syntax

* Add a new delimiter, e.g.::

    def f(a, b=None, %, *, c=42, **kwargs)
    def f(a, b=None; *, c=42, **kwargs)

  Pro: backwards compatible
  Con: requires new syntax, in second version semi-colon vs. comma is
hard to spot


So at the moment, it looks to me like the double-underscores and the
decorator are the top competitors.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From jimjjewett at gmail.com  Fri May 18 23:52:01 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Fri, 18 May 2007 17:52:01 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
Message-ID: <fb6fbf560705181452p58420e78j4f320f131d83b5a3@mail.gmail.com>

On 5/16/07, George Sakkis <george.sakkis at gmail.com> wrote:
> I see the utility of positional-only arguments, not just
> for the sake of symmetry but for pragmatic reasons; in fact the same
> reasons that serve as rationale to the keywords-only PEP.

uhh... could you spell those out, please?

keywords-only is justified by functions that take both *args and a
keyword that meets meets at least one of

    (1)  Wasn't there before, so you can't stick it in front for
backwards-compatibility reasons.  (think "cmp")

    (2)  Doesn't have a default

    (3)  Should always be called by name, for readability.

The following signature is awful

    def max(cmp=mysort, *args):

And if you've already released max, it isn't even legal.


How could there ever be an argument that *needs* to be positional?

There are some that don't work if you call them by keyword, because
they happen to be implemented in C without keyword support, but ... is
there any reason to postively forbid using the argument name?  The
closest I can come to an example is

    def lappend(object):
        # This mimics list.append, and the *real* function wouldn't
        # take a keyword, so neither will I, just to prevent bad habits.

Even that can already be written if you really want to...

    def lappend(*object):
        if len(object) != 1: raise TypeError("lappend takes ...")
        object = object[0]
        ...

-jJ


From steven.bethard at gmail.com  Sat May 19 01:04:09 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Fri, 18 May 2007 17:04:09 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <fb6fbf560705181452p58420e78j4f320f131d83b5a3@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<fb6fbf560705181452p58420e78j4f320f131d83b5a3@mail.gmail.com>
Message-ID: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>

On 5/18/07, Jim Jewett <jimjjewett at gmail.com> wrote:
> How could there ever be an argument that *needs* to be positional?

As I've mentioned before, a great example of this is the dict()
signature. It takes an optional "container" argument, followed by
arbitrary keywords.  If you write this in the naive way::

    def __init__(self, container=None, **kwargs)
        ...
        for key, value in kwargs.items():
            self[key] = value

then you get TypeErrors for the following code::

    d.update(sequence=1, container=2)
    d.update(other=1, self=2)

That is, the **kwargs can never include anything named 'self' or
'container'. If you could declare these two arguments as
positional-only, you'd never run into this problem.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From steven.bethard at gmail.com  Sat May 19 01:11:27 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Fri, 18 May 2007 17:11:27 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<fb6fbf560705181452p58420e78j4f320f131d83b5a3@mail.gmail.com>
	<d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
Message-ID: <d11dcfba0705181611r3dcb5baahf740a6b85f4a97f1@mail.gmail.com>

On 5/18/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> On 5/18/07, Jim Jewett <jimjjewett at gmail.com> wrote:
> > How could there ever be an argument that *needs* to be positional?
>
> As I've mentioned before, a great example of this is the dict()
> signature. It takes an optional "container" argument, followed by
> arbitrary keywords.  If you write this in the naive way::
>
>     def __init__(self, container=None, **kwargs)
>         ...
>         for key, value in kwargs.items():
>             self[key] = value
>
> then you get TypeErrors for the following code::
>
>     d.update(sequence=1, container=2)
>     d.update(other=1, self=2)

Sorry, those should have been

    dict(sequence=1, container=2)
    dict(other=1, self=2)

Of course, the same argument is valid for dict.update().

> That is, the **kwargs can never include anything named 'self' or
> 'container'. If you could declare these two arguments as
> positional-only, you'd never run into this problem.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From castironpi at comcast.net  Sat May 19 04:55:49 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 18 May 2007 21:55:49 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705171814h2b6b3ce1k8ee58a2e3e3aa78a@mail.gmail.com>
Message-ID: <20070519025555.23EE01E4004@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of George Sakkis
> def foo(a, b=42,           # pos-only
>              % ,                   # delimiter
>              c=0, d=None, # pos-or-kw
>              *args,              # varargs
>              e=-1,z='',        # kw-only
>              **kwds            # keyword dictionary
> )
> 
> Pros:
> - Backwards compatible: args are pos-or-kw by default as they are now;
> only those before the new delimiter are positional.
> - Easy to change the status of a parameter; just move it to the
> appropriate section (at least if it has a default value).
> 
> Cons:
> - Yet another magic symbol, smells like perl (reusing the single star
> would be ambiguous).
> - The presumably common cases of functions without pos-or-kw args is
> clumsy:
> def foo(a, b, c=31, %):  # all pos-only
> def bar(a, b=1, %, *, c=31, d=None):  # pos-only or kw-only
> 
> Overall, I still prefer the double underscores.
> 
> George
> 

One of the things I like about Python is we've got some extra room in the
syntax to complexify.  Careful how we spend it.  The extra is on a budget,
not unlimited as some things are.

def foo(a, b=42;           # pos-only
             c=0, d=None, # pos-or-kw
             *args;          # varargs
             e=-1,z='',        # kw-only
             **kwds            # keyword dictionary
)

def foo(a, b, c=31; ):  # all pos-only
def bar(a, b=1;; c=31, d=None):  # pos-only or kw-only

> - Yet another magic symbol, smells like perl (reusing the single star
> would be ambiguous).

True dat.



From castironpi at comcast.net  Sat May 19 06:07:39 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Fri, 18 May 2007 23:07:39 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
Message-ID: <20070519040745.6CF001E4004@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces+castironpi=comcast.net at python.org
> [mailto:python-ideas-bounces+castironpi=comcast.net at python.org] On Behalf
> Of Steven Bethard
> Sent: Friday, May 18, 2007 6:04 PM
> To: Jim Jewett
> Cc: python-ideas at python.org; benji at zope.com
> Subject: Re: [Python-ideas] Positional only arguments
> 
> On 5/18/07, Jim Jewett <jimjjewett at gmail.com> wrote:
> > How could there ever be an argument that *needs* to be positional?
> 
> As I've mentioned before, a great example of this is the dict()
> signature. It takes an optional "container" argument, followed by
> arbitrary keywords.  If you write this in the naive way::
> 
>     def __init__(self, container=None, **kwargs)
>         ...
>         for key, value in kwargs.items():
>             self[key] = value
> 
> then you get TypeErrors for the following code::
> 
>     d.update(sequence=1, container=2)
>     d.update(other=1, self=2)
> 
> That is, the **kwargs can never include anything named 'self' or
> 'container'. If you could declare these two arguments as
> positional-only, you'd never run into this problem.
> 
> STeVe

Might you use d.update(container=2, sequence=1)?  'Can never' caught me up.

> > How could there ever be an argument that *needs* to be positional?

To deliberately poise, evaluate extremes.  Couple continuums going on here
so don't contradict one with another's counterexample.

Annotate every call parameter?  Double equals sign?  Not advocating, but
illustrating this one.

Balance is trade-off between flexibility to call, and convenience to define.

Function decoration is a fledgling addition to syntax.  Can we use this to
kindle, as opposed to snuff?  Shows great ease of use promise.



From steven.bethard at gmail.com  Sat May 19 06:15:22 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Fri, 18 May 2007 22:15:22 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
Message-ID: <d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>

On 5/18/07, Aaron Brady <castironpi at comcast.net> wrote:
> Steven Bethard wrote:
> > On 5/18/07, Jim Jewett <jimjjewett at gmail.com> wrote:
> > > How could there ever be an argument that *needs* to be positional?
> >
> > As I've mentioned before, a great example of this is the dict()
> > signature. It takes an optional "container" argument, followed by
> > arbitrary keywords.  If you write this in the naive way::
> >
> >     def __init__(self, container=None, **kwargs)
> >         ...
> >         for key, value in kwargs.items():
> >             self[key] = value
> >
> > then you get TypeErrors for the following code::
> >
> >     d.update(sequence=1, container=2)
> >     d.update(other=1, self=2)
> >
> > That is, the **kwargs can never include anything named 'self' or
> > 'container'. If you could declare these two arguments as
> > positional-only, you'd never run into this problem.
>
> Might you use d.update(container=2, sequence=1)?  'Can never' caught me up.

Not sure I understand the question. My point was only that you'll
never reproduce this behavior::

    >>> dict(self=1, other=2)
    {'self': 1, 'other': 2}
    >>> d = {}
    >>> d.update(container=2, sequence=1)
    >>> d
    {'container': 2, 'sequence': 1}

Of course, you can rename the 'self' and 'container' parameters to
something else, but that just means that you can't use whatever new
names you choose. The only way to solve this is to use real
positional-only arguments, which currently means using *args and
parsing out things within the function body.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From rhamph at gmail.com  Sat May 19 07:49:57 2007
From: rhamph at gmail.com (Adam Olsen)
Date: Fri, 18 May 2007 23:49:57 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
Message-ID: <aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>

On 5/18/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> On 5/16/07, George Sakkis <george.sakkis at gmail.com> wrote:
> > I see the utility of positional-only arguments, not just
> > for the sake of symmetry but for pragmatic reasons; in fact the same
> > reasons that serve as rationale to the keywords-only PEP.
>
> In the hopes of keeping this discussion enough on track that we can
> eventually come to a conclusion, I thought I'd just take a couple
> minutes to summarize the proposals so far. I'm looking at the
> following function as an example::
>
>     def f(a, b=None, *, c=42, **kwargs)
>
> where ``a`` and ``b`` should be positional-only and ``c`` should be
> keyword-only. Here are the alternatives I've seen so far:

* Use ** for keyword-only and * for positional-only:

    def (a, b=None, *, **, c=42, **kwargs):

  Pro: backwards compatible, reuses existing meanings
  Con: requires new syntax, changes keyword-only PEP

-- 
Adam Olsen, aka Rhamphoryncus


From talin at acm.org  Sat May 19 07:49:43 2007
From: talin at acm.org (Talin)
Date: Fri, 18 May 2007 22:49:43 -0700
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
	<d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>
Message-ID: <464E8FF7.5000208@acm.org>

Steven Bethard wrote:
> Not sure I understand the question. My point was only that you'll
> never reproduce this behavior::
> 
>     >>> dict(self=1, other=2)
>     {'self': 1, 'other': 2}
>     >>> d = {}
>     >>> d.update(container=2, sequence=1)
>     >>> d
>     {'container': 2, 'sequence': 1}
> 
> Of course, you can rename the 'self' and 'container' parameters to
> something else, but that just means that you can't use whatever new
> names you choose. The only way to solve this is to use real
> positional-only arguments, which currently means using *args and
> parsing out things within the function body.

I would just use names beginning with an underscore, or some other 
convention that is unlikely to occur as a dict key.

-- Talin



From steven.bethard at gmail.com  Sat May 19 08:40:38 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Sat, 19 May 2007 00:40:38 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <464E8FF7.5000208@acm.org>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
	<d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>
	<464E8FF7.5000208@acm.org>
Message-ID: <d11dcfba0705182340h17e26435u91fc0c1ecccbf163@mail.gmail.com>

On 5/18/07, Talin <talin at acm.org> wrote:
> Steven Bethard wrote:
> > Not sure I understand the question. My point was only that you'll
> > never reproduce this behavior::
> >
> >     >>> dict(self=1, other=2)
> >     {'self': 1, 'other': 2}
> >     >>> d = {}
> >     >>> d.update(container=2, sequence=1)
> >     >>> d
> >     {'container': 2, 'sequence': 1}
> >
> > Of course, you can rename the 'self' and 'container' parameters to
> > something else, but that just means that you can't use whatever new
> > names you choose. The only way to solve this is to use real
> > positional-only arguments, which currently means using *args and
> > parsing out things within the function body.
>
> I would just use names beginning with an underscore, or some other
> convention that is unlikely to occur as a dict key.

So should I take that as a +1 for:

* Enforce double-underscore names as being positional-only syntactically, e.g.::

   def f(__a, __b=None, *, c=42, **kwargs)

 Pro: requires no new syntax
 Con: slightly backwards incompatible (but who calls f(__a) anyway?)

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From arno at marooned.org.uk  Sat May 19 09:22:43 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Sat, 19 May 2007 08:22:43 +0100 (BST)
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705182340h17e26435u91fc0c1ecccbf163@mail.gmail.com>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
	<d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>
	<464E8FF7.5000208@acm.org>
	<d11dcfba0705182340h17e26435u91fc0c1ecccbf163@mail.gmail.com>
Message-ID: <61964.80.195.169.49.1179559363.squirrel@webmail.marooned.org.uk>


On Sat, May 19, 2007 7:40 am, Steven Bethard wrote:
[...]
> So should I take that as a +1 for:
>
> * Enforce double-underscore names as being positional-only syntactically,
> e.g.::
>
>    def f(__a, __b=None, *, c=42, **kwargs)
>
>  Pro: requires no new syntax
>  Con: slightly backwards incompatible (but who calls f(__a) anyway?)
>


- There is also incompatibility in the definition of functions: 'def f(a,
__b)' is currently correct, it wouldn't be anymore.

- How would this work with name mangling and methods?  For example:

class Foo(object):
    def posfun(__self, __a, b, ...):

* Would self have to be renamed __self? (As positional only arguments
should come first)

* Would __self and __a be mangled, as is the rule within classes up to
now?  If so care has to be taken I suppose.

-- 
Arnaud




From arno at marooned.org.uk  Sun May 20 10:56:18 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Sun, 20 May 2007 09:56:18 +0100 (BST)
Subject: [Python-ideas] Positional only arguments
Message-ID: <63611.80.195.169.49.1179651378.squirrel@webmail.marooned.org.uk>


On Wed, May 16, 2007 5:25 pm, George Sakkis wrote:
[...]
>
> What's the future of "private" attributes in Py3K ? I remember Raymond
> Hettinger bringing up a challenge on c.l.py about a decorator that
> could replace the double underscore mangling and Michele Simionato
> caming up with a bytecode hack that showed it is possible.

IIRC Michele Simionato made a 'CurrentClass' name available to methods,
which contains the class that the method is defined in.  While
interesting, this doesn't help create 'private' attribute, as name
mangling does.  In fact it is possible to implement this in pure Python
using decorators and metaclasses.

I tried to take up the challenge (without bytecode hackery, which I am not
capable of) but it turned out you need to chase around the call stack a
lot!

-- 
Arnaud




From arno at marooned.org.uk  Sun May 20 16:08:33 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Sun, 20 May 2007 15:08:33 +0100 (BST)
Subject: [Python-ideas] Implementing PEP 3130 using decorators
Message-ID: <64117.80.195.169.49.1179670113.squirrel@webmail.marooned.org.uk>

Hi

PEP 3130, 'Access to Current Module/Class/Function', proposed the
introduction of new keywords (__class__, __function__, and __module__) to
refer to what lexical unit theses names were in.  It was rejected, but I
have thought about a way to produce the same functionality without the
need of new keywords, by using decorators instead.  It would go like this:

class Foo(object):

    # some defs...

    @bindclass
    def bar(thisclass, self):
        # Within this method the name 'thiclass' refers to class Foo
        # ...

    @bindclass
    def bar(Foo, self):
        # The name of 'thisclass' can be chosen, just like 'self' can.
        # Within this method the name 'Foo' refers to class Foo, even
        # after Foo is bound to another object
        # ...

    # More defs...

@bindfunction
def factorial(thisfunction, n):
    # Within this function the name 'thisfunction' refers to the factorial
    # function (with only one argument), even after 'factorial' is bound
    # to another object
    if n > 0:
        return n * thisfunction(n - 1)
    else:
        return 1

Here is an implementation:

class bindclass(object):
    def __init__(self, f):
        self.f = f
    def bind(self, cls, attr):
        def bound_m(*args, **kwargs):
            return self.f(cls, *args, **kwargs)
        bound_m.__name__ = attr
        self.m = bound_m
    def __get__(self, obj, objtype=None):
        return self.m.__get__(obj, objtype)

class Type(type):
    def __init__(self, name, bases, attrs):
        for attr, val in attrs.iteritems():
            if isinstance(val, bindclass):
                val.bind(self, attr)

class Object(object):
    __metaclass__ = Type


def bindfunction(f):
    def bound_f(*args, **kwargs):
        return f(bound_f, *args, **kwargs)
    bound_f.__name__ = f.__name__
    return bound_f

And an example:

class Foo(Object):
    @bindclass
    def foo(this_class, self):
        return this_class, self

class Bar(Foo):
    @bindclass
    def bar(this_class, self):
        return this_class, self

f = Foo()
b = Bar()

f.foo() # -> Foo, Foo object
b.foo() # -> Foo, Foo object
f.bar() # -> Bar, Foo object

-- 
Arnaud




From steven.bethard at gmail.com  Sun May 20 17:24:22 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Sun, 20 May 2007 09:24:22 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <61964.80.195.169.49.1179559363.squirrel@webmail.marooned.org.uk>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
	<d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>
	<464E8FF7.5000208@acm.org>
	<d11dcfba0705182340h17e26435u91fc0c1ecccbf163@mail.gmail.com>
	<61964.80.195.169.49.1179559363.squirrel@webmail.marooned.org.uk>
Message-ID: <d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>

On 5/19/07, Arnaud Delobelle <arno at marooned.org.uk> wrote:
>
> On Sat, May 19, 2007 7:40 am, Steven Bethard wrote:
> [...]
> > So should I take that as a +1 for:
> >
> > * Enforce double-underscore names as being positional-only syntactically,
> > e.g.::
> >
> >    def f(__a, __b=None, *, c=42, **kwargs)
> >
> >  Pro: requires no new syntax
> >  Con: slightly backwards incompatible (but who calls f(__a) anyway?)
>
> - There is also incompatibility in the definition of functions: 'def f(a,
> __b)' is currently correct, it wouldn't be anymore.

Good point.  Though I also suspect that's pretty low frequency.

> - How would this work with name mangling and methods?  For example:
>
> class Foo(object):
>     def posfun(__self, __a, b, ...):
>
> * Would self have to be renamed __self? (As positional only arguments
> should come first)

Yes.

> * Would __self and __a be mangled, as is the rule within classes up to
> now?  If so care has to be taken I suppose.

I don't see any reason to mangle them.  The only time you'd ever
notice is using locals().


I've also noticed that the current @posonly decorator won't solve the
dict() and dict.update() problem::

>>> @posonly(2)
... def update(self, container=None, **kwargs):
...     print self, container, kwargs
...
>>> update(self=1, other=2)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<interactive input>", line 8, in posf
    raise TypeError("%s() arg '%s' is posonly" % (name, kw))
TypeError: update() arg 'self' is posonly

I think it should probably be defined as something like::

def posonly(n=None):
    def get_positional_only_wrapper(func, n=n):
        if n is None:
            n = func.func_code.co_argcount
        n -= len(func.func_defaults)
        def positional_only_wrapper(*args, **kwargs):
            if len(args) < n:
                msg = '%s() expected %i positional arguments, found %i'
                raise TypeError(msg % (func.__name__, n, len(args)))
            return func(*args, **kwargs)
        return positional_only_wrapper
    return get_positional_only_wrapper

But note that this still doesn't solve the dict() and dict.update()
problem because we still can't get 'self' and 'container' in the
**kwargs::

>>> @posonly(2)
... def update(self, container=None, **kwargs):
...     print self, container, kwargs
...
>>> update('foo', self=1, other=2)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<interactive input>", line 10, in positional_only_wrapper
    return func(*args, **kwargs)
TypeError: update() got multiple values for keyword argument 'self'


STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From george.sakkis at gmail.com  Sun May 20 18:31:40 2007
From: george.sakkis at gmail.com (George Sakkis)
Date: Sun, 20 May 2007 12:31:40 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
	<d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>
	<464E8FF7.5000208@acm.org>
	<d11dcfba0705182340h17e26435u91fc0c1ecccbf163@mail.gmail.com>
	<61964.80.195.169.49.1179559363.squirrel@webmail.marooned.org.uk>
	<d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>
Message-ID: <91ad5bf80705200931q53325a33t3bc231306382af09@mail.gmail.com>

On 5/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> On 5/19/07, Arnaud Delobelle <arno at marooned.org.uk> wrote:
> > - How would this work with name mangling and methods?  For example:
> >
> > class Foo(object):
> >     def posfun(__self, __a, b, ...):
> >
> > * Would self have to be renamed __self? (As positional only arguments
> > should come first)
>
> Yes.

Ouch, hadn't thought of that. Many people find explicit self ugly, and
now you'll tell them they *have to* spell it __self (or __s for fewer
keystrokes) ? That's indeed ugly.

The semicolon proposal looks better, at least for this case:

class Foo(object):
    def posfun(self, a; b, ...):


George

-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."


From rrr at ronadam.com  Sun May 20 19:08:20 2007
From: rrr at ronadam.com (Ron Adam)
Date: Sun, 20 May 2007 12:08:20 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705200931q53325a33t3bc231306382af09@mail.gmail.com>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>	<d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>	<464E8FF7.5000208@acm.org>	<d11dcfba0705182340h17e26435u91fc0c1ecccbf163@mail.gmail.com>	<61964.80.195.169.49.1179559363.squirrel@webmail.marooned.org.uk>	<d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>
	<91ad5bf80705200931q53325a33t3bc231306382af09@mail.gmail.com>
Message-ID: <46508084.9080708@ronadam.com>

George Sakkis wrote:
> On 5/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:
>> On 5/19/07, Arnaud Delobelle <arno at marooned.org.uk> wrote:
>>> - How would this work with name mangling and methods?  For example:
>>>
>>> class Foo(object):
>>>     def posfun(__self, __a, b, ...):
>>>
>>> * Would self have to be renamed __self? (As positional only arguments
>>> should come first)
>> Yes.
> 
> Ouch, hadn't thought of that. Many people find explicit self ugly, and
> now you'll tell them they *have to* spell it __self (or __s for fewer
> keystrokes) ? That's indeed ugly.
> 
> The semicolon proposal looks better, at least for this case:
> 
> class Foo(object):
>     def posfun(self, a; b, ...):

I would also say identifying the semicolon isn't a problem.  After all 
we've been telling the difference between periods and comma's for quite a 
long time now with no difficulty.  So it's more a matter of just getting 
used to looking for it in function signatures.

Ron








From steven.bethard at gmail.com  Sun May 20 19:13:01 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Sun, 20 May 2007 11:13:01 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
Message-ID: <d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>

On 5/18/07, Adam Olsen <rhamph at gmail.com> wrote:
> On 5/18/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> >
> > In the hopes of keeping this discussion enough on track that we can
> > eventually come to a conclusion, I thought I'd just take a couple
> > minutes to summarize the proposals so far. I'm looking at the
> > following function as an example::
> >
> >     def f(a, b=None, *, c=42, **kwargs)
> >
> > where ``a`` and ``b`` should be positional-only and ``c`` should be
> > keyword-only. Here are the alternatives I've seen so far:
>
> * Use ** for keyword-only and * for positional-only:
>
>     def (a, b=None, *, **, c=42, **kwargs):
>
>   Pro: backwards compatible, reuses existing meanings
>   Con: requires new syntax, changes keyword-only PEP

I like the idea of matching the * with positional-only arguments and
the ** with keyword-only arguments.  In the example above though, I
don't really like how we look forward for ** but backward for *. I
feel like I the semantics should instead be::

- Everything after a * is a positional-only argument
- Everything after a ** is a keyword-only argument

These interpretations are consistent with the current meanings of
*args and **kwargs.

So to write the dict() or dict.update() signatures, we'd write::

    def update(*, self, container=None, **kwargs)

And to write the signature from my example, we'd write::

    def f(*, a, b=None, **, c=42, **kwargs)

My only use cases are for functions with '*' at the beginning, because
the only time I care about having positional only arguments is when I
also have a **kwargs, and in that situation, I want *all* other
arguments to be positional only.

Does anyone have a use case that requires both positional-only and
positional-or-keyword arguments?

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From steven.bethard at gmail.com  Sun May 20 19:16:47 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Sun, 20 May 2007 11:16:47 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <46508084.9080708@ronadam.com>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
	<d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>
	<464E8FF7.5000208@acm.org>
	<d11dcfba0705182340h17e26435u91fc0c1ecccbf163@mail.gmail.com>
	<61964.80.195.169.49.1179559363.squirrel@webmail.marooned.org.uk>
	<d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>
	<91ad5bf80705200931q53325a33t3bc231306382af09@mail.gmail.com>
	<46508084.9080708@ronadam.com>
Message-ID: <d11dcfba0705201016y569bba60g64518bb7c322bae@mail.gmail.com>

On 5/20/07, Ron Adam <rrr at ronadam.com> wrote:
> George Sakkis wrote:
> > The semicolon proposal looks better, at least for this case:
> >
> > class Foo(object):
> >     def posfun(self, a; b, ...):
>
> I would also say identifying the semicolon isn't a problem.  After all
> we've been telling the difference between periods and comma's for quite a
> long time now with no difficulty.  So it's more a matter of just getting
> used to looking for it in function signatures.

Of course, in most Python code, there are spaces after commas, but not periods::

    (foo, bar, baz)
    foo.bar.baz

In the semi-colon proposal, the spacing around commas and semi-colons
will be exactly the same.

That said, I'd really like positional-only arguments one way or
another, so if they have to come with a semi-colon, I'm willing to
accept that.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From arno at marooned.org.uk  Sun May 20 20:59:29 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Sun, 20 May 2007 19:59:29 +0100 (BST)
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
	<d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>
	<464E8FF7.5000208@acm.org>
	<d11dcfba0705182340h17e26435u91fc0c1ecccbf163@mail.gmail.com>
	<61964.80.195.169.49.1179559363.squirrel@webmail.marooned.org.uk>
	<d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>
Message-ID: <64296.80.195.169.49.1179687569.squirrel@webmail.marooned.org.uk>


On Sun, May 20, 2007 4:24 pm, Steven Bethard wrote:
> On 5/19/07, Arnaud Delobelle <arno at marooned.org.uk> wrote:
[...]
>> * Would __self and __a be mangled, as is the rule within classes up to
>> now?  If so care has to be taken I suppose.
>
> I don't see any reason to mangle them.  The only time you'd ever
> notice is using locals().

I was asking because this means name mangling will have to be triggered
conditionally in this case.

>
> I've also noticed that the current @posonly decorator won't solve the
> dict() and dict.update() problem::
>
>>>> @posonly(2)
> ... def update(self, container=None, **kwargs):
> ...     print self, container, kwargs
> ...
>>>> update(self=1, other=2)
> Traceback (most recent call last):
>   File "<interactive input>", line 1, in <module>
>   File "<interactive input>", line 8, in posf
>     raise TypeError("%s() arg '%s' is posonly" % (name, kw))
> TypeError: update() arg 'self' is posonly

Yes.  I don't see how this can be avoided in pure Python.  But I came up
with the solution below (I'm not saying it's good :)

def posonly(arg=0, safe_kwargs=False):
    def deco(f, nposargs=0):
        name = f.__name__
        if nposargs == 0: nposargs = f.func_code.co_argcount
        if safe_kwargs: nposargs += 1
        posargnames = f.func_code.co_varnames[:nposargs]
        if safe_kwargs:
            def posf(*args, **kwargs):
                safe_kwargs = dict((k, kwargs.pop(k)) for k in posargnames
                                   if kwargs.has_key(k))
                return f(safe_kwargs, *args, **kwargs)
        else:
            def posf(*args, **kwargs):
                for kw in kwargs:
                    if kw in posargnames:
                        raise TypeError("'%s()' arg %s is posonly"
                                         % (name, kw))
                return f(*args, **kwargs)
        posf.__name__ = name
        return posf
    if isinstance(arg, int):
        return lambda f: deco(f, arg)
    else:
        return deco(arg)

Note: again this is a 'proof of concept' implementation.  Perhaps I should
have started from my own implementation of 'posonly' instead of mine...

If the optional argument 'safe_kwargs' is set to True, then the decorated
function must provide an extra first positional argument which will
contain the keyword arguments whose name is one of the positional argument
names.

>>> class MyDict(object):
>>>    @posonly(2, safe_kwargs=True)
>>>    def update(safe_kwargs, self, container=None, **kwargs):
>>>        return self, container, safe_kwargs, kwargs

>>> d=MyDict()

>>> d.update({1:2}, self=3, other=5)
>>> (<__main__.MyDict object at 0x133c3d0>, {1: 2}, {'self': 3}, {'other':
5})

It solves the problem I think.  It's not the most elegant but the question
is whether the need for such a feature is strong enough to require new
syntax.  My personal opinion is that it isn't, as I've never needed it :) 
but I have limited experience.

One could imagine a 'all_safe_kwargs' optional argument to posonly that
would pack all the keyword arguments together and pass them on to the
decorated function so that dict.update could be written:

@posonly(2, all_safe_kwargs=True)
def update(kwargs, self, container=None):
    # All keyword args are now in 'kwargs'
    ...

-- 
Arnaud




From steven.bethard at gmail.com  Sun May 20 22:32:52 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Sun, 20 May 2007 14:32:52 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <64296.80.195.169.49.1179687569.squirrel@webmail.marooned.org.uk>
References: <d11dcfba0705181604q2186f9dfm2e52c262ac953a0f@mail.gmail.com>
	<464e780e.562683cf.2949.0fe8SMTPIN_ADDED@mx.google.com>
	<d11dcfba0705182115x6f221ab9nf8c5fe8e016d2c24@mail.gmail.com>
	<464E8FF7.5000208@acm.org>
	<d11dcfba0705182340h17e26435u91fc0c1ecccbf163@mail.gmail.com>
	<61964.80.195.169.49.1179559363.squirrel@webmail.marooned.org.uk>
	<d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>
	<64296.80.195.169.49.1179687569.squirrel@webmail.marooned.org.uk>
Message-ID: <d11dcfba0705201332j2327d8eem7d9550dedd0d328f@mail.gmail.com>

On 5/20/07, Arnaud Delobelle <arno at marooned.org.uk> wrote:
> On Sun, May 20, 2007 4:24 pm, Steven Bethard wrote:
> > I've also noticed that the current @posonly decorator won't solve the
> > dict() and dict.update() problem::
[snip]
> Yes.  I don't see how this can be avoided in pure Python.  But I came up
> with the solution below (I'm not saying it's good :)
[snip]
> >>> class MyDict(object):
> >>>    @posonly(2, safe_kwargs=True)
> >>>    def update(safe_kwargs, self, container=None, **kwargs):
> >>>        return self, container, safe_kwargs, kwargs

Since currently the only use case for positional-only arguments is the
dict() and dict.update() signature, I would simplify the decorator to
look like::

    def positional_kwargs(func):
        def func_with_positional_kwargs(*args, **kwargs):
            n_missing = func.func_code.co_argcount - len(args) - 1
            args += func.func_defaults[-n_missing - 1:-1]
            args += (kwargs,)
            return func(*args)
        functools.update_wrapper(func_with_positional_kwargs, func)
        return func_with_positional_kwargs

You could use it like::

    >>> class D(object):
    ...     @positional_kwargs
    ...     def __init__(self, container=None, kwargs={}):
    ...         print self, container, kwargs
    ...
    >>> d = D(self=1, container=2)
    <__main__.D object at 0x00F05E30> None {'self': 1, 'container': 2}

That's not too bad because you're just replacing **kwargs with
kwargs={}. And it's relatively easy to explain. I guess that would
cover all the use cases I care about.

I still lean slightly towards the lone '*' and '**' proposal,
particularly since one of them is already introduced by `PEP 3102`_,
but putting this decorator in functools is a good backup plan.

.. _PEP 3102: http://www.python.org/dev/peps/pep-3102/

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From george.sakkis at gmail.com  Mon May 21 02:11:04 2007
From: george.sakkis at gmail.com (George Sakkis)
Date: Sun, 20 May 2007 20:11:04 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
Message-ID: <91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>

On 5/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:

> So to write the dict() or dict.update() signatures, we'd write::
>
>     def update(*, self, container=None, **kwargs)
>
> And to write the signature from my example, we'd write::
>
>     def f(*, a, b=None, **, c=42, **kwargs)
>
> My only use cases are for functions with '*' at the beginning, because
> the only time I care about having positional only arguments is when I
> also have a **kwargs, and in that situation, I want *all* other
> arguments to be positional only.
>
> Does anyone have a use case that requires both positional-only and
> positional-or-keyword arguments?

I don't have a hard use case, but more of a good API design argument,
similar to those used to support the second subproposal of PEP 3102
(e.g. see [1]). Maybe it's just me but I often cannot find a good name
for a parameter (at least not when I first write it) or I think of a
more appropriate name later. I'd like to be able to go back and change
it, knowing it won't break anything as it is always passed
positionally. IOW, it's a way to say "these names are not part of the
function's signature" and enforce this rather than just document it.

For instance, think of a function that initially was designed to work
for sequences and was defined as "def f(sequence, **kwds)". Later the
implementor realizes that the same function works (or its
implementation can easily change so that it works) for arbitrary
iterables. It would be nice to go back and change the signature to
"def f(iterable, **kwds)", knowing that nobody is calling it as
f(sequence=range(10)).

George


[1] http://mail.python.org/pipermail/python-dev/2006-May/064695.html

-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."


From steven.bethard at gmail.com  Mon May 21 02:26:23 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Sun, 20 May 2007 18:26:23 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
Message-ID: <d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>

On 5/20/07, George Sakkis <george.sakkis at gmail.com> wrote:
> On 5/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:
>
> > So to write the dict() or dict.update() signatures, we'd write::
> >
> >     def update(*, self, container=None, **kwargs)
> >
> > And to write the signature from my example, we'd write::
> >
> >     def f(*, a, b=None, **, c=42, **kwargs)
> >
> > My only use cases are for functions with '*' at the beginning, because
> > the only time I care about having positional only arguments is when I
> > also have a **kwargs, and in that situation, I want *all* other
> > arguments to be positional only.
> >
> > Does anyone have a use case that requires both positional-only and
> > positional-or-keyword arguments?
[snip]
> For instance, think of a function that initially was designed to work
> for sequences and was defined as "def f(sequence, **kwds)". Later the
> implementor realizes that the same function works (or its
> implementation can easily change so that it works) for arbitrary
> iterables. It would be nice to go back and change the signature to
> "def f(iterable, **kwds)", knowing that nobody is calling it as
> f(sequence=range(10)).

This is a good example for why you might want positional-only
arguments.  But I guess I wasn't clear -- I'm looking for an example
where you need both a positional-only argument and a
positional-or-keyword argument *in the same signature*.

The reason I ask is that I'd like to propose that the lone * can only
appear at the beginning of the signature. That would cover the dict()
and dict.update() use cases as well as your use case above::

    def f(*, sequence, **kwds)

Are there any use cases that it wouldn't cover? Seems like the
cautious programmer from your example above would want all of his
positional arguments to be positional-only.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From george.sakkis at gmail.com  Mon May 21 04:14:05 2007
From: george.sakkis at gmail.com (George Sakkis)
Date: Sun, 20 May 2007 22:14:05 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
Message-ID: <91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>

On 5/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:

> On 5/20/07, George Sakkis <george.sakkis at gmail.com> wrote:
> > On 5/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> >
> > > So to write the dict() or dict.update() signatures, we'd write::
> > >
> > >     def update(*, self, container=None, **kwargs)
> > >
> > > And to write the signature from my example, we'd write::
> > >
> > >     def f(*, a, b=None, **, c=42, **kwargs)
> > >
> > > My only use cases are for functions with '*' at the beginning, because
> > > the only time I care about having positional only arguments is when I
> > > also have a **kwargs, and in that situation, I want *all* other
> > > arguments to be positional only.
> > >
> > > Does anyone have a use case that requires both positional-only and
> > > positional-or-keyword arguments?
> [snip]
> > For instance, think of a function that initially was designed to work
> > for sequences and was defined as "def f(sequence, **kwds)". Later the
> > implementor realizes that the same function works (or its
> > implementation can easily change so that it works) for arbitrary
> > iterables. It would be nice to go back and change the signature to
> > "def f(iterable, **kwds)", knowing that nobody is calling it as
> > f(sequence=range(10)).
>
> This is a good example for why you might want positional-only
> arguments.  But I guess I wasn't clear -- I'm looking for an example
> where you need both a positional-only argument and a
> positional-or-keyword argument *in the same signature*.
>
> The reason I ask is that I'd like to propose that the lone * can only
> appear at the beginning of the signature. That would cover the dict()
> and dict.update() use cases as well as your use case above::
>
>     def f(*, sequence, **kwds)
>
> Are there any use cases that it wouldn't cover? Seems like the
> cautious programmer from your example above would want all of his
> positional arguments to be positional-only.

Are you proposing the removal of positional-or-keyword arguments
altogether or only in the presence of positional-only ? In the former
case, perhaps this needs a separate thread on its own as it's too big
of a change. In the latter case, whatever reasons one has for using
positional-or-keyword arguments, chances are that they will hold also
in the presence of positional-only.

Honestly, I can't think of a compelling reason for
positional-or-keyword arguments (with or without the presence of
positional-only in the same signature) other than that by definition
offer two ways to the caller to spell the same thing. Even that could
be considered a misfeature since it goes against TOOWTDI. In any case,
that's more of a language design and philosophy argument ("should the
caller of a function have the freedom on how to pass the arguments or
that should be decided only by the function writer ?") rather than a
hard use case.

George

-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."


From steven.bethard at gmail.com  Mon May 21 04:35:37 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Sun, 20 May 2007 20:35:37 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
Message-ID: <d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>

On 5/20/07, George Sakkis <george.sakkis at gmail.com> wrote:
> Are you proposing the removal of positional-or-keyword arguments

No. My current proposal is:

- Everything after a * is a positional-only argument, up to the first **
- Everything after a ** is a keyword-only argument
- A lone * may only appear at the beginning of the signature

In essence, this is changing the lone * of `PEP 3102`_ into a lone **,
and allowing a lone * at the beginning of the signature to indicate
that all positional arguments are positional-only.

.. _PEP 3102: http://www.python.org/dev/peps/pep-3102/

That means that in the following signature::

    def f(*, a, b=None, *args, **, c=42, **kwargs)

- 'a' and 'b' are positional-only
- 'args' is positional-only (as usual)
- 'c' is keyword-only
- 'kwargs' is keyword-only (as usual)

If you want positional-or-keyword arguments, simply omit the initial *::

    def f(a, b=None, *args, **, c=42, **kwargs)

- 'a' and 'b' are positional-or-keyword (as usual)
- 'args' is positional-only (as usual)
- 'c' is keyword-only
- 'kwargs' is keyword-only (as usual)

If you want keyword-only arguments with no *args, simply omit it::

    def f(a, b=None, **, c=42, **kwargs)

- 'a' and 'b' are positional-or-keyword (as usual)
- 'c' is keyword-only
- 'kwargs' is keyword-only (as usual)

Does anyone have use cases that this doesn't cover?

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From aahz at pythoncraft.com  Mon May 21 06:24:57 2007
From: aahz at pythoncraft.com (Aahz)
Date: Sun, 20 May 2007 21:24:57 -0700
Subject: [Python-ideas] Ideas towards GIL removal
In-Reply-To: <4622BAD4.2020706@canterbury.ac.nz>
References: <461ED2F9.9020407@canterbury.ac.nz> <46225CE4.4040207@acm.org>
	<bbaeab100704151252u3ef30786qb45c2ea20f6f9269@mail.gmail.com>
	<4622BAD4.2020706@canterbury.ac.nz>
Message-ID: <20070521042456.GA26693@panix.com>

On Mon, Apr 16, 2007, Greg Ewing wrote:
> Brett Cannon wrote:
>>
>> And I know some people love the (mostly) instantaneous garbage
>> collection when the refcount should be at 0.
>
> Yeah, and even a 6 millisecond pause could be too long in some
> applications, such as high frame rate animation.  6 milliseconds is a
> *long* time for today's GHz processors.

Hrm.  Assuming that really is the maximum, I don't think it's an issue
for Python applications: 6ms slices still allow for >150 frames/sec.  If
overall object creation/destruction throughput is increased or this
allows greater throughput on multi-core machines without dramatically
decreasing performance for single-CPU machines, it may well be
worthwhile.

But my primary concern remains the issue of Python being a glue language
with external libraries: the GIL is one of our best weapons for making
it easy.  This approach seems like it would be easier to integrate than
other options I've seen.
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"Look, it's your affair if you want to play with five people, but don't
go calling it doubles."  --John Cleese anticipates Usenet


From rhamph at gmail.com  Mon May 21 08:36:42 2007
From: rhamph at gmail.com (Adam Olsen)
Date: Mon, 21 May 2007 00:36:42 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
Message-ID: <aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>

On 5/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> On 5/20/07, George Sakkis <george.sakkis at gmail.com> wrote:
> > Are you proposing the removal of positional-or-keyword arguments
>
> No. My current proposal is:
>
> - Everything after a * is a positional-only argument, up to the first **
> - Everything after a ** is a keyword-only argument
> - A lone * may only appear at the beginning of the signature
>
> In essence, this is changing the lone * of `PEP 3102`_ into a lone **,
> and allowing a lone * at the beginning of the signature to indicate
> that all positional arguments are positional-only.
>
> .. _PEP 3102: http://www.python.org/dev/peps/pep-3102/
>
> That means that in the following signature::
>
>     def f(*, a, b=None, *args, **, c=42, **kwargs)
>
> - 'a' and 'b' are positional-only
> - 'args' is positional-only (as usual)
> - 'c' is keyword-only
> - 'kwargs' is keyword-only (as usual)
>
> If you want positional-or-keyword arguments, simply omit the initial *::
>
>     def f(a, b=None, *args, **, c=42, **kwargs)

** is redundant here.  You get the same behaviour without it:

    def f(a, b=None, *args, c=42, **kwargs)

See below though.


> - 'a' and 'b' are positional-or-keyword (as usual)
> - 'args' is positional-only (as usual)
> - 'c' is keyword-only
> - 'kwargs' is keyword-only (as usual)
>
> If you want keyword-only arguments with no *args, simply omit it::
>
>     def f(a, b=None, **, c=42, **kwargs)
>
> - 'a' and 'b' are positional-or-keyword (as usual)
> - 'c' is keyword-only
> - 'kwargs' is keyword-only (as usual)
>
> Does anyone have use cases that this doesn't cover?

I initially had the same reservations you do about my proposal, but
now I think there's a bigger problem: it undermines the obviousness of
PEP 3102's behaviour.

Consider this example:

    def compare(a, b, *args, key=None):

Although not legal today, the behaviour is obvious.  All positional
arguments get sucked up in *args so key *must* be keyword-only.  That
leads to this variant:

    def compare(a, b, *, key=None):

You continue sucking up extra positional args, but since it's nameless
there must be none of them.  Again, obvious.  Changing the token
required from * to ** or giving * extra behaviour when nameless just
isn't obvious.

Most of the proposed syntax changes also have a question of whether or
not to include *args:
  "def f(a, *, *args)" or "def(a, *args, *)"?
  "def f((a), *args)" or "def f((a, *args))"?
  "def f(__a, *args)" or "def(__a, *__args)"?

Finally (I hope) is the problem of motivation.  Where as PEP 3102 is
motivated by "explicit is better than implicit", positional-only
arguments actually *want* implicit!  It seems to be more for
completeness and "C functions already support it".

-1 on any syntax changes.  A decorator may be okay, but I'm unsure the
use cases are significant enough to warrant adding it.  Go figure.

-- 
Adam Olsen, aka Rhamphoryncus


From steven.bethard at gmail.com  Mon May 21 08:58:43 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Mon, 21 May 2007 00:58:43 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
Message-ID: <d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>

On 5/21/07, Adam Olsen <rhamph at gmail.com> wrote:
> On 5/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> > No. My current proposal is:
> >
> > - Everything after a * is a positional-only argument, up to the first **
> > - Everything after a ** is a keyword-only argument
> > - A lone * may only appear at the beginning of the signature
> >
> > In essence, this is changing the lone * of `PEP 3102`_ into a lone **,
> > and allowing a lone * at the beginning of the signature to indicate
> > that all positional arguments are positional-only.
> >
> > .. _PEP 3102: http://www.python.org/dev/peps/pep-3102/
> >
> > That means that in the following signature::
> >
> >     def f(*, a, b=None, *args, **, c=42, **kwargs)
> >
> > - 'a' and 'b' are positional-only
> > - 'args' is positional-only (as usual)
> > - 'c' is keyword-only
> > - 'kwargs' is keyword-only (as usual)
> >
> > If you want positional-or-keyword arguments, simply omit the initial *::
> >
> >     def f(a, b=None, *args, **, c=42, **kwargs)
>
> ** is redundant here.  You get the same behaviour without it:
>
>     def f(a, b=None, *args, c=42, **kwargs)
>
> See below though.

I note that below you argue for explicit is better than implicit.
Requiring the ** even when it could be inferred from the *args is a
good example of EIBTI.  I don't have strong feelings on this issue
though.

> I initially had the same reservations you do about my proposal, but
> now I think there's a bigger problem: it undermines the obviousness of
> PEP 3102's behaviour.
[snip]
>
>     def compare(a, b, *, key=None):
>
> You continue sucking up extra positional args, but since it's nameless
> there must be none of them.  Again, obvious.

I have to disagree. The first thing I think when I see a lone * is
multiplication, not "keyword-only arguments start after me". I would
say it's just as obvious to see::

    def g(*, a, b)

and say, "oh, it's after a * so it must be positional-only just like
*args is". That is, I don't think the PEP 3102 meaning for lone * is
any more intuitive than the meaning I'm proposing here.

> Where as PEP 3102 is motivated by "explicit is better than implicit",
> positional-only arguments actually *want* implicit!

I don't follow this logic. How is a positional-only argument more
implicit?  You still have to supply it on every function call.  It's
not like you can omit it.  Or are you saying that using positional
arguments instead of keyword arguments is implicit?

> A decorator may be okay, but I'm unsure the
> use cases are significant enough to warrant adding it.

Just for reference, here are the current motivating use cases:

* User mapping types that need to match the dict() and dict.update()
method signatures
* Code where positional argument names might change, e.g. George's def
f(sequence) which later becomes def f(iterable)

Particularly since user mappings are relatively common, I do think
this issue deserves at least a decorator.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From steven.bethard at gmail.com  Mon May 21 09:08:58 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Mon, 21 May 2007 01:08:58 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
Message-ID: <d11dcfba0705210008o58639306ia9b319be13bf139@mail.gmail.com>

On 5/21/07, Adam Olsen <rhamph at gmail.com> wrote:
> now I think there's a bigger problem: it undermines the obviousness of
> PEP 3102's behaviour.
>
> Consider this example:
>
>     def compare(a, b, *args, key=None):
>
> Although not legal today, the behaviour is obvious.  All positional
> arguments get sucked up in *args so key *must* be keyword-only.

This may not be so obvious anymore now that we have extended iterable
unpacking from `PEP 3132`_.  Given an iterable unpacking like::

    a, b, *c, d = iterable

I may assume that names after a *args work just like names before one::

    def f(a, b, *c, d)

So in this case I'd assume that the 'd' is also positional, not keyword-only.

Again, I'm not saying people can't learn the appropriate meaning, just
that it's not inherently obvious.

.. _PEP 3132: http://www.python.org/dev/peps/pep-3132/

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From greg.ewing at canterbury.ac.nz  Mon May 21 09:07:12 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Mon, 21 May 2007 19:07:12 +1200
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
Message-ID: <46514520.2040907@canterbury.ac.nz>

Steven Bethard wrote:
> That means that in the following signature::
> 
>     def f(*, a, b=None, *args, **, c=42, **kwargs)

I don't like this. Having more than one * or ** in
the same signature seems like it would be very confusing.

I think the desire for positional-only args would be
addressed well enough using a naming convention. Even
without further explanation, if I saw something like

   def f(_a, _b, _c):
     ...

it would be pretty clear to me that the author intended
the parameter names to be an implementation detail.

This could even be enforced if relying on a convention
were not considered strong enough, although it would
be more consistent to insist on a double underscore to
get automatic enforcement.

--
Greg


From steven.bethard at gmail.com  Mon May 21 09:15:49 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Mon, 21 May 2007 01:15:49 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <46514520.2040907@canterbury.ac.nz>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<46514520.2040907@canterbury.ac.nz>
Message-ID: <d11dcfba0705210015r4991d1easa2f95d86d8290f1@mail.gmail.com>

On 5/21/07, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> I think the desire for positional-only args would be
> addressed well enough using a naming convention. Even
> without further explanation, if I saw something like
>
>    def f(_a, _b, _c):
>      ...
>
> it would be pretty clear to me that the author intended
> the parameter names to be an implementation detail.

So what about the signature for dict() and dict.update() where you
want to write::

    def update(self, container=None, **kwargs)

Note that I shouldn't want to write '__container' because it's not an
implementation detail.  It's a valid positional argument that my
clients can use.  But if I write 'container', then I'm limiting what
they can send as **kwargs and I can't reproduce the dict behavior::

    >>> d = {}
    >>> d.update(container=1)
    >>> d
    {'container': 1}

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From greg.ewing at canterbury.ac.nz  Mon May 21 09:14:57 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Mon, 21 May 2007 19:14:57 +1200
Subject: [Python-ideas] Ideas towards GIL removal
In-Reply-To: <20070521042456.GA26693@panix.com>
References: <461ED2F9.9020407@canterbury.ac.nz> <46225CE4.4040207@acm.org>
	<bbaeab100704151252u3ef30786qb45c2ea20f6f9269@mail.gmail.com>
	<4622BAD4.2020706@canterbury.ac.nz> <20070521042456.GA26693@panix.com>
Message-ID: <465146F1.2090408@canterbury.ac.nz>

Aahz wrote:
 >
> On Mon, Apr 16, 2007, Greg Ewing wrote:
> 
 > > even a 6 millisecond pause could be too long in some
> > applications, such as high frame rate animation.
>
> 6ms slices still allow for >150 frames/sec.

Only if you don't want to do anything else during your frame.
At 50fps, 6ms is nearly one-third of your frame time.

However, I tend to agree that this approach has the greatest
chance of succeeding of any suggestion I've seen so far.

--
Greg


From greg.ewing at canterbury.ac.nz  Mon May 21 09:39:34 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Mon, 21 May 2007 19:39:34 +1200
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
	<d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
Message-ID: <46514CB6.6050203@canterbury.ac.nz>

Steven Bethard wrote:

> I don't think the PEP 3102 meaning for lone * is
> any more intuitive than the meaning I'm proposing here.

Although I wouldn't go so far as to call the PEP 3102
behaviour "obvious", it is a fairly *logical* extension
of the existing semantics.

On the other hand, a rule like "arguments after a lone *
are positional-only" is something new and arbitrary. It
doesn't follow logically from anything existing.

Also, your proposal assigns two quite different meanings
to *. If it's followed by a name, it sucks up all remaining
positional args, but if it's not, it can't suck up
anything, since it's followed by more positional args!

--
Greg


From greg.ewing at canterbury.ac.nz  Mon May 21 09:45:31 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Mon, 21 May 2007 19:45:31 +1200
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705210008o58639306ia9b319be13bf139@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
	<d11dcfba0705210008o58639306ia9b319be13bf139@mail.gmail.com>
Message-ID: <46514E1B.9070904@canterbury.ac.nz>

Steven Bethard wrote:
> On 5/21/07, Adam Olsen <rhamph at gmail.com> wrote:
> 
> > All positional
> > arguments get sucked up in *args so key *must* be keyword-only.
> 
> This may not be so obvious anymore now that we have extended iterable
> unpacking from `PEP 3132`_.  Given an iterable unpacking like::
> 
>     a, b, *c, d = iterable

I'm not in favour of allowing a * which isn't at the end
here, for various reasons, one of which is that it weakens
the analogy with call signatures.

--
Greg


From steven.bethard at gmail.com  Mon May 21 10:16:57 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Mon, 21 May 2007 02:16:57 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <46514E1B.9070904@canterbury.ac.nz>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
	<d11dcfba0705210008o58639306ia9b319be13bf139@mail.gmail.com>
	<46514E1B.9070904@canterbury.ac.nz>
Message-ID: <d11dcfba0705210116m906870cy3af266592da14d79@mail.gmail.com>

On 5/21/07, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Steven Bethard wrote:
> > On 5/21/07, Adam Olsen <rhamph at gmail.com> wrote:
> >
> > > All positional
> > > arguments get sucked up in *args so key *must* be keyword-only.
> >
> > This may not be so obvious anymore now that we have extended iterable
> > unpacking from `PEP 3132`_.  Given an iterable unpacking like::
> >
> >     a, b, *c, d = iterable
>
> I'm not in favour of allowing a * which isn't at the end
> here, for various reasons, one of which is that it weakens
> the analogy with call signatures.

I wasn't either, but I believe the PEP has already been accepted and
implemented.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From steven.bethard at gmail.com  Mon May 21 10:18:58 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Mon, 21 May 2007 02:18:58 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <46514CB6.6050203@canterbury.ac.nz>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
	<d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
	<46514CB6.6050203@canterbury.ac.nz>
Message-ID: <d11dcfba0705210118s6c99308bu2fba729d376ff6d3@mail.gmail.com>

On 5/21/07, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Also, your proposal assigns two quite different meanings
> to *. If it's followed by a name, it sucks up all remaining
> positional args, but if it's not, it can't suck up
> anything, since it's followed by more positional args!

Note this is also true of the * in PEP 3102.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From rrr at ronadam.com  Mon May 21 19:18:28 2007
From: rrr at ronadam.com (Ron Adam)
Date: Mon, 21 May 2007 12:18:28 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
	<d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
Message-ID: <4651D464.2020806@ronadam.com>

Steven Bethard wrote:
> On 5/21/07, Adam Olsen <rhamph at gmail.com> wrote:
>> On 5/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:
>>> No. My current proposal is:
>>>
>>> - Everything after a * is a positional-only argument, up to the first **
>>> - Everything after a ** is a keyword-only argument
>>> - A lone * may only appear at the beginning of the signature
>>>
>>> In essence, this is changing the lone * of `PEP 3102`_ into a lone **,
>>> and allowing a lone * at the beginning of the signature to indicate
>>> that all positional arguments are positional-only.
>>>
>>> .. _PEP 3102: http://www.python.org/dev/peps/pep-3102/
>>>
>>> That means that in the following signature::
>>>
>>>     def f(*, a, b=None, *args, **, c=42, **kwargs)
>>>
>>> - 'a' and 'b' are positional-only
>>> - 'args' is positional-only (as usual)
>>> - 'c' is keyword-only
>>> - 'kwargs' is keyword-only (as usual)
>>>
>>> If you want positional-or-keyword arguments, simply omit the initial *::
>>>
>>>     def f(a, b=None, *args, **, c=42, **kwargs)
>> ** is redundant here.  You get the same behaviour without it:
>>
>>     def f(a, b=None, *args, c=42, **kwargs)
>>
>> See below though.
> 
> I note that below you argue for explicit is better than implicit.
> Requiring the ** even when it could be inferred from the *args is a
> good example of EIBTI.  I don't have strong feelings on this issue
> though.
> 
>> I initially had the same reservations you do about my proposal, but
>> now I think there's a bigger problem: it undermines the obviousness of
>> PEP 3102's behaviour.
> [snip]
>>     def compare(a, b, *, key=None):
>>
>> You continue sucking up extra positional args, but since it's nameless
>> there must be none of them.  Again, obvious.
> 
> I have to disagree. The first thing I think when I see a lone * is
> multiplication, not "keyword-only arguments start after me". I would
> say it's just as obvious to see::
> 
>     def g(*, a, b)
> 
> and say, "oh, it's after a * so it must be positional-only just like
> *args is". That is, I don't think the PEP 3102 meaning for lone * is
> any more intuitive than the meaning I'm proposing here.


I agree with Greg, it seems arbitrary.  The number of meanings for the '*' 
is also growing too large I think.

     *   multiply
     *   pack in function defs            # but at call time.
     *   pack in left hand expressions    # left of '='
     *   unpack in function calls
     *   positional only indicator in function defs

     **  power
     **  pack dictionary in functions defs
     **  unpack dictionary in function calls
     **  keyword only indicator in function defs


I'm sure this will get confusing to new users.  Yes, each one is clear by 
context, but there's a lot of subtle behaviors by context going on here.


What I would like is for unpack to be '^' instead of '*', then you would 
have...

Packing operations:

     *   multiply
     *   pack in function defs
     *   pack in left hand expressions

     **  power
     **  pack dictionary in functions defs

Unpacking operations:

     ^   unpack in function calls
     ^   unpack in right hand expressions   (possible)
     ^   positional only in function defs   (See why I think so below)

     ^^  unpack dictionary in function calls
     ^^  keyword only in function defs      (also see below)


I think these become much easier to parse visually and mentally, so it's 
more of a human interface issue than a computer parsing issue.


When using the "name=value" form in function definitions, it can be a 
positional or keyword argument.  So all you need is a way to say this is 
either one or the other.

(Using * here to show similarity, introducing the '^' further down.)

      *(b=2, c=3)    positional only args
      *args          rest of args

      **(b=2, c=3)   keywords only kwds
      **kwds         rest of keywords

def f(a, *(b=2, c=3), *args)       # b and c are positional only

def f(a, **(b=2, c=3), **kwds)     # b and c are keyword only

Now the problem with this is when it's use with the *() and **() form, it 
resembles unpacking behavior, but in the *args, and **kwds form, it's 
packing behavior.  Normally you would have only packing in a function def 
and unpacking in a function call.



Now if we use ^ for unpacking, and * for packing, it reduces the number of 
meanings for the '*' and fixes the context of positional and keyword only 
arguments.

def f(a, ^(b=2, c=3), *rest):   b and c are positional only here.

def f(a, d=5, ^^(b=2, c=3), **rest_kwds):   # b and c are keywords only here.

I feel this code better expresses it's intent.  Think of the ^() as unpack 
these as args, and **() as unpack these as keywords.


If '^' is used outside of function defs like the '*', it can retain it's 
meaning.

a, b, *c = 1, 2, 3, 4, 5    # pack remainder

z = (x, y, z)
a, b, c, d = (a, ^z)        # unpack z



There is the possibility of extending this for use in other ways as well.

xlist = [[1, 2], [3, 4, 5], [6, 7, 8, 9]]

alist = [^x for x in xlist]

This would have list "extend" behavior instead of list "append" behavior.



Ok, just some possible ideas of how to organize all this.

Cheers,
    Ron









>> Where as PEP 3102 is motivated by "explicit is better than implicit",
>> positional-only arguments actually *want* implicit!
> 
> I don't follow this logic. How is a positional-only argument more
> implicit?  You still have to supply it on every function call.  It's
> not like you can omit it.  Or are you saying that using positional
> arguments instead of keyword arguments is implicit?
> 
>> A decorator may be okay, but I'm unsure the
>> use cases are significant enough to warrant adding it.
> 
> Just for reference, here are the current motivating use cases:
> 
> * User mapping types that need to match the dict() and dict.update()
> method signatures
> * Code where positional argument names might change, e.g. George's def
> f(sequence) which later becomes def f(iterable)
> 
> Particularly since user mappings are relatively common, I do think
> this issue deserves at least a decorator.
> 
> STeVe



From steven.bethard at gmail.com  Mon May 21 19:55:04 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Mon, 21 May 2007 11:55:04 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <4651D464.2020806@ronadam.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
	<d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
	<4651D464.2020806@ronadam.com>
Message-ID: <d11dcfba0705211055r2093e8e2t76af5167e835a13b@mail.gmail.com>

On 5/21/07, Ron Adam <rrr at ronadam.com> wrote:
> Steven Bethard wrote:
> > On 5/21/07, Adam Olsen <rhamph at gmail.com> wrote:
> >>
> >>     def compare(a, b, *, key=None):
> >>
> >> You continue sucking up extra positional args, but since it's nameless
> >> there must be none of them.  Again, obvious.
> >
> > I have to disagree. The first thing I think when I see a lone * is
> > multiplication, not "keyword-only arguments start after me". I would
> > say it's just as obvious to see::
> >
> >     def g(*, a, b)
> >
> > and say, "oh, it's after a * so it must be positional-only just like
> > *args is". That is, I don't think the PEP 3102 meaning for lone * is
> > any more intuitive than the meaning I'm proposing here.
>
> I agree with Greg, it seems arbitrary.  The number of meanings for the '*'
> is also growing too large I think.

Yes, both my proposal and the PEP 3102 use of * are pretty arbitrary,
and I agree that we're probably getting too many uses of *.  I'm going
to try to post a decorator that I think will cover the use cases so
far.

> What I would like is for unpack to be '^' instead of '*'

-1.  This is at least as arbitrary as any of the '*', '**' or ';'
suggestions, so I see no reason to prefer it.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From steven.bethard at gmail.com  Mon May 21 20:30:38 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Mon, 21 May 2007 12:30:38 -0600
Subject: [Python-ideas] positional only arguments decorator
Message-ID: <d11dcfba0705211130y6163556ica7f30d62de6258f@mail.gmail.com>

Ok, looks like there's not much chance of agreeing on a syntax, so
here's a decorator that covers the two use cases I know of::

* matching the signature of dict() and dict.update()
* allowing arguments to have their names changed without worrying
about backwards compatibility (e.g. ``def func(sequence)`` changing to
``def func(iterable)``)

I've pasted the docstring and code below.  The docstring should give
you a pretty good idea of the functionality.  Let me know if you have
use cases this wouldn't cover.

"""
Functions declared ad @positional_only prohibit any arguments from being
passed in as keyword arguments::

    >>> @positional_only
    ... def foo(a, b=None, *args):
    ...     return a, b, args
    ...
    >>> foo(1, 2, 3)
    (1, 2, (3,))
    >>> foo(a=1, b=2)
    Traceback (most recent call last):
      ...
    TypeError: foo() does not allow keyword arguments

Note that you can't use **kwargs arguments with a @positional_only
function::

    >>> @positional_only
    ... def foo(a, b=None, **kwargs):
    ...     pass
    ...
    Traceback (most recent call last):
      ...
    TypeError: foo() may not have **kwargs

If you need the functionality of **kwargs, you can request it by
adding a final argument with the name _kwargs. The keyword arguments
will be passed in (as a dict) through this argument::

    >>> @positional_only
    ... def foo(a, b=None, _kwargs=None):
    ...     return a, b, _kwargs
    ...
    >>> foo(1)
    (1, None, {})
    >>> foo(1, 2)
    (1, 2, {})
    >>> foo(1, bar=42, baz='spam')
    (1, None, {'baz': 'spam', 'bar': 42})

When your function is called with the wrong number of arguments, your
callers will only see the number of arguments they expected. That is,
argument counts will not include the _kwargs argument::

    >>> foo()
    Traceback (most recent call last):
      ...
    TypeError: foo() takes at least 1 positional argument(s) (0 given)
    >>> foo(1, 2, 3)
    Traceback (most recent call last):
      ...
    TypeError: foo() takes at most 2 positional argument(s) (3 given)

Note that unlike a normal **kwargs, using _kwargs in a
@positional_only function causes *all* keyword arguments to be
collected, even those with the same names as other function
parameters::

    >>> foo(1, a=42, b='spam')
    (1, None, {'a': 42, 'b': 'spam'})
    >>> foo(1, _kwargs='this is just silly')
    (1, None, {'_kwargs': 'this is just silly'})

This is of course because all function parameters are considered to
be positional only and therefore unnamed for the purposes of argument
parsing.

Note that you cannot use *args or **kwargs with the _kwargs argument::

    >>> @positional_only
    ... def foo(a, b, _kwargs, *args):
    ...     pass
    ...
    Traceback (most recent call last):
      ...
    TypeError: foo() may not have *args
    >>> @positional_only
    ... def foo(a, b, _kwargs, **kwargs):
    ...     pass
    ...
    Traceback (most recent call last):
      ...
    TypeError: foo() may not have **kwargs

"""

import doctest
import inspect
import functools

def positional_only(func):
    name = func.__name__

    # don't allow **kwargs
    arg_names, args_name, kwargs_name, _ = inspect.getargspec(func)
    if kwargs_name is not None:
        raise TypeError('%s() may not have **kwargs' % name)

    # if no keyword arguments were requested, create a wrapper that
    # only accepts positional arguments (as *args)
    if not arg_names or arg_names[-1] != '_kwargs':

        # wrapper that raises an error for **kwargs
        def positional_wrapper(*args, **kwargs):
            if kwargs:
                msg = '%s() does not allow keyword arguments'
                raise TypeError(msg % name)
            return func(*args)

    # if keyword arguments were requested (through a final _kwargs),
    # create a wrapper that collects **kwargs and passes them in as
    # the final positional argument
    else:

        # don't allow *args
        if args_name is not None:
            msg = '%s() may not have *args'
            raise TypeError(msg % func.__name__)

        # determine defaults and expected argument counts
        defaults = func.func_defaults
        defaults = defaults and defaults[:-1] or []
        n_expected = func.func_code.co_argcount - 1
        min_expected = n_expected - len(defaults)

        def positional_wrapper(*args, **kwargs):
            # raise a TypeError for wrong number of arguments here
            # because func() needs to take the extra 'kwargs'
            # argument but the caller shouldn't know it
            arg_count_err = None
            if len(args) < min_expected:
                arg_count_err = 'at least %i' % min_expected
            if len(args) > n_expected:
                arg_count_err = 'at most %i' % n_expected
            if arg_count_err is not None:
                msg = '%s() takes %s positional argument(s) (%i given)'
                raise TypeError(msg % (name, arg_count_err, len(args)))

            # fill in defaults and add the final _kwargs argument,
            # then call the function with only positional arguments
            n_missing = n_expected - len(args)
            args += func.func_defaults[-n_missing - 1:-1]
            args += (kwargs,)
            return func(*args)

    # return the wrapped function
    functools.update_wrapper(positional_wrapper, func)
    return positional_wrapper

if __name__ == '__main__':
    doctest.testmod()


STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From jimjjewett at gmail.com  Tue May 22 00:47:01 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Mon, 21 May 2007 18:47:01 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705210015r4991d1easa2f95d86d8290f1@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<46514520.2040907@canterbury.ac.nz>
	<d11dcfba0705210015r4991d1easa2f95d86d8290f1@mail.gmail.com>
Message-ID: <fb6fbf560705211547l2dba57b1k8a773a7cfcdeed8a@mail.gmail.com>

On 5/21/07, Steven Bethard <steven.bethard at gmail.com> wrote:

>     def update(self, container=None, **kwargs)

> Note that I shouldn't want to write '__container' because it's not an
> implementation detail.

Yes, it is.

The fact that there *is* a parameter there isn't an implementation
detail, but the *choice of name* for that parameter is explicitly an
implementation detail -- if it weren't, then you wouldn't need to
insist on positional-only calling.

-jJ


From jimjjewett at gmail.com  Tue May 22 00:57:24 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Mon, 21 May 2007 18:57:24 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <4651D464.2020806@ronadam.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
	<d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
	<4651D464.2020806@ronadam.com>
Message-ID: <fb6fbf560705211557s781f10e4i645daab1dd2071ab@mail.gmail.com>

> What I would like is for unpack to be '^' instead of '*', then you would
> have...

My first reaction was negative -- but then I remembered that I was
caught by this trap myself more than once, because of the asymmetry
between pack and unpack, with * magically doing the normally-right
thing.

So now I wonder if I wouldn't like if after all, and I'm instead
picking at the presentation, so you can make a stronger case.

On 5/21/07, Ron Adam <rrr at ronadam.com> wrote:

> Now if we use ^ for unpacking, and * for packing, it reduces the number of
> meanings for the '*' and fixes the context of positional and keyword only
> arguments.

> def f(a, ^(b=2, c=3), *rest):   b and c are positional only here.

I don't think there should ever be positional-only arguments *after* a
keywordable argument.  Perhaps

    # a is a mandatory positional argument
    # b is an optional positional argument
    # c can be passed as a keyword, or as the third positional argument
    def f(^a, ^b=2, c=3, *rest):

Or were you suggesting a tuple of the positional-only arguments, like

    # a is a mandatory positional argument
    # b is an optional positional argument
    # c can be passed as a keyword, or as the third positional argument
    def f(^(a, b=2), c=3, *rest):


> There is the possibility of extending this for use in other ways as well.
>
> xlist = [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
>
> alist = [^x for x in xlist]
>
> This would have list "extend" behavior instead of list "append" behavior.

So alist == [1, 2, 3, 4, 5, 6, 7, 8, 9]?

-jJ


From castironpi at comcast.net  Tue May 22 00:59:51 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Mon, 21 May 2007 17:59:51 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>
Message-ID: <20070521225954.119641E4005@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Steven Bethard
> Sent: Sunday, May 20, 2007 10:24 AM
> 
> I've also noticed that the current @posonly decorator won't solve the
> dict() and dict.update() problem::
> 
> >>> @posonly(2)
> ... def update(self, container=None, **kwargs):
> ...     print self, container, kwargs
> ...
> >>> update(self=1, other=2)

Question on it, the example.  Is this not a feature of all UserDict
subclasses?  Yet we have that anyway.

>>> from UserDict import *
>>> class C(UserDict):
...     pass
...
>>> c= C( a=1, b=2 )
>>> print c
{'a': 1, 'b': 2}
>>> c.update( self=3 )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: update() got multiple values for keyword argument 'self'

Where are you -def-ing update?




From castironpi at comcast.net  Tue May 22 01:02:23 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Mon, 21 May 2007 18:02:23 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
Message-ID: <20070521230228.662421E400C@bag.python.org>



> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Steven Bethard
> Sent: Monday, May 21, 2007 1:59 AM
>
> I don't follow this logic. How is a positional-only argument more
> implicit?  You still have to supply it on every function call.  It's
> not like you can omit it.

Not sure about it.  If it's required, there is already support for it.  Only
omit the default value.

> Particularly since user mappings are relatively common, I do think
> this issue deserves at least a decorator.

+1



From steven.bethard at gmail.com  Tue May 22 01:07:06 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Mon, 21 May 2007 17:07:06 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <4652246a.047611f9.32bc.ffffd14dSMTPIN_ADDED@mx.google.com>
References: <d11dcfba0705200824i64704a3gb34433c073ecab4f@mail.gmail.com>
	<4652246a.047611f9.32bc.ffffd14dSMTPIN_ADDED@mx.google.com>
Message-ID: <d11dcfba0705211607udef7830ic3d868e1894df486@mail.gmail.com>

On 5/21/07, Aaron Brady <castironpi at comcast.net> wrote:
> Question on it, the example.  Is this not a feature of all UserDict
> subclasses?  Yet we have that anyway.
>
> >>> from UserDict import *
> >>> class C(UserDict):
> ...     pass
> ...
> >>> c= C( a=1, b=2 )
> >>> print c
> {'a': 1, 'b': 2}
> >>> c.update( self=3 )
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: update() got multiple values for keyword argument 'self'

Yes, it's a bug still present in UserDict. Using the @positional_only
decorator I posted in a separate thread, we can make it work
correctly::

    >>> class C(object):
    ...     @positional_only
    ...     def __init__(self, container=None, _kwargs=None):
    ...         print container, _kwargs
    ...
    >>> C(self=1, container=2)
    None {'self': 1, 'container': 2}

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From castironpi at comcast.net  Tue May 22 01:03:25 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Mon, 21 May 2007 18:03:25 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <4651D464.2020806@ronadam.com>
Message-ID: <20070521230834.701B11E4006@bag.python.org>


> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Ron Adam
> 
> If '^' is used outside of function defs like the '*', it can retain it's
> meaning.
> 
> a, b, *c = 1, 2, 3, 4, 5    # pack remainder
> 
> z = (x, y, z)
> a, b, c, d = (a, ^z)        # unpack z

Don't forget.  Any the things you want can be composed in hand.

> >>>     def f(*, a, b=None, *args, **, c=42, **kwargs)

def f( *args, **kwargs ):
	if len( args ) < 2: raise error
	if 'b' in kwargs: raise error
	if 'c' not in kwargs: raise error
	a, b, args = args[:2], args[2:]
	c = kwargs['c']

It's an approximation; use case to the contrary?



From rhamph at gmail.com  Tue May 22 03:52:46 2007
From: rhamph at gmail.com (Adam Olsen)
Date: Mon, 21 May 2007 19:52:46 -0600
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>
	<d11dcfba0705181407qa765928xec4f5d974a1a1973@mail.gmail.com>
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>
	<d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>
Message-ID: <aac2c7cb0705211852y4be88a38p24211a9d4bdaf3c5@mail.gmail.com>

On 5/21/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> Just for reference, here are the current motivating use cases:
>
> * User mapping types that need to match the dict() and dict.update()
> method signatures

I wasn't aware the proposals given would meet this use case!  PEP 3102
has no effect on correct code, instead it just adds some error
detection for incorrect code.  In contrast, the dict()/dict.update()
signature use case needs semantics to change for an example like this:

  def x((a=None), **kwargs): ...
  x(a=3)

This can't be wrapped properly without very special care.  For
instance, this would behave wrong:

  def method(self, *args, **kwargs):
    x(*args, **kwargs)

I'm strongly against adding a feature to split **kwargs into a
separate namespace when we have such a common convention of NOT doing
it for self[1][2].  The decorator proposed in the other thread is a
much better solution unless we want to overturn that convention.


[1] Google codesearch for "self[^()]*\*\* lang:python" returned 28,800
results.. make that 200 results.. or 186 results.. numbers aren't too
accurate it seems.
[2] "\([a-z][^()]*\*\* lang:python" claims 29,500, but won't let me go
past 200 results.  Maybe there's an internal limiter?

-- 
Adam Olsen, aka Rhamphoryncus


From rrr at ronadam.com  Tue May 22 04:05:17 2007
From: rrr at ronadam.com (Ron Adam)
Date: Mon, 21 May 2007 21:05:17 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <fb6fbf560705211557s781f10e4i645daab1dd2071ab@mail.gmail.com>
References: <91ad5bf80705160750u712fbc88o3a5379db5ddeda15@mail.gmail.com>	
	<aac2c7cb0705182249k575c1db4pda7e7a887ac6d0b5@mail.gmail.com>	
	<d11dcfba0705201013u4add3432jc8edd7bc8d0fb89@mail.gmail.com>	
	<91ad5bf80705201711l4debd819ybde15aaf38a94045@mail.gmail.com>	
	<d11dcfba0705201726l7069b28ag4a485d8911890e55@mail.gmail.com>	
	<91ad5bf80705201914m2443aa7atfe4d5250bfd0d164@mail.gmail.com>	
	<d11dcfba0705201935t2d8503a6lc45ae646c0daeffb@mail.gmail.com>	
	<aac2c7cb0705202336v5ae20059medc68e3ab7aca063@mail.gmail.com>	
	<d11dcfba0705202358w7c92280dm133747bf0246639a@mail.gmail.com>	
	<4651D464.2020806@ronadam.com>
	<fb6fbf560705211557s781f10e4i645daab1dd2071ab@mail.gmail.com>
Message-ID: <46524FDD.4090007@ronadam.com>

Jim Jewett wrote:
>> What I would like is for unpack to be '^' instead of '*', then you would
>> have...
> 
> My first reaction was negative -- but then I remembered that I was
> caught by this trap myself more than once, because of the asymmetry
> between pack and unpack, with * magically doing the normally-right
> thing.
> 
> So now I wonder if I wouldn't like if after all, and I'm instead
> picking at the presentation, so you can make a stronger case.

Yes, it's gotten me a few times as well.  Usually when I have a class and 
some of the methods are accepting *args, **kwds, and some aren't.  Then I 
find I'm packing arguments in some cases and unpacking them in others in 
the same subclass, and the methods definitions are not on the same page so 
it isn't immediately obvious I got them mixed up.  As I said it isn't a 
computer issue, it's a human interface issue.


> On 5/21/07, Ron Adam <rrr at ronadam.com> wrote:
> 
>> Now if we use ^ for unpacking, and * for packing, it reduces the 
>> number of
>> meanings for the '*' and fixes the context of positional and keyword only
>> arguments.
> 
>> def f(a, ^(b=2, c=3), *rest):   b and c are positional only here.
> 
> I don't think there should ever be positional-only arguments *after* a
> keywordable argument.  Perhaps
> 
>    # a is a mandatory positional argument
>    # b is an optional positional argument
>    # c can be passed as a keyword, or as the third positional argument
>    def f(^a, ^b=2, c=3, *rest):
> 
> Or were you suggesting a tuple of the positional-only arguments, like
> 
>    # a is a mandatory positional argument
>    # b is an optional positional argument
>    # c can be passed as a keyword, or as the third positional argument
>    def f(^(a, b=2), c=3, *rest):

Ah, ok, I see what I missed.  I think I got optional args mixed up with 
positional args in my mind.  Not quite the same thing.

So yes, the second example fits what I was trying to think of better.

     # a is mandatory, positional
     # b is optional, positional
     # c is optional, positional, or by keyword
     # d is mandatory, keyword only
     # e is optional, keyword only
     def f(^(a, b=2), c=3, ^^(d, e=5)):


Of course it could be interpreted a bit differently given the unpacking 
context.

    # x is a two tuple (a, b)
    # y is a single value, c
    # z is a dict, {'d':4, 'e':5}
    result = f(x, y, z)

Which solves a different problem entirely.  ;-)

It allows you to specify unpacking behavior in the definition instead of 
requiring it on the calling side.


So I guess I'd have to fall back to the semi-colon as the positional only 
and keyword only designators.

    def f(a, b=2; c=3; d, e=5):


Or alternately use the colon as it is used in slices.

    def f(a, b=2: c=3: d, e=5):

I'd almost rather change the slices to semicolons and keep the colon unique 
and with only one purpose.

And ...

    def f(a, b=2, c=3)

would be equivalent to...

    def f(; a, b=2, c=3;):  No positional only, no keyword only


Anyway, I'm not sure there is a simple way to do this.  Sigh...


>> There is the possibility of extending this for use in other ways as well.
>>
>> xlist = [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
>>
>> alist = [^x for x in xlist]
>>
>> This would have list "extend" behavior instead of list "append" behavior.
> 
> So alist == [1, 2, 3, 4, 5, 6, 7, 8, 9]?

Exactly.

Cheers,
    Ron




From castironpi at comcast.net  Tue May 22 11:45:01 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 22 May 2007 04:45:01 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <46524FDD.4090007@ronadam.com>
Message-ID: <20070522094505.5714D1E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Ron Adam
>
>     def f(; a, b=2, c=3;):  No positional only, no keyword only

Do you prohibit defaults in type 1, the pos-only?

Not necc.  Does this look right?

>>> def f( a=0; b=1 ):
...	print a, b
>>> f()
0, 1

Also, does this look right?

>>> def f( a=0; b ):
...	print a, b
  File "<stdin>", line 1
SyntaxError: non-default argument follows default argument

Any more groups?  So far I have pos-only, pos-or-kw, and kw-only.

If not, a ascii character works fine to delimit, like * and **.

Do we want to annotate each parameter individually?  This could get out of
hand.  But decorators won't let you do

@f( k )
	def j( k ):
		...

where

@f( 'k' )
	def j( k ):
		...

gets unwieldy and could show promise.  Cf. Steven's positional only
arguments decorator.



From castironpi at comcast.net  Tue May 22 12:03:54 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 22 May 2007 05:03:54 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <20070522094505.5714D1E4003@bag.python.org>
Message-ID: <20070522100358.208671E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Aaron Brady
> Sent: Tuesday, May 22, 2007 4:45 AM
> > -----Original Message-----
> > From: python-ideas-bounces at python.org [mailto:python-ideas-
> > bounces at python.org] On Behalf Of Ron Adam
> >
> >     def f(; a, b=2, c=3;):  No positional only, no keyword only
> 
> @f( 'k' )
> 	def j( k ):
> 		...
> 
> gets unwieldy and could show promise.  Cf. Steven's positional only
> arguments decorator.

Cf. PEP 3102 Talin http://www.python.org/dev/peps/pep-3102/
Cf. PEP 3107 Winder and Lownds http://www.python.org/dev/peps/pep-3107/
Cf. PEP 3117 Brandl http://www.python.org/dev/peps/pep-3117/

def f( @k, @j )

Half-way compromise to Brandl, only in declaration not in use, and always
optional.




From castironpi at comcast.net  Tue May 22 12:00:47 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 22 May 2007 05:00:47 -0500
Subject: [Python-ideas] crazy ideas
Message-ID: <20070522101758.6789C1E4005@bag.python.org>

Annotated list callers:

q = d[a,b,c] is deque

simple sugar for

from collections import deque
q = deque( a, b, c )


might also do

s = s[a,b,c]

for

s = set([a,b,c])



From adam at atlas.st  Tue May 22 14:45:28 2007
From: adam at atlas.st (Adam Atlas)
Date: Tue, 22 May 2007 08:45:28 -0400
Subject: [Python-ideas] crazy ideas
In-Reply-To: <20070522101758.6789C1E4005@bag.python.org>
References: <20070522101758.6789C1E4005@bag.python.org>
Message-ID: <C0FCF4E8-B9F3-435C-8AE3-77618F2A8DD3@atlas.st>


On 22 May 2007, at 06.00, Aaron Brady wrote:
> Annotated list callers:
>
> q = d[a,b,c] is deque

Won't work... how could that be distinguished from getting an item of  
a dictionary named `d` keyed by the tuple (a, b, c)?


From castironpi at comcast.net  Tue May 22 14:55:57 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 22 May 2007 07:55:57 -0500
Subject: [Python-ideas] crazy ideas
In-Reply-To: <C0FCF4E8-B9F3-435C-8AE3-77618F2A8DD3@atlas.st>
Message-ID: <20070522125602.23D761E400B@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Adam Atlas
> 
> On 22 May 2007, at 06.00, Aaron Brady wrote:
> > Annotated list callers:
> >
> > q = d[a,b,c] is deque
> 
> Won't work... how could that be distinguished from getting an item of
> a dictionary named `d` keyed by the tuple (a, b, c)?

Doh.

In syntax design, the grouping characters go pretty quickly.  d<a,b,c> is
-almost- ambiguous[1], perhaps that?

[1] ...with (d<a),b,(c>e) a<b,c,d>e but isn't.



From grosser.meister.morti at gmx.net  Tue May 22 16:16:51 2007
From: grosser.meister.morti at gmx.net (=?ISO-8859-1?Q?Mathias_Panzenb=F6ck?=)
Date: Tue, 22 May 2007 16:16:51 +0200
Subject: [Python-ideas] crazy ideas
In-Reply-To: <20070522125602.23D761E400B@bag.python.org>
References: <20070522125602.23D761E400B@bag.python.org>
Message-ID: <4652FB53.1030408@gmx.net>

maybe d{a,b,c}?

whatever, I think in python3 there will be {a,b,c} as short syntax for set([a,b,c]).


From g.brandl at gmx.net  Tue May 22 17:04:18 2007
From: g.brandl at gmx.net (Georg Brandl)
Date: Tue, 22 May 2007 17:04:18 +0200
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <20070522100358.208671E4003@bag.python.org>
References: <20070522094505.5714D1E4003@bag.python.org>
	<20070522100358.208671E4003@bag.python.org>
Message-ID: <f2v0pt$n2a$1@sea.gmane.org>

Aaron Brady schrieb:
>> -----Original Message-----
>> From: python-ideas-bounces at python.org [mailto:python-ideas-
>> bounces at python.org] On Behalf Of Aaron Brady
>> Sent: Tuesday, May 22, 2007 4:45 AM
>> > -----Original Message-----
>> > From: python-ideas-bounces at python.org [mailto:python-ideas-
>> > bounces at python.org] On Behalf Of Ron Adam
>> >
>> >     def f(; a, b=2, c=3;):  No positional only, no keyword only
>> 
>> @f( 'k' )
>> 	def j( k ):
>> 		...
>> 
>> gets unwieldy and could show promise.  Cf. Steven's positional only
>> arguments decorator.
> 
> Cf. PEP 3102 Talin http://www.python.org/dev/peps/pep-3102/
> Cf. PEP 3107 Winder and Lownds http://www.python.org/dev/peps/pep-3107/
> Cf. PEP 3117 Brandl http://www.python.org/dev/peps/pep-3117/
> 
> def f( @k, @j )
> 
> Half-way compromise to Brandl, only in declaration not in use, and always
> optional.

I'd prefer no compromises being made when it comes to PEP 3117.

Georg



From g.brandl at gmx.net  Tue May 22 17:05:49 2007
From: g.brandl at gmx.net (Georg Brandl)
Date: Tue, 22 May 2007 17:05:49 +0200
Subject: [Python-ideas] crazy ideas
In-Reply-To: <20070522101758.6789C1E4005@bag.python.org>
References: <20070522101758.6789C1E4005@bag.python.org>
Message-ID: <f2v0so$n2a$2@sea.gmane.org>

Aaron Brady schrieb:
> Annotated list callers:
> 
> q = d[a,b,c] is deque
> 
> simple sugar for
> 
> from collections import deque
> q = deque( a, b, c )
> 
> 
> might also do
> 
> s = s[a,b,c]
> 
> for
> 
> s = set([a,b,c])

Would you be happy with {a, b, c}?

Georg



From rrr at ronadam.com  Tue May 22 19:20:46 2007
From: rrr at ronadam.com (Ron Adam)
Date: Tue, 22 May 2007 12:20:46 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <200705220243203.SM01928@sccrmhc13.comcast.net>
References: <200705220243203.SM01928@sccrmhc13.comcast.net>
Message-ID: <4653266E.7060706@ronadam.com>

Aaron Brady wrote:
>> -----Original Message-----
>> From: python-ideas-bounces at python.org [mailto:python-ideas-
>> bounces at python.org] On Behalf Of Ron Adam
>>
>>     def f(; a, b=2, c=3;):  No positional only, no keyword only
> 
> Do you prohibit defaults in type 1, the pos-only?

No

> Not necc.  Does this look right?
> 
>>>> def f( a=0; b=1 ):
> ...	print a, b
>>>> f()
> 0, 1

That's fine.  'a' is positional only and 'b' is either.

Having defaults and being positional only are two different things.

With the above function the following would be allowed.

    f()
    f(1)
    f(1, 2)
    f(1, b=2)
    f(b=2)

But not:  (If positional only also means no assignment with keywords at 
call time.)

    f(a=1)         #  Keyword not allowed for 'a' at call time.
    f(b=2, a=1)    #  'a' is positional only


> Also, does this look right?
> 
>>>> def f( a=0; b ):
> ...	print a, b
>   File "<stdin>", line 1
> SyntaxError: non-default argument follows default argument

Looks ok to me.  Even the error is correct.


> Any more groups?  So far I have pos-only, pos-or-kw, and kw-only.
> 
> If not, a ascii character works fine to delimit, like * and **.

Any character can possibly do it, but does it make sense given that they 
already have a meaning?


I have a feeling we are trying to do too much at once.

    required
    optional

    with default
    with out default

    in order
    in order only

    with keyword
    with keyword only

Can these be ordered into *any* decision tree that makes sense?


> Do we want to annotate each parameter individually?  This could get out of
> hand.  But decorators won't let you do
> 
> @f( k )
> 	def j( k ):
> 		...
> 
> where
> 
> @f( 'k' )
> 	def j( k ):
> 		...
> 
> gets unwieldy and could show promise.  Cf. Steven's positional only
> arguments decorator.

I think we should let Steven's decorator be developed further.  It will at 
least give a way to test ideas and find more use cases.  Then if there are 
some frequent and common use cases.  Then look at what is actually needed.

Cheers,
    Ron


From castironpi at comcast.net  Tue May 22 20:24:28 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 22 May 2007 13:24:28 -0500
Subject: [Python-ideas] crazy ideas
In-Reply-To: <f2v0so$n2a$2@sea.gmane.org>
Message-ID: <20070522182432.6032C1E4012@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Georg Brandl
> 
> Aaron Brady schrieb:
> > Annotated list callers:
> >
> > q = d[a,b,c] is deque
> >
> > simple sugar for
> >
> > from collections import deque
> > q = deque( a, b, c )
> >
> >
> > might also do
> >
> > s = s[a,b,c]
> >
> > for
> >
> > s = set([a,b,c])
> 
> Would you be happy with {a, b, c}?
> 
> Georg
> 
Yes, impartiality being hard to come by.

Is it a deque or a set?  d{a,b,c} could allow you flexibility.

Don't generalize too -far-, though.  This could be used anywhere, akin to
r"a\bc", but don't allow users to 'cook their own'.  Plenty of room but
needs say so with official support.  Queue.Queue, Collections.Deque,
Collections.DefaultDict, set, UserGeom.Point?[1], that's all I can think of.


[1] r{ p{0,0}, p{10,10} }

FTR for the record, how often it's used today doesn't tell how often it will
be used with convenienter syntax, impartiality still being hard to come by.



From scott+python-ideas at scottdial.com  Tue May 22 20:26:22 2007
From: scott+python-ideas at scottdial.com (Scott Dial)
Date: Tue, 22 May 2007 14:26:22 -0400
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <20070521230834.701B11E4006@bag.python.org>
References: <20070521230834.701B11E4006@bag.python.org>
Message-ID: <465335CE.5060807@scottdial.com>

Aaron Brady wrote:
>>>>>     def f(*, a, b=None, *args, **, c=42, **kwargs)
> 
> def f( *args, **kwargs ):
> 	if len( args ) < 2: raise error
> 	if 'b' in kwargs: raise error
> 	if 'c' not in kwargs: raise error
> 	a, b, args = args[:2], args[2:]
> 	c = kwargs['c']
> 
> It's an approximation; use case to the contrary?
> 

I'm not sure why else you would post this reply other than a lack of 
understanding. The whole point of this discussion is to avoid burying 
this information inside the function body and have a complete function 
signature. f(*args, **kwargs) is the least useful function signature 
possible in python.

-- 
Scott Dial
scott at scottdial.com
scodial at cs.indiana.edu


From castironpi at comcast.net  Tue May 22 20:42:34 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 22 May 2007 13:42:34 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <465335CE.5060807@scottdial.com>
Message-ID: <20070522184238.6E1521E401D@bag.python.org>

> -----Original Message-----
> From: Scott Dial [mailto:scott+python-ideas at scottdial.com]
> Sent: Tuesday, May 22, 2007 1:26 PM
> 
> Aaron Brady wrote:
> >>>>>     def f(*, a, b=None, *args, **, c=42, **kwargs)
> >
> > def f( *args, **kwargs ):
> > 	if len( args ) < 2: raise error
> > 	if 'b' in kwargs: raise error
> > 	if 'c' not in kwargs: raise error
> > 	a, b, args = args[:2], args[2:]
> > 	c = kwargs['c']
> >
> > It's an approximation; use case to the contrary?
> >
> 
> I'm not sure why else you would post this reply other than a lack of
> understanding. The whole point of this discussion is to avoid burying
> this information inside the function body and have a complete function
> signature. f(*args, **kwargs) is the least useful function signature
> possible in python.
> 
> --
> Scott Dial
> scott at scottdial.com
> scodial at cs.indiana.edu

You all seemed to me to be wanting things to apply in every case.  This
does, but you scream at me here too.

Generality or speciality, take your pick.

I would say perl is highly specialized, very useful, more than python for a
certain subset of tasks.  What subset?

Are you here for popularity, money, productivity, aesthetics, deep
aesthetics, raw lines of code per day per time zone around the world, or
none of the above?  'Cause ML is a beautiful idea; doesn't take a grad
student to appreciate that.  Just to keep your job is money.  Love it.



From jcarlson at uci.edu  Tue May 22 21:33:45 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 22 May 2007 12:33:45 -0700
Subject: [Python-ideas] crazy ideas
In-Reply-To: <20070522182432.6032C1E4012@bag.python.org>
References: <f2v0so$n2a$2@sea.gmane.org>
	<20070522182432.6032C1E4012@bag.python.org>
Message-ID: <20070522122942.85E1.JCARLSON@uci.edu>


"Aaron Brady" <castironpi at comcast.net> wrote:
> > > s = s[a,b,c]
> > >
> > > for
> > >
> > > s = set([a,b,c])
> > 
> > Would you be happy with {a, b, c}?
> > 
> Yes, impartiality being hard to come by.
> 
> Is it a deque or a set?  d{a,b,c} could allow you flexibility.

It's the set syntax for Python 3.0.  Getting deque syntax, or a prefix
for arbitrary types that are rarely used is not going to happen.  There
was already huge resistance to the set syntax, and those are used easily
10 times more than deques.

In terms of having a syntax for deques, I honestly don't see the problem
with deque([a,b,c]).  It has all of 6 more characters to type than your
proposed d{a,b,c} syntax, without cluttering up the language with yet
another bit of syntax that can be replaced with a 2 line function...

def d(*args):
    return deque(args)

Repeat this to yourself until you realize that it's the only sane
approach to Python language design: not every X line function should be
made into a builtin or syntax.

 - Josiah



From castironpi at comcast.net  Tue May 22 21:42:01 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 22 May 2007 14:42:01 -0500
Subject: [Python-ideas] crazy ideas
In-Reply-To: <20070522122942.85E1.JCARLSON@uci.edu>
Message-ID: <20070522194208.4368B1E4009@bag.python.org>

> -----Original Message-----
> From: Josiah Carlson [mailto:jcarlson at uci.edu]
> Sent: Tuesday, May 22, 2007 2:34 PM
> 
> "Aaron Brady" <castironpi at comcast.net> wrote:
> > Is it a deque or a set?  d{a,b,c} could allow you flexibility.
> 
> Repeat this to yourself until you realize that it's the only sane
> approach to Python language design: not every X line function should be
> made into a builtin or syntax.
> 
Duh, so why don't we pick out some choice N-line functions?  And make those
syntax.

Let me know if this gets "too heated" for n/g postings, and I'll take it
outside[1].  We tend to have loves; we know not what.

[1]Future topics include the evolution of English from Proto-Indoeuropean,
past Latin, why English is good, and hence why Python should take out some
good reservations, and be like English.  It's a language that gets -used-.
Regular yet idiomatic, like Python could be.  Dream where?  Lifespan of
languages is looking at a couple to few decades- not ten minutes, nor ten
centuries.  Let's look at leadership.  You want to talk precedent?



From ian.bollinger at gmail.com  Tue May 22 21:44:36 2007
From: ian.bollinger at gmail.com (Ian D. Bollinger)
Date: Tue, 22 May 2007 15:44:36 -0400
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <20070515140958.8578.JCARLSON@uci.edu>
References: <20070515134716.8575.JCARLSON@uci.edu> <f2d6mm$2ep$1@sea.gmane.org>
	<20070515140958.8578.JCARLSON@uci.edu>
Message-ID: <46534824.6050700@gmail.com>

Josiah Carlson wrote:
> I choose as standard what works in the most cases.  Since list() works
> everywhere, using it on lists makes the most sense to me.
>
>   
Good point. Would it be worth specifying this in the official style guide?


From ian.bollinger at gmail.com  Tue May 22 21:53:37 2007
From: ian.bollinger at gmail.com (Ian D. Bollinger)
Date: Tue, 22 May 2007 15:53:37 -0400
Subject: [Python-ideas] crazy ideas
In-Reply-To: <20070522122942.85E1.JCARLSON@uci.edu>
References: <f2v0so$n2a$2@sea.gmane.org>	<20070522182432.6032C1E4012@bag.python.org>
	<20070522122942.85E1.JCARLSON@uci.edu>
Message-ID: <46534A41.2010609@gmail.com>

Josiah Carlson wrote:
> In terms of having a syntax for deques, I honestly don't see the problem
> with deque([a,b,c]).  It has all of 6 more characters to type than your
> proposed d{a,b,c} syntax, without cluttering up the language with yet
> another bit of syntax that can be replaced with a 2 line function...
>
> def d(*args):
>     return deque(args)
>   
But what about all the memory overhead of constructing the list argument?!
(I turn off my car radio to save gas.)

- Ian D. Bollinger


From castironpi at comcast.net  Tue May 22 21:58:29 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 22 May 2007 14:58:29 -0500
Subject: [Python-ideas] crazy ideas
In-Reply-To: <46534A41.2010609@gmail.com>
Message-ID: <20070522195834.2E59D1E4003@bag.python.org>

> -----Original Message-----
> From: Ian D. Bollinger [mailto:ian.bollinger at gmail.com]
> Sent: Tuesday, May 22, 2007 2:54 PM
> 
> Josiah Carlson wrote:
> > In terms of having a syntax for deques, I honestly don't see the problem
> > with deque([a,b,c]).  It has all of 6 more characters to type than your
> > proposed d{a,b,c} syntax, without cluttering up the language with yet
> > another bit of syntax that can be replaced with a 2 line function...
> >
> > def d(*args):
> >     return deque(args)
> >
> But what about all the memory overhead of constructing the list argument?!
> (I turn off my car radio to save gas.)

I take the bowling ball out of my trunk.



From ntoronto at cs.byu.edu  Tue May 22 22:09:40 2007
From: ntoronto at cs.byu.edu (Neil Toronto)
Date: Tue, 22 May 2007 14:09:40 -0600
Subject: [Python-ideas] crazy ideas
In-Reply-To: <20070522195834.2E59D1E4003@bag.python.org>
References: <20070522195834.2E59D1E4003@bag.python.org>
Message-ID: <46534E04.6000003@cs.byu.edu>

Aaron Brady wrote:
>> -----Original Message-----
>> From: Ian D. Bollinger [mailto:ian.bollinger at gmail.com]
>> Sent: Tuesday, May 22, 2007 2:54 PM
>>
>> Josiah Carlson wrote:
>>     
>>> In terms of having a syntax for deques, I honestly don't see the problem
>>> with deque([a,b,c]).  It has all of 6 more characters to type than your
>>> proposed d{a,b,c} syntax, without cluttering up the language with yet
>>> another bit of syntax that can be replaced with a 2 line function...
>>>
>>> def d(*args):
>>>     return deque(args)
>>>
>>>       
>> But what about all the memory overhead of constructing the list argument?!
>> (I turn off my car radio to save gas.)
>>     
>
> I take the bowling ball out of my trunk.
>   

I dust the dashboard.

Neil



From castironpi at comcast.net  Tue May 22 22:14:42 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Tue, 22 May 2007 15:14:42 -0500
Subject: [Python-ideas] crazy ideas
In-Reply-To: <46534E04.6000003@cs.byu.edu>
Message-ID: <20070522201447.63CB81E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Neil Toronto
> Sent: Tuesday, May 22, 2007 3:10 PM
> Cc: python-ideas at python.org
> Subject: Re: [Python-ideas] crazy ideas
> 
> Aaron Brady wrote:
> >> -----Original Message-----
> >> From: Ian D. Bollinger [mailto:ian.bollinger at gmail.com]
> >> Sent: Tuesday, May 22, 2007 2:54 PM
> >>
> >> Josiah Carlson wrote:
> >>
> >>> In terms of having a syntax for deques, I honestly don't see the
> problem
> >>> with deque([a,b,c]).  It has all of 6 more characters to type than
> your
> >>> proposed d{a,b,c} syntax, without cluttering up the language with yet
> >>> another bit of syntax that can be replaced with a 2 line function...
> >>>
> >>> def d(*args):
> >>>     return deque(args)
> >>>
> >>>
> >> But what about all the memory overhead of constructing the list
> argument?!
> >> (I turn off my car radio to save gas.)
> >>
> >
> > I take the bowling ball out of my trunk.
> >
> 
> I dust the dashboard.
> 
> Neil

Radio's sounding good.  It's the crap vs. worse crap finals.



From jcarlson at uci.edu  Tue May 22 23:29:51 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 22 May 2007 14:29:51 -0700
Subject: [Python-ideas] crazy ideas
In-Reply-To: <46534A41.2010609@gmail.com>
References: <20070522122942.85E1.JCARLSON@uci.edu> <46534A41.2010609@gmail.com>
Message-ID: <20070522142355.85E7.JCARLSON@uci.edu>


"Ian D. Bollinger" <ian.bollinger at gmail.com> wrote:
> 
> Josiah Carlson wrote:
> > In terms of having a syntax for deques, I honestly don't see the problem
> > with deque([a,b,c]).  It has all of 6 more characters to type than your
> > proposed d{a,b,c} syntax, without cluttering up the language with yet
> > another bit of syntax that can be replaced with a 2 line function...
> >
> > def d(*args):
> >     return deque(args)
> >   
> But what about all the memory overhead of constructing the list argument?!
> (I turn off my car radio to save gas.)

Even with syntax, the content of the deque needs to be loaded on the
stack for either a 'stack to deque' operation (like the equivalent stack
to list or stack to tuple operations), or a stack to list to deque
operation.  And unless you are creating huge deques in-line, starting
from a list won't incur any significant memory overhead as short lists 
(0, 4, 8, 16, etc.) are usually handled by Python's small memory
allocator.

If you really want to prove it to yourself that it doesn't matter, try
benchmarking the difference between...

    d = deque(())
    d = deque([])

    d = deque((1,2,3,4,5,6,7,8,9,10))
    d = deque([1,2,3,4,5,6,7,8,9,10])


 - Josiah



From jcarlson at uci.edu  Tue May 22 23:31:35 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 22 May 2007 14:31:35 -0700
Subject: [Python-ideas] Have list/deque grow a copy() method
In-Reply-To: <46534824.6050700@gmail.com>
References: <20070515140958.8578.JCARLSON@uci.edu> <46534824.6050700@gmail.com>
Message-ID: <20070522143009.85EA.JCARLSON@uci.edu>


"Ian D. Bollinger" <ian.bollinger at gmail.com> wrote:
> Josiah Carlson wrote:
> > I choose as standard what works in the most cases.  Since list() works
> > everywhere, using it on lists makes the most sense to me.
> >
> >
> Good point. Would it be worth specifying this in the official style guide?

I think that would be more hand-holding than we really want to be doing.

 - Josiah



From ian.bollinger at gmail.com  Tue May 22 23:38:16 2007
From: ian.bollinger at gmail.com (Ian D. Bollinger)
Date: Tue, 22 May 2007 17:38:16 -0400
Subject: [Python-ideas] crazy ideas
In-Reply-To: <20070522142355.85E7.JCARLSON@uci.edu>
References: <20070522122942.85E1.JCARLSON@uci.edu> <46534A41.2010609@gmail.com>
	<20070522142355.85E7.JCARLSON@uci.edu>
Message-ID: <465362C8.1080701@gmail.com>

Josiah Carlson wrote:
> "Ian D. Bollinger" <ian.bollinger at gmail.com> wrote:
>   
>> But what about all the memory overhead of constructing the list argument?!
>> (I turn off my car radio to save gas.)
>>     
>
> Even with syntax, the content of the deque needs to be loaded on the
> stack for either a 'stack to deque' operation (like the equivalent stack
> to list or stack to tuple operations), or a stack to list to deque
> operation.  And unless you are creating huge deques in-line, starting
> from a list won't incur any significant memory overhead as short lists 
> (0, 4, 8, 16, etc.) are usually handled by Python's small memory
> allocator.
>
> If you really want to prove it to yourself that it doesn't matter, try
> benchmarking the difference between...
>
>     d = deque(())
>     d = deque([])
>
>     d = deque((1,2,3,4,5,6,7,8,9,10))
>     d = deque([1,2,3,4,5,6,7,8,9,10])
>
>   
Er, I was trying to be ironic, hence the comment about gas mileage. :(

- Ian D. Bollinger


From arno at marooned.org.uk  Tue May 22 20:16:31 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Tue, 22 May 2007 19:16:31 +0100
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <4653266E.7060706@ronadam.com>
References: <200705220243203.SM01928@sccrmhc13.comcast.net>
	<4653266E.7060706@ronadam.com>
Message-ID: <3675F215-BC6E-49DD-86F0-D83CE2814305@marooned.org.uk>


On 22 May 2007, at 18:20, Ron Adam wrote:

> Aaron Brady wrote:
[...]
>> gets unwieldy and could show promise.  Cf. Steven's positional only
>> arguments decorator.
>
> I think we should let Steven's decorator be developed further.
[...]

No really that's too much: I don't deserve the credit.  I only came up
with the idea of the decorator (with an implementation) and provided
a solution to the problem of keyword arguments with the same name as
positional ones.  So don't mention me :)

-- 
Arnaud




From rrr at ronadam.com  Wed May 23 04:52:01 2007
From: rrr at ronadam.com (Ron Adam)
Date: Tue, 22 May 2007 21:52:01 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <3675F215-BC6E-49DD-86F0-D83CE2814305@marooned.org.uk>
References: <200705220243203.SM01928@sccrmhc13.comcast.net>	<4653266E.7060706@ronadam.com>
	<3675F215-BC6E-49DD-86F0-D83CE2814305@marooned.org.uk>
Message-ID: <4653AC51.1080103@ronadam.com>

Arnaud Delobelle wrote:
> On 22 May 2007, at 18:20, Ron Adam wrote:
> 
>> Aaron Brady wrote:
> [...]
>>> gets unwieldy and could show promise.  Cf. Steven's positional only
>>> arguments decorator.
>> I think we should let Steven's decorator be developed further.
> [...]
> 
> No really that's too much: I don't deserve the credit.  I only came up
> with the idea of the decorator (with an implementation) and provided
> a solution to the problem of keyword arguments with the same name as
> positional ones.  So don't mention me :)


Correction:

"""I think we should let Arnaud Delobelle's decorator be developed further."""


Sorry about that, please don't let my mistake stop you from coming up with 
more good ideas.

Sincere apologies,
    Ron


From castironpi at comcast.net  Wed May 23 17:04:23 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Wed, 23 May 2007 10:04:23 -0500
Subject: [Python-ideas] crazy ideas
In-Reply-To: <465362C8.1080701@gmail.com>
Message-ID: <20070523150430.384E11E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Ian D. Bollinger
> Sent: Tuesday, May 22, 2007 4:38 PM
> 
> Josiah Carlson wrote:
> > "Ian D. Bollinger" <ian.bollinger at gmail.com> wrote:
> >
> >> But what about all the memory overhead of constructing the list
> argument?!
> >> (I turn off my car radio to save gas.)
> >>

> > If you really want to prove it to yourself that it doesn't matter, try
> > benchmarking the difference between...
> >
> >     d = deque(())
> >     d = deque([])
> >
> >     d = deque((1,2,3,4,5,6,7,8,9,10))
> >     d = deque([1,2,3,4,5,6,7,8,9,10])
> >
> >
> Er, I was trying to be ironic, hence the comment about gas mileage. :(
> 
> - Ian D. Bollinger

Point very well taken.  Gas mileage extrapolates to two things here.
Running time and coding-time[1] "miles" per backend dev-time and
clutter-time.  Even if it's free, it's still free clutter.  Guido's
demonstrating efficiency pretty advisedly.

[1]  How expensive is it, per instance and in total, to write deque([a,b,c])
instead of d<a,b,c>?



From castironpi at comcast.net  Wed May 23 17:08:48 2007
From: castironpi at comcast.net (Aaron Brady)
Date: Wed, 23 May 2007 10:08:48 -0500
Subject: [Python-ideas] Positional only arguments
In-Reply-To: <4653AC51.1080103@ronadam.com>
Message-ID: <20070523150849.91B371E4003@bag.python.org>

> -----Original Message-----
> From: python-ideas-bounces at python.org [mailto:python-ideas-
> bounces at python.org] On Behalf Of Ron Adam
> Sent: Tuesday, May 22, 2007 9:52 PM
> 
> 
> Correction:
> 
> """I think we should let Arnaud Delobelle's decorator be developed
> further."""
> 
> 
> Sorry about that, please don't let my mistake stop you from coming up with
> more good ideas.
> 
> Sincere apologies,
>     Ron

Something like

@restrict( a=PosOnly, b=NameOnly )
def f( a, b='i', c=None ):
	...

You could reject 3102.



From bwinton at latte.ca  Wed May 23 17:32:13 2007
From: bwinton at latte.ca (Blake Winton)
Date: Wed, 23 May 2007 11:32:13 -0400
Subject: [Python-ideas] crazy ideas
In-Reply-To: <20070523150430.384E11E4003@bag.python.org>
References: <20070523150430.384E11E4003@bag.python.org>
Message-ID: <46545E7D.4090308@latte.ca>

Aaron Brady wrote:
> [1]  How expensive is it, per instance and in total, to write deque([a,b,c])
> instead of d<a,b,c>?

I'ld be more interested in how expensive it is, per instance and in 
total, to _read_ deque([a,b,c]) instead of d<a,b,c>?

Speaking as someone who reads way more code than they write, I find the 
extra verbosity of "deque" to be quite helpful, and one fewer thing I 
have to try to remember when reading someone else's code.

Later,
Blake.



From paul.hankin at pobox.com  Wed May 23 17:51:20 2007
From: paul.hankin at pobox.com (Paul Hankin)
Date: Wed, 23 May 2007 16:51:20 +0100
Subject: [Python-ideas] crazy ideas
In-Reply-To: <46545E7D.4090308@latte.ca>
References: <20070523150430.384E11E4003@bag.python.org>
	<46545E7D.4090308@latte.ca>
Message-ID: <fafba9320705230851h63482b46t3310d0efc7b44450@mail.gmail.com>

On 23/05/07, Blake Winton <bwinton at latte.ca> wrote:
> Aaron Brady wrote:
> > [1]  How expensive is it, per instance and in total, to write deque([a,b,c])
> > instead of d<a,b,c>?
>
> I'ld be more interested in how expensive it is, per instance and in
> total, to _read_ deque([a,b,c]) instead of d<a,b,c>?
>
> Speaking as someone who reads way more code than they write, I find the
> extra verbosity of "deque" to be quite helpful, and one fewer thing I
> have to try to remember when reading someone else's code.

Isn't there a problem with ambiguity? Eg
f(d<a, b, c> -e)


From george.sakkis at gmail.com  Wed May 23 17:57:34 2007
From: george.sakkis at gmail.com (George Sakkis)
Date: Wed, 23 May 2007 11:57:34 -0400
Subject: [Python-ideas] crazy ideas
In-Reply-To: <fafba9320705230851h63482b46t3310d0efc7b44450@mail.gmail.com>
References: <20070523150430.384E11E4003@bag.python.org>
	<46545E7D.4090308@latte.ca>
	<fafba9320705230851h63482b46t3310d0efc7b44450@mail.gmail.com>
Message-ID: <91ad5bf80705230857y3fbc8d39t33c507626e3bf5@mail.gmail.com>

On 5/23/07, Paul Hankin <paul.hankin at pobox.com> wrote:

> On 23/05/07, Blake Winton <bwinton at latte.ca> wrote:
> > Aaron Brady wrote:
> > > [1]  How expensive is it, per instance and in total, to write deque([a,b,c])
> > > instead of d<a,b,c>?
> >
> > I'ld be more interested in how expensive it is, per instance and in
> > total, to _read_ deque([a,b,c]) instead of d<a,b,c>?
> >
> > Speaking as someone who reads way more code than they write, I find the
> > extra verbosity of "deque" to be quite helpful, and one fewer thing I
> > have to try to remember when reading someone else's code.
>
> Isn't there a problem with ambiguity? Eg
> f(d<a, b, c> -e)

Can we please let this pointless idea and the respective thread R.I.P. ?

-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."


From collinw at gmail.com  Thu May 24 02:27:44 2007
From: collinw at gmail.com (Collin Winter)
Date: Wed, 23 May 2007 17:27:44 -0700
Subject: [Python-ideas] [Python-Dev] nodef
In-Reply-To: <1b151690705231708v19ab6f5mb647007d6bcd1cea@mail.gmail.com>
References: <1b151690705231708v19ab6f5mb647007d6bcd1cea@mail.gmail.com>
Message-ID: <43aa6ff70705231727i2b70b9a5hd4800018a23b052b@mail.gmail.com>

[moving to python-ideas, where it belongs]

On 5/23/07, Martin Blais <blais at furius.ca> wrote:
> I often have the need for a generic object to use as the default value
> for a function parameter, where 'None' is a valid value for the
> parameter.  For example:
>
>     _sentinel = object()
>
>     def first(iterable, default=_sentinel):
>         """Return the first element of the iterable, otherwise the default value (if
>         specified).
>         """
>         for elem in iterable:   # thx to rhettinger for optim.
>           return elem
>         if default is _sentinel:
>           raise StopIteration
>         return default
>
> Here, 'default' could legally accept None, so I cannot use that as the
> default value, nor anything else as far as I'm concerned (I don't know
> what lives in the iterable, so why should I make assumptions?).
> Sometimes in the past I've create generic objects, declared a class,
> e.g.:
>
>   class NoDef: pass
>   def foo(default=NoDef):
>       ...
>
> and lately I've even started using the names of builtin functions (it
> bothers me a little bit though, that I do that).
>
> I think Python needs a builtin for this very purpose.  I propose
> 'nodef', a unique object whose sole purpose is to serve as a default
> value.  It should be unique, in the same sense that 'None' is unique.

I've run into this situation several times before, and I've never felt
that defining my own sentinel was unduly taxing. Having a built-in
would only save a single line, the initial "sentinel = object()".

Collin Winter


From terry at jon.es  Thu May 24 02:56:53 2007
From: terry at jon.es (Terry Jones)
Date: Thu, 24 May 2007 02:56:53 +0200
Subject: [Python-ideas] [Python-Dev] nodef
In-Reply-To: Your message at 17:27:44 on Wednesday, 23 May 2007
References: <1b151690705231708v19ab6f5mb647007d6bcd1cea@mail.gmail.com>
	<43aa6ff70705231727i2b70b9a5hd4800018a23b052b@mail.gmail.com>
Message-ID: <18004.58069.315719.640582@terry-jones-computer.local>

Adding nodef would be another step on the road to anarchy and nihilism. It
wouldn't be long before people began using nodef as a possible value for a
function, and then where would we be?

Besides, using xxx = object() seems like a safer bet. Your code is unlikely
to be accidentally called by someone else using your semi-private xxx
object. If there were a documented official nodef object, someone would
eventually call you with nodef instead of None.

Terry


From showell30 at yahoo.com  Sat May 26 18:06:25 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Sat, 26 May 2007 09:06:25 -0700 (PDT)
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
Message-ID: <914604.8688.qm@web33509.mail.mud.yahoo.com>

I find myself often writing somewhat tedious code in
Python that is just slicing/aggregating fairly simple
data structures like a list of dictionaries.

Here is something that I'm trying to express, roughly:

   charges = 
       sum float(charge) from events 
       on setup, install
       group by name

Here is the Python code that I wrote:

    def groupDictBy(lst, keyField):
        dct = {}
        for item in lst:
            keyValue = item[keyField]
            if keyValue not in dct:
                dct[keyValue] = []
            dct[keyValue].append(item)
        return dct

    dct = groupDictBy(events, 'name')
    for name in dct:
        events = dct[name]
        charges = {}
        for bucket in ('setup', 'install'):
            charges[bucket] = sum(
                    [float(event['charge']) for
                    event in events
                    if event['bucket'] == bucket])

Comments are welcome on improving the code itself, but
I wonder if Python 3k (or 4k?) couldn't have some kind
of native SQL-like ways of manipulating lists and
dictionaries.  I don't have a proposal myself, just
wonder if others have felt this kind of pain, and
maybe it will spark a Pythonic solution.




       
____________________________________________________________________________________Sick sense of humor? Visit Yahoo! TV's 
Comedy with an Edge to see what's on, when. 
http://tv.yahoo.com/collections/222


From arno at marooned.org.uk  Sat May 26 18:58:53 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Sat, 26 May 2007 17:58:53 +0100
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <914604.8688.qm@web33509.mail.mud.yahoo.com>
References: <914604.8688.qm@web33509.mail.mud.yahoo.com>
Message-ID: <4BB75E2A-92F8-48D2-81DB-427ACA86AC8F@marooned.org.uk>


On 26 May 2007, at 17:06, Steve Howell wrote:

> I find myself often writing somewhat tedious code in
> Python that is just slicing/aggregating fairly simple
> data structures like a list of dictionaries.
>
> Here is something that I'm trying to express, roughly:
>
>    charges =
>        sum float(charge) from events
>        on setup, install
>        group by name

I don't really understand that :)

> Here is the Python code that I wrote:
>
>     def groupDictBy(lst, keyField):
>         dct = {}
>         for item in lst:
>             keyValue = item[keyField]
>             if keyValue not in dct:
>                 dct[keyValue] = []
>             dct[keyValue].append(item)
>         return dct
>

isn't that itertools.groupby?

>     dct = groupDictBy(events, 'name')
>     for name in dct:
>         events = dct[name]
>         charges = {}
>         for bucket in ('setup', 'install'):
>             charges[bucket] = sum(
>                     [float(event['charge']) for
>                     event in events
>                     if event['bucket'] == bucket])

from itertools import groupby
from operator import itemgetter

charges = {}
for name, n_evts in groupby(events, itemgetter('name')):
     charges[name] = dict((bucket, sum(float(e['charge']) for e in  
b_evts)
     	for bucket, b_evts in groupby(n_evts, itemgetter('bucket'))
         if bucket in ('setup', 'install'))

The last line can be omitted if the only two existing buckets are
'setup' and 'install'.

Untested!  I've changed your code slightly as in your snippet 'charges'
is reset to {} at each iteration of the loop.

-- 
Arnaud




From blais at furius.ca  Thu May 24 16:42:34 2007
From: blais at furius.ca (Martin Blais)
Date: Thu, 24 May 2007 07:42:34 -0700
Subject: [Python-ideas] [Python-Dev] nodef
In-Reply-To: <43aa6ff70705231727i2b70b9a5hd4800018a23b052b@mail.gmail.com>
References: <1b151690705231708v19ab6f5mb647007d6bcd1cea@mail.gmail.com>
	<43aa6ff70705231727i2b70b9a5hd4800018a23b052b@mail.gmail.com>
Message-ID: <1b151690705240742u63103adel34b5c8b98eb004e6@mail.gmail.com>

On 5/23/07, Collin Winter <collinw at gmail.com> wrote:
> [moving to python-ideas, where it belongs]
>
> > I think Python needs a builtin for this very purpose.  I propose
> > 'nodef', a unique object whose sole purpose is to serve as a default
> > value.  It should be unique, in the same sense that 'None' is unique.
>
> I've run into this situation several times before, and I've never felt
> that defining my own sentinel was unduly taxing. Having a built-in
> would only save a single line, the initial "sentinel = object()".

There is another benefit to a builtin 'nodef', BTW, which is that of a
consistent meaning for the word.  Having a consistent name for this
concept--across all programs, if it were in the language--makes it
more obvious what you're trying to achieve.  Otherwise, you decide to
use 'sentinel', I choose 'NoDef', Barry uses 'missing', and we're all
speaking a different "language".

Thought I do admit that the possibility of misuse of a builtin 'nodef'
is slightly troubling.  I guess object() is our (gensym), I did not
know that.

cheers,


From arno at marooned.org.uk  Sat May 26 21:30:35 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Sat, 26 May 2007 20:30:35 +0100
Subject: [Python-ideas] [Python-Dev] nodef
In-Reply-To: <1b151690705240742u63103adel34b5c8b98eb004e6@mail.gmail.com>
References: <1b151690705231708v19ab6f5mb647007d6bcd1cea@mail.gmail.com>
	<43aa6ff70705231727i2b70b9a5hd4800018a23b052b@mail.gmail.com>
	<1b151690705240742u63103adel34b5c8b98eb004e6@mail.gmail.com>
Message-ID: <2A826EFD-045D-42AA-8B7F-7BE413B95E85@marooned.org.uk>


On 24 May 2007, at 15:42, Martin Blais wrote:

> On 5/23/07, Collin Winter <collinw at gmail.com> wrote:
>> [moving to python-ideas, where it belongs]
>>
>>> I think Python needs a builtin for this very purpose.  I propose
>>> 'nodef', a unique object whose sole purpose is to serve as a default
>>> value.  It should be unique, in the same sense that 'None' is  
>>> unique.
>>
>> I've run into this situation several times before, and I've never  
>> felt
>> that defining my own sentinel was unduly taxing. Having a built-in
>> would only save a single line, the initial "sentinel = object()".
>
> There is another benefit to a builtin 'nodef', BTW, which is that of a
> consistent meaning for the word.  Having a consistent name for this
> concept--across all programs, if it were in the language--makes it
> more obvious what you're trying to achieve.  Otherwise, you decide to
> use 'sentinel', I choose 'NoDef', Barry uses 'missing', and we're all
> speaking a different "language".

Just as you find that 'None' is sometimes a valid value for a  
function parameter (and this is the reason why you would like  
'nodef'), if there was a 'nodef' builtin you would sometimes find  
that it is a meaningful value for a function parameter.  Would you  
then advocate the creation of a 'really_nodef' builtin? And then a  
'this_time_i_really_mean_it_nodef' builtin?

This is why a 'nodef' keyword is not a good idea. 'None' is useful  
because often you expect an argument of a certain type (e.g. a list,  
so you know it should not be 'None').

-- 
Arnaud




From showell30 at yahoo.com  Sun May 27 00:11:55 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Sat, 26 May 2007 15:11:55 -0700 (PDT)
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <4BB75E2A-92F8-48D2-81DB-427ACA86AC8F@marooned.org.uk>
Message-ID: <403979.10572.qm@web33503.mail.mud.yahoo.com>


--- Arnaud Delobelle <arno at marooned.org.uk> wrote:

> 
> On 26 May 2007, at 17:06, Steve Howell wrote:
> 
> > I find myself often writing somewhat tedious code
> in
> > Python that is just slicing/aggregating fairly
> simple
> > data structures like a list of dictionaries.
> >
> > Here is something that I'm trying to express,
> roughly:
> >
> >    charges =
> >        sum float(charge) from events
> >        on setup, install
> >        group by name
> 
> I don't really understand that :)
> 

Let me try again:

select
    name,
    bucket,
    sum(float(charge))
from events
where bucket in ('install', 'setup')
group by name, bucket

The idea here is that events is a list of Python
dictionaries keyed by fields "name", "bucket", and
"charge", and I only care about install/setup charges.

Here is a rough Python statement of what I'm trying to
do:

charges = {}
for name, n_evts in groupby(events,
itemgetter('name')):
    print name
    print dict([(bucket, sum([float(e['charge']) for e
in b_evts])) for
            bucket, b_evts in groupby(n_evts,
itemgetter('bucket'))
            if bucket in ('setup', 'install')])


> > Here is the Python code that I wrote:
> >
> >     def groupDictBy(lst, keyField):
> >         dct = {}
> >         for item in lst:
> >             keyValue = item[keyField]
> >             if keyValue not in dct:
> >                 dct[keyValue] = []
> >             dct[keyValue].append(item)
> >         return dct
> >
> 
> isn't that itertools.groupby?
> 

The problem with itertools.groupby is that it assumes
sorted lists.  So the code below does not behave how
you might expect.  It reports Joe's charges twice, and
it loses Steve's $50 install charge.

from itertools import groupby
from operator import itemgetter

events = [
        {'name': 'Joe',   'bucket': 'install',
'charge': 100},
        {'name': 'Joe',   'bucket': 'setup',  
'charge': 20},
        {'name': 'Steve', 'bucket': 'install',
'charge': 50},
        {'name': 'Steve', 'bucket': 'setup',  
'charge': 30},
        {'name': 'Steve', 'bucket': 'install',
'charge': 1000},
        {'name': 'Steve', 'bucket': 'upgrade',
'charge': 440},
        {'name': 'Joe',   'bucket': 'setup',  
'charge': 40},
        ]


charges = {}
for name, n_evts in groupby(events,
itemgetter('name')):
    print name
    print dict([(bucket, sum([float(e['charge']) for e
in b_evts])) for
            bucket, b_evts in groupby(n_evts,
itemgetter('bucket'))
            if bucket in ('setup', 'install')])



       
____________________________________________________________________________________Pinpoint customers who are looking for what you sell. 
http://searchmarketing.yahoo.com/


From arno at marooned.org.uk  Sun May 27 11:03:14 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Sun, 27 May 2007 10:03:14 +0100
Subject: [Python-ideas] positional only arguments decorator
In-Reply-To: <d11dcfba0705211130y6163556ica7f30d62de6258f@mail.gmail.com>
References: <d11dcfba0705211130y6163556ica7f30d62de6258f@mail.gmail.com>
Message-ID: <75AAE6B2-8D9D-43CF-A151-DF0C92964BA7@marooned.org.uk>


On 21 May 2007, at 19:30, Steven Bethard wrote:

> Ok, looks like there's not much chance of agreeing on a syntax, so
> here's a decorator that covers the two use cases I know of::
>
> * matching the signature of dict() and dict.update()
> * allowing arguments to have their names changed without worrying
> about backwards compatibility (e.g. ``def func(sequence)`` changing to
> ``def func(iterable)``)

I propose a slightly different solution.  It may be a bit of a hack,  
but I don't see why it should not be safe. This solution allows you  
to use * and ** in order to write a definition like:

 >>> @posonly
... def update(self, container=None, **kwargs):
...     return self, container, kwargs
...
 >>> update('self')
('self', None, {})
 >>> update('self', 'container')
('self', 'container', {})
 >>> update('self', self='abc', container='xyz', foo='bar')
('self', None, {'self': 'abc', 'foo': 'bar', 'container': 'xyz'})
 >>>

Or:

 >>> @posonly
... def foo(x, y=1, *args, **kwargs):
...     return x, y, args, kwargs
...
 >>> foo('hey')
('hey', 1, (), {})
 >>> foo(*'spam')
('s', 'p', ('a', 'm'), {})
 >>> foo(577, x=314, args=1618, kwargs=2718)
(577, 1, (), {'x': 314, 'args': 1618, 'kwargs': 2718})
 >>>

Without * or ** it gives the following behaviour:

 >>> @posonly
... def f(abc, xyz=42):
...     return abc, xyz
...
 >>> f(3)
(3, 42)
 >>> f(4, 5)
(4, 5)
 >>> f(abc=3)
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "qrg.py", line 147, in posf
     raise TypeError('posonly function %s() got keyword argument'
TypeError: posonly function f() got keyword argument
 >>> f()
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "qrg.py", line 152, in posf
     return flat_f(*args, **kwargs)
TypeError: f() takes at least 1 argument (0 given)
 >>>

This is achieved by 'flattening' the function first.  Here is the code:

import new
import inspect

def flattened(f):
     """Changes a function f(...[, *y] [, **z])
        to f(...[, y=None] [, z=None])"""
     fc = f.func_code
     defaults = f.func_defaults
     flags = fc.co_flags
     argcount = fc.co_argcount
     has_varargs = flags & 4
     if has_varargs:
         flags ^= 4
         argcount += 1
         if defaults: defaults += (None,)
     has_varkwargs = flags & 8
     if has_varkwargs:
         flags ^= 8
         argcount += 1
         if defaults: defaults += (None,)
     flat_code = new.code(argcount, fc.co_nlocals, fc.co_stacksize,  
flags,
         fc.co_code, fc.co_consts, fc.co_names, fc.co_varnames,
         fc.co_filename, fc.co_name, fc.co_firstlineno, fc.co_lnotab)
     flat_f = new.function(flat_code, f.func_globals, f.func_name,  
defaults,
                           f.func_closure)
     return flat_f


def posonly(f):
     "posonly(f) makes the arguments of f positional only"
     f_args, f_varargs, f_varkwargs, f_defaults = inspect.getargspec(f)
     f_nargs = len(f_args)
     f_name = f.__name__
     flat_f = flattened(f)
     def posf(*args, **kwargs):
         if f_varkwargs:
             kwargs = {f_varkwargs: kwargs}
         elif kwargs:
             raise TypeError('posonly function %s() got keyword  
argument'
                             % f_name)
         if f_varargs:
             kwargs[f_varargs] = args[f_nargs:]
             args = args[:f_nargs]
         return flat_f(*args, **kwargs)
     posf.__name__ = f_name
     return posf

-- 
Arnaud




From stephen at xemacs.org  Sun May 27 13:35:03 2007
From: stephen at xemacs.org (Stephen J. Turnbull)
Date: Sun, 27 May 2007 20:35:03 +0900
Subject: [Python-ideas] [Python-Dev] nodef
In-Reply-To: <1b151690705240742u63103adel34b5c8b98eb004e6@mail.gmail.com>
References: <1b151690705231708v19ab6f5mb647007d6bcd1cea@mail.gmail.com>
	<43aa6ff70705231727i2b70b9a5hd4800018a23b052b@mail.gmail.com>
	<1b151690705240742u63103adel34b5c8b98eb004e6@mail.gmail.com>
Message-ID: <87zm3q33fc.fsf@uwakimon.sk.tsukuba.ac.jp>

Martin Blais writes:

 > There is another benefit to a builtin 'nodef', BTW, which is that of a
 > consistent meaning for the word.  Having a consistent name for this
 > concept--across all programs, if it were in the language

You can have a consistent name for the *concept*, but having a
consistent name for the *object* across all programs defeats its
purpose.


From steven.bethard at gmail.com  Sun May 27 17:37:41 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Sun, 27 May 2007 09:37:41 -0600
Subject: [Python-ideas] positional only arguments decorator
In-Reply-To: <75AAE6B2-8D9D-43CF-A151-DF0C92964BA7@marooned.org.uk>
References: <d11dcfba0705211130y6163556ica7f30d62de6258f@mail.gmail.com>
	<75AAE6B2-8D9D-43CF-A151-DF0C92964BA7@marooned.org.uk>
Message-ID: <d11dcfba0705270837q66006447l9cc771c382b20784@mail.gmail.com>

On 5/27/07, Arnaud Delobelle <arno at marooned.org.uk> wrote:
>
> On 21 May 2007, at 19:30, Steven Bethard wrote:
>
> > Ok, looks like there's not much chance of agreeing on a syntax, so
> > here's a decorator that covers the two use cases I know of::
> >
> > * matching the signature of dict() and dict.update()
> > * allowing arguments to have their names changed without worrying
> > about backwards compatibility (e.g. ``def func(sequence)`` changing to
> > ``def func(iterable)``)
>
> I propose a slightly different solution.  It may be a bit of a hack,
> but I don't see why it should not be safe. This solution allows you
> to use * and ** in order to write a definition like:
>
>  >>> @posonly
> ... def update(self, container=None, **kwargs):
> ...     return self, container, kwargs
> ...
>  >>> update('self')
> ('self', None, {})
>  >>> update('self', 'container')
> ('self', 'container', {})
>  >>> update('self', self='abc', container='xyz', foo='bar')
> ('self', None, {'self': 'abc', 'foo': 'bar', 'container': 'xyz'})

Cool!  Yes, it's hackish, but at least the results are pretty. ;-)

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From arno at marooned.org.uk  Mon May 28 13:22:45 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Mon, 28 May 2007 12:22:45 +0100
Subject: [Python-ideas] positional only arguments decorator
In-Reply-To: <75AAE6B2-8D9D-43CF-A151-DF0C92964BA7@marooned.org.uk>
References: <d11dcfba0705211130y6163556ica7f30d62de6258f@mail.gmail.com>
	<75AAE6B2-8D9D-43CF-A151-DF0C92964BA7@marooned.org.uk>
Message-ID: <6444B195-5B3A-49D9-BEB3-85FDEA6B234A@marooned.org.uk>


On 27 May 2007, at 10:03, Arnaud Delobelle wrote:
[...]
> This is achieved by 'flattening' the function first.  Here is the  
> code:
>
> import new
> import inspect
[...]

Well it turns out there can be problems as my code does not  
initialise the co_freevars and co_cellvars of the code objects it  
creates.  I blame it on the python doc (;-) which shows the signature  
of new.code as:

code(argcount, nlocals, stacksize, flags, codestring, constants,  
names, varnames, filename, name, firstlineno, lnotab)

Missing out on the last two optional arguments (freevars and  
cellvars). I only found that out by looking at Object/codeobject.c  
(which shows how clever I am, since I could have simply typed 'help 
(code.new)').  Moreover the file Lib/new.py says that the 'new'  
module is now deprecated, and that 'import types' should be used  
instead.

So here is the modified code.  The 'posonly' decorator is used in  
exactly the same way as I've described in my previous email.   
Compared with the previous version, I have tried to reduce the  
overhead caused by making a function 'posonly' to a minimum (this is  
why there are three definitions of 'posf').  Note that when a posonly  
function is called incorrectly , there should be a helpful error  
message, which is the 'builtin' one most of the time.

Please tell me if it is not appropriate to send code to the list as  
I'm doing.

-----------------------------------------------
from types import CodeType, FunctionType
import inspect

code_args = (
     'argcount', 'nlocals', 'stacksize', 'flags', 'code',
     'consts', 'names', 'varnames', 'filename', 'name',
     'firstlineno', 'lnotab', 'freevars', 'cellvars'
     )

function_args = ('code', 'globals', 'name', 'defaults', 'closure')

def copy_code(code_obj, **kwargs):
     "Make a copy of a code object, maybe changing some attributes"
     for arg in code_args:
         if not kwargs.has_key(arg):
             kwargs[arg] = getattr(code_obj, 'co_%s' % arg)
     return CodeType(*map(kwargs.__getitem__, code_args))

def copy_function(function_obj, **kwargs):
     "Make a copy of a function object, maybe changing some attributes"
     for arg in function_args:
         if not kwargs.has_key(arg):
             kwargs[arg] = getattr(function_obj, 'func_%s' % arg)
     return FunctionType(*map(kwargs.__getitem__, function_args))

def rename_function(f, name):
     f.__name__ = name
     f.func_code = copy_code(f.func_code, name=name)

def flattened(f):
     """Changes a function f(...[, *y] [, **z])
        to f(...[, y=None] [, z=None])"""
     fc = f.func_code
     defaults = f.func_defaults
     flags = fc.co_flags
     argcount = fc.co_argcount
     for bit in 4, 8:
         if flags & bit:
             flags ^= bit
             argcount += 1
             if defaults: defaults += (None,)
     flat_code = copy_code(fc, argcount=argcount, flags=flags)
     flat_f = copy_function(f, code=flat_code, defaults=defaults)
     return flat_f

def posonly(f):
     "posonly(f) makes the arguments of f positional only"
     f_args, f_varargs, f_varkwargs, f_defaults = inspect.getargspec(f)
     f_nargs = len(f_args)
     f_name = f.__name__
     flat_f = flattened(f)
     if f_varargs and f_varkwargs:
         def posf(*args, **kwargs):
             kwargs = {f_varkwargs: kwargs}
             kwargs[f_varargs] = args[f_nargs:]
             args = args[:f_nargs]
             return flat_f(*args, **kwargs)
     elif f_varkwargs: # and not f_varargs
         def posf(*args, **kwargs):
             kwargs = {f_varkwargs: kwargs}
             if len(args) > f_nargs:
                 msg = '%s() takes at most %i arguments (%i given)'
                 raise TypeError(msg % (f_name, f_nargs, len(args)))
             return flat_f(*args, **kwargs)
     else: # not f_varkwargs
         def posf(*args): return f(*args)
     rename_function(posf, f_name)
     return posf
-----------------------------------------------

-- 
Arnaud




From aahz at pythoncraft.com  Mon May 28 22:23:11 2007
From: aahz at pythoncraft.com (Aahz)
Date: Mon, 28 May 2007 13:23:11 -0700
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <914604.8688.qm@web33509.mail.mud.yahoo.com>
References: <914604.8688.qm@web33509.mail.mud.yahoo.com>
Message-ID: <20070528202311.GC18819@panix.com>

On Sat, May 26, 2007, Steve Howell wrote:
>
> Comments are welcome on improving the code itself, but I wonder if
> Python 3k (or 4k?) couldn't have some kind of native SQL-like ways of
> manipulating lists and dictionaries.  I don't have a proposal myself,
> just wonder if others have felt this kind of pain, and maybe it will
> spark a Pythonic solution.

What's wrong with sqlite?
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"Look, it's your affair if you want to play with five people, but don't
go calling it doubles."  --John Cleese anticipates Usenet


From showell30 at yahoo.com  Mon May 28 23:57:44 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Mon, 28 May 2007 14:57:44 -0700 (PDT)
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <20070528202311.GC18819@panix.com>
Message-ID: <314501.96528.qm@web33514.mail.mud.yahoo.com>


--- Aahz <aahz at pythoncraft.com> wrote:
> 
> What's wrong with sqlite?

Nothing, but I want Python itself to give me the SQL
syntax to manipulate lists-of-dictionaries like lists
of dictionaries, without having to go through some a
module.

In the example that I gave earlier in the thread, what
would the sqlite solution look like?  To transform any
particular list of dicitionaries into another list of
dictionaries, would I have to do a create-table in
sqlite, or does it already have some kind of mode
where it can work directly on a Python dataset?




 
____________________________________________________________________________________
Be a PS3 game guru.
Get your game face on with the latest PS3 news and previews at Yahoo! Games.
http://videogames.yahoo.com/platform?platform=120121


From rrr at ronadam.com  Tue May 29 00:49:30 2007
From: rrr at ronadam.com (Ron Adam)
Date: Mon, 28 May 2007 17:49:30 -0500
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ? (and
	other suggestions)
Message-ID: <465B5C7A.7070306@ronadam.com>



The dictionary fromkeys method seems out of place as well as miss-named.  IMHO


In the current 2.5 branch it occurs only twice. (excluding tests)

----
$ grep -r "fromkeys" Lib/*.py
Lib/httplib.py:        header_names = dict.fromkeys([k.lower() for k in 
headers])
Lib/UserDict.py:    def fromkeys(cls, iterable, value=None):
----

In httplib.py, it is used as a set to remove duplicates.


There are enough correct uses of it in the wild to keep the behavior, but 
it can be done in a better way.

I feel it really should be called set_keys and implemented as a method that 
operates on the current dictionary instead of being a constructor for a new 
dictionary.  That will allow you to add keys with a default value to an 
already existing dictionary, or to create a new one with a dictionary 
constructor.

      dict().set_keys(s, v=None)    # The current fromkeys behavior.

I think this reads better and can be used in a wider variety of situations.

It could be useful for setting an existing dictionary to a default state.

     # reset status of items.
     status.set_keys(status.keys(), v=0)

Or more likely, resetting a partial sub set of the keys to some initial state.


The reason I started looking at this is I wanted to split a dictionary into 
smaller dictionaries and my first thought was that fromkeys would do that. 
    But of course it doesn't.

What I wanted was to be able to specify the keys and get the values from 
the existing dictionary into the new dictionary without using a for loop to 
iterate over the keys.

    d = dict(1='a', 2='b', 3='c', 4='d', 5='e')

    d_odds = d.from_keys([1, 3, 5])      # new dict of items 1, 3, 5
    d_evens = d.from_keys([2, 4])        # new dict of items 2, 4

There currently isn't a way to split a dictionary without iterating it's 
contents even if you know the keys you need before hand.

A from_keys method would be the inverse complement of the update method.


A del_keys method could replace the clear method.  del_keys would be more 
useful as it could operate on a partial set of keys.

    d.delkeys(d.keys())    # The current clear method behavior.


Some potentially *very common* uses:

      # This first one works now, but I included it for completeness.  ;-)

      mergedicts(d1, d2):
          """ Combine two dictionaries. """
          dd = dict(d1)
          return dd.update(d2)

      splitdict(d, keys):
          """ Split dictionary d using keys. """
          keys_rest = set(d.keys()) - set(keys)
          return d.from_keys(keys), d.from_keys(keys_rest)

      split_from_dict(d, keys):
          """ Removes and returns a subdict of d with keys. """
          dd = d.from_keys(keys)
          d.del_keys(keys)
          return dd

      copy_items(d1, d2, keys):
          """ Copy items from dictionary d1 to d2. """
          d2.update(d1.from_keys(keys))      # I really like this!

      move_items(d1, d2, keys):
          """ Move items from dictionary d1 to d2. """
          d2.update(d1.from_keys(keys))
          d1.del_keys(keys)


I think the set_keys, from_keys, and del_keys methods could add both 
performance and clarity benefits to python.

So to summarize...

     1.  Replace existing fromkeys method with a set_keys method.

     2.  Add a partial copy items from_keys method.

     3.  Replace the clear method with a del_keys method.


So this replaces two methods and adds one more.  Overall I think the 
usefulness of these would be very good.

I also think it will work very well with the python 3000 keys method 
returning an iterator.  (And still be two fewer methods than we currently 
have.)

Any thoughts?

Cheers,
   Ron


From jcarlson at uci.edu  Tue May 29 01:56:17 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Mon, 28 May 2007 16:56:17 -0700
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <465B5C7A.7070306@ronadam.com>
References: <465B5C7A.7070306@ronadam.com>
Message-ID: <20070528162407.869C.JCARLSON@uci.edu>


Ron Adam <rrr at ronadam.com> wrote:
> There are enough correct uses of it in the wild to keep the behavior, but 
> it can be done in a better way.
> 
> I feel it really should be called set_keys and implemented as a method that 
> operates on the current dictionary instead of being a constructor for a new 
> dictionary.  That will allow you to add keys with a default value to an 
> already existing dictionary, or to create a new one with a dictionary 
> constructor.
> 
>       dict().set_keys(s, v=None)    # The current fromkeys behavior.

The problem with that is that when a method mutates an object, it
shouldn't return the object.  Your new .set_keys() method violates this
behavior that is used in lists, sets, dicts, deques, arrays, etc.

I don't have time to comment on the rest at the moment, will do when I
get a chance.


 - Josiah



From aahz at pythoncraft.com  Tue May 29 02:14:22 2007
From: aahz at pythoncraft.com (Aahz)
Date: Mon, 28 May 2007 17:14:22 -0700
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <314501.96528.qm@web33514.mail.mud.yahoo.com>
References: <20070528202311.GC18819@panix.com>
	<314501.96528.qm@web33514.mail.mud.yahoo.com>
Message-ID: <20070529001422.GA14967@panix.com>

On Mon, May 28, 2007, Steve Howell wrote:
> --- Aahz <aahz at pythoncraft.com> wrote:
>> 
>> What's wrong with sqlite?
> 
> Nothing, but I want Python itself to give me the SQL syntax to
> manipulate lists-of-dictionaries like lists of dictionaries, without
> having to go through some a module.
>
> In the example that I gave earlier in the thread, what would the
> sqlite solution look like?  To transform any particular list of
> dicitionaries into another list of dictionaries, would I have to do
> a create-table in sqlite, or does it already have some kind of mode
> where it can work directly on a Python dataset?

You'd have to convert your data into sqlite tables, of course, but:

* It's not much work

* Your specific needs for operating on data are likely to be different
from everyone else's -- the reason SQL works is precisely because it
imposes constraints on data format

To the extent that Python provides anything roughly comparable to SQL,
use listcomps and genexps.

Think of it this way: if Python requires you to use a library for regex
manipulation, what makes SQL-like data processing sufficiently special
that it belongs in the language itself?
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"Look, it's your affair if you want to play with five people, but don't
go calling it doubles."  --John Cleese anticipates Usenet


From rrr at ronadam.com  Tue May 29 02:21:48 2007
From: rrr at ronadam.com (Ron Adam)
Date: Mon, 28 May 2007 19:21:48 -0500
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
 (and other suggestions)
In-Reply-To: <20070528162407.869C.JCARLSON@uci.edu>
References: <465B5C7A.7070306@ronadam.com>
	<20070528162407.869C.JCARLSON@uci.edu>
Message-ID: <465B721C.3080106@ronadam.com>

Josiah Carlson wrote:
> Ron Adam <rrr at ronadam.com> wrote:
>> There are enough correct uses of it in the wild to keep the behavior, but 
>> it can be done in a better way.
>>
>> I feel it really should be called set_keys and implemented as a method that 
>> operates on the current dictionary instead of being a constructor for a new 
>> dictionary.  That will allow you to add keys with a default value to an 
>> already existing dictionary, or to create a new one with a dictionary 
>> constructor.
>>
>>       dict().set_keys(s, v=None)    # The current fromkeys behavior.
> 
> The problem with that is that when a method mutates an object, it
> shouldn't return the object.  Your new .set_keys() method violates this
> behavior that is used in lists, sets, dicts, deques, arrays, etc.

Huh?  Where does it return an object?

> I don't have time to comment on the rest at the moment, will do when I
> get a chance.
> 
>  - Josiah

Ok  :-)

Ron




From rrr at ronadam.com  Tue May 29 02:29:07 2007
From: rrr at ronadam.com (Ron Adam)
Date: Mon, 28 May 2007 19:29:07 -0500
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
 (and other suggestions)
In-Reply-To: <465B721C.3080106@ronadam.com>
References: <465B5C7A.7070306@ronadam.com>	<20070528162407.869C.JCARLSON@uci.edu>
	<465B721C.3080106@ronadam.com>
Message-ID: <465B73D3.9010603@ronadam.com>

Ron Adam wrote:
> Josiah Carlson wrote:
>> Ron Adam <rrr at ronadam.com> wrote:
>>> There are enough correct uses of it in the wild to keep the behavior, but 
>>> it can be done in a better way.
>>>
>>> I feel it really should be called set_keys and implemented as a method that 
>>> operates on the current dictionary instead of being a constructor for a new 
>>> dictionary.  That will allow you to add keys with a default value to an 
>>> already existing dictionary, or to create a new one with a dictionary 
>>> constructor.
>>>
>>>       dict().set_keys(s, v=None)    # The current fromkeys behavior.
>> The problem with that is that when a method mutates an object, it
>> shouldn't return the object.  Your new .set_keys() method violates this
>> behavior that is used in lists, sets, dicts, deques, arrays, etc.
> 
> Huh?  Where does it return an object?


Whoops,  Ok I see it now.   So the example should be...

      d = dict()
      d.set_keys(s, v=none)


I think that would work fine.



>> I don't have time to comment on the rest at the moment, will do when I
>> get a chance.
>>
>>  - Josiah
> 
> Ok  :-)
> 
> Ron
> 
> 
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
> 
> 



From adam at atlas.st  Tue May 29 02:29:49 2007
From: adam at atlas.st (Adam Atlas)
Date: Mon, 28 May 2007 20:29:49 -0400
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <914604.8688.qm@web33509.mail.mud.yahoo.com>
References: <914604.8688.qm@web33509.mail.mud.yahoo.com>
Message-ID: <86BD9376-372F-4CE4-9A38-7575A0E60B9B@atlas.st>


On 26 May 2007, at 12.06, Steve Howell wrote:
> Here is the Python code that I wrote:
>
>     def groupDictBy(lst, keyField):
>         dct = {}
>         for item in lst:
>             keyValue = item[keyField]
>             if keyValue not in dct:
>                 dct[keyValue] = []
>             dct[keyValue].append(item)
>         return dct

I think this is basically equivalent to itertools.groupby. You could do:

   for name, events in itertools.groupby(events, lambda e: e 
['name']): ...

Untested, but I'm pretty sure that's what you're doing here. The main  
difference is that it returns an iterable of 2-tuples instead of a  
dictionary (but you can just pass it straight to dict() if need be),  
and that it requires you to pass it a key function (here a simple  
lambda) instead of a dictionary key.

>     dct = groupDictBy(events, 'name')
>     for name in dct:
>         events = dct[name]
>         charges = {}
>         for bucket in ('setup', 'install'):
>             charges[bucket] = sum(
>                     [float(event['charge']) for
>                     event in events
>                     if event['bucket'] == bucket])

I'm not quite sure what the intended function of this is. You group  
dct by the 'name' field, but for each iteration of the loop, you're  
setting the `charges` variable anew, basically throwing away the  
value produced by any previous iteration. That's not intended, is it?

Second, it looks almost like the inner loop could also be an  
itertools.groupby call. Grouping by 'bucket'. Ignoring the previous  
paragraph, I think it would be something like this:

for name, events in itertools.groupby(events, lambda e: e['name']):
     charges = dict([(bucket, sum([float(event['charge']) for event  
in v]))
         for bucket, v in itertools.groupby(events, lambda e: e 
['bucket'])])

And of course if you meant to have 'charges' be an array or a dict or  
something, with a value for each iteration of the outer loop, then  
this could be made into a one-liner by changing the for loop into a  
list comprehension. It's not as terse as SQL, but it gets the job done.

> Comments are welcome on improving the code itself, but
> I wonder if Python 3k (or 4k?) couldn't have some kind
> of native SQL-like ways of manipulating lists and
> dictionaries.  I don't have a proposal myself, just
> wonder if others have felt this kind of pain, and
> maybe it will spark a Pythonic solution.

I don't really have an opinion for now, but if this does happen, I  
think the best way would be to have a new 'table' type supporting  
operations like this. (I think a stdlib module would do; I don't  
think this is quite important enough to warrant a global builtin  
type. And filling `dict` itself with these methods could get  
cluttersome.)

I started writing a paragraph here about what types of methods it  
could have, returning various types of iterators, but then I realized  
that I was basically describing SQLAlchemy. So I think we shouldn't  
reinvent the wheel there; it would be an interesting exercise to see  
if SQLAlchemy could be made to operate on native Python data  
structures, though.


From jcarlson at uci.edu  Tue May 29 02:41:33 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Mon, 28 May 2007 17:41:33 -0700
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <465B721C.3080106@ronadam.com>
References: <20070528162407.869C.JCARLSON@uci.edu>
	<465B721C.3080106@ronadam.com>
Message-ID: <20070528173945.869F.JCARLSON@uci.edu>


Ron Adam <rrr at ronadam.com> wrote:
> Josiah Carlson wrote:
> > Ron Adam <rrr at ronadam.com> wrote:
> >> There are enough correct uses of it in the wild to keep the behavior, but 
> >> it can be done in a better way.
> >>
> >> I feel it really should be called set_keys and implemented as a method that 
> >> operates on the current dictionary instead of being a constructor for a new 
> >> dictionary.  That will allow you to add keys with a default value to an 
> >> already existing dictionary, or to create a new one with a dictionary 
> >> constructor.
> >>
> >>       dict().set_keys(s, v=None)    # The current fromkeys behavior.
> > 
> > The problem with that is that when a method mutates an object, it
> > shouldn't return the object.  Your new .set_keys() method violates this
> > behavior that is used in lists, sets, dicts, deques, arrays, etc.
> 
> Huh?  Where does it return an object?

If you are looking to replace dict.fromkeys(...), then dict().set_keys
(...) must return the dictionary that was just created and mutated.


 - Josiah



From jcarlson at uci.edu  Tue May 29 03:18:22 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Mon, 28 May 2007 18:18:22 -0700
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <465B5C7A.7070306@ronadam.com>
References: <465B5C7A.7070306@ronadam.com>
Message-ID: <20070528174325.86A2.JCARLSON@uci.edu>


Ron Adam <rrr at ronadam.com> wrote:
> The dictionary fromkeys method seems out of place as well as miss-named.  IMHO

It is perfectly named (IMNSHO ;), create a dictionary from the keys
provided; dict.fromkeys() .


> There are enough correct uses of it in the wild to keep the behavior, but 
> it can be done in a better way.

I wasn't terribly convinced by your later arguments, so I'm -1.


> I think this reads better and can be used in a wider variety of situations.
> 
> It could be useful for setting an existing dictionary to a default state.
> 
>      # reset status of items.
>      status.set_keys(status.keys(), v=0)

This can be done today:

    status.update((i, 0) for i in status.keys())
    #or
    status.update(dict.fromkeys(status, 0))


> Or more likely, resetting a partial sub set of the keys to some initial state.
> 
> 
> The reason I started looking at this is I wanted to split a dictionary into 
> smaller dictionaries and my first thought was that fromkeys would do that. 
>     But of course it doesn't.

Changing the bahvior of dict.fromkeys() is not going to happen. We can
remove it, we can add a new method, but changing will lead to not so
subtle breakage as people who were used to the old behavior try to use
the updated method.

Note that this isn't a matter of "it's ok to break in 3.0", because
dict.fromkeys() is not seen as being a design mistake by any of the
'heavy hitters' in python-dev or python-3000 that I have heard (note
that I am certainly not a 'heavy hitter').


> What I wanted was to be able to specify the keys and get the values from 
> the existing dictionary into the new dictionary without using a for loop to 
> iterate over the keys.
> 
>     d = dict(1='a', 2='b', 3='c', 4='d', 5='e')
> 
>     d_odds = d.from_keys([1, 3, 5])      # new dict of items 1, 3, 5
>     d_evens = d.from_keys([2, 4])        # new dict of items 2, 4
> 
> There currently isn't a way to split a dictionary without iterating it's 
> contents even if you know the keys you need before hand.

Um...

    def from_keys(d, iterator):
        return dict((i, d[i]) for i in iterator)


> A del_keys method could replace the clear method.  del_keys would be more 
> useful as it could operate on a partial set of keys.
> 
>     d.delkeys(d.keys())    # The current clear method behavior.

I can't remember ever needing something like this that wasn't handled by
d.clear() .


> Some potentially *very common* uses:
> 
>       # This first one works now, but I included it for completeness.  ;-)
> 
>       mergedicts(d1, d2):
>           """ Combine two dictionaries. """
>           dd = dict(d1)
>           return dd.update(d2)

    dict((i, d2.get(i, d1.get(i))) for i in itertools.chain(d1,d2))


>       splitdict(d, keys):
>           """ Split dictionary d using keys. """
>           keys_rest = set(d.keys()) - set(keys)
>           return d.from_keys(keys), d.from_keys(keys_rest)

I can't think of a simple one-liner for this one that wouldn't duplicate
work.


>       split_from_dict(d, keys):
>           """ Removes and returns a subdict of d with keys. """
>           dd = d.from_keys(keys)
>           d.del_keys(keys)
>           return dd

    dict((i, d.pop(i, None)) for i in keys)

>       copy_items(d1, d2, keys):
>           """ Copy items from dictionary d1 to d2. """
>           d2.update(d1.from_keys(keys))      # I really like this!

    d2.update((i, d1[i]) for i in keys)


>       move_items(d1, d2, keys):
>           """ Move items from dictionary d1 to d2. """
>           d2.update(d1.from_keys(keys))
>           d1.del_keys(keys)

    d2.update((i, d1.pop(i, None)) for i in keys)

> I think the set_keys, from_keys, and del_keys methods could add both 
> performance and clarity benefits to python.

Performance, sometimes, for some use-cases.  Clarity?  Maybe.  Your
split* functions are a bit confusing to me, and I've never really needed
any of the functions that you list.


> So to summarize...
> 
>      1.  Replace existing fromkeys method with a set_keys method.
>      2.  Add a partial copy items from_keys method.
>      3.  Replace the clear method with a del_keys method.

Not all X line functions should be builtins.  If you find that you are
doing the above more often than you think you should, create a module
with all of the related functionality that automatically patches the
builtins on import and place it in the Python cheeseshop.  If people
find that the functionality helps them, then we should consider it for
inclusion.  As it stands, most of the methods you offer have a very
simple one-line version that is already very efficient.


> So this replaces two methods and adds one more.  Overall I think the 
> usefulness of these would be very good.

I don't find the current dictionary API to be lacking in any way other
than "what do I really need to override to get functionality X", but
that is a documentation issue more than anything.


> I also think it will work very well with the python 3000 keys method 
> returning an iterator.  (And still be two fewer methods than we currently 
> have.)

I'm sorry, but I can't really see how your changes would add to Python's
flexibility without cluttering up interfaces and confusing current users.


 - Josiah



From rrr at ronadam.com  Tue May 29 06:04:06 2007
From: rrr at ronadam.com (Ron Adam)
Date: Mon, 28 May 2007 23:04:06 -0500
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
 (and other suggestions)
In-Reply-To: <20070528174325.86A2.JCARLSON@uci.edu>
References: <465B5C7A.7070306@ronadam.com>
	<20070528174325.86A2.JCARLSON@uci.edu>
Message-ID: <465BA636.8070501@ronadam.com>

Josiah Carlson wrote:
> Ron Adam <rrr at ronadam.com> wrote:
>> The dictionary fromkeys method seems out of place as well as miss-named.  IMHO
> 
> It is perfectly named (IMNSHO ;), create a dictionary from the keys
> provided; dict.fromkeys() .

That's ok, I won't hold it against you.  ;-)

What about it's being out of place?  Is this case like 'sorted' vs 'sort' 
for lists?

I'm ok with leaving it names as is if that's a real problem.  Another name 
for the mutate with keys method can be found.  That may reduce possible 
confusion as well.


>> There are enough correct uses of it in the wild to keep the behavior, but 
>> it can be done in a better way.
> 
> I wasn't terribly convinced by your later arguments, so I'm -1.

Yes, I'm not the most influential writer.

I'm not sure I can convince you it's better if you already think it's not. 
  That has more to do with your personal preference.  So lets look at how 
much it's actually needed in the current (and correct) form.


(These are rough estimates, I can try to come up with more accurate 
statistics if that is desired.)

Doing a search on google code turns up 300 hits for "lang:python \.fromkeys\(".

Looking at a sample of those, it looks like about 80% use it as a set() 
constructor to remove duplicates.  (For compatibility reason with python 
2.3 code, or for pytohn 2.3 and earlier code.)

Is there a way to narrow this down to python 2.4 and later? (anyone?)

A bit more sampling, it looks like about 8 of 10 of those remaining 20% can 
be easily converted to the following form without any trouble.

     d = dict()
     d.set_keys(keys, v=value)

That would leave about 12 cases (YMV) that need the inline functionality. 
For those a simple function can do it.

     def dict_from_keys(keys, v=value):
         d = dict()
         d.set_keys(keys, v)
         return d

Is 12 cases out of about 315,000 python files a big enough need to keep the 
current behavior?   315,000 is the number returned from google code for all 
python files, 'lang:python'. (I'm sure there are some duplicates)


Is this more convincing.   ;-)

(If anyone can come up with better numbers, that would be cool.)

>> I think this reads better and can be used in a wider variety of situations.
>>
>> It could be useful for setting an existing dictionary to a default state.
>>
>>      # reset status of items.
>>      status.set_keys(status.keys(), v=0)
> 
> This can be done today:

Of course all of the examples I gave can be done today.  But they nearly 
all require iterating in python in some form.


>     status.update((i, 0) for i in status.keys())
>     #or
>     status.update(dict.fromkeys(status, 0))

The first example requires iterating over the keys.  The second example 
works if you want to initialize all the keys.  In which case, there is no 
reason to use the update method.  dict.fromkeys(status, 0) is enough.


>> Or more likely, resetting a partial sub set of the keys to some initial state.
>>
>>
>> The reason I started looking at this is I wanted to split a dictionary into 
>> smaller dictionaries and my first thought was that fromkeys would do that. 
>>     But of course it doesn't.
> 
> Changing the bahvior of dict.fromkeys() is not going to happen. We can
> remove it, we can add a new method, but changing will lead to not so
> subtle breakage as people who were used to the old behavior try to use
> the updated method.
> 
> Note that this isn't a matter of "it's ok to break in 3.0", because
> dict.fromkeys() is not seen as being a design mistake by any of the
> 'heavy hitters' in python-dev or python-3000 that I have heard (note
> that I am certainly not a 'heavy hitter').

Then lets find a different name.


>> What I wanted was to be able to specify the keys and get the values from 
>> the existing dictionary into the new dictionary without using a for loop to 
>> iterate over the keys.
>>
>>     d = dict(1='a', 2='b', 3='c', 4='d', 5='e')
>>
>>     d_odds = d.from_keys([1, 3, 5])      # new dict of items 1, 3, 5
>>     d_evens = d.from_keys([2, 4])        # new dict of items 2, 4
>>
>> There currently isn't a way to split a dictionary without iterating it's 
>> contents even if you know the keys you need before hand.
> 
> Um...
> 
>     def from_keys(d, iterator):
>         return dict((i, d[i]) for i in iterator)

(iterating)

Yep as I said just above this.

  """There currently isn't a way to split a dictionary without iterating 
it's contents ..."""

Lists have __getslice__, __setslice__, and __delslice__.  It could be 
argued that those can be handled just as well with iterators and loops as 
well.  Of course we see them as seq[s:s+x], on both lists and strings.  So 
why not have an equivalent for dictionaries.  We can't slice them, but we 
do have key lists to use in the same way.


>> A del_keys method could replace the clear method.  del_keys would be more 
>> useful as it could operate on a partial set of keys.
>>
>>     d.delkeys(d.keys())    # The current clear method behavior.
> 
> I can't remember ever needing something like this that wasn't handled by
> d.clear() .

All or nothing.  d = dict() works just as well.

BTW, google code give 500 hits for "\.clear\(".  But it very un-clear how 
many of those are false positives due to other objects having a clear 
method.  It's probably a significant percentage in this case.


>> Some potentially *very common* uses:
>>
>>       # This first one works now, but I included it for completeness.  ;-)
>>
>>       mergedicts(d1, d2):
>>           """ Combine two dictionaries. """
>>           dd = dict(d1)
>>           return dd.update(d2)
> 
>     dict((i, d2.get(i, d1.get(i))) for i in itertools.chain(d1,d2))

(iterating)

And I'd prefer to define the function in this case for readability reasons.


>>       splitdict(d, keys):
>>           """ Split dictionary d using keys. """
>>           keys_rest = set(d.keys()) - set(keys)
>>           return d.from_keys(keys), d.from_keys(keys_rest)
> 
> I can't think of a simple one-liner for this one that wouldn't duplicate
> work.

:-)

This is one of the main motivators.


>>       split_from_dict(d, keys):
>>           """ Removes and returns a subdict of d with keys. """
>>           dd = d.from_keys(keys)
>>           d.del_keys(keys)
>>           return dd
> 
>     dict((i, d.pop(i, None)) for i in keys)

(iterating)


>>       copy_items(d1, d2, keys):
>>           """ Copy items from dictionary d1 to d2. """
>>           d2.update(d1.from_keys(keys))      # I really like this!
> 
>     d2.update((i, d1[i]) for i in keys)

(iterating)


>>       move_items(d1, d2, keys):
>>           """ Move items from dictionary d1 to d2. """
>>           d2.update(d1.from_keys(keys))
>>           d1.del_keys(keys)
> 
>     d2.update((i, d1.pop(i, None)) for i in keys)

(iterating)


>> I think the set_keys, from_keys, and del_keys methods could add both 
>> performance and clarity benefits to python.
> 
> Performance, sometimes, for some use-cases.  Clarity?  Maybe.  Your
> split* functions are a bit confusing to me, and I've never really needed
> any of the functions that you list.

I think sometime our need is determined by what is available for use.  So 
if it's not available, our minds filter it out from the solutions we 
consider.  That way, we don't need the things we don't have or can't get.

My minds "need filter" seems to be broken in that respect. I often need 
things I don't have.  But sometimes that works out to be good.  ;-)


>> So to summarize...
>>
>>      1.  Replace existing fromkeys method with a set_keys method.
>>      2.  Add a partial copy items from_keys method.
>>      3.  Replace the clear method with a del_keys method.
> 
> Not all X line functions should be builtins.

Of course I knew someone would point this out.  I'm not requesting the 
above example functions be builtins.  Only the changes to the dict methods 
be considered.    They would allow those above functions to work in a more 
efficient way and I'd be happy to add those functions to my own library.

With these methods in most cases the functions wouldn't even be needed. 
You would just use the methods in combinations with each other directly and 
the result would still be readable without a lot of 'code' overhead.

Also consider this from a larger view.  List has __getslice__, 
__setslice__, and __delslice__.  Set has numerous methods that operate on 
more than one element.

Dictionaries are suppose to be highly efficient, but they only have limited 
methods that can operate on more than one item at a time,  so you end up 
iterating over the keys to do nearly everything.

So as an alternative, leave fromkeys and clear alone and add...

     getkeys(keys)  ->  dict
     setkeys(keys, v=None)
     delkeys(keys)

Where these offer the equivalent of list slice functionality to dictionaries.


If you find that you are
> doing the above more often than you think you should, create a module
> with all of the related functionality that automatically patches the
> builtins on import and place it in the Python cheeseshop.  If people
> find that the functionality helps them, then we should consider it for
> inclusion.  As it stands, most of the methods you offer have a very
> simple one-line version that is already very efficient.

Iterators and for loops are fairly efficient for small dictionaries, but 
iterating can still be considerable slower than the equivalent C code if 
they are large dictionaries.


>> So this replaces two methods and adds one more.  Overall I think the 
>> usefulness of these would be very good.
> 
> I don't find the current dictionary API to be lacking in any way other
> than "what do I really need to override to get functionality X", but
> that is a documentation issue more than anything.

>> I also think it will work very well with the python 3000 keys method 
>> returning an iterator.  (And still be two fewer methods than we currently 
>> have.)
> 
> I'm sorry, but I can't really see how your changes would add to Python's
> flexibility without cluttering up interfaces and confusing current users.

I think it cleans up the API more than it clutters it up.  It coverts two 
limited use methods to be more general, and adds one more that works with 
the already existing update method nicely.

In both cases of the two existing methods, fromkeys and clear, your 
arguments, that there all ready exists easy one line functions to do this, 
would be enough of a reason to not have them in the first place.  So do you 
feel they should be removed?


I plan on doing a search of places where these things can make a difference 
in making the code more readable and/or faster.

Cheers,
    Ron


From showell30 at yahoo.com  Tue May 29 13:06:24 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 04:06:24 -0700 (PDT)
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <20070529001422.GA14967@panix.com>
Message-ID: <77963.57573.qm@web33501.mail.mud.yahoo.com>


--- Aahz <aahz at pythoncraft.com> wrote:
> Think of it this way: if Python requires you to use
> a library for regex
> manipulation, what makes SQL-like data processing
> sufficiently special
> that it belongs in the language itself?

There is a difference.

Regexes would never leverage python expressions
*inside* the regex, even if they were more directly
integrated into the language like Perl.  (And, for the
record, I prefer Python's philosophy to make regexes a
module, but I do appreciate the short name, re, and
the fact that it's battery included).

In the case of SQL, I can imagine something like this:

def convert_to_euros(salary): ...

result_set = [[[
select deptno, total(convert_to_euros(salary))
from emp
where country = 'France'
group by deptno
]]] # where emp is a list of dictionaries

Obviously, I understand that you can solve this
problem in Python now, but you either have to do this:

   1) Use more bulky way to describe the expression:

   sql(..., criteria=lambda row: row['country'] ==
'France')

   2) Rely on some library to parse the SQL for you,
which is good enough for the year 2007, but I wonder
why the Python interpreter itself couldn't interpret
the SQL to bytecode (at startup time) just as easily
as, say, SQLAlchemy or sqlite, does at runtime.








       
____________________________________________________________________________________Pinpoint customers who are looking for what you sell. 
http://searchmarketing.yahoo.com/


From showell30 at yahoo.com  Tue May 29 14:07:48 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 05:07:48 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
Message-ID: <422478.77150.qm@web33501.mail.mud.yahoo.com>

ABSTRACT:

I propose the following syntax:

   rowexpr: convert_to_euros(salary) > 50000 and
deptno = 10

Rowexpr returns a function object that can be called
with one argument, row, and the items "salary" and
"deptno" are used to derefence row.

RATIONALE:

A lot of time people write Python code that works with
other small interpreters, such as SQL engines, math
libraries, etc., that have an expression syntax of
their own.  To use SQL as an example, I may want my
SQL engine to use this Python expression:

   where convert_to_euros(salary) > 50000 and deptno =
10

To interact with SQL engines, I could imagine code
like the following:
 
  sql(..., lambda row: convert_to_euros(row['salary']
> 50000 and row['deptno'] = 10) # not concise

  sql(..., sql_parse('convert_to_euros(salary) > 50000
and deptno = 10') # requires sophisticated library

  sql(..., [and_op,
[ge_op(func_call_op(convert_to_euros, 'salary'),
50000), eq_opt(itemgetter_op('deptno'), 10)]) #
UGLY!!!



SOLUTION:

Let the Python interpreter build expression objects
for you.  You write:

   rowexpr: convert_to_euros(salary) > 50000 and
deptno = 10

Python translates that into the same bytecode as:

lambda row: convert_to_euros(row['salary'] > 50000 and
row['deptno'] == 10

Benefits:

    1) Allows smaller code.
    2) Having Python translate the rowexpr creates an
opportunity for better error messages, catching more
things at startup time, etc.
    3) In the particular case of SQL, it enable the
development methodology that you might start off by
writing code that processes data in memory, but with
mostly SQL-like syntax, and then switch over to a real
SQL database as scalability becomes a bigger concern.

COMMON OBJECTIONS:

   1) More syntax, of course.

   2) Folks used to SQL would still need to adjust to
differences between Python expressions (==) and SQL
(=).

   3) In the case of SQL, people may already be happy
enough with current tools, and of course, interpreters
external to Python can cache expressions, etc.

OPEN QUESTIONS:

Would a rowexpr be limited to dictionaries, or could
it also try to access object attributes?




       
____________________________________________________________________________________Be a better Globetrotter. Get better travel answers from someone who knows. Yahoo! Answers - Check it out.
http://answers.yahoo.com/dir/?link=list&sid=396545469


From bwinton at latte.ca  Tue May 29 16:09:11 2007
From: bwinton at latte.ca (Blake Winton)
Date: Tue, 29 May 2007 10:09:11 -0400
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <422478.77150.qm@web33501.mail.mud.yahoo.com>
References: <422478.77150.qm@web33501.mail.mud.yahoo.com>
Message-ID: <465C3407.6030903@latte.ca>

Steve Howell wrote:
> Let the Python interpreter build expression objects
> for you.  You write:
>    rowexpr: convert_to_euros(salary) > 50000 and
> deptno = 10
> Python translates that into the same bytecode as:
> lambda row: convert_to_euros(row['salary'] > 50000 and
> row['deptno'] == 10

I'm sorry, why would that not be translated into:

lambda row: row['convert_to_euros'](row['salary'] > row['50000'] 
row['and'] row['deptno'] == row['10']

?  Specifically, how would python know what to dereference and what not 
to?  What if there were two things, named the same, one in the row and 
one in the namespace?  (i.e. a variable named 'salary')  How would you 
escape things which would have been dereferenced but you didn't want to 
be?  (i.e. "rowexpr: convert_to_euros(salary) > salary")

I guess I'm kind of wasting my time here, since the introduction of a 
new keyword for this application really isn't going to happen, based on 
other decisions I've seen Guido make, but I do think that you need to 
think a little more about how the implementation of this feature would 
work.  (Or perhaps you've done that thinking, and you just need to fill 
in the proposal with that information.)

Thanks,
Blake.


From george.sakkis at gmail.com  Tue May 29 17:03:38 2007
From: george.sakkis at gmail.com (George Sakkis)
Date: Tue, 29 May 2007 11:03:38 -0400
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <465C3407.6030903@latte.ca>
References: <422478.77150.qm@web33501.mail.mud.yahoo.com>
	<465C3407.6030903@latte.ca>
Message-ID: <91ad5bf80705290803l7d6cade1s52ee8eceecc7b985@mail.gmail.com>

On 5/29/07, Blake Winton <bwinton at latte.ca> wrote:

> Steve Howell wrote:
> > Let the Python interpreter build expression objects
> > for you.  You write:
> >    rowexpr: convert_to_euros(salary) > 50000 and
> > deptno = 10
> > Python translates that into the same bytecode as:
> > lambda row: convert_to_euros(row['salary'] > 50000 and
> > row['deptno'] == 10
>
> I'm sorry, why would that not be translated into:
>
> lambda row: row['convert_to_euros'](row['salary'] > row['50000']
> row['and'] row['deptno'] == row['10']
>
> ?  Specifically, how would python know what to dereference and what not
> to?  What if there were two things, named the same, one in the row and
> one in the namespace?  (i.e. a variable named 'salary')  How would you
> escape things which would have been dereferenced but you didn't want to
> be?  (i.e. "rowexpr: convert_to_euros(salary) > salary")
>
> I guess I'm kind of wasting my time here, since the introduction of a
> new keyword for this application really isn't going to happen, based on
> other decisions I've seen Guido make, but I do think that you need to
> think a little more about how the implementation of this feature would
> work.  (Or perhaps you've done that thinking, and you just need to fill
> in the proposal with that information.)

Indeed, such half baked ideas have no chance of being taken seriously
as language additions. Take a look at packages such as buzhug [1] and
(especially) SqlAlchemy [2], not only because they might end up
solving your problem but also to appreciate the complexity involved in
supporting arbitrary SQL-like expressions at the language level, since
you clearly underestimate it or haven't quite thought about it.

George


[1] http://buzhug.sourceforge.net/
[2] http://www.sqlalchemy.org/docs/


-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."


From stargaming at gmail.com  Tue May 29 18:12:23 2007
From: stargaming at gmail.com (Stargaming)
Date: Tue, 29 May 2007 18:12:23 +0200
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <314501.96528.qm@web33514.mail.mud.yahoo.com>
References: <20070528202311.GC18819@panix.com>
	<314501.96528.qm@web33514.mail.mud.yahoo.com>
Message-ID: <f3hjda$1s3$1@sea.gmane.org>

Steve Howell schrieb:
> --- Aahz <aahz at pythoncraft.com> wrote:
> 
>>What's wrong with sqlite?
> 
> 
> Nothing, but I want Python itself to give me the SQL
> syntax to manipulate lists-of-dictionaries like lists
> of dictionaries, without having to go through some a
> module.

Are there any non-SQL use cases for SQL syntax?
And how would all those DBs adapt? With yet another interface? And if 
you allow me to add, I consider all your examples kinda unpythonic.



From jcarlson at uci.edu  Tue May 29 18:35:41 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 29 May 2007 09:35:41 -0700
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <465BA636.8070501@ronadam.com>
References: <20070528174325.86A2.JCARLSON@uci.edu>
	<465BA636.8070501@ronadam.com>
Message-ID: <20070529000414.86A5.JCARLSON@uci.edu>


Ron Adam <rrr at ronadam.com> wrote:
> Josiah Carlson wrote:
> > Ron Adam <rrr at ronadam.com> wrote:
> >> The dictionary fromkeys method seems out of place as well as miss-named.  IMHO
> > 
> > It is perfectly named (IMNSHO ;), create a dictionary from the keys
> > provided; dict.fromkeys() .
> 
> That's ok, I won't hold it against you.  ;-)
> 
> What about it's being out of place?  Is this case like 'sorted' vs 'sort' 
> for lists?

Sorted returns a list because it is the only mutable ordered sequence in
Python, hence the only object that makes sense to return from a sorted
function.


> >> There are enough correct uses of it in the wild to keep the behavior, but 
> >> it can be done in a better way.
> > 
> > I wasn't terribly convinced by your later arguments, so I'm -1.
> 
> Yes, I'm not the most influential writer.
> 
> I'm not sure I can convince you it's better if you already think it's not. 
>   That has more to do with your personal preference.  So lets look at how 
> much it's actually needed in the current (and correct) form.
[snip]
> Is 12 cases out of about 315,000 python files a big enough need to keep the 
> current behavior?   315,000 is the number returned from google code for all 
> python files, 'lang:python'. (I'm sure there are some duplicates)
> 
> 
> Is this more convincing.   ;-)

Not to me, as I use dict.fromkeys(), and going from a simple expression
to an assignment then mutate is unnecessary cognitive load.  It would
have been more convincing had you offered...

    dict((i, v) for i in keys)

But then again, basically every one of your additions is a one line
expression.  I would also consider the above myself, if it weren't for
the fact that I'm supporting a Python 2.3 codebase.  Please see my
discussion below of *removing* functionality.


> >> I think this reads better and can be used in a wider variety of situations.
> >>
> >> It could be useful for setting an existing dictionary to a default state.
> >>
> >>      # reset status of items.
> >>      status.set_keys(status.keys(), v=0)
> > 
> > This can be done today:
> 
> Of course all of the examples I gave can be done today.  But they nearly 
> all require iterating in python in some form.

Premature optimization...  Note that you don't know where you are
getting your data, so the overhead of looping and setting data may be
inconsequential to the overall running of the update.  Since you
basically use the "but it iterates in Python rather than C" for the rest
of your arguments, I'm going to stick with my belief that you are
prematurely optimizing.  Until you can show significant use-cases in the
wild, and show that the slowdown of these functions in Python compared
to C is sufficient to render the addition of the functions in your own
personal library useless, I'm going to stick with my -1.


> >     status.update((i, 0) for i in status.keys())
> >     #or
> >     status.update(dict.fromkeys(status, 0))
> 
> The first example requires iterating over the keys.  The second example 
> works if you want to initialize all the keys.  In which case, there is no 
> reason to use the update method.  dict.fromkeys(status, 0) is enough.

I was pointing out how you would duplicate exactly the functionality you
were proposing for dict.set_keys().  It is very difficult for me to
offer you alternate implementations for your own use, or as reasons why
I don't believe they should be added, if you move the target ;).


> >> Or more likely, resetting a partial sub set of the keys to some initial state.
> >>
> >>
> >> The reason I started looking at this is I wanted to split a dictionary into 
> >> smaller dictionaries and my first thought was that fromkeys would do that. 
> >>     But of course it doesn't.
> > 
> > Changing the bahvior of dict.fromkeys() is not going to happen. We can
> > remove it, we can add a new method, but changing will lead to not so
> > subtle breakage as people who were used to the old behavior try to use
> > the updated method.
> > 
> > Note that this isn't a matter of "it's ok to break in 3.0", because
> > dict.fromkeys() is not seen as being a design mistake by any of the
> > 'heavy hitters' in python-dev or python-3000 that I have heard (note
> > that I am certainly not a 'heavy hitter').
> 
> Then lets find a different name.

Usually we find substantial use-cases for which this new functionality
would be useful, _then_ we argue about names (usually for months ;). The
only exception to this is in 3rd party modules posted in the cheeseshop,
but then we don't usually hash out the details of it here, as it is a
3rd party module.


> >> What I wanted was to be able to specify the keys and get the values from 
> >> the existing dictionary into the new dictionary without using a for loop to 
> >> iterate over the keys.
> >>
> >>     d = dict(1='a', 2='b', 3='c', 4='d', 5='e')
> >>
> >>     d_odds = d.from_keys([1, 3, 5])      # new dict of items 1, 3, 5
> >>     d_evens = d.from_keys([2, 4])        # new dict of items 2, 4
> >>
> >> There currently isn't a way to split a dictionary without iterating it's 
> >> contents even if you know the keys you need before hand.
> > 
> > Um...
> > 
> >     def from_keys(d, iterator):
> >         return dict((i, d[i]) for i in iterator)
> 
> (iterating)
> 
> Yep as I said just above this.
> 
>   """There currently isn't a way to split a dictionary without iterating 
> it's contents ..."""

You aren't splitting the dictionary.  You are fetching certain values
from the dictionary based on the contents of a provided iterator.  The
*only* thing you gain from the iterator vs. built-in method is a bit of
speed.  But if speed is your only argument, for a group of functions
that I don't remember anyone having ever asked for before, then you
better check your rationale.

In the standard library there exists the deque type in collections.  Why
does Python have a deque?  Because it was discovered over 10+ years of
Python use that pretty much everyone needs a queue, with a large portion
of those needing a double ended queue (put the just fetched item back at
the front).  Because there were so many users, and because it was used
in *many* performance critical applications, it was implemented in C by
Raymond Hettinger and became the first member of the collections module.
A similar thing happened with default dictionaries and it being faked
many times by many different people, implemented and tossed into the
collections module again.


As for iteration over a sequence to generate a new sequence, you need to
do this regardless of whether it is in C or Python. The *only* difference
between the C and Python versions of this is a difference in speed, but
again, use-cases before naming and optimization.  I like to see things
"in the wild".


> Lists have __getslice__, __setslice__, and __delslice__.  It could be 
> argued that those can be handled just as well with iterators and loops as 
> well.  Of course we see them as seq[s:s+x], on both lists and strings.  So 
> why not have an equivalent for dictionaries.  We can't slice them, but we 
> do have key lists to use in the same way.

Your function examples are a bit like adding set manipulation
functionality through functional programming-like functions. Take your
merge operations as an example.  With sets, it's spelled s1 | s2.  It is
a bit round-about, but your from_keys functionality is a bit like s1 -
(s1 - s2), or really set(s2) because sets have no associated values. 
Anyways.


> >> A del_keys method could replace the clear method.  del_keys would be more 
> >> useful as it could operate on a partial set of keys.
> >>
> >>     d.delkeys(d.keys())    # The current clear method behavior.
> > 
> > I can't remember ever needing something like this that wasn't handled by
> > d.clear() .
> 
> All or nothing.  d = dict() works just as well.

Not when you want to mutate a dictionary.


> And I'd prefer to define the function in this case for readability reasons.
> 
> 
> >>       splitdict(d, keys):
> >>           """ Split dictionary d using keys. """
> >>           keys_rest = set(d.keys()) - set(keys)
> >>           return d.from_keys(keys), d.from_keys(keys_rest)
> > 
> > I can't think of a simple one-liner for this one that wouldn't duplicate
> > work.
> 
> :-)
> 
> This is one of the main motivators.

I've never needed to do this.  And I've never seen source that needed to
do this either.  So whether this is a main motivator for you doesn't
sway me.


[snip your pointing out that iteration happens in Python and not C]

> >> I think the set_keys, from_keys, and del_keys methods could add both 
> >> performance and clarity benefits to python.
> > 
> > Performance, sometimes, for some use-cases.  Clarity?  Maybe.  Your
> > split* functions are a bit confusing to me, and I've never really needed
> > any of the functions that you list.
> 
> I think sometime our need is determined by what is available for use.  So 
> if it's not available, our minds filter it out from the solutions we 
> consider.  That way, we don't need the things we don't have or can't get.
> 
> My minds "need filter" seems to be broken in that respect. I often need 
> things I don't have.  But sometimes that works out to be good.  ;-)

Yeah, I don't buy your 'need filter' reasoning.  Typically people resist
doing things that are difficult or inconvenient to do.  Take decoration
for example.  Before decorator syntax, decoration was a pain in the butt. 
Yeah, you wrote the same number of lines of code, but there was such a
disconnect from the signature of the function/method (and class in 2.6)
that it was just too inconvenient to write, maintain, and understand.

In the case of dictionaries, all but two or three of the things you
would like to offer is available via a very simple dict(generator
expression). If people aren't thinking of ways to use generator
expressions to make their lives easier (this is the case in multiple
threads daily in comp.lang.python), is that Python's fault, or is it the
developer's?

I like to think of Python's syntax and semantics as just rich enough for
people to write what they want and to understand it quickly, but not so
rich that you need to spend time thinking what something means (the Perl
argument). Adding functionality to existing objects needs to do a few
things, not the least of which is solving a problem that happens in the
wild, but also that it doesn't overly burdon those who implement similar
functionality. Remember, dictionaries are *the* canonical mapping
interface, and anyone who implements a complete mapping interface
necessarily would need to implement the 3 methods you propose. For what?
To clean up the interface?

I'm sorry, but to add 3 methods, even with the assmuption that two
previous methods were going to be removed, in order to "clean up" the
interface doesn't convince me.  Please find me real-world use-cases
where your new methods would improve readability.

...

Also, I develop software for fun and profit.  Since basically everyone
else here probably does some selection of the same, I'm sure that they
will tell you pretty much the same thing: if we restricted our needs to
what we already have, software wouldn't get written, or would only be
proposed by marketing.


> >> So to summarize...
> >>
> >>      1.  Replace existing fromkeys method with a set_keys method.
> >>      2.  Add a partial copy items from_keys method.
> >>      3.  Replace the clear method with a del_keys method.
> > 
> > Not all X line functions should be builtins.
> 
> Of course I knew someone would point this out.

I'm usually the one to invoke it.  Maybe I have less tolerance to
arguably trivial additions to Python than others.


> I'm not requesting the 
> above example functions be builtins.  Only the changes to the dict methods 
> be considered.    They would allow those above functions to work in a more 
> efficient way and I'd be happy to add those functions to my own library.
> 
> With these methods in most cases the functions wouldn't even be needed. 
> You would just use the methods in combinations with each other directly and 
> the result would still be readable without a lot of 'code' overhead.

My single expression replacements were to show that the functions aren't
needed now, as most are *easily* implemented in Python 2.5 in a
straightforward manner.


> Also consider this from a larger view.  List has __getslice__, 
> __setslice__, and __delslice__.  Set has numerous methods that operate on 
> more than one element.

Lists are ordered sequences, dictionaries are not.  Sets are not
mappings, they are sets (which is why they have set operations). 
Dictionaries are a mapping from keys to values, used as both an
arbitrary data store as well as data and method member lookups on
objects. The most common use-cases of dictionaries *don't* call for any
of the additional functionality that you have offered.  If they did,
then it would have already been added.


> Dictionaries are suppose to be highly efficient, but they only have limited 
> methods that can operate on more than one item at a time,  so you end up 
> iterating over the keys to do nearly everything.

Iteration is a fundamental building block in Python.  That's why for
loops, iterators, generators, generator expressions, list comprehensions,
etc., all use iteration over an iterator to do their work.  Building
more functionality into dictionaries won't make them easier to use, it
will merely add more methods that you think will help.  Is there anyone
else who likes this idea?  Please speak up.


> So as an alternative, leave fromkeys and clear alone and add...
> 
>      getkeys(keys)  ->  dict
>      setkeys(keys, v=None)
>      delkeys(keys)
> 
> Where these offer the equivalent of list slice functionality to dictionaries.

getkeys/setkeys/delkeys seem to me like they should be named
getitems/setitems/delitems, because they are getting/setting/deleting the
entire key->value association, not merely the keys.


> > If you find that you are
> > doing the above more often than you think you should, create a module
> > with all of the related functionality that automatically patches the
> > builtins on import and place it in the Python cheeseshop.  If people
> > find that the functionality helps them, then we should consider it for
> > inclusion.  As it stands, most of the methods you offer have a very
> > simple one-line version that is already very efficient.
> 
> Iterators and for loops are fairly efficient for small dictionaries, but 
> iterating can still be considerable slower than the equivalent C code if 
> they are large dictionaries.

Lets find out.

    >>> d = dict.fromkeys(xrange(10000000))
    >>> import time
    >>> if 1:
    ...     t = time.time()
    ...     e = dict(d)
    ...     print time.time()-t
    ...
    1.21899986267
    >>> del e
    >>> if 1:
    ...     t = time.time()
    ...     e = dict(d.iteritems())
    ...     print time.time()-t
    ...
    2.75
    >>> del e
    >>> if 1:
    ...     t = time.time()
    ...     e = dict((i,j) for i,j in d.iteritems())
    ...     print time.time()-t
    ...
    6.95399999619
    >>> del e
    >>> if 1:
    ...     t = time.time()
    ...     e = dict((i, d[i]) for i in d)
    ...     print time.time()-t
    ...
    7.54699993134
    >>>

Those all seem to be pretty reasonable timings to me.  In the best case
you are talking about 6.2 times faster to use the C rather than Python
version.


> >> So this replaces two methods and adds one more.  Overall I think the 
> >> usefulness of these would be very good.
> > 
> > I don't find the current dictionary API to be lacking in any way other
> > than "what do I really need to override to get functionality X", but
> > that is a documentation issue more than anything.
> 
> >> I also think it will work very well with the python 3000 keys method 
> >> returning an iterator.  (And still be two fewer methods than we currently 
> >> have.)
> > 
> > I'm sorry, but I can't really see how your changes would add to Python's
> > flexibility without cluttering up interfaces and confusing current users.
> 
> I think it cleans up the API more than it clutters it up.  It coverts two 
> limited use methods to be more general, and adds one more that works with 
> the already existing update method nicely.

But you propose a further half dozen functions.  If you aren't proposing
them for inclusion, why bother including them in your proposal,
especially when they have very simple replacements that are, arguably,
easier to understand than the function bodies you provided.


> In both cases of the two existing methods, fromkeys and clear, your 
> arguments, that there all ready exists easy one line functions to do this, 
> would be enough of a reason to not have them in the first place.  So do you 
> feel they should be removed?

We don't remove functionality in Python unless there is a good reason. 
Typically that reason is because the functionality is broken, the old
functionality is not considered "Pythonic", or generally because a group 
of people believe there is a better way. Guido is more or less happy
with dictionaries as-is (except for the keys(), values(), and items()
methods, which are changing), and no one in python-dev has complained
about dictionary functionalty that I can remember. As such, even if you
think that your changes would clean up dictionary methods, it is
unlikely to happen precisely because *others* aren't mentioning,
"dictionaries need to be cleaned up".


> I plan on doing a search of places where these things can make a difference 
> in making the code more readable and/or faster.

I don't care about faster.  Show me code that is easier to understand.

I will mention that all of your functionality smells very much like a
functional programming approach to Python.  This makes a difference
because some functional programming tools (reduce, map, filter, ...) are
slated for removal in Python 3.0, so adding functional programming tools
(when we are removing others), is unlikely to gain much traction.


 - Josiah



From jimjjewett at gmail.com  Tue May 29 20:23:55 2007
From: jimjjewett at gmail.com (Jim Jewett)
Date: Tue, 29 May 2007 14:23:55 -0400
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <20070529000414.86A5.JCARLSON@uci.edu>
References: <20070528174325.86A2.JCARLSON@uci.edu>
	<465BA636.8070501@ronadam.com> <20070529000414.86A5.JCARLSON@uci.edu>
Message-ID: <fb6fbf560705291123i1c35db9enf9962266f2dcda39@mail.gmail.com>

On 5/29/07, Josiah Carlson <jcarlson at uci.edu> wrote:
> Ron Adam <rrr at ronadam.com> wrote:
> > Josiah Carlson wrote:

> > > dict.fromkeys() is not seen as being a design mistake

ermm.... I think at least a few see it as something of a leftover, for
using dicts as sets.  The docs also (weakly) support this view.  This
isn't quite the only use case, but I doubt fromkeys would be added
today (given both sets and subclasses of defaultdict); there just
isn't quite enough discomfort to remove it.

> > >>       splitdict(d, keys):
> > >>           """ Split dictionary d using keys. """
> > >>           keys_rest = set(d.keys()) - set(keys)
> > >>           return d.from_keys(keys), d.from_keys(keys_rest)

> > > I can't think of a simple one-liner for this one that wouldn't
> > > duplicate work.

*this* is the core of a useful idea.  list (and set and generator)
comprehensions can't partition very well, because they have only a
single output.  There isn't a good way to say:

    list_a = [x for x in src if pred(a)]
    src = [x for x in src if not pred(a)]
    list_b = [x for x in src if pred(b)]
    src = [x for x in src if not pred(b)]
    list_c = [x for x in src if pred(c)]
    list_other = [x for x in src if not pred(c)]

On the other hand, you can do it (inefficiently) as above, or you can
write an (ugly) version using a custom function, so the solution would
have to be pretty good before it justified complicating the
comprehension APIs.

> unlikely to happen precisely because *others* aren't mentioning,
> "dictionaries need to be cleaned up".

Not in so many words; Raymond is very reluctant to add anything,
because the API is already fairly large.  Guido's ABC for mappings
(http://svn.python.org/view/sandbox/trunk/abc/) is explicitly a small
subset of what dict offers (and doesn't include fromkeys).

That said, saying "too large, this isn't needed" is still a far cry
from "so we'll remove it", let alone "and add this stuff to replace
it".

-jJ


From rrr at ronadam.com  Tue May 29 22:21:05 2007
From: rrr at ronadam.com (Ron Adam)
Date: Tue, 29 May 2007 15:21:05 -0500
Subject: [Python-ideas] Dictionary group key/value modificaton methods.
In-Reply-To: <20070529000414.86A5.JCARLSON@uci.edu>
References: <20070528174325.86A2.JCARLSON@uci.edu>
	<465BA636.8070501@ronadam.com>
	<20070529000414.86A5.JCARLSON@uci.edu>
Message-ID: <465C8B31.4080805@ronadam.com>


Ok,  I'm going to try to summarize this a bit so we don't go around in 
circles on details that are adjacent to the issue I'm trying to address.


+ Adding methods to "copyitems", "seteach", and "delitems"; to do partial 
group operations on dictionaries in C rather than iterating in python can 
possibly have as much as a %500 percent performance increase over iterating 
in python to do the same thing.

- It needs to be shown that these situations occur often enough to result 
in a meaningful benefit.

(It doesn't replace the need to iterate dictionaries as there are many 
cases where that's exactly what you need.)

+ The methods add some improvements to readability over the iterator form.

- There is not a significant reduction in lines of code, so again it needs 
to be shown that this would be useful often enough to be a significant benefit.


Providing there are enough use cases to demonstrate a significant benefit, 
we will then need to address the following issues.

    + What to call them.
    + The details of the implementation.


Most of the arguments against fit into the following categories...

    - Changes the status quo
    - It's premature optimization
    - Adds additional complexity to dictionaries
    - Personal preference

These are subjective but still important issues, and these will need to be 
addressed after it is demonstrated there is sufficient use cases for these 
features, if each of these is relevant and to what degree.


Some examples:

     # Combine two dictionaries.  (works already)
     dd = dict(d1)
     dd.update(d2)

     # Split dictionary d using a key list.
     keys_rest = set(d.keys()) - set(keys)
     d1, d2 = d.getitems(keys), d.getitems(keys_rest)

     # Remove a subdict of d with keys.
     dd = d.getitems(keys)
     d.delitems(keys)

     # Copy items from dictionary d1 to d2.
     #
     # The getitems method returns a dictionary so it will
     # work directly with the update method.
     #
     d2.update(d1.getitems(keys))

     # Move items from dictionary d1 to d2.
     d2.update(d1.getitems(keys))
     d1.del_keys(keys)

     # Setting items to a specified value with a list of keys.
     d.seteach(keys, None)


Use cases:

    ### TODO


>> Josiah Carlson wrote:
>>> Ron Adam <rrr at ronadam.com> wrote:

>> Is 12 cases out of about 315,000 python files a big enough need to keep the 
>> current behavior?   315,000 is the number returned from google code for all 
>> python files, 'lang:python'. (I'm sure there are some duplicates)
>>
>> Is this more convincing.   ;-)
> 
> Not to me, as I use dict.fromkeys(), and going from a simple expression
> to an assignment then mutate is unnecessary cognitive load.  It would
> have been more convincing had you offered...
> 
>     dict((i, v) for i in keys)

Well, there you go. :-)


> But then again, basically every one of your additions is a one line
> expression.  I would also consider the above myself, if it weren't for
> the fact that I'm supporting a Python 2.3 codebase.  Please see my
> discussion below of *removing* functionality.

This is probably something that is better suited for python 3000.  But it's 
possible it could be back ported to 2.6.  It would have no effect on python 
2.5 and earlier.  And probably minimal effect on 2.x in regards to 2.3 
compatibility.

I don't see .fromkeys() being removed in 2.x.


 > Until you can show significant use-cases in the
> wild, and show that the slowdown of these functions in Python compared
> to C is sufficient to render the addition of the functions in your own
> personal library useless, I'm going to stick with my -1.

Your own tests show a maximum speedup of 620%.  My testing shows it is 300% 
to 500% over a range of sizes.  I would still call that sufficient.

And before you point it out... yes, only if it can be shown to be useful in 
a wide range of situations. I fully intend to find use cases.  If I can't 
find any, then none of this will matter.


> I was pointing out how you would duplicate exactly the functionality you
> were proposing for dict.set_keys().  It is very difficult for me to
> offer you alternate implementations for your own use, or as reasons why
> I don't believe they should be added, if you move the target ;).

But programming is full of moving targets.  ;-)

In any case, look at the overall picture and try not to prematurely shoot 
this down based on implementation details that can be changed as needed.

And I'll attempt to do a use case study from the python library.


 > Until you can show significant use-cases

> Usually we find substantial use-cases ....

 > ... that I don't remember anyone having ever asked for before

 > ... but again, use-cases ...

> I've never needed to do this.

 > Please find me real-world use-cases ...

 > Show me code that is easier to understand.


Ok, I get it.  :-)


>> Also consider this from a larger view.  List has __getslice__, 
>> __setslice__, and __delslice__.  Set has numerous methods that operate on 
>> more than one element.
> 
> Lists are ordered sequences, dictionaries are not.  Sets are not
> mappings, they are sets (which is why they have set operations). 
> Dictionaries are a mapping from keys to values, used as both an
> arbitrary data store as well as data and method member lookups on
> objects. The most common use-cases of dictionaries *don't* call for any
> of the additional functionality that you have offered.

 > If they did, then it would have already been added.

This statement isn't true.  It only shows the resistance to these changes 
is greater than the efforts of those who have tried to introduce those 
changes.  (not without good cause)

To be clear, I in no way want the bar dropped to a lower level as to what 
is added to python or not added.  I accept that sufficient benefit needs to 
be demonstrated, and will try to do that.

Quality is more important than quantity in this case.


>> Dictionaries are suppose to be highly efficient, but they only have limited 
>> methods that can operate on more than one item at a time,  so you end up 
>> iterating over the keys to do nearly everything.
> 
> Iteration is a fundamental building block in Python.  That's why for
> loops, iterators, generators, generator expressions, list comprehensions,
> etc., all use iteration over an iterator to do their work.  Building
> more functionality into dictionaries won't make them easier to use, it
> will merely add more methods that you think will help.  Is there anyone
> else who likes this idea?  Please speak up.

Lets rephrase this to be less subjective...

Does anyone think having a approximately 500% improvement in some 
dictionary operations would be good if it can be done in a way that is both 
easier to read, use, and has enough use cases to be worth while?


> getkeys/setkeys/delkeys seem to me like they should be named
> getitems/setitems/delitems, because they are getting/setting/deleting the
> entire key->value association, not merely the keys.

Sounds good, how about...

     getitems, delitems, and seteach ?


The update method corresponds to setitems, where setitems is the inverse 
operations to getitems.  I don't see any reason to change update.

     d1.update(d2.getitems(keys))

So seteach, is a better name for a method that sets each key to a value.



Cheers,
    Ron





From showell30 at yahoo.com  Tue May 29 23:28:11 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 14:28:11 -0700 (PDT)
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <f3hjda$1s3$1@sea.gmane.org>
Message-ID: <420674.70880.qm@web33510.mail.mud.yahoo.com>


--- Stargaming <stargaming at gmail.com> wrote:
> 
> Are there any non-SQL use cases for SQL syntax?

Isn't that kind of a silly question?  Of course not.  

SQL syntax only applies to relational data.  Of
course, such data doesn't have to exist in a
"database" for the syntax to be useful.  It just has
to be relational.

I would ask the opposite question--are there any cases
where you manipulate basically relational data without
the power of SQL?  There are many answers there, and
one them is Python.




      ____________________________________________________________________________________
Park yourself in front of a world of choices in alternative vehicles. Visit the Yahoo! Auto Green Center.
http://autos.yahoo.com/green_center/ 


From showell30 at yahoo.com  Tue May 29 23:38:17 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 14:38:17 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <465C3407.6030903@latte.ca>
Message-ID: <642129.84253.qm@web33511.mail.mud.yahoo.com>

Guys, please don't judge me too harshly on the basis
of a quick sketch of an idea.  I'm obviously skimming
over a lot of ideas in a quick pass.  FWIW I've built
virtual machines before, and way back I worked at
Oracle and at times had to debug their PL/SQL
implementation, so it's not like I don't understand
what I'm asking for.

I am also fully aware of Python's culture and have
fought against frivolous language additions myself,
although I'm biased like everybody else by own
experience, so one person's frivolous is another
person's can't-live-without-it.  

I will respond to the main technical objection--how to
scope these--in a separate reply.

Thanks.




       
____________________________________________________________________________________Be a better Globetrotter. Get better travel answers from someone who knows. Yahoo! Answers - Check it out.
http://answers.yahoo.com/dir/?link=list&sid=396545469


From showell30 at yahoo.com  Tue May 29 23:55:07 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 14:55:07 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <465C3407.6030903@latte.ca>
Message-ID: <777248.90724.qm@web33511.mail.mud.yahoo.com>


--- Blake Winton <bwinton at latte.ca> wrote:

> Steve Howell wrote:
> > Let the Python interpreter build expression
> objects
> > for you.  You write:
> >    rowexpr: convert_to_euros(salary) > 50000 and
> > deptno = 10
> > Python translates that into the same bytecode as:
> > lambda row: convert_to_euros(row['salary'] > 50000
> and
> > row['deptno'] == 10
> 

My language here was imprecise.  I should have said
something to the effect of this:

The interpreter would translate the "rowexpr" into
bytecode that would execute the same way as the
"lambda" example given the scope of the method
convert_to_euros in the example above.

Also, the bytecode would not be the "same" as the
lambda; it would just have similar complexity.

> I'm sorry, why would that not be translated into:
> 
> lambda row: row['convert_to_euros'](row['salary'] >
> row['50000'] 
> row['and'] row['deptno'] == row['10']
> 

I am suggesting that in a rowexpr expression, instead
of the typical local scope being the default scope,
"row" would be the local scope for dereferencing. 
Since I am proposing an expression syntax, does not
the local scope go away?

If you look at where salary, row, and deptno sit in
the expression, it seems pretty clear to me that a
well-defined scoping scheme would try to dereference
row by default for all those tokens, and probably give
up there, throwing an exception.

The convert_to_euros token in the expression obviously
poses a thornier problem.  Do you prefer
row.convert_to_euros, if such a think exists, or do
you go right to what would be the typical scope of a
similar lambda expression, and prefer, say, the
definition of "def convert_to_euros" that sits at the
module level?  I would think the latter.

The interpreter surely can evaluate such an expression
and determine that convert_to_euros is going to be
used a callable.  Now, whether convert_to_euros is
actually callable at run time is another story, but if
it isn't, an exception is thrown, and at least you're
not debugging somebody else's library to figure out
why.  Python would just tell you.

I don't mean to oversimplify this, which is why I'm
batting it around on a forum with a lot of smart
people.  But clearly it could be done.  Whether it
*should* be done is, of course, a question for debate,
and I accept this.






       
____________________________________________________________________________________Be a better Globetrotter. Get better travel answers from someone who knows. Yahoo! Answers - Check it out.
http://answers.yahoo.com/dir/?link=list&sid=396545469


From showell30 at yahoo.com  Wed May 30 00:05:50 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 15:05:50 -0700 (PDT)
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <f3hjda$1s3$1@sea.gmane.org>
Message-ID: <201431.56993.qm@web33507.mail.mud.yahoo.com>


--- Stargaming <stargaming at gmail.com> wrote:

> Steve Howell schrieb:
> > --- Aahz <aahz at pythoncraft.com> wrote:
> > 
> >>What's wrong with sqlite?
> > 
> > 
> > Nothing, but I want Python itself to give me the
> SQL
> > syntax to manipulate lists-of-dictionaries like
> lists
> > of dictionaries, without having to go through some
> a
> > module.
> 
> And how would all those DBs adapt? With yet another
> interface? 

Where did I ever propose eliminating the interfaces
that DB adapters already have?  Or where did I propose
any requirement to interface to the SQL syntax?

The DB adapters would continue to move data from
external/local databases to lists-of-dictionaries,
objects, etc., as they do now.  I'm just saying that
once you pull data into Python, you should continue to
have the option to manipulate relational data with
SQL.  Presumbably most people who use SQL databases
already have to understand the syntax anyway.  And
those that don't can simply ignore it.




       
____________________________________________________________________________________
Moody friends. Drama queens. Your life? Nope! - their life, your story. Play Sims Stories at Yahoo! Games.
http://sims.yahoo.com/  


From jcarlson at uci.edu  Wed May 30 00:41:40 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 29 May 2007 15:41:40 -0700
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <777248.90724.qm@web33511.mail.mud.yahoo.com>
References: <465C3407.6030903@latte.ca>
	<777248.90724.qm@web33511.mail.mud.yahoo.com>
Message-ID: <20070529152310.86AF.JCARLSON@uci.edu>


Steve Howell <showell30 at yahoo.com> wrote:
> I don't mean to oversimplify this, which is why I'm
> batting it around on a forum with a lot of smart
> people.  But clearly it could be done.  Whether it
> *should* be done is, of course, a question for debate,
> and I accept this.

You are proposing to insert a mini-language into Python so as to make
certain relational data processing tasks easier.  As you say, your
particular proposal is pretty much just an alias for lambda where you
don't specify the 'row' argument, names are acquired from the passed
dictionary, and maybe you get some free enclosing scope goodies.

Honestly, without explicit stating of where data is coming from, either
via row['column'] or row.column, and the explicit naming of the argument
to be passed (as in lambda argument: expression), it smells far too
magical for Python.  Never mind the fact that you will tend to get
better performance by not using a lambda/your hacked lambda, as the
direct execution will have fewer function calls...  That is...

    pred = lambda row: (convert_to_euros(row['salary']) > 50000
                        and row['deptno'] == 10)

    a = [f(i) for i in rows if pred(i)]

will run slower than

    b = [f(i) for i in rows if
                  convert_to_euros(row['salary']) > 50000
                  and row['depno'] == 10]

While the former *may* be easier to read (depending on who you are), the
latter will be faster in all cases.  The only way for the pred() version
to be faster is if your rowexpr: variant was actually a macro expansion,
but we don't do macro expansions in Python, so it will be slower.

So, what do we have?  Possible minor clarity win (but certainly not over
lambdas), small length reduction over lambdas, slower execution compared
to inlining the code (equal to lambda), more syntax.

Put me down for -1.


 - Josiah



From scott+python-ideas at scottdial.com  Wed May 30 00:38:56 2007
From: scott+python-ideas at scottdial.com (Scott Dial)
Date: Tue, 29 May 2007 18:38:56 -0400
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <201431.56993.qm@web33507.mail.mud.yahoo.com>
References: <201431.56993.qm@web33507.mail.mud.yahoo.com>
Message-ID: <465CAB80.2020606@scottdial.com>

Steve Howell wrote:
> Presumbably most people who use SQL databases
> already have to understand the syntax anyway.  And
> those that don't can simply ignore it.

That simply will never be true. If there is new syntax added to Python, 
than the burden is on everyone to understand other people's code that 
uses such a feature. I'm very familiar with SQL and I am still not 
convinced that I want to see it in my Python. First of all, the concept 
of a relational table is ill-defined.

I gather from your code that you believe this to be a list containing 
dictionaries, but why could this not be a tuple of tuples? For that 
matter, any iterable of iterables? Or how about using tuple'd indices, 
and so on.. It would be impossible to graft the SQL language onto all of 
the variations on the idea of a "table" in Python.

Python does not have a relational table data structure, thus there 
cannot be a relational language used to address such a structure. It 
would not be wise to create a syntax that relies on a particular 
composition of data structures.

-- 
Scott Dial
scott at scottdial.com
scodial at cs.indiana.edu


From showell30 at yahoo.com  Wed May 30 01:24:39 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 16:24:39 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <20070529152310.86AF.JCARLSON@uci.edu>
Message-ID: <348829.53748.qm@web33502.mail.mud.yahoo.com>

Josiah wrote:

http://mail.python.org/pipermail/python-ideas/2007-May/000835.html


Josiah, you are correct about all the following, and I
apologize for any incorrect paraphrase:

  1) I am proposing to add a mini-language within
Python.
  2) I want relational data processing tasks to be
easier within Python.
  3) I want rowexpr to acquire names from the passed
first argument (with sensible scoping rules, of
course).
  4) Point #4 essentially amounts to free enclosing
scope goodies.
  5) My proposal does indeed smell of magic.
  6) I do want the code to be easier to read for me
(with the full caveat that YMMV).
  7) I want the small clarity win.
  8) I think the only way to achieve this particular
clarity win is to add syntax.

You may be incorrect about the following, or I may
just be understanding your points, but I'm not wrong
about any of these, since I'm just characterizing my
own feelings:

  1) I don't want rowexpr to be pretty much an alias
for lambda; I actually want it to be more powerful.

  2) I'm not sweating performance here; I'm already
using an interpreted language.  I don't want Python to
be faster for my day-to-day tasks; I want it to be
more expressive.  I even--and I'll dare say--want the
language to be BIGGER.

  3) I'm not ignorant of the resistance to macro
expansions in Python, but I do think a year-2010
Python interpreter could compile SQL syntax directly
into bytecode.






       
____________________________________________________________________________________Be a better Globetrotter. Get better travel answers from someone who knows. Yahoo! Answers - Check it out.
http://answers.yahoo.com/dir/?link=list&sid=396545469


From showell30 at yahoo.com  Wed May 30 01:39:12 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 16:39:12 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <348829.53748.qm@web33502.mail.mud.yahoo.com>
Message-ID: <496892.28622.qm@web33501.mail.mud.yahoo.com>


--- Steve Howell <showell30 at yahoo.com> wrote:
>   3) I want rowexpr to acquire names from the passed
> first argument (with sensible scoping rules, of
> course).
>   4) Point #4 essentially amounts to free enclosing
> scope goodies.

er, point #3

> 
> You may be incorrect about the following, or I may
> just be understanding your points [...]

er, s/understanding/misunderstanding/

That wasn't a Freudian slip.  See careless typing
above (where I disrespectfully agree with you ;)



       
____________________________________________________________________________________Get the Yahoo! toolbar and be alerted to new email wherever you're surfing.
http://new.toolbar.yahoo.com/toolbar/features/mail/index.php


From showell30 at yahoo.com  Wed May 30 02:23:18 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 17:23:18 -0700 (PDT)
Subject: [Python-ideas] SQL-like way to manipulate Python data structures
In-Reply-To: <465CAB80.2020606@scottdial.com>
Message-ID: <431939.73532.qm@web33502.mail.mud.yahoo.com>


--- Scott Dial <scott+python-ideas at scottdial.com>
wrote:

> Steve Howell wrote:
> > Presumbably most people who use SQL databases
> > already have to understand the syntax anyway.  And
> > those that don't can simply ignore it.
> 
> That simply will never be true. If there is new
> syntax added to Python, 
> than the burden is on everyone to understand other
> people's code that 
> uses such a feature. I'm very familiar with SQL and
> I am still not 
> convinced that I want to see it in my Python. 

I fully concede to working under the premise that most
Python programmers know SQL, and you're a perfect
example, I guess, but I realize there are exceptions,
and I don't deny that as a tradeoff, just like I don't
deny that any expansion of a language's functionality
reduces comprehension for average users.  Written any
decorators lately?


> First
> of all, the concept 
> of a relational table is ill-defined.
> 

SQL's been around for at least 20 years, as has the
concept of a relational table.  So it's not exactly
ill-defined.  Start here, if you disagree:

http://en.wikipedia.org/wiki/Relational_model

> I gather from your code that you believe this to be
> a list containing 
> dictionaries, but why could this not be a tuple of
> tuples?

In the code that I posted, I don't "believe" that I'm
dealing with a list of dictionaries, I "know" because
I wrote it.  You can check it out yourself.

But I agree with your implied premise that the Python
interpreter doesn't know what it's dealing with, and I
fully accept in my proposal that Python, not some
third-party library, would properly throw an exception
when it found my data not to fit the relational model,
just as generator expressions sometimes throw run-time
expressions, just as lambdas throw run-time
expressions, etc.  I'm ok with that.

>  For that 
> matter, any iterable of iterables? Or how about
> using tuple'd indices, 
> and so on.. It would be impossible to graft the SQL
> language onto all of 
> the variations on the idea of a "table" in Python.
> 

I'm not proposing to graft SQL on to all variations of
the "table" in Python, just the ones that conform to a
relational model.

> Python does not have a relational table data
> structure, thus there 
> cannot be a relational language used to address such
> a structure. 

Python certainly expresses data structures that don't
fit the relational model, but please explain to me how
a list of dictionaries doesn't fit the relational
model.  And don't bore me with the explanation that
dictionaries can be heterogeneous; I'd just have
Python throw an exception there.




 
____________________________________________________________________________________
Expecting? Get great news right away with email Auto-Check. 
Try the Yahoo! Mail Beta.
http://advision.webevents.yahoo.com/mailbeta/newmail_tools.html 


From jcarlson at uci.edu  Wed May 30 02:31:40 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Tue, 29 May 2007 17:31:40 -0700
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <348829.53748.qm@web33502.mail.mud.yahoo.com>
References: <20070529152310.86AF.JCARLSON@uci.edu>
	<348829.53748.qm@web33502.mail.mud.yahoo.com>
Message-ID: <20070529165018.86B2.JCARLSON@uci.edu>


Steve Howell <showell30 at yahoo.com> wrote:
> Josiah wrote:
> You may be incorrect about the following, or I may
> just be understanding your points, but I'm not wrong
> about any of these, since I'm just characterizing my
> own feelings:
> 
>   1) I don't want rowexpr to be pretty much an alias
> for lambda; I actually want it to be more powerful.

Technically speaking, lambda is sufficient for turing completeness, so
the only thing to be gained is a reduction in what you write.  As you
offer...

    predicate = rowexpr: manipulation(column1) > value1 and \
                         column2 < value2

    predicate = lambda row: manipulation(row['column1']) > value1 and \
                            row['column2'] < value)

Is that reduction worthwhile?  I personally don't think so, but my list
comprehensions tend to have fairly minimal predicates.  One thing to
take into consideration is that Guido has previously shot down 'order by'
syntax in list comprehensions and generator expressions because he
didn't think that they were Pythonic (I seem to remember 'ugly' and
'worthless', but maybe that was my response to them).


>   2) I'm not sweating performance here; I'm already
> using an interpreted language.  I don't want Python to
> be faster for my day-to-day tasks; I want it to be
> more expressive.  I even--and I'll dare say--want the
> language to be BIGGER.

That's fine, but realize that Python 3.0 is moving towards a smaller,
clearer language; see the dictionary changes, range/xrange, exception
handling, etc.


>   3) I'm not ignorant of the resistance to macro
> expansions in Python, but I do think a year-2010
> Python interpreter could compile SQL syntax directly
> into bytecode.

It could, but I would happily bet you $100 that it won't.  If you are
really intent on getting this, despite the arguments against it (from
everyone so far), you could add your own syntax with logix, which will
handle arbitrary SQL statement and compile it into Python bytecode
(given sufficient information on how to do so).

Yes, that's a cop-out, but sometimes the only way people get the
language that they want is if they can add syntax at their whim.  I've
personally found that while I disagree with Guido on very many things
related to Python, I'm usually too lazy to bother to add syntax I think
I may need when I'm able to (with very minimal effort) write a helper
function or two to do basically everything I need in lieu of syntax.


 - Josiah



From showell30 at yahoo.com  Wed May 30 02:43:35 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 17:43:35 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <20070529165018.86B2.JCARLSON@uci.edu>
Message-ID: <446905.76199.qm@web33503.mail.mud.yahoo.com>


--- Josiah Carlson <jcarlson at uci.edu> wrote:

> Technically speaking, lambda is sufficient for
> turing completeness [...]

...as is Perl, or machine code, to pick sort of
opposite ends of the spectrum :)

> Is that reduction worthwhile?  I personally don't
> think so, but my list
> comprehensions tend to have fairly minimal
> predicates.  One thing to
> take into consideration is that Guido has previously
> shot down 'order by'
> syntax in list comprehensions and generator
> expressions because he
> didn't think that they were Pythonic (I seem to
> remember 'ugly' and
> 'worthless', but maybe that was my response to
> them).
> 

:)

I am only expressing my own aesthetics, and I would
certainly defer to Guido on most matters aesthetic,
since he's written an aesthetically beautiful
language.

But having said that, I don't want my proposal
automatically lumped in with every proposal that Guido
has found unaesthetic, or rejected, and I believe he
has even been known to change his mind from time to
time.

For all the real-world warts of SQL, I think SQL is a
very aesthetically pleasing way to express
transformations of relational data structures, and
Python contains relational data structures, and
therefore I think Python can benefit from using SQL as
just one way of expressing relational transformations
(and I'm still a little bit TIMTOWTDI from my Perl
days, I fully admit).

I fully concede all the obvious objections--more
syntax, more ways to do it, difficulty of implementing
it within the VM, ability of people to already
manipulate relational data structures more cleanly
than me in Python, etc.

I'm not asking for this in Fall 2007, BTW, I'm
expressing this as a vision for a bigger, better
Python, maybe year 2010, even though smaller is
usually better.  And syntactically, I am only
extending the language by one keyword, or one new way
of triple-quoting. 

For my own use, native SQL would benefit the clarity
of my (already working, but sometimes ugly) code more
than some other additions proposed in Py3k, but YMMV.



  



 
____________________________________________________________________________________
Finding fabulous fares is fun.  
Let Yahoo! FareChase search your favorite travel sites to find flight and hotel bargains.
http://farechase.yahoo.com/promo-generic-14795097


From aahz at pythoncraft.com  Wed May 30 02:49:51 2007
From: aahz at pythoncraft.com (Aahz)
Date: Tue, 29 May 2007 17:49:51 -0700
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <446905.76199.qm@web33503.mail.mud.yahoo.com>
References: <20070529165018.86B2.JCARLSON@uci.edu>
	<446905.76199.qm@web33503.mail.mud.yahoo.com>
Message-ID: <20070530004951.GA17586@panix.com>

On Tue, May 29, 2007, Steve Howell wrote:
>
> For all the real-world warts of SQL, I think SQL is a very
> aesthetically pleasing way to express transformations of relational
> data structures, and Python contains relational data structures, and
> therefore I think Python can benefit from using SQL as just one way
> of expressing relational transformations (and I'm still a little bit
> TIMTOWTDI from my Perl days, I fully admit).

Aside from the standard featuritis objection, my objection stems almost
entirely from the difficulty of defining appropriate data structures on
which to operate.  SQL works partly because data in SQL tables is already
*by definition* in a relational format -- which won't be true in Python,
causing all kinds of runtime errors that IMO are inappropriate for SQL.
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"as long as we like the same operating system, things are cool." --piranha


From showell30 at yahoo.com  Wed May 30 02:58:28 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 17:58:28 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <20070529165018.86B2.JCARLSON@uci.edu>
Message-ID: <711641.42448.qm@web33506.mail.mud.yahoo.com>


--- Josiah Carlson <jcarlson at uci.edu> wrote:
> It could, but I would happily bet you $100 that it
> won't.  

Maybe not by 2010, but I'll make a gentlemen's bet
that native SQL is in Python by 2005.

> If you are
> really intent on getting this, despite the arguments
> against it (from
> everyone so far), you could add your own syntax with
> logix, which will
> handle arbitrary SQL statement and compile it into
> Python bytecode
> (given sufficient information on how to do so).

Ok, the logix approach to introducing new syntax is
good to know.  I thought my pain would at least
resonate with a few people, but it obviously has not
so far.
 
> Yes, that's a cop-out, but sometimes the only way
> people get the
> language that they want is if they can add syntax at
> their whim.  I've
> personally found that while I disagree with Guido on
> very many things
> related to Python, I'm usually too lazy to bother to
> add syntax I think
> I may need when I'm able to (with very minimal
> effort) write a helper
> function or two to do basically everything I need in
> lieu of syntax.
> 

As I said in another reply, I have working code, so I
don't NEED the syntax, just want it, think it's a good
idea, and I hope I've picked the correct forum in
expressing a sort of
wouldn't-it-be-great-if-Python-did-this suggestion.

My progression in programming has always been to think
that the current paradigm was brilliant (even in my
C++ days!), and then only to discover there were even
better paradigms.






       
____________________________________________________________________________________Yahoo! oneSearch: Finally, mobile search 
that gives answers, not web links. 
http://mobile.yahoo.com/mobileweb/onesearch?refer=1ONXIC


From showell30 at yahoo.com  Wed May 30 03:00:02 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 18:00:02 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
Message-ID: <180820.85412.qm@web33509.mail.mud.yahoo.com>


--- Steve Howell <showell30 at yahoo.com> wrote:

> 
> --- Josiah Carlson <jcarlson at uci.edu> wrote:
> > It could, but I would happily bet you $100 that it
> > won't.  
> 
> Maybe not by 2010, but I'll make a gentlemen's bet
> that native SQL is in Python by 2005.
> 

...when I come back in my time machine.

2015



       
____________________________________________________________________________________Sick sense of humor? Visit Yahoo! TV's 
Comedy with an Edge to see what's on, when. 
http://tv.yahoo.com/collections/222


From showell30 at yahoo.com  Wed May 30 03:12:25 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 18:12:25 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <20070529165018.86B2.JCARLSON@uci.edu>
Message-ID: <588847.47591.qm@web33506.mail.mud.yahoo.com>


--- Josiah Carlson <jcarlson at uci.edu> wrote:
> 
> [...] you could add your own syntax with
> logix [...]

Or PyPy.  Despite our disagreement, you are helping me
to expand my thinking.  Thank you.




      ____________________________________________________________________________________
Park yourself in front of a world of choices in alternative vehicles. Visit the Yahoo! Auto Green Center.
http://autos.yahoo.com/green_center/ 


From talin at acm.org  Wed May 30 03:22:01 2007
From: talin at acm.org (Talin)
Date: Tue, 29 May 2007 18:22:01 -0700
Subject: [Python-ideas] Idea: The DSL operator.
Message-ID: <d1b71f830705291822r887ccb3he51b09f54777cc3e@mail.gmail.com>

This is in response to the various suggestions for embedding SQL
syntax in Python and various other suggestions made over the years.

Note that this suggestion is only a starting point for discussion, I
don't have any illusion that the idea as presented here would have
strong support. I'm fully aware that the actual proposal given below
looks "butt-ugly", but maybe someone can invent something better.

Background: Python is frequently used as a foundation for Domain
Specific Languages (DSLs). Examples include SQLObject, SCons, and many
others. These are all examples of a mini-language which is constructed
on top of the Python syntax, using operator overloading. The DSL is
often embedded within Python code (as in the case of SQLObject), and
can be invoked programmatically from regular (non-DSL) Python code.

However, there are some limitations on what can be expressed. For
example, in current interpreters, it is not possible to override the
'and' and 'or' operator. While there currently is a PEP that proposes
adding this capability, there is some disagreement as to how much this
would impact the efficiency of the non-override case. The reason is
because in the non-override case, the compiler is able to take
advantage of the "shortcut" properties of these operators; If the
operators can be overridden (which is a post-compiler operation), then
the compiler would no longer be able to make these optimization
assumptions.

A similar limitation in DSLs is the treatment of unbound identifiers.
Identifiers which have already been bound to objects are not a
problem, since you can simply override the various operators of those
objects. However, for identifiers which have not yet been assigned to
a variable, a number of ugly hacks are required. Typically what is
done is to have a set of "special" objects which act as placeholders
for unbound variable names, for example _x, _y, _z, and so on.
Unfortunately, this requires the person writing the DSL expression to
pre-declare unbound variables, which is exactly the opposite of how
regular Python works. Another method that is sometimes used is to
declare unbound variables as attributes of some general "unbound
variable" object, so you can say something like Query.x, Query.y, and
so forth. But again, this is rather wordy and robs the DSL of its
ability to concisely express a particular semantic intent, which is
the whole point of DSLs in the first place.

Another limitation of Python's ability to represent DSLs is that you
cannot override the assignment operator.

My idea is to alleviate these problems by giving DSLs some help at the
parsing level. By informing the parser that a given expression is a
DSL, we can relax some of the normal assumptions of the Python syntax,
and instead require the DSL interpreter to handle them, which allows
the DSL to have greater flexibility.

Two things we want to avoid: First, we want to avoid "programmable
syntax", meaning that we cannot define DSL-specific semantics at parse
time. The reason for this is that DSLs are generally defined in their
own specific imported modules, and the Python parser has no knowledge
of imports, and therefore has no access to the DSL's syntax rules.

Secondly, we want to avoid conflicts between multiple DSLs. So for
example, if I am using two different DSLs in the same module, we can't
have two different meanings for "and", for example.

The solution to both of these concerns is to say that the parser's
support for DSLs is completely generic - in other words, we can tell
the parser that a given expression is a DSL, but we can tell it
nothing specific about that *particular* DSL. Instead, it is up to the
DSL interpreter - which operates at runtime, not parse time - to take
up where the parser left off.

This is similar to PJE's suggestion of a way to "quote" Python syntax,
returning an AST. In such a scheme, the Python parser doesn't
completely compile the quoted expression to Python byte code, but
instead produces an AST (or AST-like data structure which might not
exactly be an AST), which is then interpreted by the DSL.

So far this all seems reasonable enough to my ear :) Next is the part
where I go mad. (As my friend Sara said to me recently, "I'm not a mad
scientist - I'm a mad natural philosopher.")

For purposes of dicussion I am going to introduce the token '??' (two
consecutive question marks) as the "DSL operator", in other words a
signal to the parser that a given expression is a DSL. I'm sure that
there could be a long and intense bikeshed discussion debating the
specific operator syntax, but for now I'll choose ?? since it's
unambiguously parsable.

The '??' operator can be used in one of three ways. First, you can
declare an entire expression as a DSL:

    a = ??(c + d)

The parser will take all of the tokens inside the parenthesized group
and return them as an AST, it will not attempt to generate code to
evaluate any of the operators within the group.

There's an extra bit of syntactic sugar: If the DSL expression is the
only argument to a function, you can combine the function call and the
DSL quote:

   func??(c+d)

Meaning "pass the AST for 'c + d' to the function 'func'". For most
DSLs, the 'func' will actually be the name of the DSL, so the typical
use pattern will be 'name_of_dsl??(expr)'.

The second use is to quote an identifier:

    a = ??c + d

Now, you would think that this would quote the variable 'c' and
attempt to add it to 'd', but this is not the way it works. Instead,
the ?? operator invokes a kind of operator overloading that happens at
the parser level, meaning that any attempt to create an expression
that operates on a quoted variable also gets quoted. This only affects
binary and unary operators, not functions calls, array references or
assignment. So in this case, the entire expression "??c + d" gets
quoted.

The third way a DSL operator can be used is to quote an operator:

    a = c ??= d

Again, this allows us to generate the AST "c = d" and assign it to the
variable "a".

(I recognize that these last two syntactical variations would make the
interpretation of regular Python ASTs significantly more complex,
which is a serious drawback. Part of the motivation for both of these
variations is to deal with the 'and', 'or' and '=' problem, by
overriding the Python compiler's normal treatment of these operators.
However, it may be that the first form alone is sufficient, which
would be relatively easy to handle in the Python compiler I think -
you would simply have the AST.c module look for a DSL operator, and
don't call the normal AST processing steps for arguments to that
operator.)

Some examples of DSLs using the operator:

An SQL query as a DSL:

   query = SQL??(name == "John" and age > 25)
   result_iter = query.execute()

Syntax for an algebraic solver:

   @arity??(x + x)
   def reduce(x):
       return 2 * x

   @arity??(x + 0)
   def reduce(x):
       return x

   @arity??(x * 0)
   def reduce(x):
       return 0

   @arity??(x * 1)
   def reduce(x):
       return x

   @arity??(x * a + y * a)
   def reduce(x):
       return (x+y)*a

   # (and so on for all the other reduce() rules)

   print(reduce??((a+b*3) + (a+b*3)))
   >>> a*2+b*6

(In the above, we define a function 'reduce' that is similar to a
generic function, except that the dispatch logic is based on the form
of the AST being passed as an argument, using a one-way unification
algorithm to do argument pattern matching.)

I realize that there are some aspects of this proposal that may seem
silly, and that's true, and the only reason I'm even suggesting this
at all is that much of what I'm writing here is already been suggested
or at least implied by previous discussions.

Flame on!

-- 
-- Talin


From showell30 at yahoo.com  Wed May 30 03:22:16 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 18:22:16 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <20070530004951.GA17586@panix.com>
Message-ID: <998077.51447.qm@web33510.mail.mud.yahoo.com>

--- Aahz <aahz at pythoncraft.com> wrote:

> Aside from the standard featuritis objection, my
> objection stems almost
> entirely from the difficulty of defining appropriate
> data structures on
> which to operate.  SQL works partly because data in
> SQL tables is already
> *by definition* in a relational format -- which
> won't be true in Python,
> causing all kinds of runtime errors that IMO are
> inappropriate for SQL.


In theory, I obviously agree, as a list can be full of
all kinds of heterogeneous structures, and the fact
that it can be is one of the beauties of Python, and
certainly trying to apply native, byte-code
interpreted SQL to such structures would certainly
lead to run-time errors that even unit tests couldn't
even catch in theory, much less practice.

But, in my own day-to-day practice (I've recently been
working on a billing system, which is not rocket
science, just tedious), I find myself constantly
calling into my DB API, which returns me a list of
dictionaries, and the transformation from database to
network to API to Python doesn't diminish the
relational perfectness of the data whatsoever.

Then I find myself transforming the SQL result set in
many ways in Python.  Some of those transformations
are non-relational, which is the whole reason to bring
the data into Python in the first place.  But other
transforms are relational, and that's where I want
SQL.

Which raises the natural question--to the extent that
I want to do more relational transforms on the data
that I already have, why don't I just farm that back
out to my relational database?  The two-part answer is
that 1) of course I can, but 2) I don't want to,
because I already have the data in Python.

Answer #3 is Peoplesoft.  If you've never worked with
a really awkward database structure in the real world,
please count yourself lucky, and I'll buy you drinks
at your 30th birthday party.

Do you understand at least my motivation, if not
necessarily agreeing with the wisdom of my overall
proposal?




       
____________________________________________________________________________________Looking for a deal? Find great prices on flights and hotels with Yahoo! FareChase.
http://farechase.yahoo.com/


From showell30 at yahoo.com  Wed May 30 03:51:39 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 18:51:39 -0700 (PDT)
Subject: [Python-ideas] Idea: The DSL operator.
In-Reply-To: <d1b71f830705291822r887ccb3he51b09f54777cc3e@mail.gmail.com>
Message-ID: <574890.98074.qm@web33503.mail.mud.yahoo.com>

Talin wrote:

> An SQL query as a DSL:
>   query = SQL??(name == "John" and age > 25)
>   result_iter = query.execute()

Can you flesh this out with the added complication
that my SQL?? thingy wants to include in its
expression some kind of Python function that sits at
the module level, such convert_birthday_to_age?

My fear is that even with an AST at my DSL library's
disposal, I would still want hints from Python as to
better ways to scope things in the AST given to me,
and without actually changing the Python bytecode, I
still have my hands tied.

Or am I being too pessimistic?  Or does your proposal
already account for that?






       
____________________________________________________________________________________Pinpoint customers who are looking for what you sell. 
http://searchmarketing.yahoo.com/


From rrr at ronadam.com  Wed May 30 04:12:56 2007
From: rrr at ronadam.com (Ron Adam)
Date: Tue, 29 May 2007 21:12:56 -0500
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
 (and other suggestions)
In-Reply-To: <fb6fbf560705291123i1c35db9enf9962266f2dcda39@mail.gmail.com>
References: <20070528174325.86A2.JCARLSON@uci.edu>	
	<465BA636.8070501@ronadam.com>
	<20070529000414.86A5.JCARLSON@uci.edu>
	<fb6fbf560705291123i1c35db9enf9962266f2dcda39@mail.gmail.com>
Message-ID: <465CDDA8.50102@ronadam.com>

Jim Jewett wrote:
> On 5/29/07, Josiah Carlson <jcarlson at uci.edu> wrote:
>> Ron Adam <rrr at ronadam.com> wrote:
>> > Josiah Carlson wrote:

> *this* is the core of a useful idea.  list (and set and generator)
> comprehensions can't partition very well, because they have only a
> single output.  There isn't a good way to say:
> 
>    list_a = [x for x in src if pred(a)]
>    src = [x for x in src if not pred(a)]
>    list_b = [x for x in src if pred(b)]
>    src = [x for x in src if not pred(b)]
>    list_c = [x for x in src if pred(c)]
>    list_other = [x for x in src if not pred(c)]
> 
> On the other hand, you can do it (inefficiently) as above, or you can
> write an (ugly) version using a custom function, so the solution would
> have to be pretty good before it justified complicating the
> comprehension APIs.

I can't see how it could be done with out as you say... complicating the 
comprehension APIs.

However, I do think there could be very useful uses for a standard sorting 
structure of some sort.  That's the sorting as in mail sorters, or category 
sorters, that produce several streams of output instead of just one.

Would that be called a de-comprehension?

Mabye something like the following as a starting point?




# generate some random data

import random
import string

def random_pnum(length):
     ok_digits = string.letters + string.digits
     digits = [random.choice(ok_digits) for n in range(length)]
     return ''.join(digits)

src = []
for x in range(10):
     src.append(random_pnum(10))


# A de - comprehension generator

def decomp(seq, *cmps):
    results = dict(((c.__name__, []) for c in cmps))
    rest = []
    for x in seq:
       for c in cmps:
          if c(x):
              results[c.__name__].append(x)
              break
       else:
          rest.append(x)
    for c in cmps:
       yield results[c.__name__]
    yield rest


# Tests

def a_g(s):
    return s[0].lower() in "abcdefg"

def h_m(s):
    return s[0].lower() in "hijklm"

def n_z(s):
    return s[0].lower() in "nopqrstuvwxyz"

decmps = [a_g, h_m, n_z]
ag, hm, nz, other = decomp(src, *decmps)

print 'ag =', ag
print 'hm =', hm
print 'nz =', nz
print 'other =', other


-------------------

ag = ['c8WQe60G6J', 'EMY7O8qzTg']
hm = ['lDunyeOM98', 'LJuPg8ncZd']
nz = ['uhhuhd9YdO', 'qAuQvfTc6N', 'vpJz47pkP5', 'YOq6m4IXBn']
other = ['8JE6PuXxBz', '4ttyMdpuQY']



From showell30 at yahoo.com  Wed May 30 04:15:17 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 19:15:17 -0700 (PDT)
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <465CDDA8.50102@ronadam.com>
Message-ID: <43274.80903.qm@web33505.mail.mud.yahoo.com>


--- Ron Adam <rrr at ronadam.com> wrote:
> Would that be called a de-comprehension?
> 

LOL



 
____________________________________________________________________________________
Expecting? Get great news right away with email Auto-Check. 
Try the Yahoo! Mail Beta.
http://advision.webevents.yahoo.com/mailbeta/newmail_tools.html 


From showell30 at yahoo.com  Wed May 30 04:32:16 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 19:32:16 -0700 (PDT)
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <465CDDA8.50102@ronadam.com>
Message-ID: <297639.8702.qm@web33512.mail.mud.yahoo.com>


--- Ron Adam <rrr at ronadam.com> wrote:
> # Tests
> 
> def a_g(s):
>     return s[0].lower() in "abcdefg"
> 
> def h_m(s):
>     return s[0].lower() in "hijklm"
> 
> def n_z(s):
>     return s[0].lower() in "nopqrstuvwxyz"
> 
> decmps = [a_g, h_m, n_z]
> ag, hm, nz, other = decomp(src, *decmps)
> 
> print 'ag =', ag
> print 'hm =', hm
> print 'nz =', nz
> print 'other =', other
> 
> 
> -------------------
> 
> ag = ['c8WQe60G6J', 'EMY7O8qzTg']
> hm = ['lDunyeOM98', 'LJuPg8ncZd']
> nz = ['uhhuhd9YdO', 'qAuQvfTc6N', 'vpJz47pkP5',
> 'YOq6m4IXBn']
> other = ['8JE6PuXxBz', '4ttyMdpuQY']
> 

Am I misunderstanding (de-comprehensing) something
here?  How does the code above return those result
sets?  Or, more specifically, why does ag include 'T'
in its results set?



 
____________________________________________________________________________________
Sucker-punch spam with award-winning protection. 
Try the free Yahoo! Mail Beta.
http://advision.webevents.yahoo.com/mailbeta/features_spam.html


From rrr at ronadam.com  Wed May 30 04:45:49 2007
From: rrr at ronadam.com (Ron Adam)
Date: Tue, 29 May 2007 21:45:49 -0500
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
 (and other suggestions)
In-Reply-To: <297639.8702.qm@web33512.mail.mud.yahoo.com>
References: <297639.8702.qm@web33512.mail.mud.yahoo.com>
Message-ID: <465CE55D.6060607@ronadam.com>

Steve Howell wrote:
> --- Ron Adam <rrr at ronadam.com> wrote:
>> # Tests
>>
>> def a_g(s):
>>     return s[0].lower() in "abcdefg"
>>
>> def h_m(s):
>>     return s[0].lower() in "hijklm"
>>
>> def n_z(s):
>>     return s[0].lower() in "nopqrstuvwxyz"
>>
>> decmps = [a_g, h_m, n_z]
>> ag, hm, nz, other = decomp(src, *decmps)
>>
>> print 'ag =', ag
>> print 'hm =', hm
>> print 'nz =', nz
>> print 'other =', other
>>
>>
>> -------------------
>>
>> ag = ['c8WQe60G6J', 'EMY7O8qzTg']
>> hm = ['lDunyeOM98', 'LJuPg8ncZd']
>> nz = ['uhhuhd9YdO', 'qAuQvfTc6N', 'vpJz47pkP5',
>> 'YOq6m4IXBn']
>> other = ['8JE6PuXxBz', '4ttyMdpuQY']
>>
> 
> Am I misunderstanding (de-comprehensing) something
> here?  How does the code above return those result
> sets?  Or, more specifically, why does ag include 'T'
> in its results set?

The data in this case simulates 10 digit partnumbers which can include a-z, 
A-Z, and 0-9.

It doesn't alter the data, it just sorts it into smaller groups according 
to some predefined tests.  In this case.. it's only testing the first 
letter of each item.

What is tested is entirely up to you.  You could have lists of records as 
your data and test fields and divide the data according to that.

Cheers,
    Ron


From showell30 at yahoo.com  Wed May 30 04:53:03 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 19:53:03 -0700 (PDT)
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <465CE55D.6060607@ronadam.com>
Message-ID: <996023.85950.qm@web33501.mail.mud.yahoo.com>


--- Ron Adam <rrr at ronadam.com> wrote:

> Steve Howell wrote:
> > --- Ron Adam <rrr at ronadam.com> wrote:
> >> # Tests
> >>
> >> def a_g(s):
> >>     return s[0].lower() in "abcdefg"
> >>
> >> def h_m(s):
> >>     return s[0].lower() in "hijklm"
> >>
> >> def n_z(s):
> >>     return s[0].lower() in "nopqrstuvwxyz"
> >>
> >> decmps = [a_g, h_m, n_z]
> >> ag, hm, nz, other = decomp(src, *decmps)
> >>
> >> print 'ag =', ag
> >> print 'hm =', hm
> >> print 'nz =', nz
> >> print 'other =', other
> >>
> >>
> >> -------------------
> >>
> >> ag = ['c8WQe60G6J', 'EMY7O8qzTg']
> >> hm = ['lDunyeOM98', 'LJuPg8ncZd']
> >> nz = ['uhhuhd9YdO', 'qAuQvfTc6N', 'vpJz47pkP5',
> >> 'YOq6m4IXBn']
> >> other = ['8JE6PuXxBz', '4ttyMdpuQY']
> >>
> > 
> > Am I misunderstanding (de-comprehensing) something
> > here?  How does the code above return those result
> > sets?  Or, more specifically, why does ag include
> 'T'
> > in its results set?
> 
> The data in this case simulates 10 digit partnumbers
> which can include a-z, 
> A-Z, and 0-9.
> 
> It doesn't alter the data, it just sorts it into
> smaller groups according 
> to some predefined tests.  In this case.. it's only
> testing the first 
> letter of each item.
> 
> What is tested is entirely up to you.  You could
> have lists of records as 
> your data and test fields and divide the data
> according to that.
> 

Ok, apologies for quoting away the parts of your code
that probably answer my own question.

But to your bigger question--I think you can set up a
list comprehension that does partitioning by having
the list comprension or generator expression simply
return a list of tuples where the first element in the
tuple is a value that suggest where it fits in the
partition, then feed that tuple to dict() or whatever.

But I don't have a specific code example to prove it.

For simple binary partitions, there is the bool
function.





       
____________________________________________________________________________________Choose the right car based on your needs.  Check out Yahoo! Autos new Car Finder tool.
http://autos.yahoo.com/carfinder/


From rrr at ronadam.com  Wed May 30 05:30:19 2007
From: rrr at ronadam.com (Ron Adam)
Date: Tue, 29 May 2007 22:30:19 -0500
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
 (and other suggestions)
In-Reply-To: <996023.85950.qm@web33501.mail.mud.yahoo.com>
References: <996023.85950.qm@web33501.mail.mud.yahoo.com>
Message-ID: <465CEFCB.1020107@ronadam.com>

Steve Howell wrote:
> --- Ron Adam <rrr at ronadam.com> wrote:
> 
>> Steve Howell wrote:
>>> --- Ron Adam <rrr at ronadam.com> wrote:
>>>> # Tests
>>>>
>>>> def a_g(s):
>>>>     return s[0].lower() in "abcdefg"
>>>>
>>>> def h_m(s):
>>>>     return s[0].lower() in "hijklm"
>>>>
>>>> def n_z(s):
>>>>     return s[0].lower() in "nopqrstuvwxyz"
>>>>
>>>> decmps = [a_g, h_m, n_z]
>>>> ag, hm, nz, other = decomp(src, *decmps)
>>>>
>>>> print 'ag =', ag
>>>> print 'hm =', hm
>>>> print 'nz =', nz
>>>> print 'other =', other
>>>>
>>>>
>>>> -------------------
>>>>
>>>> ag = ['c8WQe60G6J', 'EMY7O8qzTg']
>>>> hm = ['lDunyeOM98', 'LJuPg8ncZd']
>>>> nz = ['uhhuhd9YdO', 'qAuQvfTc6N', 'vpJz47pkP5',
>>>> 'YOq6m4IXBn']
>>>> other = ['8JE6PuXxBz', '4ttyMdpuQY']
>>>>
>>> Am I misunderstanding (de-comprehensing) something
>>> here?  How does the code above return those result
>>> sets?  Or, more specifically, why does ag include
>> 'T'
>>> in its results set?
>> The data in this case simulates 10 digit partnumbers
>> which can include a-z, 
>> A-Z, and 0-9.
>>
>> It doesn't alter the data, it just sorts it into
>> smaller groups according 
>> to some predefined tests.  In this case.. it's only
>> testing the first 
>> letter of each item.
>>
>> What is tested is entirely up to you.  You could
>> have lists of records as 
>> your data and test fields and divide the data
>> according to that.
>>
> 
> Ok, apologies for quoting away the parts of your code
> that probably answer my own question.
> 
> But to your bigger question--I think you can set up a
> list comprehension that does partitioning by having
> the list comprension or generator expression simply
> return a list of tuples where the first element in the
> tuple is a value that suggest where it fits in the
> partition, then feed that tuple to dict() or whatever.
> 
> But I don't have a specific code example to prove it.

That would depend on what level of abstraction you want.  I find python 
already handles the simple things fairly well, so I tend to look for the 
next level up now.  That makes it a bit harder to find the balance between 
being too specific and too general.


 > For simple binary partitions, there is the bool
 > function.

Or more likely you may have a method in a class that tests for a particular 
condition.

     pass, fail = decomp(list_of_classes, lambda x: x.test())


Cheers,
   Ron


From showell30 at yahoo.com  Wed May 30 05:31:49 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Tue, 29 May 2007 20:31:49 -0700 (PDT)
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <465CDDA8.50102@ronadam.com>
Message-ID: <695025.66300.qm@web33507.mail.mud.yahoo.com>


--- Ron Adam <rrr at ronadam.com> wrote:

> However, I do think there could be very useful uses
> for a standard sorting 
> structure of some sort.  That's the sorting as in
> mail sorters, or category 
> sorters, that produce several streams of output
> instead of just one.
> 
> Would that be called a de-comprehension?
> 

Here is some category-sorting code, FWIW, where every
employee, Fred or not, gets a 50% raise, and employees
are partitioned according to their Fredness.

It doesn't use a general iterator, so maybe I'm
missing your point.


def partitions(lst):
    dct = {}
    for k, value in lst:
        dct.setdefault(k, []).append(value)
    return dct.items()

def is_fred(emp):
    return 'Fred' in emp[0]


emps = [
    ('Fred Smith', 50),
    ('Fred Jones', 40),
    ('Joe Blow', 30),
    ]

def pay_increase(salary): return salary * 0.5

emp_groups = partitions([(is_fred(emp),
        (emp[0], pay_increase(emp[1]))) for
        emp in emps])

for fredness, emps in emp_groups:
    print
    print 'is Fred?', fredness
    for name, pay_increase in emps:
        print name, pay_increase

----

is Fred? False
Joe Blow 15.0

is Fred? True
Fred Smith 25.0
Fred Jones 20.0



      ____________________________________________________________________________________
Park yourself in front of a world of choices in alternative vehicles. Visit the Yahoo! Auto Green Center.
http://autos.yahoo.com/green_center/ 


From gsakkis at rutgers.edu  Wed May 30 05:58:58 2007
From: gsakkis at rutgers.edu (George Sakkis)
Date: Tue, 29 May 2007 23:58:58 -0400
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
	(and other suggestions)
In-Reply-To: <695025.66300.qm@web33507.mail.mud.yahoo.com>
References: <465CDDA8.50102@ronadam.com>
	<695025.66300.qm@web33507.mail.mud.yahoo.com>
Message-ID: <91ad5bf80705292058l40b74e57o80854b5a1a25da3@mail.gmail.com>

On 5/29/07, Steve Howell <showell30 at yahoo.com> wrote:
>
> --- Ron Adam <rrr at ronadam.com> wrote:
>
> > However, I do think there could be very useful uses
> > for a standard sorting
> > structure of some sort.  That's the sorting as in
> > mail sorters, or category
> > sorters, that produce several streams of output
> > instead of just one.
> >
> > Would that be called a de-comprehension?
> >
>
> Here is some category-sorting code, FWIW, where every
> employee, Fred or not, gets a 50% raise, and employees
> are partitioned according to their Fredness.
>
> It doesn't use a general iterator, so maybe I'm
> missing your point.
>
> (snipped)

Or maybe you skipped homework on the itertools.groupby thread of c.l.py. ;-)

George

-- 
"If I have been able to see further, it was only because I stood on
the shoulders of million monkeys."


From rrr at ronadam.com  Wed May 30 06:24:39 2007
From: rrr at ronadam.com (Ron Adam)
Date: Tue, 29 May 2007 23:24:39 -0500
Subject: [Python-ideas] dict.fromkeys() better as dict().setkeys() ?
 (and other suggestions)
In-Reply-To: <695025.66300.qm@web33507.mail.mud.yahoo.com>
References: <695025.66300.qm@web33507.mail.mud.yahoo.com>
Message-ID: <465CFC87.2030600@ronadam.com>

Steve Howell wrote:
> --- Ron Adam <rrr at ronadam.com> wrote:
> 
>> However, I do think there could be very useful uses
>> for a standard sorting 
>> structure of some sort.  That's the sorting as in
>> mail sorters, or category 
>> sorters, that produce several streams of output
>> instead of just one.
>>
>> Would that be called a de-comprehension?
>>
> 
> Here is some category-sorting code, FWIW, where every
> employee, Fred or not, gets a 50% raise, and employees
> are partitioned according to their Fredness.
> 
> It doesn't use a general iterator, so maybe I'm
> missing your point.

Since you aren't really creating two lists, the problem below doesn't 
really fit this particular solution.  But maybe we can make it work from a 
different point of view.

emps = {
     'Fred Smith': 50.0,
     'Fred Jones': 40.0,
     'Joe Blow': 30,
     }

def pay_increase(salary): return salary * 0.5

def is_fred(emp):
     return 'Fred' in emp[0]

# give all Freds a raise
freds, notfreds = decomp(emps.keys(), is_fred):
for name in freds:
     emp[name] = pay_increas(emp[name])

#
# Then we can use the freds list again to generate a report.
#

Of course in this case the following would work just as well...

freds = []
for name in emps:
     if is_fred(name):
         emp[name] = pay_increas(emp[name])
         freds.append(name)


One reason to generating more than one list is if each list is going to be 
handled as batches, or in different ways, or at different times than you 
otherwise would by just iterating it.

Cheers,
    Ron



> def partitions(lst):
>     dct = {}
>     for k, value in lst:
>         dct.setdefault(k, []).append(value)
>     return dct.items()
> 
> def is_fred(emp):
>     return 'Fred' in emp[0]
> 
> 
> emps = [
>     ('Fred Smith', 50),
>     ('Fred Jones', 40),
>     ('Joe Blow', 30),
>     ]
> 
> def pay_increase(salary): return salary * 0.5
> 
> emp_groups = partitions([(is_fred(emp),
>         (emp[0], pay_increase(emp[1]))) for
>         emp in emps])
> 
> for fredness, emps in emp_groups:
>     print
>     print 'is Fred?', fredness
>     for name, pay_increase in emps:
>         print name, pay_increase
> 
> ----
> 
> is Fred? False
> Joe Blow 15.0
> 
> is Fred? True
> Fred Smith 25.0
> Fred Jones 20.0
> 
> 
> 
>       ____________________________________________________________________________________
> Park yourself in front of a world of choices in alternative vehicles. Visit the Yahoo! Auto Green Center.
> http://autos.yahoo.com/green_center/ 
> 
> 



From arno at marooned.org.uk  Wed May 30 12:41:51 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Wed, 30 May 2007 11:41:51 +0100
Subject: [Python-ideas] About list comprehension syntax
Message-ID: <8C1BDF74-1DAB-4F64-A28E-16788C48AA95@marooned.org.uk>

Hi

List comprehensions (and generator expressions) come in two  
'flavours' at the moment:

(1) [f(x) for x in L], which stands for map(f, L). Let's call this a  
'map comprehension'

(2) [f(x) for x in L if p(x)], which stands for map(f, filter(p, L)).  
Let's call this a 'map-filter comprehension'.

Now if one wants to write simply filter(p, L) as a list  
comprehension, one has to write:

(3) [x for x in L if p(x)].  This could be called a 'filter  
comprehension'.

the 'x for x in L' is not very nice IMHO, but it is often handy to  
use such expressions over 'filter(...)', eg building the sublist of a  
given list consisting of all the items of a given type could be  
written as:

filter(lambda x: isinstance(x, FilteringType), heterogeneous_list)

or:

[x for x in heterogenous_list if isinstance(x, FilteringType)]

I still prefer the list comprehension over the lambda/filter  
combination, but neither feels very satisfying (to me :) (not that  
one cannot use partial in the filter version)

Why not just drop the 'x for' at the start of a 'filter  
comprehension' (or generator expression)?  Thus (3) could be written  
more simply as:

(3') [x in L if p(x)]

This is consistent with common mathematical notation:

* { f(x) | x \in L } means the set of all f(x) for x in L
* { f(x) | x \in L, p(x) } means the set of all f(x) for x in L  
satisfying predicate p.
* { x \in L | p(x) } means the set of all x in L satisfying predicate p.

-- 
Arnaud




From stargaming at gmail.com  Wed May 30 15:45:27 2007
From: stargaming at gmail.com (Stargaming)
Date: Wed, 30 May 2007 15:45:27 +0200
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <465C3407.6030903@latte.ca>
References: <422478.77150.qm@web33501.mail.mud.yahoo.com>
	<465C3407.6030903@latte.ca>
Message-ID: <f3jv5q$4p4$1@sea.gmane.org>

Blake Winton wrote:
> Steve Howell wrote:
> 
>>Let the Python interpreter build expression objects
>>for you.  You write:
>>   rowexpr: convert_to_euros(salary) > 50000 and
>>deptno = 10
>>Python translates that into the same bytecode as:
>>lambda row: convert_to_euros(row['salary'] > 50000 and
>>row['deptno'] == 10
> 
> 
> I'm sorry, why would that not be translated into:
> 
> lambda row: row['convert_to_euros'](row['salary'] > row['50000'] 
> row['and'] row['deptno'] == row['10']

Sticking to your logic, why would it be > instead of row['>']? This is,
I guess, particularly simple with Python's tokenizer because neither
50000 nor and can be valid identifiers.


> ?  Specifically, how would python know what to dereference and what not 
> to?  What if there were two things, named the same, one in the row and 
> one in the namespace?  (i.e. a variable named 'salary')  

That's a harder one, indeed. Perhaps, nothing should be dereferenced (at
``compile'' time, don't know if that's a valid term in CPython's
interpreter chain tho), as it is in a lambda-expression.


> How would you 
> escape things which would have been dereferenced but you didn't want to 
> be?  (i.e. "rowexpr: convert_to_euros(salary) > salary")

ACK. If included (and I have major doubts it has a chance over 0.001%),
it could just support "easy" expressions, such as lambdas do today.

> I guess I'm kind of wasting my time here, since the introduction of a 
> new keyword for this application really isn't going to happen, based on 
> other decisions I've seen Guido make, but I do think that you need to 
> think a little more about how the implementation of this feature would 
> work.  (Or perhaps you've done that thinking, and you just need to fill 
> in the proposal with that information.)

Well, discussing in a mature manner can IMO never be a waste of time but
I have to agree, I would not want this as a keyword either. A common
idiom (aka stdlib module) *could* be handy, though.

Regards,
Stargaming



From arno at marooned.org.uk  Wed May 30 17:16:43 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Wed, 30 May 2007 16:16:43 +0100
Subject: [Python-ideas] positional only arguments decorator
In-Reply-To: <d11dcfba0705270837q66006447l9cc771c382b20784@mail.gmail.com>
References: <d11dcfba0705211130y6163556ica7f30d62de6258f@mail.gmail.com>
	<75AAE6B2-8D9D-43CF-A151-DF0C92964BA7@marooned.org.uk>
	<d11dcfba0705270837q66006447l9cc771c382b20784@mail.gmail.com>
Message-ID: <870D2002-DA52-44EA-B42A-3239917544A7@marooned.org.uk>


On 27 May 2007, at 16:37, Steven Bethard wrote:

> On 5/27/07, Arnaud Delobelle <arno at marooned.org.uk> wrote:
>>
>> On 21 May 2007, at 19:30, Steven Bethard wrote:
>>
>>> Ok, looks like there's not much chance of agreeing on a syntax, so
>>> here's a decorator that covers the two use cases I know of::
>>>
>>> * matching the signature of dict() and dict.update()
>>> * allowing arguments to have their names changed without worrying
>>> about backwards compatibility (e.g. ``def func(sequence)``  
>>> changing to
>>> ``def func(iterable)``)
>>
>> I propose a slightly different solution.  It may be a bit of a hack,
>> but I don't see why it should not be safe. This solution allows you
>> to use * and ** in order to write a definition like:
>>
>>>>> @posonly
>> ... def update(self, container=None, **kwargs):
>> ...     return self, container, kwargs
>> ...
>>>>> update('self')
>> ('self', None, {})
>>>>> update('self', 'container')
>> ('self', 'container', {})
>>>>> update('self', self='abc', container='xyz', foo='bar')
>> ('self', None, {'self': 'abc', 'foo': 'bar', 'container': 'xyz'})
>
> Cool!  Yes, it's hackish, but at least the results are pretty. ;-)

Wait!  I think I've got a devastatingly simple solution.  I've  
thought about this while looking at the PyEval_EvalCodeEx() function  
in Python/ceval.c.  It turns out that  the 'co_varnames' attribute of  
a code object is only used in order to 'slot in' arguments passed as  
keywords.  So by adding a '@' to the names we make these arguments  
positional only (one could choose any decoration including a  
character which is illegal in identifiers).  This method has two  
advantages:

* there is **no** overhead at all in calling a positional only function.

* the function keeps its original signature (positional only  
arguments are flagged with the trailing '@').

There is one 'drawback' (which could be considered a useful feature):

* if x is positional, f(**{'x@':1}) will work.

Here is the code.
------------------------------------------------------------------
from types import CodeType

code_args = (
     'argcount', 'nlocals', 'stacksize', 'flags', 'code',
     'consts', 'names', 'varnames', 'filename', 'name',
     'firstlineno', 'lnotab', 'freevars', 'cellvars'
     )

def copy_code(code_obj, **kwargs):
     "Make a copy of a code object, maybe changing some attributes"
     for arg in code_args:
         if not kwargs.has_key(arg):
             kwargs[arg] = getattr(code_obj, 'co_%s' % arg)
     return CodeType(*map(kwargs.__getitem__, code_args))

def posonly(f):
     code = f.func_code
     varnames, nargs = code.co_varnames, code.co_argcount
     varnames = ( tuple(v+'@' for v in varnames[:nargs])
                  + varnames[nargs:] )
     f.func_code = copy_code(code, varnames = varnames)
     return f
------------------------------------------------------------------

That's it!  Example:

 >>> @posonly
... def update(self, container=None, **kwargs):
...     return self, container, kwargs
...
 >>> update(1,2, self=3, container=4, x=5)
(1, 2, {'x': 5, 'self': 3, 'container': 4})
 >>> update(1)
(1, None, {})
 >>> help(update) # Notice the unobfuscated signature!
Help on function update in module __main__:

update(self@, container@=None, **kwargs)
 >>> # 'container' is still accessible by name:
... update(1, **{'container@':2})
(1, 2, {})
 >>>

-- 
Arnaud




From tjreedy at udel.edu  Wed May 30 18:30:47 2007
From: tjreedy at udel.edu (Terry Reedy)
Date: Wed, 30 May 2007 12:30:47 -0400
Subject: [Python-ideas] About list comprehension syntax
References: <8C1BDF74-1DAB-4F64-A28E-16788C48AA95@marooned.org.uk>
Message-ID: <f3k8rl$e0c$1@sea.gmane.org>


"Arnaud Delobelle" <arno at marooned.org.uk> wrote in 
message news:8C1BDF74-1DAB-4F64-A28E-16788C48AA95 at marooned.org.uk...
| Hi
|
| List comprehensions (and generator expressions) come in two
| 'flavours' at the moment:

Actually, you can have 1 to many for clauses and 0 to many if clauses.

| (1) [f(x) for x in L], which stands for map(f, L). Let's call this a
| 'map comprehension'
|
| (2) [f(x) for x in L if p(x)], which stands for map(f, filter(p, L)).
| Let's call this a 'map-filter comprehension'.
|
| Now if one wants to write simply filter(p, L) as a list
| comprehension, one has to write:
|
| (3) [x for x in L if p(x)].  This could be called a 'filter
| comprehension'.
|
| the 'x for x in L' is not very nice IMHO, but it is often handy to
| use such expressions over 'filter(...)', eg building the sublist of a
| given list consisting of all the items of a given type could be
| written as:
|
| filter(lambda x: isinstance(x, FilteringType), heterogeneous_list)
|
| or:
|
| [x for x in heterogenous_list if isinstance(x, FilteringType)]
|
| I still prefer the list comprehension over the lambda/filter
| combination, but neither feels very satisfying (to me :) (not that
| one cannot use partial in the filter version)
|
| Why not just drop the 'x for' at the start of a 'filter
| comprehension' (or generator expression)?

Because such micro abbreviations are against the spirit of Python, which is 
designed for readability over writablilty.  Even for a writer, it might 
take as much time to mentally deal with the exception and to simply type 
'for x', which takes all of a second.  Also, this breaks the mapping 
between for/if statements and clauses and makes the code ambiguous for both 
humans and the parser

|  Thus (3) could be written more simply as:
|
| (3') [x in L if p(x)]

(x in L) is a legal expression already.  (x in L) if p(x) looks like the 
beginning of (x in L) if p(x) else 'blah' .  The whole thing looks like a 
list literal with an incompletely specified one element.

| This is consistent with common mathematical notation:

'Common mathematical notation' is not codified and varies from writer to 
writer and even within the work of one writer.  Humans make do and make 
guesses, but parser programs are less flexible.

| * { f(x) | x \in L } means the set of all f(x) for x in L
| * { f(x) | x \in L, p(x) } means the set of all f(x) for x in L
| satisfying predicate p.
| * { x \in L | p(x) } means the set of all x in L satisfying predicate p.

I personally do not like the inconsistency of the last form, which flips 
'\in L' over the bar just because f(x) is the identify function.  It would 
be OK though in a situation where that was the only set comprehension being 
used.  But that is not the case with Python.

Terry Jan Reedy





From bjourne at gmail.com  Wed May 30 18:36:57 2007
From: bjourne at gmail.com (=?ISO-8859-1?Q?BJ=F6rn_Lindqvist?=)
Date: Wed, 30 May 2007 18:36:57 +0200
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <91ad5bf80705290803l7d6cade1s52ee8eceecc7b985@mail.gmail.com>
References: <422478.77150.qm@web33501.mail.mud.yahoo.com>
	<465C3407.6030903@latte.ca>
	<91ad5bf80705290803l7d6cade1s52ee8eceecc7b985@mail.gmail.com>
Message-ID: <740c3aec0705300936m3802e527oa5fc7524c0e27b55@mail.gmail.com>

On 5/29/07, George Sakkis <george.sakkis at gmail.com> wrote:
> Indeed, such half baked ideas have no chance of being taken seriously
> as language additions.

Remember that this list is called python-ideas for a reason. It is the
place for half-baked ideas.

-- 
mvh Bj?rn


From jcarlson at uci.edu  Wed May 30 18:45:24 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Wed, 30 May 2007 09:45:24 -0700
Subject: [Python-ideas] About list comprehension syntax
In-Reply-To: <8C1BDF74-1DAB-4F64-A28E-16788C48AA95@marooned.org.uk>
References: <8C1BDF74-1DAB-4F64-A28E-16788C48AA95@marooned.org.uk>
Message-ID: <20070530094220.86D3.JCARLSON@uci.edu>


Arnaud Delobelle <arno at marooned.org.uk> wrote:
> Why not just drop the 'x for' at the start of a 'filter  
> comprehension' (or generator expression)?  Thus (3) could be written  
> more simply as:

Explicit is better than implicit.
Special cases aren't special enough to break the rules.
There should be one-- and preferably only one --obvious way to do it.


 - Josiah



From jcarlson at uci.edu  Wed May 30 19:34:17 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Wed, 30 May 2007 10:34:17 -0700
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <740c3aec0705300936m3802e527oa5fc7524c0e27b55@mail.gmail.com>
References: <91ad5bf80705290803l7d6cade1s52ee8eceecc7b985@mail.gmail.com>
	<740c3aec0705300936m3802e527oa5fc7524c0e27b55@mail.gmail.com>
Message-ID: <20070530103147.86E2.JCARLSON@uci.edu>


"BJ?rn Lindqvist" <bjourne at gmail.com> wrote:
> On 5/29/07, George Sakkis <george.sakkis at gmail.com> wrote:
> > Indeed, such half baked ideas have no chance of being taken seriously
> > as language additions.
> 
> Remember that this list is called python-ideas for a reason. It is the
> place for half-baked ideas.

Indeed, but when they are called out as half-baked (explicitly or
implicitly), and are offered no love by others in the list, perhaps it's
time to let them die.

On the other hand, there is the other argument that comp.lang.python is
the right place to post half-baked ideas, which are then baked, brought
to python-ideas for another round of "you didn't put in blueberries",
before making it to python-dev/python-3000 .

 - Josiah



From arno at marooned.org.uk  Wed May 30 19:31:55 2007
From: arno at marooned.org.uk (Arnaud Delobelle)
Date: Wed, 30 May 2007 18:31:55 +0100
Subject: [Python-ideas] About list comprehension syntax
In-Reply-To: <f3k8rl$e0c$1@sea.gmane.org>
References: <8C1BDF74-1DAB-4F64-A28E-16788C48AA95@marooned.org.uk>
	<f3k8rl$e0c$1@sea.gmane.org>
Message-ID: <FF207374-0F57-4955-B77C-29D2A7B570D0@marooned.org.uk>


On 30 May 2007, at 17:30, Terry Reedy wrote:

>
> "Arnaud Delobelle" <arno at marooned.org.uk> wrote in
> message news:8C1BDF74-1DAB-4F64-A28E-16788C48AA95 at marooned.org.uk...
> | Hi
> |
> | List comprehensions (and generator expressions) come in two
> | 'flavours' at the moment:
>
> Actually, you can have 1 to many for clauses and 0 to many if clauses.

That's true.  I use that very seldom in fact.
[...]
> |
> | Now if one wants to write simply filter(p, L) as a list
> | comprehension, one has to write:
> |
> | (3) [x for x in L if p(x)].  This could be called a 'filter
> | comprehension'.
[...]
> | Why not just drop the 'x for' at the start of a 'filter
> | comprehension' (or generator expression)?
>
> Because such micro abbreviations are against the spirit of Python,  
> which is
> designed for readability over writablilty.  Even for a writer, it  
> might
> take as much time to mentally deal with the exception and to simply  
> type
> 'for x', which takes all of a second.

I wasn't suggesting this to save myself from typing 5 characters.   
You'll find it strange but I actually find [x in L if p(x)] more  
readable than [x for x in L if p(x)].  To me it says that I'm  
filtering, not mapping.

> Also, this breaks the mapping
> between for/if statements and clauses and makes the code ambiguous  
> for both
> humans and the parser
>

By ambiguous do you mean 'difficult to parse'?  I didn't think it was  
ambiguous in the technical sense.

> |  Thus (3) could be written more simply as:
> |
> | (3') [x in L if p(x)]
>
> (x in L) is a legal expression already.  (x in L) if p(x) looks  
> like the
> beginning of (x in L) if p(x) else 'blah' .  The whole thing looks  
> like a
> list literal with an incompletely specified one element.

I'm not sure I understand. I agree that

	x if (y in L if p(y)) else z

doesn't look great. Neither does

	x if (y for y in L if p(y)) else z

Well, the 'for' in the second one is a bit of a hint, I suppose.  I  
wouldn't write either anyway.  Most of the time when I write a list  
comprehension / generator expression it is to bind it to a name.

> | This is consistent with common mathematical notation:
>
> 'Common mathematical notation' is not codified and varies from  
> writer to
> writer and even within the work of one writer.  Humans make do and  
> make
> guesses, but parser programs are less flexible.

Yet all modern mathematicians will understand the three forms without  
any hesitation and 'making guesses' (consciously at least).

> | * { f(x) | x \in L } means the set of all f(x) for x in L
> | * { f(x) | x \in L, p(x) } means the set of all f(x) for x in L
> | satisfying predicate p.
> | * { x \in L | p(x) } means the set of all x in L satisfying  
> predicate p.
>
> I personally do not like the inconsistency of the last form, which  
> flips
> '\in L' over the bar just because f(x) is the identify function.

In fact the last form is 'the consistent one', as the first two  
should really be written as:

* { y \in M | \exists x \in L, y=f(x) }
* { y \in M | \exists x \in L, p(x) and y=f(x) }

(M being the codomain of f)

;oP

Anyway, while I still like the idea, you've made me think about it as  
some sort of 'useless tinkering', which is probably is.

-- 
Arnaud




From showell30 at yahoo.com  Thu May 31 01:40:02 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Wed, 30 May 2007 16:40:02 -0700 (PDT)
Subject: [Python-ideas] how rowexpr would be implemented
In-Reply-To: <f3jv5q$4p4$1@sea.gmane.org>
Message-ID: <230085.20835.qm@web33501.mail.mud.yahoo.com>


--- Stargaming <stargaming at gmail.com> wrote:

> 
> > ?  Specifically, how would python know what to
> dereference and what not 
> > to?  What if there were two things, named the
> same, one in the row and 
> > one in the namespace?  (i.e. a variable named
> 'salary')  
> 
> That's a harder one, indeed. Perhaps, nothing should
> be dereferenced (at
> ``compile'' time, don't know if that's a valid term
> in CPython's
> interpreter chain tho), as it is in a
> lambda-expression.
> 
> 

Admitting to not fully understanding the Python
innards, here's some food for thought on how this
would be done:

  1) Not to diminish the parsing-into-AST stage, I
won't cover that here, as other problems are trickier.
 Despite pretty different semantics, I think rowexpr
would look a lot like lambda at the syntactic level.

  2) You'd add a case to compiler_visit_expr for
Rowexpr_kind in compile.c.

  3) There's a pretty small method in compile.c called
compiler_lambda that would be the model for
compiler_rowexpr.  The compiler_rowexp would generate
an opcode that caused the single (implied,
C++-"this"-like) arg to be popped, and possibly that
opcode would have to be different than a normal opcode
to pop one argument off the stack, so that ceval.c can
do the right thing, but I'm not so sure.

  4) You might need to add something to compiler_unit
that is analogous to u_varnames, u_cellvars,
u_freevars, etc., so that when you recursively call
down to evaluate the expression in the rowexpr, the
lower methods know to look in a different place to
scope the words "salary," "convert_to_euros," and
"dept" in the example expression 'where
convert_to_euros(salary) > 50000 an dept = "software
development"'.

  5) The behavior of compiler_expr would NOT change
for most operators, such as Num_kind, Str_kind,
Attribute_kind, Subscript_kind, etc., as rowexpr
doesn't change how any of those are intrerpreted
compared to an expression in other scopes.

  6) Compiler_expr eventually gets to building opcodes
that give you salary, convert_to_euros, and dept, and
those pieces of code need to look into compiler_unit
to determine if they're part of the rowexpr, and do
the right thing.

  7) I'm sure there's more.  I'm here to learn.







       
____________________________________________________________________________________Get the free Yahoo! toolbar and rest assured with the added security of spyware protection.
http://new.toolbar.yahoo.com/toolbar/features/norton/index.php


From showell30 at yahoo.com  Thu May 31 02:29:20 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Wed, 30 May 2007 17:29:20 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <f3jv5q$4p4$1@sea.gmane.org>
Message-ID: <860739.28878.qm@web33506.mail.mud.yahoo.com>


--- Stargaming <stargaming at gmail.com> wrote:
> 
> That's a harder one, indeed. Perhaps, nothing should
> be dereferenced (at
> ``compile'' time, don't know if that's a valid term
> in CPython's
> interpreter chain tho), as it is in a
> lambda-expression.
> 

Just tried a few examples, almost everything
interesting happens at runtime:

======== PYTHON 2.3

Valid Python:

salary = 2
print (lambda: salary)() # prints 2

---

Valid, but useless, Python (no errors)

lambda: salary

---

Run-time error:

x = lambda: salary
x()

NameError: global name 'salary' is not defined

---

Run-time error:

x = lambda: convert_to_euros(salary)
x()

NameError: global name 'convert_to_euros' is not
defined

---

Run-time error:

def convert_to_euros(amt): return amt.impossible
salary = None
x = lambda: convert_to_euros(salary)
x()

AttributeError: 'NoneType' object has no attribute
'impossible'

---

Run-time error:

def convert_to_euros(amt): raise 'this does not get
here'
row = None
x = lambda row: convert_to_euros(row['salary'])
x(row)

TypeError: 'NoneType' object is unsubscriptable

======= THEORETICAL

Valid Python:

row = {'salary': 50000}
def convert_to_euros(amt): return amt / 2
x = rowexpr: convert_to_euros(salary)
print x(row) # prints 25000


---

Run-time error:

def convert_to_euros(amt): raise 'this does not get
here'
row = None
x = rowexpr: convert_to_euros(salary)
x(row)

TypeError: 'NoneType' object is unsubscriptable

---





      ____________________________________________________________________________________
Park yourself in front of a world of choices in alternative vehicles. Visit the Yahoo! Auto Green Center.
http://autos.yahoo.com/green_center/ 


From santagada at gmail.com  Thu May 31 03:20:33 2007
From: santagada at gmail.com (Leonardo Santagada)
Date: Wed, 30 May 2007 22:20:33 -0300
Subject: [Python-ideas] Make a CPAN like system for Py3K
Message-ID: <939F8BD5-04E0-4FFC-AFB3-0F9457DE96A3@gmail.com>

I know about cheeseshop and I know about setuptools. But how about  
all this be standard tools on python 3.0, so we can have something  
like CPAN but better. With setuptools being default on py3k you can  
already easy_install everything, ok but then we can do even more.  
When the user run a python script, if it requires a version of a lib  
that he doesn't have it could download it and install in his home  
folder (something in the lines of ~/pythonlibs). This will make it  
much easier to distribute python programs. I think this is somewhat  
like what java webstart does. What do you guys think? Also why no one  
is talking about having a tool like setuptools in the stdlib?

--
Leonardo Santagada
"If it looks like a duck, and quacks like a duck, we have at least to  
consider the possibility that we have a small aquatic bird of the  
family anatidae on our hands." - Douglas Adams





From adam at atlas.st  Thu May 31 03:23:43 2007
From: adam at atlas.st (Adam Atlas)
Date: Wed, 30 May 2007 21:23:43 -0400
Subject: [Python-ideas] Make a CPAN like system for Py3K
In-Reply-To: <939F8BD5-04E0-4FFC-AFB3-0F9457DE96A3@gmail.com>
References: <939F8BD5-04E0-4FFC-AFB3-0F9457DE96A3@gmail.com>
Message-ID: <528310D8-9BA2-4674-BDE9-F5A3F432BF7A@atlas.st>

If I remember correctly, setuptools is to be included starting  
already with Python 2.6.


On 30 May 2007, at 21.20, Leonardo Santagada wrote:
> I know about cheeseshop and I know about setuptools. But how about
> all this be standard tools on python 3.0, so we can have something
> like CPAN but better. With setuptools being default on py3k you can
> already easy_install everything, ok but then we can do even more.
> When the user run a python script, if it requires a version of a lib
> that he doesn't have it could download it and install in his home
> folder (something in the lines of ~/pythonlibs). This will make it
> much easier to distribute python programs. I think this is somewhat
> like what java webstart does. What do you guys think? Also why no one
> is talking about having a tool like setuptools in the stdlib?



From greg.ewing at canterbury.ac.nz  Thu May 31 03:59:25 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Thu, 31 May 2007 13:59:25 +1200
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <777248.90724.qm@web33511.mail.mud.yahoo.com>
References: <777248.90724.qm@web33511.mail.mud.yahoo.com>
Message-ID: <465E2BFD.3000405@canterbury.ac.nz>

Steve Howell wrote:
> I don't mean to oversimplify this, which is why I'm
> batting it around on a forum with a lot of smart
> people.  But clearly it could be done.  Whether it
> *should* be done is, of course, a question for debate,
> and I accept this.

My objection this idea is that it's going in the
opposite direction to what I'd like to see. In my
opinion, having to embed one programming language
inside another leads to ugly code.

I would rather have an elegant way to deal with
relational databases by writing Python code *instead*
of SQL, than yet another mechanism for embedding
SQL in Python.

-- 
Greg Ewing, Computer Science Dept, +--------------------------------------+
University of Canterbury,	   | Carpe post meridiem!          	  |
Christchurch, New Zealand	   | (I'm not a morning person.)          |
greg.ewing at canterbury.ac.nz	   +--------------------------------------+


From steven.bethard at gmail.com  Thu May 31 04:22:01 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Wed, 30 May 2007 20:22:01 -0600
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <860739.28878.qm@web33506.mail.mud.yahoo.com>
References: <f3jv5q$4p4$1@sea.gmane.org>
	<860739.28878.qm@web33506.mail.mud.yahoo.com>
Message-ID: <d11dcfba0705301922s1def8eb8s5c272ec812c9385d@mail.gmail.com>

On 5/30/07, Steve Howell <showell30 at yahoo.com> wrote:
> ======= THEORETICAL
>
> Valid Python:
>
> row = {'salary': 50000}
> def convert_to_euros(amt): return amt / 2
> x = rowexpr: convert_to_euros(salary)
> print x(row) # prints 25000

>>> def rowexpr(expr):
...     def evaluate(row):
...         d = dict(row)
...         d.update(globals())
...         exec '__result__ = ' + expr in d
...         return d['__result__']
...     return evaluate
...
>>> def convert_to_euros(amt):
...     return amt / 2
...
>>> x = rowexpr('convert_to_euros(salary)')
>>> row = dict(salary=50000)
>>> print x(row)
25000

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From showell30 at yahoo.com  Thu May 31 04:33:33 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Wed, 30 May 2007 19:33:33 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <465E2BFD.3000405@canterbury.ac.nz>
Message-ID: <679178.87771.qm@web33514.mail.mud.yahoo.com>


--- Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> 
> I would rather have an elegant way to deal with
> relational databases by writing Python code
> *instead*
> of SQL, than yet another mechanism for embedding
> SQL in Python.
> 

You're wanting to solve a slightly different problem
than I was, but can you elaborate on this a bit?  How
do you currently interact with relational databases?
Are you objecting to some ugliness of SQL itself, or
do you want a more powerful abstraction?

To the extent that I have to work with awkward legacy
database structures, I find that my strategy is
usually this:

   1) Write minimal SQL to get most of the data that I
need up front.

   2) Manipulate the data many ways in Python.

   3) Write minimal SQL to put data back in the
database.





 
____________________________________________________________________________________
Be a PS3 game guru.
Get your game face on with the latest PS3 news and previews at Yahoo! Games.
http://videogames.yahoo.com/platform?platform=120121


From aahz at pythoncraft.com  Thu May 31 04:59:33 2007
From: aahz at pythoncraft.com (Aahz)
Date: Wed, 30 May 2007 19:59:33 -0700
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <998077.51447.qm@web33510.mail.mud.yahoo.com>
References: <20070530004951.GA17586@panix.com>
	<998077.51447.qm@web33510.mail.mud.yahoo.com>
Message-ID: <20070531025933.GA22999@panix.com>

On Tue, May 29, 2007, Steve Howell wrote:
>
> Do you understand at least my motivation, if not necessarily agreeing
> with the wisdom of my overall proposal?

Sort of.  I still think that your proposal deserves to be shot down for
the same reasons that including regexes as part of the language should be
shot down.  I'm slightly less opposed to Talin's DSL idea, though.
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"as long as we like the same operating system, things are cool." --piranha


From aahz at pythoncraft.com  Thu May 31 05:02:05 2007
From: aahz at pythoncraft.com (Aahz)
Date: Wed, 30 May 2007 20:02:05 -0700
Subject: [Python-ideas] Idea: The DSL operator.
In-Reply-To: <d1b71f830705291822r887ccb3he51b09f54777cc3e@mail.gmail.com>
References: <d1b71f830705291822r887ccb3he51b09f54777cc3e@mail.gmail.com>
Message-ID: <20070531030205.GB22999@panix.com>

On Tue, May 29, 2007, Talin wrote:
>
> This is in response to the various suggestions for embedding SQL
> syntax in Python and various other suggestions made over the years.

Why not try to figure out a way to build a Quixote-like system into
Python?  IOW, any DSL should *not* go into Python files; instead, they
should go into separate files that can be processed by the Python parser
and then executed.
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"as long as we like the same operating system, things are cool." --piranha


From greg.ewing at canterbury.ac.nz  Thu May 31 05:05:52 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Thu, 31 May 2007 15:05:52 +1200
Subject: [Python-ideas] About list comprehension syntax
In-Reply-To: <8C1BDF74-1DAB-4F64-A28E-16788C48AA95@marooned.org.uk>
References: <8C1BDF74-1DAB-4F64-A28E-16788C48AA95@marooned.org.uk>
Message-ID: <465E3B90.1030701@canterbury.ac.nz>

Arnaud Delobelle wrote:

> Why not just drop the 'x for' at the start of a 'filter  
> comprehension' (or generator expression)?  Thus (3) could be written  
> more simply as:
> 
> (3') [x in L if p(x)]

It would be very nice, but could be difficult to parse,
because there's no clue you're not looking at a normal
list constructor until you get to the 'if'.

-- 
Greg Ewing, Computer Science Dept, +--------------------------------------+
University of Canterbury,	   | Carpe post meridiem!          	  |
Christchurch, New Zealand	   | (I'm not a morning person.)          |
greg.ewing at canterbury.ac.nz	   +--------------------------------------+


From showell30 at yahoo.com  Thu May 31 05:24:59 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Wed, 30 May 2007 20:24:59 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <d11dcfba0705301922s1def8eb8s5c272ec812c9385d@mail.gmail.com>
Message-ID: <928379.98919.qm@web33505.mail.mud.yahoo.com>

--- Steven Bethard <steven.bethard at gmail.com> wrote:
> >>> def rowexpr(expr):
> ...     def evaluate(row):
> ...         d = dict(row)
> ...         d.update(globals())
> ...         exec '__result__ = ' + expr in d
> ...         return d['__result__']
> ...     return evaluate
> ...
> >>> def convert_to_euros(amt):
> ...     return amt / 2
> ...
> >>> x = rowexpr('convert_to_euros(salary)')
> >>> row = dict(salary=50000)
> >>> print x(row)
> 25000
> 

Thanks.

I tried it out with a slightly more involved
expression.

x = rowexpr(
        'convert_to_euros(salary) '
        'if dept == "foo" else 0')
rows = [dict(dept='foo', salary=i) for i in
range(10000)]
transform = [x(row) for row in rows]

Here were my findings:

1) Not horribly slow.

    3.4 seconds on my box for 10000 calls

2) I introduced a syntax error, and it was more clear
than I thought it would be.  It happens at runtime, of
course, which is less than ideal, and it doesn't
directly point me out to the line of code with the
syntax error, but it does suggest the error:

  File "sql.py", line 14, in <module>
    transform = [x(row) for row in rows]
  File "sql.py", line 5, in evaluate
    exec '__result__ = ' + expr in d
  File "<string>", line 1
    __result__ = convert_to_euros(salary) if dept =
"foo" else 0
                                                  ^
SyntaxError: invalid syntax





 
____________________________________________________________________________________
Don't get soaked.  Take a quick peak at the forecast
with the Yahoo! Search weather shortcut.
http://tools.search.yahoo.com/shortcuts/#loc_weather


From jcarlson at uci.edu  Thu May 31 06:30:55 2007
From: jcarlson at uci.edu (Josiah Carlson)
Date: Wed, 30 May 2007 21:30:55 -0700
Subject: [Python-ideas] About list comprehension syntax
In-Reply-To: <465E3B90.1030701@canterbury.ac.nz>
References: <8C1BDF74-1DAB-4F64-A28E-16788C48AA95@marooned.org.uk>
	<465E3B90.1030701@canterbury.ac.nz>
Message-ID: <20070530212851.86FB.JCARLSON@uci.edu>


Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Arnaud Delobelle wrote:
> 
> > Why not just drop the 'x for' at the start of a 'filter  
> > comprehension' (or generator expression)?  Thus (3) could be written  
> > more simply as:
> > 
> > (3') [x in L if p(x)]
> 
> It would be very nice, but could be difficult to parse,
> because there's no clue you're not looking at a normal
> list constructor until you get to the 'if'.

Even then it's not terribly clear except that there's a missing 'else'
clause for conditionals...

    y = [x in L if p(x) else None]

Will create a list of a single value in Python 2.5 .

 - Josiah



From talin at acm.org  Thu May 31 06:28:53 2007
From: talin at acm.org (Talin)
Date: Wed, 30 May 2007 21:28:53 -0700
Subject: [Python-ideas] Idea: The DSL operator.
In-Reply-To: <20070531030205.GB22999@panix.com>
References: <d1b71f830705291822r887ccb3he51b09f54777cc3e@mail.gmail.com>
	<20070531030205.GB22999@panix.com>
Message-ID: <465E4F05.1070404@acm.org>

Aahz wrote:
> On Tue, May 29, 2007, Talin wrote:
>> This is in response to the various suggestions for embedding SQL
>> syntax in Python and various other suggestions made over the years.
> 
> Why not try to figure out a way to build a Quixote-like system into
> Python?  IOW, any DSL should *not* go into Python files; instead, they
> should go into separate files that can be processed by the Python parser
> and then executed.

That really depends on the DSL. Some DSLs want to be embedded - having 
to segregate SQL query statements into a separate file is a non-starter 
IMHO.

-- Talin


From showell30 at yahoo.com  Thu May 31 06:37:49 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Wed, 30 May 2007 21:37:49 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <20070531025933.GA22999@panix.com>
Message-ID: <64476.28634.qm@web33514.mail.mud.yahoo.com>


--- Aahz <aahz at pythoncraft.com> wrote:

> On Tue, May 29, 2007, Steve Howell wrote:
> >
> > Do you understand at least my motivation, if not
> necessarily agreeing
> > with the wisdom of my overall proposal?
> 
> Sort of.  I still think that your proposal deserves
> to be shot down for
> the same reasons that including regexes as part of
> the language should be
> shot down.  I'm slightly less opposed to Talin's DSL
> idea, though.

The more I think about the general themes in this
discussion, the more I think PyPy is gonna be the
proving ground for those kind of ideas.




      ____________________________________________________________________________________Shape Yahoo! in your own image.  Join our Network Research Panel today!   http://surveylink.yahoo.com/gmrs/yahoo_panel_invite.asp?a=7 




From steven.bethard at gmail.com  Thu May 31 07:38:40 2007
From: steven.bethard at gmail.com (Steven Bethard)
Date: Wed, 30 May 2007 23:38:40 -0600
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <928379.98919.qm@web33505.mail.mud.yahoo.com>
References: <d11dcfba0705301922s1def8eb8s5c272ec812c9385d@mail.gmail.com>
	<928379.98919.qm@web33505.mail.mud.yahoo.com>
Message-ID: <d11dcfba0705302238w23b83887iebe7ad8dcca36bfe@mail.gmail.com>

On 5/30/07, Steve Howell <showell30 at yahoo.com> wrote:
> --- Steven Bethard <steven.bethard at gmail.com> wrote:
> > >>> def rowexpr(expr):
> > ...     def evaluate(row):
> > ...         d = dict(row)
> > ...         d.update(globals())
> > ...         exec '__result__ = ' + expr in d
> > ...         return d['__result__']
> > ...     return evaluate
> > ...
[snip]
> I tried it out with a slightly more involved
> expression.
>
> x = rowexpr(
>         'convert_to_euros(salary) '
>         'if dept == "foo" else 0')
> rows = [dict(dept='foo', salary=i) for i in
> range(10000)]
> transform = [x(row) for row in rows]
>
> Here were my findings:
>
> 1) Not horribly slow.
>
>     3.4 seconds on my box for 10000 calls
>
> 2) I introduced a syntax error, and it was more clear
> than I thought it would be.  It happens at runtime, of
> course, which is less than ideal

You can get the syntax error a little earlier (at the time of the
rowexpr() call) by using compile()::

>>> def rowexpr(expr):
...     code = compile('__result__ = ' + expr, '<rowexpr>', 'exec')
...     def evaluate(row):
...         d = dict(globals())
...         d.update(row)
...         exec code in d
...         return d['__result__']
...     return evaluate
...
>>> def convert_to_euros(amt):
...     return amt / 2
...
>>> x = rowexpr('convert_to_euros(salary)')
>>> row = dict(salary=50000)
>>> print x(row)
25000
>>> rowexpr('convert_to_euros(salary) if dept = "foo" else 0')
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<interactive input>", line 2, in rowexpr
  File "<rowexpr>", line 1
    __result__ = convert_to_euros(salary) if dept = "foo" else 0
                                                  ^
SyntaxError: invalid syntax


STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


From greg.ewing at canterbury.ac.nz  Thu May 31 08:23:14 2007
From: greg.ewing at canterbury.ac.nz (Greg Ewing)
Date: Thu, 31 May 2007 18:23:14 +1200
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <679178.87771.qm@web33514.mail.mud.yahoo.com>
References: <679178.87771.qm@web33514.mail.mud.yahoo.com>
Message-ID: <465E69D2.4050100@canterbury.ac.nz>

Steve Howell wrote:

> You're wanting to solve a slightly different problem
> than I was, but can you elaborate on this a bit?

I know, it's more or less the complementary problem to
what you're talking about. My point is that I don't like
embedding SQL in my Python even when I'm dealing with
a relational database, so I'm even less inclined to
do so when dealing with Python data structures. I
find that the existing features of the Python language
do that well enough already.

> Are you objecting to some ugliness of SQL itself, or
> do you want a more powerful abstraction?

Some of both. There's the general awkwardness involved
whenever one language is embedded in another, plus the
fact that I don't particularly like some aspects of
SQL in particular.

But often I also want a more powerful abstraction. The
SQL that I need at a given point in the program isn't
always fixed, and I need to generate it dynamically.

As an example, in a recent project I needed to extract
data from a number of tables to produce a report. The
user has a variety of choices as to which fields are
included in the report, and can optionally specify
selection criteria for various fields, either a single
value or a range of values.

To accommodate this efficiently, I have to dynamically
generate an SQL statement which includes or excludes
'where' clause terms of various sorts, and joins
as necessary to pull in requested data from auxiliary
tables.

In this kind of application, there are few or no
complete SQL statements written into the source,
only fragments that get combined by an SQL-generation
framework of some kind. So a facility like the one
you suggest wouldn't help with this kind of problem.

--
Greg


From showell30 at yahoo.com  Thu May 31 08:39:05 2007
From: showell30 at yahoo.com (Steve Howell)
Date: Wed, 30 May 2007 23:39:05 -0700 (PDT)
Subject: [Python-ideas] proposal to add rowexpr as a keyword
In-Reply-To: <465E69D2.4050100@canterbury.ac.nz>
Message-ID: <988912.85401.qm@web33508.mail.mud.yahoo.com>


--- Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> 
> To accommodate this efficiently, I have to
> dynamically
> generate an SQL statement which includes or excludes
> 'where' clause terms of various sorts, and joins
> as necessary to pull in requested data from
> auxiliary
> tables.
> 

I can definitely relate to that sort of pain.


       
____________________________________________________________________________________Building a website is a piece of cake. Yahoo! Small Business gives you all the tools to get online.
http://smallbusiness.yahoo.com/webhosting 


From bborcic at gmail.com  Thu May 31 11:51:54 2007
From: bborcic at gmail.com (Boris Borcic)
Date: Thu, 31 May 2007 11:51:54 +0200
Subject: [Python-ideas] About list comprehension syntax
In-Reply-To: <f3k8rl$e0c$1@sea.gmane.org>
References: <8C1BDF74-1DAB-4F64-A28E-16788C48AA95@marooned.org.uk>
	<f3k8rl$e0c$1@sea.gmane.org>
Message-ID: <f3m5t3$c51$1@sea.gmane.org>

Terry Reedy wrote:
> "Arnaud Delobelle" 
...
> |  Thus (3) could be written more simply as:
> |
> | (3') [x in L if p(x)]
> 
> (x in L) is a legal expression already.  

That's the only real issue IMO - and I agree there is no acceptable solution.

> (x in L) if p(x) looks like the 
> beginning of (x in L) if p(x) else 'blah' .  The whole thing looks like a 
> list literal with an incompletely specified one element.
> 
> | This is consistent with common mathematical notation:
> 
> 'Common mathematical notation' is not codified and varies from writer to 
> writer and even within the work of one writer.  Humans make do and make 
> guesses, but parser programs are less flexible.

I guess it also depends on how much math (eg theorem proofs) one had to deal 
with. FWIW, it took me months to adapt to the correct Python listcomp/genexp 
syntax, after being bitten dozens of times by Python not accepting Arnaud's (3') 
form above. The latter was *much* more natural to my fingers.

Cheers, BB



From ali.sabil at gmail.com  Thu May 31 15:15:11 2007
From: ali.sabil at gmail.com (Ali Sabil)
Date: Thu, 31 May 2007 15:15:11 +0200
Subject: [Python-ideas] Attribute Docstrings and Annotations
Message-ID: <6b4de4d80705310615j5cf712fdldb5e685d2c4a4a7a@mail.gmail.com>

Hello all,

I was looking into function annotations, that are to be introduced in
Python3k, and I found this old message sent to this mailing list :
http://mail.python.org/pipermail/python-ideas/2007-January/000037.html

I would like to restart the discussion of attribute annotation, because in
my opinion it can be a very powerful feature. I personally think about using
it for SOAP message serialization, or any kind of XML serialization, the
Idea would be to annotate various object attribues to be either marshaled as
XML Elements or XML Attributes of the current Node that reflects the Object.

Thank you,

--
Ali
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070531/5f00e51b/attachment.html>