<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, 10 Feb 2016 at 14:21 Georg Brandl <<a href="mailto:g.brandl@gmx.net">g.brandl@gmx.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This came up in python-ideas, and has met mostly positive comments,<br>
although the exact syntax rules are up for discussion.<br>
<br>
cheers,<br>
Georg<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
PEP: 515<br>
Title: Underscores in Numeric Literals<br>
Version: $Revision$<br>
Last-Modified: $Date$<br>
Author: Georg Brandl<br>
Status: Draft<br>
Type: Standards Track<br>
Content-Type: text/x-rst<br>
Created: 10-Feb-2016<br>
Python-Version: 3.6<br>
<br>
Abstract and Rationale<br>
======================<br>
<br>
This PEP proposes to extend Python's syntax so that underscores can be used in<br>
integral and floating-point number literals.<br>
<br>
This is a common feature of other modern languages, and can aid readability of<br>
long literals, or literals whose value should clearly separate into parts, such<br>
as bytes or words in hexadecimal notation.<br>
<br>
Examples::<br>
<br>
    # grouping decimal numbers by thousands<br>
    amount = 10_000_000.0<br>
<br>
    # grouping hexadecimal addresses by words<br>
    addr = 0xDEAD_BEEF<br>
<br>
    # grouping bits into bytes in a binary literal<br>
    flags = 0b_0011_1111_0100_1110<br></blockquote><div><br></div><div>I assume all of these examples are possible in either the liberal or restrictive approaches?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
Specification<br>
=============<br>
<br>
The current proposal is to allow underscores anywhere in numeric literals, with<br>
these exceptions:<br>
<br>
* Leading underscores cannot be allowed, since they already introduce<br>
  identifiers.<br>
* Trailing underscores are not allowed, because they look confusing and don't<br>
  contribute much to readability.<br>
* The number base prefixes ``0x``, ``0o``, and ``0b`` cannot be split up,<br>
  because they are fixed strings and not logically part of the number.<br>
* No underscore allowed after a sign in an exponent (``1e-_5``), because<br>
  underscores can also not be used after the signs in front of the number<br>
  (``-1e5``).<br>
* No underscore allowed after a decimal point, because this leads to ambiguity<br>
  with attribute access (the lexer cannot know that there is no number literal<br>
  in ``foo._5``).<br>
<br>
There appears to be no reason to restrict the use of underscores otherwise.<br>
<br>
The production list for integer literals would therefore look like this::<br>
<br>
   integer: decimalinteger | octinteger | hexinteger | bininteger<br>
   decimalinteger: nonzerodigit [decimalrest] | "0" [("0" | "_")* "0"]<br>
   nonzerodigit: "1"..."9"<br>
   decimalrest: (digit | "_")* digit<br>
   digit: "0"..."9"<br>
   octinteger: "0" ("o" | "O") (octdigit | "_")* octdigit<br>
   hexinteger: "0" ("x" | "X") (hexdigit | "_")* hexdigit<br>
   bininteger: "0" ("b" | "B") (bindigit | "_")* bindigit<br>
   octdigit: "0"..."7"<br>
   hexdigit: digit | "a"..."f" | "A"..."F"<br>
   bindigit: "0" | "1"<br>
<br>
For floating-point literals::<br>
<br>
   floatnumber: pointfloat | exponentfloat<br>
   pointfloat: [intpart] fraction | intpart "."<br>
   exponentfloat: (intpart | pointfloat) exponent<br>
   intpart: digit (digit | "_")*<br>
   fraction: "." intpart<br>
   exponent: ("e" | "E") "_"* ["+" | "-"] digit [decimalrest]<br>
<br>
<br>
Alternative Syntax<br>
==================<br>
<br>
Underscore Placement Rules<br>
--------------------------<br>
<br>
Instead of the liberal rule specified above, the use of underscores could be<br>
limited.  Common rules are (see the "other languages" section):<br>
<br>
* Only one consecutive underscore allowed, and only between digits.<br>
* Multiple consecutive underscore allowed, but only between digits.<br>
<br>
Different Separators<br>
--------------------<br>
<br>
A proposed alternate syntax was to use whitespace for grouping.  Although<br>
strings are a precedent for combining adjoining literals, the behavior can lead<br>
to unexpected effects which are not possible with underscores.  Also, no other<br>
language is known to use this rule, except for languages that generally<br>
disregard any whitespace.<br>
<br>
C++14 introduces apostrophes for grouping, which is not considered due to the<br>
conflict with Python's string literals. [1]_<br>
<br>
<br>
Behavior in Other Languages<br>
===========================<br>
<br>
Those languages that do allow underscore grouping implement a large variety of<br>
rules for allowed placement of underscores.  This is a listing placing the known<br>
rules into three major groups.  In cases where the language spec contradicts the<br>
actual behavior, the actual behavior is listed.<br>
<br>
**Group 1: liberal (like this PEP)**<br>
<br>
* D [2]_<br>
* Perl 5 (although docs say it's more restricted) [3]_<br>
* Rust [4]_<br>
* Swift (although textual description says "between digits") [5]_<br>
<br>
**Group 2: only between digits, multiple consecutive underscores**<br>
<br>
* C# (open proposal for 7.0) [6]_<br>
* Java [7]_<br>
<br>
**Group 3: only between digits, only one underscore**<br>
<br>
* Ada [8]_<br>
* Julia (but not in the exponent part of floats) [9]_<br>
* Ruby (docs say "anywhere", in reality only between digits) [10]_<br>
<br>
<br>
Implementation<br>
==============<br>
<br>
A preliminary patch that implements the specification given above has been<br>
posted to the issue tracker. [11]_<br></blockquote><div><br></div><div>Is the implementation made easier or harder if we went with the Group 2 or 3 approaches? Are there any reasonable examples that the Group 1 approach allows that Group 3 doesn't that people have used in other languages?</div><div><br></div><div>I'm +1 on the idea, but which approach I prefer is going to be partially dependent on the difficulty of implementing (else I say Group 3 to make it easier to explain the rules).</div><div><br></div><div>-Brett</div></div></div>