[Python-ideas] User-defined literals

Nick Coghlan ncoghlan at gmail.com
Sat Jun 6 01:31:09 CEST 2015


On 6 Jun 2015 01:45, "Andrew Barnert" <abarnert at yahoo.com> wrote:
>
> On Jun 5, 2015, at 05:18, Paul Moore <p.f.moore at gmail.com> wrote:
> >
> >> On 5 June 2015 at 00:03, Andrew Barnert <abarnert at yahoo.com> wrote:
> >> If it's meant to be a "compile-time decimal value"... What kind of
value is that? What ends up in your co_consts? An instance of
decimal.Decimal? How does that get marshaled?
> >
> > Well, Python bytecode has no way of holding any form of constant
> > Decimal value, so if that's what you want you need a change to the
> > bytecode (and hence the interperter). I'm not sure how that qualifies
> > as "user-defined".
>
> That's the point I was making. Nick proposed this syntax in reply to a
message where I said that being a compile-time value is both irrelevant and
impossible, so I thought he was claiming that this syntax somehow solved
that problem where mine didn't.

I was mainly replying to Paul's angle bracket syntax proposal, not
specifically to anything you proposed. The problem I have with your
original suggestion is purely syntactic - I don't *want* user-defined
syntax to look like language-defined syntax, because it makes it too hard
for folks to know where to look things up, and I especially don't want a
suffix like "j" to mean "this is a complex literal" while "k" means "this
is a different way of spelling a normal function call that accepts a single
string argument".

I didn't say anything about my preferred syntactic idea *only* being usable
for a compile time construct, I just only consider it *interesting* if
there's a compile time AST transformation component, as that lets the hook
parse a string and break it down into its component parts to make it
transparent to the compiler, including giving it the ability to influence
the compiler's symbol table construction pass. That extra power above and
beyond a normal function call is what would give the construct its
rationale for requesting new syntax - it would be a genuinely new
capability to integrate "not Python code" with the Python compilation
toolchain, rather than an alternate spelling for existing features.

I've also been pondering the idea of how you'd notify the compiler of such
hooks, since I agree you'd want them declared inline in the module that
used them. For that, I think the idea of a "bang import" construct might
work, where a module level line of the form "from x import !y" would not
only be a normal runtime import of "y", but also allow "!y(implicitly
quoted input)" as a compile time construct.

There'd still be some tricky questions to resolve from a pragmatic
perspective, as you'd likely need a way for the bang import to make
additional runtime data available to the rendered AST produced by the bang
calls, without polluting the module global namespace, but it might suffice
to pass in a cell reference that is then populated at runtime by the bang
import step.

> > We seem to be talking at cross purposes here. The questions you're
> > asking are ones I would direct at you (assuming it's you that's after
> > a compile-time value, I'm completely lost as to who is arguing for
> > what any more :-()

That confusion is likely at least partly my fault - while this thread
provided the name, the bang call concept is one I've been pondering in
various forms (most coherently with some of the folks at SciPy last year)
since the last time we discussed switch statements (and the related "once"
statement), and it goes far beyond just defining pseudo-literals.

I brought it up here, because *as a side-effect*, it would provide
pseudo-literals by way of compile time constructs that didn't have any
variable references in the generated AST (other than constructor
references).

> (Of course Python doesn't quite have _no_ compile-time computation; it
has optional constant folding. But if you try to build on top of that
without biting the bullet and just declaring the whole language accessible
at compile time, you end up with the mess that was C++03, where
compile-time code is slow, clumsy, and completely different from runtime
code, which is a large part of why we have C++11, and also why we have D
and various other languages. I don't think Python should add _anything_ new
at compile time. You can always simulate compile time with import time,
where the full language is available, so there's no compelling reason to
make the same mistake C++ did.)

Updated with the bang import idea to complement the bang calls, my vague
notion would actually involve adding two pieces:

* a compile time hook that lets you influence both the symbol table pass
and the AST generation pass (bang import & bang call working together)
* an import time hook that lets you reliably provide required data (like
references to type constructors and other functions) to the AST generated
in step 1 (probably through bang import populating a cell made available to
the corresponding bang call invocations)

Cheers,
Nick.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150606/ed2fa063/attachment.html>


More information about the Python-ideas mailing list