Re: string interpolation for python

Discussion in 'Python' started by Yingjie Lan, Apr 2, 2012.

  1. Yingjie Lan

    Yingjie Lan Guest

    > You can already do essentially that without adding a special-case string 

    > formatting method to the general methods we already have.
    >
    >>>> balls = 5
    >>>> people = 3
    >>>> 'The {people} people have{balls}

    > balls.'.format(**locals())
    > 'The 3 people have 5 balls.'



    Clearly dynamic strings are much more powerful,
    allowing arbitrary expressions inside. It is also
    more terse and readable, since we need no dictionary.

    I would probably rather liken dynamic expressions
    as a little brother of computable documents in 
    Mathematica. It is a newkind of expression,
    rather than formatting -- though it has formatting
    connections. 

    Dynamic strings are mainly useful at time of
    writing readable code before compilation. 
    The compiler can choose to convert it into
    a string formatting expression, of course.
    To efficiently format strings at runtime, 
    the best choice (especially
    for safty reasons) is string formatting, 
    not evaluating a dynamic string.

    On the implementation, I would suppose new 
    syntax is needed (though very small).

    Yingjie
     
    Yingjie Lan, Apr 2, 2012
    #1
    1. Advertising

  2. Yingjie Lan writes:

    > Clearly dynamic strings are much more powerful,
    > allowing arbitrary expressions inside. It is also
    > more terse and readable, since we need no dictionary.

    ....
    > On the implementation, I would suppose new 
    > syntax is needed (though very small).


    I don't think you need any new syntax to implement this.
    You can use a syntax like Dynamite("Hello, $world$") now,
    similar to fraction.Fraction:

    >>> Fraction(3,4) + 1

    Fraction(7, 4)

    No special syntax there, yet it can be done.
     
    Jussi Piitulainen, Apr 2, 2012
    #2
    1. Advertising

  3. On Mon, 02 Apr 2012 00:39:42 -0700, Yingjie Lan wrote:

    >> You can already do essentially that without adding a special-case
    >> string

    >
    >> formatting method to the general methods we already have.
    >>
    >>>>> balls = 5
    >>>>> people = 3
    >>>>> 'The {people} people have {balls}

    >> balls.'.format(**locals())
    >> 'The 3 people have 5 balls.'

    >
    >
    > Clearly dynamic strings are much more powerful, allowing arbitrary
    > expressions inside.


    And so it may be a security risk, if user-input somehow ends up treated
    as a dynamic string.

    We already have three ways to evaluate arbitrary expressions:

    * Python code
    * eval
    * exec

    Why do we need yet another one?


    > It is also more terse and readable, since we need no
    > dictionary.


    I think you mean terse and unreadable, since we need no dictionary. That
    means that variables will be evaluated by magic from... where? Globals?
    Local scope? Non-local scope? All of the above?

    We already have one way of evaluating implicit variables using implicit
    rules, namely regular Python code. Why do we need a second one?


    > I would probably rather liken dynamic expressions as a little brother of
    > computable documents in Mathematica. It is a new kind of expression,
    > rather than formatting -- though it has formatting connections.


    Why do we need a new kind of expression?


    > Dynamic strings are mainly useful at time of writing readable code
    > before compilation.


    What does that mean?


    > The compiler can choose to convert it into a string
    > formatting expression, of course. To efficiently format strings at
    > runtime, the best choice (especially
    > for safty reasons) is string formatting, not evaluating a dynamic
    > string.


    So you're suggesting that we should have dynamic strings, but not
    actually use dynamic strings. The compiler should just convert them to
    regular string formatting.

    Why not cut out the middle-man and just use regular string formatting?



    --
    Steven
     
    Steven D'Aprano, Apr 2, 2012
    #3
  4. On Mon, Apr 2, 2012 at 6:26 PM, Steven D'Aprano
    <> wrote:
    > On Mon, 02 Apr 2012 00:39:42 -0700, Yingjie Lan wrote:
    >> The compiler can choose to convert it into a string
    >> formatting expression, of course. To efficiently format strings at
    >> runtime, the best choice (especially
    >> for safty reasons) is string formatting, not evaluating a dynamic
    >> string.

    >
    > So you're suggesting that we should have dynamic strings, but not
    > actually use dynamic strings. The compiler should just convert them to
    > regular string formatting.
    >
    > Why not cut out the middle-man and just use regular string formatting?


    Actually, this sounds like a job for a precompiler/preprocessor. Do
    whatever translations you want on your code, then turn it into a .py
    file for execution. But hardly necessary, as there are already two -
    err, three, I stand corrected - perfectly good ways to do it.

    ChrisA
     
    Chris Angelico, Apr 2, 2012
    #4
  5. Yingjie Lan

    Yingjie Lan Guest

    ----- Original Message -----
    > From: Steven D'Aprano <>
    > To:
    > Cc:
    > Sent: Monday, April 2, 2012 4:26 PM
    > Subject: Re: string interpolation for python
    >
    > On Mon, 02 Apr 2012 00:39:42 -0700, Yingjie Lan wrote:
    >
    >>> You can already do essentially that without adding a special-case
    >>> string

    >>
    >>> formatting method to the general methods we already have.
    >>>
    >>>>>>   balls = 5
    >>>>>>   people = 3
    >>>>>>   'The {people} people have {balls}
    >>> balls.'.format(**locals())
    >>> 'The 3 people have 5 balls.'

    >>
    >>
    >> Clearly dynamic strings are much more powerful, allowing arbitrary
    >> expressions inside.

    >
    > And so it may be a security risk, if user-input somehow ends up treated
    > as a dynamic string.
    >
    > We already have three ways to evaluate arbitrary expressions:
    >
    > * Python code
    > * eval
    > * exec
    >
    > Why do we need yet another one?
    >
    >
    >> It is also more terse and readable, since we need no
    >> dictionary.

    >
    > I think you mean terse and unreadable, since we need no dictionary. That
    > means that variables will be evaluated by magic from... where? Globals?
    > Local scope? Non-local scope? All of the above?
    >
    > We already have one way of evaluating implicit variables using implicit
    > rules, namely regular Python code. Why do we need a second one?
    >
    >
    >> I would probably rather liken dynamic expressions as a little brother of
    >> computable documents in Mathematica. It is a new kind of expression,
    >> rather than formatting -- though it has formatting connections.

    >
    > Why do we needa new kind of expression?
    >
    >
    >> Dynamic strings are mainly useful at time of writing readable code
    >> before compilation.

    >
    > What does that mean?
    >
    >
    >> The compiler can choose to convert it into a string
    >> formatting expression, of course. To efficiently format strings at
    >> runtime, the best choice (especially
    >> for safty reasons) is string formatting, not evaluating a dynamic
    >> string.

    >
    > So you're suggesting that we should have dynamic strings, but not
    > actually use dynamic strings. The compiler should just convert them to
    > regular string formatting.
    >
    > Why not cut out the middle-man and just use regular string formatting?
    >



    I believe non of the other three alternatives are as terse and readable.
    We've got template based, formattingwith dict, formatting with tuple.
    They all require the coder extra effort:

    Both template based and dict-based formatting require writing the
    identifier three times:

    >>> name = 'Peter'
    >>> "Are you %(name)s"%{'name':name}

     
    If dynamic string is used:
    >>> "Are you $name$?"


    Template:
    >>> Template("Are you $name?").substitute(name=name)


    It is three to one in compactness, what a magic 3!

    Of course, the old C style way:

    >>> "Are you %s?"%name


    Almost as terse, but not as readable, especially
    when there are many parts to substitute --
    thecoder and reader need to be careful 
    to make sure the sequence is correct.

    Why the Python community is so
    hostile to new things now? 
    Python has merits,
    but it is far from being perfect.

    Cheers,
    Yingjie
     
    Yingjie Lan, Apr 2, 2012
    #5
  6. Yingjie Lan

    Yingjie Lan Guest

    > Actually, this sounds like a job for a precompiler/preprocessor. Do

    > whatever translations you want on your code, then turn it into a .py
    > file for execution. But hardly necessary, as there are already two -
    > err, three, I stand corrected - perfectly good ways to do it.



    Agree and disagree. 

    The other ways are not perfectly good.
    They stinks in Python. 
    This new way is the most natural way.
    Effortless, natural.That's my Python.

    Cheers,
    Yingjie
     
    Yingjie Lan, Apr 2, 2012
    #6
  7. On Mon, Apr 2, 2012 at 7:11 PM, Yingjie Lan <> wrote:
    > I believe non of the other three alternatives are as terse and readable.
    > We've got template based, formatting with dict, formatting with tuple.
    > They all require the coder extra effort:
    >
    > Both template based and dict-based formatting require writing the
    > identifier three times:
    >
    >>>> name = 'Peter'
    >>>> "Are you %(name)s"%{'name':name}

    >
    > If dynamic string is used:
    >>>> "Are you $name$?"


    Yes, it's more compact. But it's also more magic. However, there's an
    alternative that's almost as compact. The only requirement is that you
    use a two-character token instead of your dollar sign: a double-quote
    and a plus.

    >>> "Are you "+name+"?"


    That allows arbitrary expressions and everything.

    > Of course, the old C style way:
    >
    >>>> "Are you %s?"%name

    >
    > Almost as terse, but not as readable, especially
    > when there are many parts to substitute --
    > the coder and reader need to be careful
    > to make sure the sequence is correct.


    I quite like this notation, personally. It's convenient, and is
    supported (with variants) in quite a few C-derived languages (and, in
    spite of the massive syntactic differences, Python does have C
    heritage).

    > Why the Python community is so
    > hostile to new things now?
    > Python has merits,
    > but it is far from being perfect.


    Hey now, no need to get defensive :) Thing is, it's up to you to
    demonstrate that your proposal justifies itself. You're proposing to
    create a massive backward-compatibility issue, so you need to prove
    that your new way of formatting strings is sufficiently awesome to be
    able to say "Well, you need Python 3.4+ to use this".

    ChrisA
     
    Chris Angelico, Apr 2, 2012
    #7
  8. Yingjie Lan

    Chris Rebert Guest

    On Mon, Apr 2, 2012 at 2:11 AM, Yingjie Lan <> wrote:
    <snip>
    > I believe non of the other three alternatives are as terse and readable.
    > We've got template based, formatting with dict, formatting with tuple.
    > They all require the coder extra effort:
    >
    > Both template based and dict-based formatting require writing the
    > identifier three times:


    False. Only once is required, though the technique to achieve it is kinda hacky.

    >>>> name = 'Peter'
    >>>> "Are you %(name)s"%{'name':name}


    "Are you %(name)s" % locals() # or vars()

    > If dynamic string is used:
    >>>> "Are you $name$?"

    >
    > Template:
    >>>> Template("Are you $name?").substitute(name=name)


    Template("Are you $name?").substitute(locals()) # or vars()

    > It is three to one in compactness, what a magic 3!

    <snip>
    > Why the Python community is so
    > hostile to new things now?


    It's more conservative than hostile. Here's some insight:
    http://www.boredomandlaziness.org/2011/02/status-quo-wins-stalemate.html

    Personally, in isolation, the only part of your proposal I find
    /truly/ objectionable is the support for arbitrary expressions, since
    it would tend towards encouraging suboptimal factoring. But we also
    don't live in an ideal world, so the existence of the other 3 (2 of
    them particularly relatively similar) alternatives is a legitimate
    practical concern when evaluating your proposal. Python is
    middle-aged; it's a blessing and a curse.

    Cheers,
    Chris
     
    Chris Rebert, Apr 2, 2012
    #8
  9. Yingjie Lan

    Yingjie Lan Guest



    >>>> "Are you "+name+"?"

    >
    > That allows arbitrary expressions and everything.


    To make that work for any type, you need:

    >>> "Are you "+ str(name) + "?"


    Another concern is performance.

    You are absolutely right, they are 
    equivalent in that both are expressions.
    As long as people start to realize that
    dynamic strings areexpressions,
    there is no magic in it any more.

    And allowing expressions in those
    dynamic strings would make sense 
    since they are ofthe same sort.

    >>> d"sin($x$) = $ sin(x):0.3f $"


    is equivalentto the expression of

    >>> "sin(%s"%x + ")= %0.3f"%sin(x)


    Comparing th e two, I would say the latter
    is more computer friendly while 
    the former, more human friendly.

    If the computed result is only to be
    used in formatting the string, it would
    be nice to save an assignment stmt.


    >>
    >> Almost as terse, but not as readable, especially
    >> when there are many parts to substitute --
    >> the coder and reader need to be careful
    >> to make sure the sequence is correct.

    >
    > I quite like this notation, personally. It's convenient, and is
    > supported (with variants) in quite a few C-derived languages (and, in
    > spite of the massive syntactic differences, Python does have C
    > heritage).


    Sure, once you get used to it, it would be harder to stop it
     theharder it is :). That's part of human nature, anyway.


    >> Why the Python community is so
    >> hostile to new things now?
    >> Python has merits,
    >> but it is far from being perfect.

    >
    > Hey now, no need to get defensive :) Thing is, it's up to you to
    > demonstrate that your proposal justifies itself. You're proposing to
    > create a massive backward-compatibility issue, so you need to prove
    > that your new way of formattingstrings is sufficiently awesome to be
    > able to say "Well, you need Python 3.4+ to use this".
    >



    OK. I have put it out as is. I trust people knows good things.

    I would simply say: this new way is much more simple 
    and much more powerful. And there is no security issues
    as long as you don't use the evil eval to evaluate expressions,
    which is alwaysa security issue.

    It is new, and has no compatibility issues with oldways at all.
    In syntax, all you need is to allow d"...", which clearly won't
    affect any old ways of business.

    Cheers,

    Yingjie
     
    Yingjie Lan, Apr 2, 2012
    #9
  10. On Mon, 02 Apr 2012 02:11:46 -0700, Yingjie Lan wrote:


    > Both template based and dict-based formatting require writing the
    > identifier three times:


    > >>> name = 'Peter'
    > >>> "Are you %(name)s"%{'name':name}


    They don't *require* this at all.

    "Are you %s" % name

    For trivial examples, you have trivial syntax. For more complex examples,
    you have a more powerful system: % can accept *any* dictionary, so you
    aren't limited to just pre-existing variables.

    That, by the way, is perhaps the biggest problem with this idea of
    dynamic strings: not that it is too powerful, but that it is TOO WEAK. It
    can only retrieve names from a single namespace, and the programmer has
    no control over which namespace that will be. The only way to feed named
    values into the dynamic string is by creating variables.

    With existing formatting systems, the programmer has complete control
    over what names get used. You can set up a series of separate namespaces
    and choose between them as needed:

    a = dict(name="Fred", job="butcher")
    b = dict(name="Sue", job="SAS sharp-shooter")
    c = dict(name="Mary", job="brain surgeon")
    d = dict(name="Tony", job="enforcer for the Russian mob")
    for namespace in (a, b, c, d):
    print ("%(name)s works as a %(job)s." % namespace)


    Using your dynamic strings:

    for namespace in (a, b, c, d):
    name = namespace["name"]
    job = namespace["job"]
    print ("$name$ works as a $job$.")

    and it has the side-effect that it has created some variables that are no
    longer needed.

    Also notice that because you have to create variables first, the dynamic
    string actually requires you to write the identifier MORE times, not
    fewer.

    So your proposal is actually weaker than what Python already has. So why
    bother? All this does is add more things to learn, more complexity in the
    compiler and parser, for what? Things that you can already do.


    > If dynamic string is used:
    > >>> "Are you $name$?"


    And where does name come from? It's all too magical. With the existing
    format strings, the programmer has *complete* control of where it comes
    from:

    "Are you %(name)s?" % locals() # from a local variable `name`
    "Are you %(name)s?" % globals() # from a global variable `name`
    "Are you %(name)s?" % namespace # from any namespace you like

    and similar for both format() and Template.


    --
    Steven
     
    Steven D'Aprano, Apr 2, 2012
    #10
  11. Yingjie Lan

    Yingjie Lan Guest

    > "Are you %(name)s" % locals() # or vars()



    This partly solves the problem, however, you 
    can't work with expressions inside, like:

    > d"sin($x$) = $sin(x)$"



    Also, what if locals() or vars() doesnot contain
    the variable "x"? (x could be nonlocal or global).


    >It's more conservative than hostile. Here's some insight:
    > http://www.boredomandlaziness.org/2011/02/status-quo-wins-stalemate.html
    >


    You are probably right...Harmless enhancement is still probable?



    > Personally, in isolation, the only part of your proposal I find
    > /truly/ objectionable is the support for arbitrary expressions, since
    > it would tend towards encouraging suboptimal factoring. But we also


    I don't quite see that as a problem. The compiler (or translator, as you 
    mentioned earlier) could easily make d"sin($x$) = $sin(x)$" into
    somethinglike: ''.join(["sin(", str(x), ") = ", str(sin(x))]
    which would far more efficient than calling the format() method.

    Cheers,
    Yingjie
     
    Yingjie Lan, Apr 2, 2012
    #11
  12. Yingjie Lan

    Yingjie Lan Guest

    ....
    > That, by the way, is perhaps the biggest problem with this idea of 


    > dynamic strings: not that it is too powerful, but that it is TOOWEAK. 

    ...
    > and similar for both format() and Template.



    Seems you miss understood my notion of dynamic string.
    Dynamic strings are expressions in disguise: the things
    in between $...$ are plain old expressions (with optional 
    formatting specifications). They are evaluated
    as if they were outside the dynamic string. We put them
    in there to to kill two birds with one stone: 
       1) ease of reading;
       2) place holding.

    Cheers,
    Yingjie
     
    Yingjie Lan, Apr 2, 2012
    #12

  13. > Seems you miss understood my notion of dynamic string.
    > Dynamic strings are expressions in disguise: the things
    > in between $...$ are plain old expressions (with optional
    > formatting specifications). They are evaluated
    > as if they were outside the dynamic string. We put them
    > in there to to kill two birds with one stone:
    > 1) ease of reading;
    > 2) place holding.



    like this one ?

    b = dict(name="Sue", job="SAS sharp-shooter")
    print "$b['name']$ works as b['job']"

    Is it really easier to read that the following ?
    "{0} works as {1}".format(b['name'],b['job'])

    In the case in which b is an object having "job" and "name" attribute,
    the dynamic string will write

    "$b.name$ works as $b.job$"
    instead of
    "{0}.name works as {0}.job".format(b)

    Laurent
     
    Laurent Claessens, Apr 2, 2012
    #13
  14. Yingjie Lan

    rusi Guest

    On Apr 2, 2:11 pm, Yingjie Lan <> wrote:
    > Almost as terse, but not as readable, especially...


    Hi Yingjie,
    Just in case you are not a native speaker of English, 'terse' is a
    mildly pejorative word, ie it is not 'good'. You probably want to use
    something like 'concise', or just plain 'short.'

    As for your suggestion, Ive nothing much to say: It probably comes
    from a perl culture and who is to way which culture is better? Not me
    anyway, whenever I look at perl code my head spins...

    [No flaming here -- I just dont know perl]
     
    rusi, Apr 2, 2012
    #14
  15. Yingjie Lan

    Yingjie Lan Guest

    > like this one ?

    >
    > b = dict(name="Sue", job="SAS sharp-shooter")
    > print "$b['name']$ works as b['job']"
    >
    > Is it really easier to read that the following ?
    > "{0} works as {1}".format(b['name'],b['job'])
    >
    > In the case in which b is an object having "job" and "name"
    > attribute, the dynamic string will write
    >
    > "$b.name$ works as $b.job$"
    > instead of
    > "{0}.name works as {0}.job".format(b)
    >



    When you already have a dict, the dict-based
    formatting would be nice.

    >>> "%(name)s works as %(job)s"%b


    If it you need to create a dict just for string

    formatting, dynamic string would be nice.
    Say your object has methods/properties
    that fetch things from your database.

    >>> class staff:

    ...@property
    ...def name(): return 'Peter'
    ...
    >>> t = staff()
    >>> vars(t)

    {}
    >>> t.name

    'Peter'
    >>> d"Staff name: $t.name$" #note the d"..." format

    'Staff name: Peter'

    Because of the d"..." format, it won't 
    affect old ways of doing things one bit.
    Allowing dynamic string wouldn't hurt 
    a bit to anything that is already there.
     
    Yingjie Lan, Apr 2, 2012
    #15
  16. Yingjie Lan

    Guest

    Yingjie Lan wrote:
    > Seems you miss understood my notion of dynamic string.
    > Dynamic strings are expressions in disguise: the things
    > in between $...$ are plain old expressions (with optional
    > formatting specifications). They are evaluated
    > as if they were outside the dynamic string.

    In that case you should re-think the delimiters, so that you have something
    that can be nested. An example (example only, I'm not in love with it as a
    final form):

    "A string that gets %(count*spacer%) in the middle"

    "A string that gets %(count*%(spacer%)%) in the middle"

    Mel.
     
    , Apr 2, 2012
    #16
  17. On Mon, Apr 2, 2012 at 9:46 PM, Yingjie Lan <> wrote:
    >>>>>  "Are you "+name+"?"

    >>
    >> That allows arbitrary expressions and everything.
    >>

    >
    > To make that work for any type, you need:
    >
    >>>> "Are you "+ str(name) + "?"

    >
    > Another concern is performance.
    >
    > You are absolutely right, they are
    > equivalent in that both are expressions.


    Right, meaning that both have the same issues of performance, need for
    str(), etc. There's absolutely no difference.

    > As long as people start to realize that
    > dynamic strings are expressions,
    > there is no magic in it any more.


    And no benefit. You lose out on syntax highlighting in your editor and
    gain nothing.

    > And allowing expressions in those
    > dynamic strings would make sense
    > since they are of the same sort.
    >
    >>>> d"sin($x$) = $ sin(x):0.3f $"

    >
    > is equivalent to the expression of
    >
    >>>> "sin(%s"%x + ")= %0.3f"%sin(x)

    >
    > Comparing th e two, I would say the latter
    > is more computer friendly while
    > the former, more human friendly.


    The former is more magical, the second is more explicit. Computers do
    tend to like the explicit, but I wouldn't assume that humans like the
    magical *necessarily*. There are times when we prefer the explicit,
    too.

    > Sure, once you get used to it, it would be harder to stop it
    >  the harder it is :). That's part of human nature, anyway.


    Maybe. But it (percent-notation) is expressive and insanely powerful.
    Moreover, it obeys the rule that you pay for the complexity you use,
    no more and no less. (Although I think there's one lack in Python's
    implementation - I can't find a way to use an argument more than once,
    without switching to "dictionary mode" and using keys for everything.
    I can't, for instance, use "Hello hello, %s %[0]s!"%name to use the
    name twice. But since that isn't in the original C implementation,
    it's hardly mandatory.)

    Some implementations go even further than Python's does and allow an
    array notation.

    sprintf("UPDATE tablename SET modified=now()%{,%s=:%[0]s%} WHERE
    key=%d",array_of_field_names,primary_key_value)
    --> "UPDATE tablename SET modified=now(),foo=:foo,bar=:bar,quux=:quux
    WHERE key=1234"

    You're still paying for no complexity you aren't actually using. It's
    clear and readable.

    > I would simply say: this new way is much more simple
    > and much more powerful. And there is no security issues
    > as long as you don't use the evil eval to evaluate expressions,
    > which is always a security issue.


    It's powerful only if you use eval to allow full expression syntax.
    Otherwise, what does it have above str.format()?

    > It is new, and has no compatibility issues with old ways at all.
    > In syntax, all you need is to allow d"...", which clearly won't
    > affect any old ways of business.


    You may well be able to get past the compatibility issues. I'm not yet
    convinced that the new syntax is worth it, but it may be possible.

    Here's a recommendation: Write a parser for your notation that turns
    it into executable Python code (that is, executable in Python 3.3
    without any d"..." support). Since a dynamic string is really an
    expression in disguise, it doesn't need to be translated at run time,
    and in fact is best translated at compile time. It wouldn't be hard to
    make the precompiler as per your equivalency above; and since you can
    use "%s"%123 without raising TypeError, you don't even have to figure
    out data types. With that written, the Python community can more
    adequately evaluate your proposal, and even start making use of it and
    getting a "feel" for the new syntax. If it catches on, someone'll
    probably invite you to write a PEP or something; if it doesn't, well,
    you still have it on your own version, and you don't have to worry
    about upgrades (your precompiler/"patch" should be able to slide up to
    a new version easily).

    I'm still against the idea personally, mainly because it's nothing but
    a more magical way of doing what we already can do, but there may well
    be many who disagree.

    Chris Angelico
     
    Chris Angelico, Apr 2, 2012
    #17
  18. Yingjie Lan

    Guest

    wrote:

    > Yingjie Lan wrote:
    >> Seems you miss understood my notion of dynamic string.
    >> Dynamic strings are expressions in disguise: the things
    >> in between $...$ are plain old expressions (with optional
    >> formatting specifications). They are evaluated
    >> as if they were outside the dynamic string.

    > In that case you should re-think the delimiters, so that you have
    > something
    > that can be nested. An example (example only, I'm not in love with it as
    > a final form):
    >
    > "A string that gets %(count*spacer%) in the middle"
    >
    > "A string that gets %(count*%(spacer%)%) in the middle"


    A less than great example, I guess. Maybe

    > "A string that gets %(count*"-%(spacer%)-"%) in the middle"



    Mel.
     
    , Apr 2, 2012
    #18
  19. Yingjie Lan

    Yingjie Lan Guest

    > Right, meaning that both have the same issues 
    > of performance, needfor


    > str(), etc. There's absolutely no difference.



    OK, performance. Here is a new solution:
     
    Suppose we have a new string method
        str.format_join([...])
    taking a list of strings and objects,
    with even-indexed ones being strings,
    odd-indexed ones being objects.
    Each even-indexed string *ends* with a formatting
    specification for the next object in the list.
    Then we can have:
    >>> d"sin($x$) = $ sin(x):0.3f $"

    get translated to:
    >>> ''.format_join(["sin(%s",x,") = %0..3f", sin(x)])

    This seems to be at least as good in performance.


    > And no benefit. You lose out on syntax highlighting 
    > in your editorand gain nothing.


    Gain: readability, terseness, hassle-free, and possibly
    better performance if done right.

    Syntax highlighting: can bedone more creatively.
    For dynamic strings, string parts are like normal 
    strings, but the embedded expressions are like
    normal expressions :)

    >
    > sprintf("UPDATE tablename SET modified=now()%{,%s=:%[0]s%} WHERE
    > key=%d",array_of_field_names,primary_key_value)
    > --> "UPDATE tablename SET modified=now(),foo=:foo,bar=:bar,quux=:quux
    > WHERE key=1234"
    >
    > You're still paying for no complexity you aren't actually using.
    > It's clear and readable.


    You are really good at that. Maybe not everybody is as
    experience as you, and I suppose the learning curve is 
    kind of hard to climb.

    > It's powerful only if you use eval to allow full expression syntax.
    > Otherwise, what does it have above str.format()?



    Those expressions are embedded, you don't need eval()
    to have the result though. Are we on the same page?

    > You maywell be able to get past the compatibility issues. I'm not yet
    > convinced that the new syntax is worth it, but it may be possible.
    >
    > Here'sa recommendation: Write a parser for your notation that turns
    > it into executable Python code (that is, executable in Python 3.3
    > without any d"..." support). 


    You mean a translator?

    The syntax is essentialfor compatibility.
    We must distinguish dynamic strings from common strings.
    They will live peacefully together. 
    (escaping the '$' in normal strings breaks compatibility, 
    and the consequence of forgetting to escape could be
    disastrous, so definitely not an option). 

    May be d" is too tiny, $"..." is easier to pick out.



    Cheers,
    Yingjie
     
    Yingjie Lan, Apr 2, 2012
    #19
  20. Yingjie Lan

    Yingjie Lan Guest

    >>   In that case you should re-think the delimiters, so that you have

    >>   something
    >> that can be nested.  An example (example only, I'm not in love with it

    > as
    >> a final form):


    Haven't really thought about that. Nesting is a big 
    issue if in the embedded expression, there is another 
    dynamic string expression. For example (the first
    '%' immediately preceding the first quote denotes
    the start of a dynamic string expression)::

    >>> first_name, family_name = "Peter", "Johns"
    >>> %"Hi $ first_name+%", $family_name$" $!"


    'Hi Peter, Johns!'

    However, nesting is really cluttering things up and
    we should forbid it without loosing power:
    The above example can be done without nesting:
    >>> >>> %"Hi $ first_name$, $family_name$!"

    'Hi Peter, Johns!'

    Can you offer an example where nesting is 
    better or necessary?

    Cheers,
    Yingjie
     
    Yingjie Lan, Apr 2, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Aiden Humphreys

    Perl/Ruby string interpolation

    Aiden Humphreys, May 22, 2005, in forum: Java
    Replies:
    5
    Views:
    876
    Tor Iver Wilhelmsen
    May 22, 2005
  2. Paul Rubin
    Replies:
    4
    Views:
    300
    Michele Simionato
    Jan 19, 2004
  3. Michele Simionato

    yet another recipe on string interpolation

    Michele Simionato, Nov 4, 2004, in forum: Python
    Replies:
    8
    Views:
    402
    Raymond Hettinger
    Nov 8, 2004
  4. Kun
    Replies:
    2
    Views:
    423
    John J. Lee
    Apr 12, 2006
  5. Alan G Isaac
    Replies:
    4
    Views:
    435
    Alan G Isaac
    Sep 13, 2009
Loading...

Share This Page