15

Why can spaces sometimes be omitted before and after key words? For example, why is the expression 2if-1e1else 1 valid?

Seems to work in both CPython 2.7 and 3.3:

$ python2
Python 2.7.3 (default, Nov 12 2012, 09:50:25) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 2if-1e1else 1
2

$ python3
Python 3.3.0 (default, Nov 12 2012, 10:01:55) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 2if-1e1else 1
2

and even in PyPy:

$ pypy
Python 2.7.2 (341e1e3821ff, Jun 07 2012, 15:42:54)
[PyPy 1.9.0 with GCC 4.2.1] on darwin
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``PyPy 1.6 released!''
>>>> 2if-1e1else 1
2
jterrace
  • 64,866
  • 22
  • 157
  • 202

1 Answers1

12

Identifiers in python are described as:

identifier ::= (letter|"_") (letter | digit | "_")* 

Hence, 2if can't be an identifier hence if must be 2,if. Similar logic applies to the rest of the expression.

Basically interpreting 2if-1e1else 1 would go something like this (the full parsing would be quite complicated):

2if not valid identifier, 2 matches digit digit ::= "0"..."9",if matches keyword. -1e1else, -1 is the unary negation (u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr) of : ( 1 which matches intpart in exponentfloat ::= (intpart | pointfloat) | exponent , e1 is exponent exponent ::= ("e" | "E") ["+" | "-"] digit+.) You can see expressions of the form Ne+|-x yields a float this from:

>>> type(2e3)
<type 'float'>

then the else is seen as the keyword, and -1 etc..

You can peruse the gammar to read more about it.

HennyH
  • 7,794
  • 2
  • 29
  • 39
  • *"...`-1` matches `intpart`..."* wait, what? Isn't `-` a unary operator? – user541686 May 14 '13 at 05:17
  • So basically, it's like this because preventing it would make the grammar/parser more complicated. – asmeurer May 14 '13 at 06:17
  • @asmeurer It's like this, because it *is* the grammar (if that makes sense) – HennyH May 14 '13 at 06:19
  • Well, duh, but I'm pretty sure the grammar didn't write itself. Every aspect of the Python language is there for reason. – asmeurer May 14 '13 at 06:28
  • Why prevent it when no sane programmer would write code like that. – Matthias May 14 '13 at 07:04
  • Even stranger because keywords can follow a letter without any space inbetween: `2jif.1jelse.1` – Armin Rigo May 14 '13 at 14:56
  • 4
    For extra fun: using `2if` in the expression is accepted, but using `2else` is not; this is probably because the latter is parsed as `2e???` with `???` being a non-number, which is a syntax error. – Armin Rigo May 14 '13 at 14:58