[Python-Dev] Python 3000 PEP: Postfix type declarations

2007-04-01 Thread Georg Brandl
PEP: XXX
Title: Postfix type declarations
Version: $Revision: $
Last-Modified: $Date: $
Author: Georg Brandl [EMAIL PROTECTED]
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 01-Apr-2007
Python-Version: 3.0


Abstract


This PEP proposes the addition of a postfix type declaration syntax to
Python. It also specifies a new ``typedef`` statement which is used to create
new mappings between types and declarators.

Its acceptance will greatly enhance the Python user experience as well as
eliminate one of the warts that deter users of other programming languages from
switching to Python.


Rationale
=

Python has long suffered from the lack of explicit type declarations.  Being one
of the few aspects in which the language deviates from its Zen, this wart has
sparked many a discussion between Python heretics and members of the PSU (for
a few examples, see [EX1]_, [EX2]_ or [EX3]_), and it also made it a large-scale
enterprise success unlikely.

However, if one wants to put an end to this misery, a decent Pythonic syntax
must be found. In almost all languages that have them, type declarations lack
this quality: they are verbose, often needing *multiple words* for a single
type, or they are hard to comprehend (e.g., a certain language uses completely
unrelated [#]_ adjectives like ``dim`` for type declaration).

Therefore, this PEP combines the move to type declarations with another bold
move that will once again prove that Python is not only future-proof but
future-embracing: the introduction of Unicode characters as an integral
constituent of source code.

Unicode makes it possible to express much more with much less characters, which
is in accordance with the Zen (Readability counts.) [ZEN]_. Additionally, it
eliminates the need for a separate type declaration statement, and last but not
least, it makes Python measure up to Perl 6, which already uses Unicode for its
operators. [#]_


Specification
=

When the type declaration mode is in operation, the grammar is changed so that
each ``NAME`` must consist of two parts: a name and a type declarator, which is
exactly one Unicode character.

The declarator uniquely specifies the type of the name, and if it occurs on the
left hand side of an expression, this type is enforced: an ``InquisitionError``
exception is raised if the returned type doesn't match the declared type. [#]_

Also, function call result types have to be specified. If the result of the call
does not have the declared type, an ``InquisitionError`` is raised.  Caution: 
the
declarator for the result should not be confused with the declarator for the
function object (see the example below).

Type declarators after names that are only read, not assigned to, are not 
strictly
necessary but enforced anyway (see the Python Zen: Explicit is better than
implicit.).

The mapping between types and declarators is not static. It can be completely
customized by the programmer, but for convenience there are some predefined
mappings for some built-in types:

=  ===
Type   Declarator
=  ===
``object`` � (REPLACEMENT CHARACTER)
``int``ℕ (DOUBLE-STRUCK CAPITAL N)
``float``  ℮ (ESTIMATED SYMBOL)
``bool``   ✓ (CHECK MARK)
``complex``ℂ (DOUBLE-STRUCK CAPITAL C)
``str``✎ (LOWER RIGHT PENCIL)
``unicode``✒ (BLACK NIB)
``tuple``  ⒯ (PARENTHESIZED LATIN SMALL LETTER T)
``list``   ♨ (HOT SPRINGS)
``dict``   ⧟ (DOUBLE-ENDED MULTIMAP)
``set``∅ (EMPTY SET) (*Note:* this is also for full sets)
``frozenset``  ☃ (SNOWMAN)
``datetime``   ⌚ (WATCH)
``function``   ƛ (LATIN SMALL LETTER LAMBDA WITH STROKE)
``generator``  ⚛ (ATOM SYMBOL)
``Exception``  ⌁ (ELECTRIC ARROW)
=  ===

The declarator for the ``None`` type is a zero-width space.

These characters should be obvious and easy to remember and type for every
programmer.


Unicode replacement units
=

Since even in our modern, globalized world there are still some old-fashioned
rebels who can't or don't want to use Unicode in their source code, and since
Python is a forgiving language, a fallback is provided for those:

Instead of the single Unicode character, they can type ``name${UNICODE NAME OF
THE DECLARATOR}$``. For example, these two function definitions are equivalent::

 def fooƛ(xℂ):
 return None

and ::

 def foo${LATIN SMALL LETTER LAMBDA WITH STROKE}$(x${DOUBLE-STRUCK CAPITAL 
C}$):
 return None${ZERO WIDTH NO-BREAK SPACE}$

This is still easy to read and makes the full power of type-annotated Python

Re: [Python-Dev] Python 3000 PEP: Postfix type declarations

2007-04-01 Thread Johann C. Rocholl
Brilliant!

On 4/1/07, Georg Brandl [EMAIL PROTECTED] wrote:
  def foo${LATIN SMALL LETTER LAMBDA WITH STROKE}$(x${DOUBLE-STRUCK 
 CAPITAL C}$):
  return None${ZERO WIDTH NO-BREAK SPACE}$

 This is still easy to read and makes the full power of type-annotated Python
 available to ASCII believers.

+1

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


Re: [Python-Dev] Python 3000 PEP: Postfix type declarations

2007-04-01 Thread Gustavo Carneiro

On 4/1/07, Georg Brandl [EMAIL PROTECTED] wrote:
[...]


Example
===

This is the standard ``os.path.normpath`` function, converted to type
declaration
syntax::

 def normpathƛ(path✎)✎:
 Normalize path, eliminating double slashes, etc.
 if path✎ == '':
 return '.'
 initial_slashes✓ = path✎.startswithƛ('/')✓
 # POSIX allows one or two initial slashes, but treats three or
more
 # as single slash.
 if (initial_slashes✓ and
 path✎.startswithƛ('//')✓ and not path✎.startswithƛ('///')✓)✓:
 initial_slashesℕ = 2
 comps♨ = path✎.splitƛ('/')♨
 new_comps♨ = []♨
 for comp✎ in comps♨:
 if comp✎ in ('', '.')⒯:
 continue
 if (comp✎ != '..' or (not initial_slashesℕ and not
new_comps♨)✓ or
  (new_comps♨ and new_comps♨[-1]✎ == '..')✓)✓:
 new_comps♨.appendƛ(comp✎)
 elif new_comps♨:
 new_comps♨.popƛ()✎
 comps♨ = new_comps♨
 path✎ = '/'.join(comps♨)✎
 if initial_slashesℕ:
 path✎ = '/'*initial_slashesℕ + path✎
 return path✎ or '.'

As you can clearly see, the type declarations add expressiveness, while at
the
same time they make the code look much more professional.



 Is this supposed to be a joke?  Please tell me this isn't a real PEP.
While I'm all for allowing unicode identifiers in Python, postfix type
annotations make Python look like Perl.  And how can you claim this code is
more readable?  It certainly is _less_ readable, not more.

 I agree that Python should support type annotations, but they should be
optional and only present at the function interfaces, i.e. specify the type
in the function parameter lists, like in plain old C.

 +1 from me for allowing unicode identifiers.

 -MAXVOTE for type annotations in identifiers.

--
Gustavo J. A. M. Carneiro
The universe is always one step beyond logic.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Python 3000 PEP: Postfix type declarations

2007-04-01 Thread Gustavo Carneiro

On 4/1/07, Gustavo Carneiro [EMAIL PROTECTED] wrote:


On 4/1/07, Georg Brandl [EMAIL PROTECTED] wrote:
[...]

 Example
 ===

 This is the standard ``os.path.normpath`` function, converted to type
 declaration
 syntax::

  def normpathƛ(path✎)✎:
  Normalize path, eliminating double slashes, etc.
  if path✎ == '':
  return '.'
  initial_slashes✓ = path✎.startswithƛ('/')✓
  # POSIX allows one or two initial slashes, but treats three or
 more
  # as single slash.
  if (initial_slashes✓ and
  path✎.startswithƛ('//')✓ and not
 path✎.startswithƛ('///')✓)✓:
  initial_slashesℕ = 2
  comps♨ = path✎.splitƛ('/')♨
  new_comps♨ = []♨
  for comp✎ in comps♨:
  if comp✎ in ('', '.')⒯:
  continue
  if (comp✎ != '..' or (not initial_slashesℕ and not
 new_comps♨)✓ or
   (new_comps♨ and new_comps♨[-1]✎ == '..')✓)✓:
  new_comps♨.appendƛ(comp✎)
  elif new_comps♨:
  new_comps♨.popƛ()✎
  comps♨ = new_comps♨
  path✎ = '/'.join(comps♨)✎
  if initial_slashesℕ:
  path✎ = '/'*initial_slashesℕ + path✎
  return path✎ or '.'

 As you can clearly see, the type declarations add expressiveness, while
 at the
 same time they make the code look much more professional.


  Is this supposed to be a joke?



 /me ashamed for not having noticed the date of this PEP... :P

--
Gustavo J. A. M. Carneiro
The universe is always one step beyond logic.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Python 3000 PEP: Postfix type declarations

2007-04-01 Thread Ron Adam
Johann C. Rocholl wrote:
 Brilliant!
 
 On 4/1/07, Georg Brandl [EMAIL PROTECTED] wrote:
  def foo${LATIN SMALL LETTER LAMBDA WITH STROKE}$(x${DOUBLE-STRUCK 
 CAPITAL C}$):
  return None${ZERO WIDTH NO-BREAK SPACE}$

 This is still easy to read and makes the full power of type-annotated Python
 available to ASCII believers.
 
 +1
 
 J

This also has the advantage that any good editor with auto correct and 
completion can convert from one form to the other as you type.  A feature I 
love in my word processor because it *always* does *exactly* what I want 
and saves me much typing.

+1ℕ



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


Re: [Python-Dev] Python 3000 PEP: Postfix type declarations

2007-04-01 Thread Guido van Rossum
+18446744073709551616 from me too.

This also fits nicely in with my plan to abandon the python-dev and
python-3000 mailing lists. Mailing lists are so 20th century! I
propose that from now on, all Python development should be carried out
on blogs, so that readers can use customized RSS feeds to read only
those contributions they are interested in. I note that all the key
developers already have a blog, e.g.:

Aahz - http://www.artima.com/weblogs/index.jsp?blogger=aahz
Neal Norwitz - http://nnorwitz.blogspot.com/
Fredrik Lundh - http://effbot.org/pyref/blog.htm
Jeremy Hylton - http://www.python.org/~jeremy/weblog/
Anthony Baxter - http://codingweasel.blogspot.com/
Phillip Eby - http://dirtsimple.org/programming/index.html
Talin - http://www.advogato.org/person/Talin/diary.html
David Ascher - http://ascher.ca/blog/
Fred Drake - http://www.advogato.org/person/fdrake/diary.html

(and myself, of course - http://www.artima.com/weblogs/index.jsp?blogger=guido)

--Guido

On 4/1/07, Collin Winter [EMAIL PROTECTED] wrote:
 On 4/1/07, Georg Brandl [EMAIL PROTECTED] wrote:
 [snip several pages of excellent ideas]
 
  The mapping between types and declarators is not static. It can be 
  completely
  customized by the programmer, but for convenience there are some predefined
  mappings for some built-in types:
 
  =  
  ===
  Type   Declarator
  =  
  ===
  ``object`` � (REPLACEMENT CHARACTER)
  ``int``ℕ (DOUBLE-STRUCK CAPITAL N)
  ``float``  ℮ (ESTIMATED SYMBOL)
  ``bool``   ✓ (CHECK MARK)
  ``complex``ℂ (DOUBLE-STRUCK CAPITAL C)
  ``str``✎ (LOWER RIGHT PENCIL)
  ``unicode``✒ (BLACK NIB)
  ``tuple``  ⒯ (PARENTHESIZED LATIN SMALL LETTER T)
  ``list``   ♨ (HOT SPRINGS)
  ``dict``   ⧟ (DOUBLE-ENDED MULTIMAP)
  ``set``∅ (EMPTY SET) (*Note:* this is also for full 
  sets)
  ``frozenset``  ☃ (SNOWMAN)
  ``datetime``   ⌚ (WATCH)
  ``function``   ƛ (LATIN SMALL LETTER LAMBDA WITH STROKE)
  ``generator``  ⚛ (ATOM SYMBOL)
  ``Exception``  ⌁ (ELECTRIC ARROW)
  =  
  ===
 
  The declarator for the ``None`` type is a zero-width space.
 
  These characters should be obvious and easy to remember and type for every
  programmer.
 
 [snip]
 
  Example
  ===
 
  This is the standard ``os.path.normpath`` function, converted to type 
  declaration
  syntax::
 
   def normpathƛ(path✎)✎:
   Normalize path, eliminating double slashes, etc.
   if path✎ == '':
   return '.'
   initial_slashes✓ = path✎.startswithƛ('/')✓
   # POSIX allows one or two initial slashes, but treats three or more
   # as single slash.
   if (initial_slashes✓ and
   path✎.startswithƛ('//')✓ and not path✎.startswithƛ('///')✓)✓:
   initial_slashesℕ = 2
   comps♨ = path✎.splitƛ('/')♨
   new_comps♨ = []♨
   for comp✎ in comps♨:
   if comp✎ in ('', '.')⒯:
   continue
   if (comp✎ != '..' or (not initial_slashesℕ and not 
  new_comps♨)✓ or
(new_comps♨ and new_comps♨[-1]✎ == '..')✓)✓:
   new_comps♨.appendƛ(comp✎)
   elif new_comps♨:
   new_comps♨.popƛ()✎
   comps♨ = new_comps♨
   path✎ = '/'.join(comps♨)✎
   if initial_slashesℕ:
   path✎ = '/'*initial_slashesℕ + path✎
   return path✎ or '.'
 
  As you can clearly see, the type declarations add expressiveness, while at 
  the
  same time they make the code look much more professional.

 My only concern is that this doesn't go far enough. While knowing that
 some object is a ⒯ is a good start, it would be so much more helpful
 to know that it's a ⒯ of ✎s. I think something like ✎✎✎3⒯ to indicate
 a 3-⒯ of ✎s would be nice. This would change the line in the above
 from if comp✎ in ('', '.')⒯: to if comp✎ in ('', '.')✎✎2⒯:, which
 I think is a nice win in terms of readability, EIBTI and all that.

 (Sidebar: I think the PEP should feature a section on how these new
 type declarations will cut down on mailing list volume and
 documentation size.)

 In light of this PEP, PEP 3107's function annotations should be
 rejected. All that hippie feel-good crap about user-defined
 annotations and open-ended semantics and no rules, man was just
 going to get us into trouble. This PEP's more modern conception of
 type annotations give the language a power and expressiveness that my
 PEP could never hope to match.

 This is clearly a move in the right direction. +4 billion.

 Collin Winter