Differences between revisions 33 and 34
Revision 33 as of 2005-09-04 05:49:24
Size: 11318
Editor: c-71-56-216-155
Comment: added request to change UserDict requirements from keys() to __iter__()
Revision 34 as of 2005-09-06 15:01:29
Size: 11320
Editor: FredDrake
Comment: fix minor typos
Deletions are marked like this. Additions are marked like this.
Line 137: Line 137:
Operators as {{{- & | ^}}} should be used for strings and lists directly in place of making firs a {{{set}}} data type (see [http://www.python.org/peps/pep-0218.html PEP 218 - Adding a Built-In Set Object Type]). Operators as {{{- & | ^}}} should be used for strings and lists directly in place of first making a {{{set}}} data type (see [http://www.python.org/peps/pep-0218.html PEP 218 - Adding a Built-In Set Object Type]).
Line 143: Line 143:
# reminder: # remainder:

Other syntax ideas and feature ideas for ["Python3.0"] .

TableOfContents()

Optional Static Typing / Adaptation

Lambda / Anonymous Methods / Closures

".." Sequences, Custom Infix Operators

Improved default value logic for Dictionaries

  • The setdefault() method is badly named and poorly designed. In a typical call, d.setdefault.(k, []).append(v), the list may be unnecessarily instantiated and discarded on every call. At a minimum, default value should be a new empty list instead of None:  d.setdefault(k).append(v) .

  • A more versatile idea is to realize that defaults generalize to the whole dictionary instead of an individual lookup. A call to setdefault would then change the whole dictionary's behavior when a key is not found:

    counts = {}
    counts.setdefault(value=0)
    for elem in data:
        counts[elem] += 1

    index = {}
    index.setdefault(function=list)
    for pageno, page in enumerate(pages):
        for line in page:
            for word in line.split():
                 index[word].append(line)

Note that it's not really necessary that setdefault() take *args and **kwargs arguments to be passed to the function; PEP 309 allows a reasonable solution to this problem:

   1 from functional import partial
   2 d.setdefault(function=partial(list, [0]))
   3 d.setdefault(function=partial(dict, a=0, b=1))

Better boolean logic

The and/or operators should only return boolean values. This makes their use less error-prone, less prone to abuse, and more closely match other languages. Also, it will simplify the underlying bytecode which currently inserts many POP_TOP instructions to complete conditionals. The need to insert these instructions also results in extra code paths and jump instructions. Overall, the language will become more intuitive, more reliable, simpler, and faster.

  • While I agree with your points. I would find "Better boolean logic" counter-productive in many instances. I personally prefer the former of these examples as the latter slows me down and, in my case, invites errors. {{{return a() or 'b'

#---

temp = a() if temp:

  • return temp

else:

  • return 'b'

}}}The latter structure always makes me shudder. I've never encountered a good use for non-boolean output from "and" (in Python. Other languages are a different story.) but using "or" in the first example is both quicker and more intuitive for many people not to mention reducing code complexity.-- StephanSokolow

Agreed, only comparison operators (==, >, <) should return True/False, leave and/or as is

Disallow calling class methods from instances

Calling with a instance is almost never what you want. When it is done, the results are not especially readable, and the code suggests that it is doing something that it isn't:

{'a'=1}.fromkeys('poof') # what happened to 'a'? 

I disagree to this. Although calling class methods on the instance from the outside will usually be rubbish, it will very often be useful and intended behavour inside instances. For example:

class mydict(dict):
  def key_copy(self):
    return self.fromkeys(self)    

This will assert that whatever subclass of mydict is created and not some other class. One could argue though that this could be achieved by the more cluttersome self.__class__.fromkeys().

Simplify the syntax for raising exceptions

  • Eliminate string exceptions entirely.
  • Alway require instantation. IOW, prefer raise ValueError(dat) to raise ValueError, dat.

  • Require that all exceptions subclass from Exception.

  • Have Exception be a new-style class

Include docstrings when printing user-defined exceptions such as implemented by http://soiland.no/software/doc_exception.py:

>>> class IdiotError(Exception):
...    """Some idiot occured"""
...
>>> raise IdiotError
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
__main__.IdiotError: Some idiot occured

Fix implementation of in-place operators

The current implementation will call __iadd__(), allowing it to do the in-place change, but then require that the method return the new value and then store it again. Ideally, all the responsibility for the update should lie with the __iadd__() method and it should return None. This simplifies the bytecode and eliminates some annoying behavior (such as a[0]+=1 succeeding and raising an error when a=([0],).

Remove the distinction between data and non-data decriptors

Having the distinction provides a tiny benefit but incurs a large cost in terms of implementation complexity and increasing the learning curve for descriptors. Using the presence or absence of a setter to distinquish the two is somewhat hackish and confuses the heck out of anyone first trying to master descriptors. Even after using descriptors for a while, that nuance remains an annoying distraction.

Note that descriptors are a somewhat advanced feature, not really expected to be used by beginners or on a day to day basis, so the extra flexibilty given by by the data/non-data descriptors distinction may still be worth the small extra complexity it adds to the protocol .

Reconsider the inclusion of __slots__ or re-evaluate its implementation

Guido has expressed that this is a highly popular, but badly misunderstood tool that is often used incorrectly.

  • If __slots__ is misspelled, there is no visible indication of failure.

  • The purpose of the tool is not to make it more difficult to assign attributes.

  • __slots__ do not inherit.

  • __slots__ complicates and slows the implementation of new-style classes.

Extra operators for strings and lists

Operators as - & | ^ should be used for strings and lists directly in place of first making a set data type (see [http://www.python.org/peps/pep-0218.html PEP 218 - Adding a Built-In Set Object Type]).

The operators /, * and % could also be used to split and stitch strings and lists:

   1 # split:
   2 'spameggsham' / 'a' == 'spameggsham'.split('a') == ['sp', 'meggsh', 'm']
   3 # remainder:
   4 'spameggsham' % 'a' == 'aa'
   5 # stitch:
   6 ['sp', 'meggsh', 'm'] * 'a' == 'spameggsham'
   7 
   8 # split list:
   9 [1, 2, 3, 4, 5] / [2, 3] == [[1], [4, 5]]
  • 'spameggsham' % 'a' == 'aa' is sort of unclear, and .count('a') works just as well. The others sound fine.-- ChrisRebert

Move rarely-used builtins to the library

pow() to the math module!

Don't remove callable()

Please don't. There are times where you want to know if an object is callable without calling it. For instance if you create a metaclass and need to wrap defined methods passed to __new__, and don't want to wrap class variables.

  • Why use callable() then? Isn't this what inspect.ismethod(), .isfunction() etc. are for? --StevenBethard

In addition, using exceptions for normal control flow is not good code style.

Make API of set, list, dict more consistent

No need for copy function. A clear function for all of them.

Make copy and deepcopy built-ins, replace copy methods by __copy__

It would clarify how copy should be done.

Don't remove cmp() and __cmp__

Even if it looks TMTOWTDI, it makes implementing comparison so easy that it must be kept. It TOOWTDI is important, maybe only keep cmp?

   1    def __cmp__(self, other):
   2       return cmp(self.member1, other.member1) or cmp(self.member2, other.member2)

Are rich comparisons really that much more complex?

   1    def __lt__(self, other):
   2       return (self.member1, other.member1) < (self.member2, other.member2)

Builtin Literal for sets

Make a set literal:

   1    # Use "< >"
   2    s = <'a', 'b', 'c'>
   3    
   4    # Or use "| |"
   5    s = |'a', 'b', 'c'|

Make extended function call syntax more iterator friendly

Extended function call syntax currently does not play well with iterators because it produces a tuple to be passed in to the function. This means API developers face a tough choice - either accept an iterator and make the function clumsier for use with a short sequence of specific variables (as the user of the API has to create a throwaway list or tuple), or use positional arguments and make the API iterator unfriendly (as an iterator passed via extended function call syntax gets unraveled and stuffed into a tuple).

If the extended function call syntax was able to avoid forcing the creation of the tuple, then the choice would be easy - always use the positional argument support.

Require __iter__() for UserDict instead of keys()

Currently, UserDict.DictMixin requires the methods __getitem__(), __setitem__(), __delitem__(), and keys() to supply the appropriate other methods of the dict interface. I would prefer that it require __iter__() instead of keys(). [http://mail.python.org/pipermail/python-list/2005-January/258569.html As I understand it], the fact that it uses keys() instead of __iter__() is mainly due to the order of introduction of keys() and __iter__(). Since keys() can easily be defined in terms of __iter__(), in Python 3.0, I'd like to see __iter__() be the required method instead. -- StevenBethard

Python3.0Suggestions (last edited 2010-05-16 23:17:52 by modemcable054)

Unable to edit the page? See the FrontPage for instructions.