Perl is worse!

Alex Martelli alex at magenta.com
Sat Jul 29 07:53:02 EDT 2000


"Steve Lamb" <grey at despair.rpglink.com> wrote in message
news:slrn8o444p.49c.grey at teleute.rpglink.com...
> On Fri, 28 Jul 2000 23:09:56 +0200, Alex Martelli <alex at magenta.com>
wrote:
> >I hope you remember that in Python there's no need for the joining
> >and later re-splitting: just putting the pair (tuple) in there is
> >so much easier and more natural.
>
>     No.  I am learning that.  A plesant side effect of this excellent
> discussion.

The quality of the discussion has surely been a pleasant surprise.
Thank you for your persistence:-).


> >Among other things, it makes it easy to save/load/change a format-string;
>
>     Nono, you misunderstand me.  I prefer the Pascal notion of variables
in
> place in the string with formatting attached to it instead of placeholder
> formatting strings with the variables hanging off the end of the string.

In Python, you can have either form, depending on your specific
preferences and needs at each case.

> Pseudo code from no language, bear with me.
>
> "Here is a string with ",$a:d:0:0," variable in it."
>
> "Here is a string with %d:0:0 variable in it.",$a
>
>     In the former I read and I see, "Oh, $a goes here with this
formatting"
> whereas in the latter it is "Oh, here is the formatting for...  uhm.. $a."

Yes, so the latter is best when you have a single format you want to
apply to several different variables at various point, the former is
best when the names are fixed.  That's why Python supplies both.

The Python syntax for a format-string including variable-names is, e.g.:

    "Here is a string with %(varname)d in it"

while the equivalent format-string without a varname would be:

    "Here is a string with %d in it"

The latter form, with anonymous placeholders, is applied (with the
% operator) to a *sequence* (or a single element, if there is just
one placeholder in the format-string).  The form with the _named_
placeholders is applied (with the same % operator) to a *mapping*,
typically a dictionary; if the dictionary you want to use happens
to be the set of variables currently bound, well, that's exactly
what the built-in function vars() is for.

So, summing up:
    "Here is a string with %(varname)d in it" % vars()
and:
    "Here is a string with %d in it" % varname

are exactly equivalent; you pays your money (metaphorically
speaking, of course), you takes your choice.

Note that the application of the format-string with the named
placeholders to vars() is *EXPLICIT*.  This lets you use any
OTHER dictionary (just as explicitly) to perform many useful
things.  Here is a typical example -- internationalization!

Say at some point in your program you have the statements:

    print "Here is a very %s %s!" % (adjective1,noun1)
    print "Here is a very %s %s!" % (adjective2,noun2)


But now you want to sell your program abroad, so the English
only messages must go.  Oh well, it is only a little work to
read the formatstring from an appropriate file, after all:

    format = getFormat("HereIs")
    print format % (adjective1,noun1)
    print format % (adjective2,noun2)

Of course, the adjective and noun will have to be gotten
in a language-specific way, too.  But there's a deeper
problem -- this form still forces the ORDER in which the
words get inserted in the format!  And different languages
prefer different word-orders.  You would not want your
program where in English it would output:
    Here is a very big house!
    Here is a very rich woman!
to emit, in Italian:
    Ecco una molto grande casa!
    Ecco una molto ricca donna!
believe me; it had better be:
    Ecco una casa molto grande!
    Ecco una donna molto ricca!

The format-string with named placeholders solves the
problem _without_ any need for the specific variable
names to be fixed!  Just change your format-string to:
    "Here is a very %(adj)s %(noun)s!"
in English, and, in Italian, to:
    "Ecco una %(noun)s molto %(adj)s!"
and the output statements to:
    print format % {'adj':adjective1, 'noun':noun1}
    print format % {'adj':adjective2, 'noun':noun2}
and you're all set.


>     Again, simplistic and not in any language, but taken to the extreme
you
> can see the problem.
>
> "%d:0:0 %c:U %s %s %s %s %d %s %s %s \
> %d:0:0!",$a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k
>
>     What variable goes with what again?

Yes, a format-string with named-placeholders does help with that, too.


But unnamed-placeholders format-string also have their place, when
the *order* of the items being formatted is really what matters,
rather than the variable-names (if any!) that they're tagged with.
I'm very happy not _having_ to invent some arbitrary name when what
I want to do is output one or more arbitrary expressions, computed
on the fly, for example.  Naming has its place, but so does quiet
anonimity...:-).


> >You just don't have to put strings together, to split them up again
later, as
> >much as is usual in Perl (it was _mandatory_ in Perl 4, which had no rich
> >data structures; it's still _popular_ in Perl 5, for various reasons).
>
>    Simplicity.

I find it simpler to use a sequence as-is rather than have to encode
it into a string, then later parse the sequence back from the string.
Using as-is takes 0 operation, the alternative takes 2:-).


> >Why else would I have been so happy, so utterly happy, to leave 8 years
of
> >Perl experience behind and start over from scratch with Python?
>
>     Masochism?  :)

Could be (I _am_, after all, a well-known sadomasochist!), but, if
it were that, I think I'd be programming in C shell (hard to think
of a more painful way to make a living; and yet there _were_ people
writing scripts in it rather than the somewhat-less-painful Bourne
shell, for reasons I've always found utterly unfathomable...).


Alex






More information about the Python-list mailing list