[Python-ideas] Custom string prefixes

Eric Snow ericsnowcurrently at gmail.com
Thu May 30 07:21:57 CEST 2013


On Mon, May 27, 2013 at 7:13 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> Welcome, and I admire your bravery!

+1

> So please don't take it personally when
> I say, your idea does not sound very good to me. In fact, it sounds
> terrible. You call this proposal "custom string prefixes", but what you
> describe is actually a second way to call a function, only not any function,
> but just functions that take a single string argument. So more like a
> function call that looks like a string.
>
> Let me start with your example:
>
>
>
>>          >>> from decimal import Decimal as D
>>          >>> D ("1.6e-9") * D ("1.0e9")
>>
>>      but I'd enounce that the following is more concise and readable:
>>
>>          >>> D"1.6e-9" * D"1.0e9"
>>
>>      with removed parens.
>
>
> Just to save a couple of parentheses, you add a lot of complication to the
> language, make it harder for people to learn, and for no real benefit except
> to save a few keystrokes. Consider:
>
> String prefixes are currently part of Python's syntax, and can operate at
> compile-time. With your proposal, they become run-time operations, like any
> function call. So this is redundant: we already have a perfectly good way of
> calling functions. Not just redundant, but also very limited, because most
> functions take more than one argument, or non-string arguments.
>
> Do you have any idea how you would implement this change? Do you at least
> have an idea for the API? What commands would the user give to define a new
> "string prefix"? How would the user query the "string prefixes" already
> defined? What happens when they combine multiple prefixes?
>
> Python is famous for being "executable pseudo-code". To a very large degree,
> code written in Python should be readable by people who are not Python
> programmers. What do you think
>
> s"ham"
>
> will mean to the reader? I think that it is better to encourage people to
> write meaningful names:
>
> make_sandwich("ham")
>
> than trying to save every last keystroke possible. Code is written once, but
> read over and over again. That half a second you save by typing s"ham" will
> cost other people dozens of seconds, maybe minutes, each time them read your
> code.

Spot on.  The language needs to fit in our brains and you could argue
that we've already pushed past that threshold.  One concern I'd have
is in how you would look up what some arbitrary prefix is supposed to
do.  Furthermore, it sounds like the intent is to apply the prefix at
run-time.  That means that the function that gets applied depends on
what's in some registry at a given moment.  So source with these
custom string prefixes will be even more ambiguous when read.

I agree that one should just use the function rather than the prefix.
I'd expect the prefix handler to not be stateful, in which case it
truly would be a functional operation, always giving the same output
for a given literal string input.  In that case, why not just call the
function at the module scope, bind the result to a name there, and use
that name wherever you like.  It's effectively a constant, right?

Now, give a twist to this idea of some stable `literal -> contstant`
operation. Consider a new syntax or built-in function for indicating
that, at compile-time, an expression should be considered equivalent
to the literal to which it evaluates.  Then the compiler would be free
to substitute the literal for the expression and store the literal in
the bytecode/constants/pyc file.  From then on that expression would
not be evaluated at run-time anymore.  Of course, the expression would
have to be entirely literal-based and evaluate to a literal.

The catch is that the compiler would have to evaluate the expression,
which would probably add disproportionate complexity to the compiler.
The other catch is that, due to how dynamic Python is, any given
expression could evaluate differently at run-time (e.g. someone
monkey-patches str.__add__ or some other function you are calling on a
string literal).  Ultimately this probably isn't worth it.  Just
evaluate the expression at module level so it's only evaluated once at
import-time and move on.  If it's really expensive, pre-calculate the
equivalent literal and stick that in your source (along with a comment
on how the literal was generated).

Well, that was diverting.

-eric


More information about the Python-ideas mailing list