[Python-3000] programmable syntax (was ... #4: interpolated strings ala perl)

Jim Jewett jimjjewett at gmail.com
Mon Dec 11 21:37:37 CET 2006


On 12/6/06, Jan Grant <jan.grant at bristol.ac.uk> wrote:

> Thank-you: I agree with pretty much everything you say. It's an
> interesting question to ask, "can one construct a convenient
> interpolation mechanism that uses the appropriate application quoting
> mechanisms where necessary?"

Since we don't know what environments will be needed (let alone their
appropriate quoting needs), the answer for builtins (including str) is
no.

What we can do is make it a bit easier (or more idiomatic) to write
domain-specific interpolators.  Doing this without risking the chaos
available to macros or programmable syntax is trickier.

> I think the question here is, is there a safe, convenient way that
> Python can determine what to do (or be told what to do) when it sees:

>         s = "some string here with {variable} in it"

No, there isn't.  Using "%" (or "\", or "{...}" as magic just
hardcodes specific implementation choices that happen to work fairly
often.

What could work is

    s = MyDomainStr("some string here with {variable} in it")

where MyDomainStr could very well be a subclass of str that just
overrides % (orthe proposed format method)

It *might* seem more natural if % was no longer associated with
strings, but with Templates.  (And I suppose str could
implement/inherit from Templates as a convenience, so long as the
concepts were separated.)

    s = Template("some string with %s in it")

There really isn't any need to store the literal characters, including "%s".

There is a need to store ("some string with ", <placeholder>, " in
it"), but pretending that this object is a (conceptual) string just
confuses things.


> PS. IF generic functions (operators) could be sensitive to return types
> and IF python6k supported a complex type inference mechanism (possibly
> including automatic coercion),

This really doesn't need to wait even for py3K.  CPython happens to
compile to bytecode, but there isn't anything in the language (except
possibly threading interactions) which automatically prevents an
optimizing compiler.  (Generally optimizing -- messing with builtins
or other modules would be worse than today.)

> then one might be able to do something like:
>
> def foo(d: sqlDriver):
>   s = "select template goes here" % (param1, param2)
>   r = d.query(s)
>
> where sqlDriver has a method
>
> def query(self, s: some_type_that_signals_sql_interpolation)
>
> and "%" is overloadable on the basis that the return type is determined
> to be compatible with "some_type_that_signals_sql_interpolation". Those
> are some mighty big "IF"s though, and you could still concoct cases
> where things would break :-)

I think you want

    def foo(d: sqlDriver):
        s = SQLTemplate("select template goes here", args=(param1, param2))
        r = d.query(s)

The exact quoting mechanism would depend on the specific sqlDriver.
Asking a SQLTemplate to store the constant portions is reasonable.
Asking it to store a reference to specific parameters may be
reasonable.  Asking a sqlDriver to know its own quoting conventions is
reasonable.

Asking the compiler to secretly replace str literals with
arbitrarily-classed objects which know to override the % method to
something whose specification may be changed even after the object is
created ... is fragile.

-jJ


More information about the Python-3000 mailing list