[Python-ideas] Reducing colon uses to increase readability

Leif Walsh leif.walsh at gmail.com
Mon Jun 30 23:34:07 CEST 2008


On Sun, Jun 29, 2008 at 6:41 PM, Andre Roberge <andre.roberge at gmail.com> wrote:
> In Python, the humble colon (:) has multiples uses:
>
> 1. as a signal to indentation increase, signaling a block of code, such as
[snip]
> However, the colon has also some other uses.
>
> 2. in slices [a:b:c]

I agree this isn't the clearest it could be.

> 3. in dict assignments {a:b}

This mirrors a number of existing languages, including English, and,
more or less (depending on your priorities) important, JSON.  It's
always been comforting that valid Python structures (in fact, simply
printed) are instantly valid JSON (for the most part...with ints and
strings and such).

> 4. in lambda assignments  (lambda x: x+1)

This (correctly) mirrors a standard function definition.  the only way
it could be closer is with something like lambda(x): x+1, but then
this is not what's up for debate.

> I would argue that, in these last three examples, there might be better choices.
> (some of these choices have been inspired by reading
> http://www.resolversystems.com/documentation/index.php/Differences_Between_Resolver_One%27s_Formula_Language_and_Python_Expressions)

Are you suggesting this because you work with both languages?  This
e-mail seems a bit self-serving, because of the inclusion of someone's
in-house language spec.

> Slices:
> ---------
>
> I would argue that, the usual slicing notation would be more readable
> if it were as follows:
>
> [a -> b; c]
>
> Thus
> [1:10:2] would become [1 -> 10; 2]
> [1:10]  would become [1 -> 10]
>
> The "shorter" combinations would not gain in terms of readability;
> they would be as follows:
>
> [ :10 : 2] would become [10; 2]
> [ :10]  would become [10;]
> [:: -1] would become [; -1]
> [:] would become [;]
>
>
> If such a change were to be made, an second slicing notation, *with a
> different meaning*,  could be introduced:
>
> [a => b; c]
>
> This would be an inclusive range, i.e.
>
> [a => b] is equivalent to [a -> b+1]

I am always very wary of multiple-character symbols.  They are harder
to type, harder to read, harder to parse (in a compiler or an editor),
and open the language up to an unbounded number of (dare I say it?)
Perlisms.

That said, I'm not sure 'arrows' are even the right approach for
slices.  Slices should be thought of as ranges, which usually lend
themselves to ellipses.  I remember (loosely, from a long time ago)
Ruby having '..' and '...' as exclusive and inclusive ranges, and I
really liked that.

With regard to the third item in a slice, the increment value, I
almost never use it, because it seems to make code a lot harder to
read clearly.  If I feel the need to use it, it's usually a good
indicator that I need to restructure my code, and if it's absolutely
necessary, I'll typically just iterate over the list with a for loop
so that I can understand what I was doing when I come back.

If my half-suggestion of ellipses were taken up, I'd say that the
colon could stay as the separator between the second and third
arguments (and, as someone said already, the semi-colon introduces
some weird parsing problems and possible ambiguities).

> dict assignments
> ------------------------
>
> Here again, I would argue that using "->" instead of ":" would make
> the code more readable - at least for beginners.
>
> numbers = {'one' -> 1, 'two' -> 2}  instead of
> numbers = {'one': 1, 'two': 2}

Like I said before, the colon is a widely-accepted way to separate
keys and values in a dict.  The only strange case I can see with this
is something like:

functions = {'plus': lambda x, y: x+y, 'minus': lambda x, y: x-y}

In fact, I'm not sure if this _is_ legal python, so before running it,
I'd just parenthesize out the lambda expressions to be sure anyway,
and this clears everything up nicely:

functions = {'plus': (lambda x, y: x+y), 'minus': (lambda x, y: x-y)}

> lambda assignments
> ---------------------------
>
> Once again, same choice.
>
> lambda x -> x+1
> is, I think, more readable than
> lambda x: x+1
>
> (but perhaps the last two [dicts and lambda] largely depends on the
> font choice...)

As a pseudo-mathematician (and a recent student of Erlang), this is
quite appealing, for a few reasons.

First, let me say that the obvious "f(x) -> x**2 shows up all over
math" is not the correct reason to say this is correct notation for
functions.  Python functions are procedures, not expressions (as they
are in Erlang and Haskell, where the arrow-notation is commonplace).
As such, a colon separating the function's name from its definition
makes perfect sense, as this is the way we write English all the time,
and I've seen more than one professor write pseudocode just like this.
 However, lambda functions _are_ single-expressions, not blocks.  This
leads me to believe that the arrow could be a good delimiter (except
for my above statement that multiple-character symbols suck).
Unfortunately for the arrow, it seems that priority in Python syntax
is given to consistency within itself, rather than consistency with
the outside world, so the fact that "lambda x: x**2" is consistent
with "def sq(x): x**2" probably pulls more weight.

Let me just say that putting something like the arrow (especially if
we ever allow non-ASCII characters into the syntax) in lambda
expressions would not be totally distasteful to me.

> ======
> Other considerations:
>
> If "->" were to be adopted for dict or lambda assignments, then the
> "naturalness" of their choice for slices would be reduced.  An
> alternative might be inspired from the mathematical notation
>
> [a, ..., b; c]
>
> I realize that this is "much" longer than [a: b: c].
>
> Final comment:
>
>  I have seen other alternatives for simple slices suggested in the past such as
> [a..b] and [a...b] which would be the equivalent of [a->b] and [a=>b];
> however, the extra "." might sometimes be difficult to read, whereas
> the difference between "->" and "=>" is much easier to see.

You're right.  This is one of the reasons I hate Ruby.  Yet another
reason to ignore your suggestion for slices :-).

-- 
Cheers,
Leif



More information about the Python-ideas mailing list