
Most of the changes in PEP 3000 are tightening up of "There should be one obvious way to do it.": * Remove multiple forms of raising exceptions, leaving just "raise instance" * Remove exec as statement, leaving the compatible tuple/call form. * Remove <>, ``, leaving !=, repr etc. Other changes are to disallow things already considered poor style like: * No assignment to True/False/None * No input() * No access to list comprehension variable And there is also completely new stuff like static type checking. While a lot of existing code will break on 3.0 it is still generally possible to write code that will run on both 2.x and 3.0: use only the "proper" forms above, do not assume the result of zip or range is a list, use absolute imports (and avoid static types, of course). I already write all my new code this way. Is this "common subset" a happy coincidence or a design principle? Not all proposed changes remove redundancy or add completely new things. Some of them just change the way certain things must be done. For example: * Moving compile, id, intern to sys * Replacing print with write/writeln And possibly the biggest change: * Reorganize the standard library to not be as shallow I'm between +0 and -1 on these. I don't find them enough of an improvement to break this "common subset" behavior. It's not quite the same as strict backward compatibility and I find it worthwhile to try to keep it. Writing programs that run on both 2.x and 3 may require ugly version-dependent tricks like: try: compile except NameError: from sys import compile or perhaps try: import urllib except ImportError: from www import urllib Should the "common subset" be a design principle of Python 3? Do compile and id really have to be moved from __builtins__ to sys? Could the rearrangement of the standard library be a bit less aggressive and try to leave commonly used modules in place? Oren

Oren Tirosh <oren.tirosh@gmail.com> wrote:
Perhaps py3k could have a py2compat module. Importing it could have the effect of (for instance) putting compile, id, and intern into the global namespace, making print an alias for writeln, alias the standard library namespace, ... ? Charles -- ----------------------------------------------------------------------- Charles Cazabon <python@discworld.dyndns.org> GPL'ed software available at: http://pyropus.ca/software/ -----------------------------------------------------------------------

Collin Winter wrote:
If we ever get the ast-branch finished, then keeping a copy of the final 2.x parser around that targets the Python AST should actually be feasible, too. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com

[Charles Cazabon]
[Greg Ewing]
[Reinhold Birkenfeld]
You'd have to enclose print arguments in parentheses. Of course, the "trailing comma" form would be lost.
And good riddance! The print statement harks back to ABC and even (unvisual) Basic. Out with it! A transitional strategy could be to start designing the new API and introduce it in Python 2.x. Here's my strawman: (1) Add two new methods the the stream (file) API and extend write(): stream.write(a1, a2, ...) -- equivalent to map(stream.write, map(str, [a1, a2, ...])) stream.writeln(a1, a2, ...) -- equivalent to stream.write(a1, a2, ..., "\n") stream.writef(fmt, a1, a2, ...) -- equivalent to stream.write(fmt % (a1, a2, ...)) (2) Add builtin functions write(), writeln(), writef() that call the corresponding method on sys.stdout. (Note: these should not just be the bound methods; assignment to sys.stdout should immediately affect those, just like for print. There's an important use case for this.) -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Thu, 2005-09-01 at 10:58, Guido van Rossum wrote:
I have to strongly disagree. The print statement is simple, easy to understand, and easy to use. For use cases like debugging or the interactive interpreter, and even for some more complicated use cases like print>>, I think it's hard to beat the useability of print with a write() function, even if builtin. -Barry

On 9/1/05, Barry Warsaw <barry@python.org> wrote:
I agree with Barry. In particular, the behaviour of adding spaces between items is something I find very useful, and it's missing from the functional forms. print greeting, name feels much more natural to me than write(greeting, " ", name) or writef("%s %s", greeting, name) And that's even worse if the original used a literal "Hello", and only later migrated to a variable greeting - remembering to get the spaces in the right place is a pain: print "Hello", name ==> print greeting, name write("Hello ", name) ==> write(greeting, name) # oops, forgot the space or write(greeting, " ", name) # non-obvious translation OK, it's a minor thing, but what's the benefit? I've used print functions a lot in things like VBScript and Javascript, and hated them every time... Paul.

[Guido van Rossum]
And good riddance! The print statement harks back to ABC and even (unvisual) Basic. Out with it!
[Barry Warsaw]
I have to strongly disagree. The print statement is simple, easy to understand, and easy to use.
[Paul Moore]
While I agree that mostly the print statement is "simple, easy to understand, and easy to use", I've seen the trailing-comma version cause confusion for a lot of newbies. I wouldn't mind at all if the trailing-comma version disappeared in Python 3.0 -- if you need this kind of complicated output, you can always use sys.stdout.write and/or string formatting. The spaces-between-items point that Paul Moore makes is IMHO the best argument against the proposed write*() functions. I think we *do* need a statement or function of some sort that does the most basic task: writing a line to sys.stdout that calls str() on each of the elements and joins them with spaces. That is, I think we need to keep *something* with functionality like: def XXX(*args): sys.stdout.write('%s\n' % ' '.join(str(a) for a in args)) Note that this would keep the Hello World example simple: XXX(greeting, name) STeVe -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy

Steven Bethard wrote:
Hypertalk (the programming language of Apple's Hypercard) had an interesting way of doing this. There were two string concatenation operators: a regular one, and a "concatenate with a space between" operator. Using these, you could build up strings for output quite nicely. It helped somewhat that Hypertalk really only had strings as a data type. A Python version of this operator would need to be willing to convert either or both operands to strings. -- Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg.ewing@canterbury.ac.nz +--------------------------------------+

Steven Bethard wrote:
... as proposed, but ...
... the trailing-comma version is indeed BASIC voodoo of ancient heritage, and not something I'd personally miss.
Of course, for Python 3.0 if we lose the keyword there's nothing to stop us calling the convenience function "print". With the removal of the trailing-comma functionality we'd only have to add parentheses to 2.X print statements to have them work :-) Next question: could the function have a sensible return value, or is None the best possible result? hesitating-to-suggest-minus-one-ly y'rs - steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/

>> And good riddance! The print statement harks back to ABC and even >> (unvisual) Basic. Out with it! Barry> I have to strongly disagree. The print statement is simple, easy Barry> to understand, and easy to use. I'm with Barry. Even for non-debug use the print statement is suitable for the majority of my output. Skip

skip@pobox.com wrote:
99.9% of my Python code is test harnesses to run low-level hardware control interface tests, for which printing to stdout works perfectly. Maybe one day I'll stick a GUI on the front end of them, but even then I will probably just be using subprocess to invoke the command line versions behind the scenes. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com

I like the present print statement because parentheses are inconvenient to type compared to lowercase letters, and it looks less cluttered without them. The parentheses in writeln("hello world") don't add any more meaning than a terminating semicolon would, so why are they necessary? Why not instead change the language so as to allow any function call to be written without parentheses (when this is unambiguous)? This could make Python more convenient for creating imperative-style DSLs (though I'm not sure this is a goal). In any case, I think "write" would be better than "print", because it is easier to type (at least for me; reaching for 'w' and than 'r' goes much faster than reaching for 'p'). I don't like "writeln" though, as in 9 of 10 cases I want the line break to be there. I'd rather have write add the line break, and "writeraw" or somesuch exclude it. By the way, if print has to go, then what about the assert, raise, and import statements? Should these be changed to use function call syntax as well? (By the way, assert and raise could be methods: ZeroDivisionError.assert(denom != 0). Surprising that Java doesn't do this ;-) Fredrik

On 9/1/05, Fredrik Johansson <fredrik.johansson@gmail.com> wrote:
Given all the other syntax it would be too ambiguous. If you really want this, please sit down and design a grammar. If you can't do that, just believe me that it would be too nasty (with too many exceptional cases) to bother.
Yuck. Also, write() and writeln() have a long history going back to Pascal. Java has print() and println(). Plus stream.write("abc") already has a meaning, and the elegance of my proposal is that that meaning remains unchanged.
It can't work for import because it defines a new name; if import were a function, then import(foo) would necessarily mean to evaluate foo first, which isn't what you want. It could work for raise (and even for break and continue) but I'd rather keep control flow as statements; you never know what the compiler could do with the information that a particular block doesn't contain a raise statement. It can't work for assert because you don't want the argument to be evaluated in -O mode. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
Here I have to agree with Barry. print is very handy, and print>> is, too. I'd rather see exec and assert becoming a function.
Do we really need writef()? It seems to be not much better than its %-formatting equivalent.
If write* is introduced, this is absolutely necessary. Reinhold -- Mail address is perfectly valid!

Actually, formatting needs to become a function. The overloading of the arithmetic mod operator has proven to be unfortunate (if only because of precedence issues). Also, the format coding scheme itself needs to be revisited. There is no shortage of people who have taken issue with the trailing s in %(myvar)s. Raymond

On 9/1/05, Raymond Hettinger <raymond.hettinger@verizon.net> wrote:
For me, it's not so much the precedence, but the fact that "%s" % x doesn't work as expected if x is a tuple; you'd have to write "%s" % (x,) which is tedious.
Maybe the syntax used in the string.Template class is the way to go? -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Right. That too.
string.Template is a bit too simplified. But perhaps it can be adapted. We still want some way to express %r, %6.2f, etc. Since string formatting has been around since Tim was in diapers, we should probably start by looking at the solutions used by other languages. With Py3.0, we have a real opportunity to break-away from doing things the way C does it. Raymond

On 9/1/05, Raymond Hettinger <raymond.hettinger@verizon.net> wrote:
Hrm. Most other languages these days do floating point formatting the way C does it. I'm happy to look for other ways to invoke the thing, but I think that we shouldn't tinker with %6.2f. (In fact, the major complaint is about the one place where I *did* tinker with it -- %(boo)s.) Maybe the ${boo} form can be extended to allow ${boo%6.2f} ??? Unfortunately that would prevent a different extension of ${boo}: %{boo+far}. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
May I also suggest the following shortcut for creating and evaluating a string template. (Ever since I thought of this, I've actually used this in code without thinking... it's just too natural): message = $"Hello, $name!" Shane

Shane Hathaway wrote:
As I recall, this has been considered before, and rejected on the grounds that it's too visually confusing having $ signs both inside and outside the quotes. -- Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg.ewing@canterbury.ac.nz +--------------------------------------+

[Raymond Hettinger]
[Guido van Rossum]
[Raymond Hettinger]
I was curious about what kind of options there were, so I googled around a bit. Here's what I found: Java[1] uses syntax like: %[argument_index$][flags][width][.precision]conversion which is basically the same as that of C, with positional argument specifiers. Some examples: String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c); System.out.format("Local time: %tT", Calendar.getInstance()); formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d") Classes can customize formatting for the 's' specifier by implementing the Formattable interface, which provides a method: formatTo(Formatter fmt, int f, int width, int precision) You can get formatted objects by calling: * The format() methods on Formatter objects * The format() methods on Strings * The format() methods on System.out, System.err, etc. .Net[2] uses syntax like: {index[,alignment][:formatString]} with examples like: String.Format("{0:dddd MMMM}", DateTime.Now) Console.WriteLine("{0:C}", MyInt) String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}", myName, DateTime.Now) Classes can customize formatting for any specifier by implementing the ICustomFormatter interface: Format(string format, object arg, IFormatProvider formatProvider); or the IFormattable interface: ToString(string format, IFormatProvider formatProvider); You can get formatted objects by calling: * The ToString method of an IFormattable instance * The Format on Strings * The Write and WriteLine methods of Console, TextWriter, StreamWriter, etc. objects I also briefly looked at Tcl/Tk[3], Common Dylan[4], OCaml[5] and Ruby[6][7], which all appear to use C-style (or similar) formatting. I believe that Ruby, in addition to having printf and sprintf, also uses the % operator like Python does. This was a pretty small sample of languages (just the first few that showed up in google), and I didn't really look at any of them other than Java and .Net in much depth, so I've may have misunderstood some of it. That said, I think it's probably pretty reasonable to conclude that C-style formatting is the choice of a lot of other languages. (Not to imply that it therefore needs to be the choice of Python.) I understand one of the complaints about string formatting in Python is having to write the "s" on things like "%(key)s". I was hoping to get some ideas for alternatives here, but I wasn't able to find any dict-style insertion like in Python. There were a few languages (Java, Tcl) with the N$ positional-style insertion, but I don't think that helps us much. People have also been discussing a builtin format() function to replace the current % operator. Translating into Python the location of the formatting operations in the languages above suggests the following possibilities: * Have all __str__() methods take additonal formatting arguments * Add a format() builtin * Add format() methods on str and unicode objects * Add format() methods on all Python streams (files, sys.stdin, etc.) Of course, these possibilities aren't mutually exclusive, but TOOWTDI suggests that we probably shouldn't have too many of them. If people know of other languages that have a different approach to string formatting, it might be useful to see them. BTW, I intentionally didn't go into Perl's string formatting because I don't know it that well, and figured there are people on this list much more qualified than myself to present it. [1]http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html [2]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm... [3]http://www.tcl.tk/man/tcl8.0/TclCmd/format.htm [4]http://gauss.gwydiondylan.org/books/drm/drm_57.html [5]http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html [6]http://www.rubycentral.com/book/ref_c_string.html#String._pc [7]http://www.rubycentral.com/book/ref_m_kernel.html#Kernel.sprintf Steve -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy

If people know of other languages that have a different approach to string formatting, it might be useful to see them.
Common Lisp has something broadly C-like but bigger and hairier. It includes powerful-but-confusing looping and conditional features, letting you say things like (format t "~{~^, ~A~}" 1 2 3 "wombat") which produces 1, 2, 3, wombat or -- you may wish to be sitting down before reading further -- (format t "~#[nothing~;~S~;~S and ~S~:;~@{~#[~; and~] ~S~^ ,~}~]." 1 2 3 "wombat") which produces 1, 2, 3, and wombat and also does the Right Thing with 0, 1 or 2 items. (The first argument to FORMAT, in case you were wondering, determines where the output should go. Feeding in T, as here, sends it to stdout. You can also give it an arbitrary stream, or NIL to return the formatted result as a string.) For the impressive and horrifying full story, see http://www.lisp.org/HyperSpec/Body/sec_22-3.html Most of the features of CL's formatted output are probably, shall we say, inappropriate for Python. It might still be worth a look, to see if there's anything under the rococo exterior that would fit. * Some languages have "picture" formats, where the structure of the format string more closely mimics that of the desired output. (This is true, e.g., of some Basics and of one variety of Perl output.) The trouble with this is that it limits how much information you can provide about *how* each value is to be formatted within the available space. * C++'s << operator represents another way to do formatted output. I regard it as an object lesson in bad design. -- g

I wrote:
C++'s << operator represents another way to do formatted output. I regard it as an object lesson in bad design.
... and should add: Of course it's usually seen as being about output more than about formatting, but in fact if you want to do what Python does with "%", C with "sprintf" and Common Lisp with (format nil ...) then the Right Thing in C++ (in so far as that exists) is usually to use << with a string stream. -- g

Le lundi 05 septembre 2005 à 16:52 +0100, Gareth McCaughan a écrit :
Uh, what about internationalization (i18n) ? In i18n you can't avoid the need for parameterized strings. For example I want to write : _("The file '%s' is read only") % filename not : _("The file") + " '" + filename + "' " + _("is read only") because the splitting in the second form will not translate correctly into other languages. You *have* to supply the whole non-splitted sentence to the translators. The bottom line, IMHO, is that there are frequent uses that mandate a nice and easy to use formatting operator. Python has it, let's not remove it. Regards Antoine.

On Mon, 2005-09-05 at 12:07, Antoine Pitrou wrote:
Actually, this was part of the motivation behind PEP 292 and Template strings, because what you really want is named parameters, not positional parameters: 'The file $filename in directory $dir is read only' There are a few techniques for getting full i18n for Template strings. -Barry

[Barry Warsaw]
'The file $filename in directory $dir is read only'
There are a few techniques for getting full i18n for Template strings.
Yet, "The file %(filename)s in directory %(dir)s is read only" % vars() is already usable. The need being already filled without Template strings, it could hardly be presented as a motivation for them. :-) -- François Pinard http://pinard.progiciels-bpi.ca

On Monday 2005-09-05 17:07, Antoine Pitrou wrote:
Yes. If you think I was arguing the opposite, then I failed to communicate clearly and I apologize.
It's clear (I think) that a good way of formatting strings is necessary. It's less clear what the best way is. Python's % is pretty good; perhaps it's possible to do even better. For instance, take your I18N example. Not all languages have the same word order, as you've observed. When there's more than one parameter, Python's %-interpolation isn't enough in general; you'd need something that can reorder the parameters. I don't know whether this is worth complicating string formatting for, but it's not obvious that it isn't. -- g

Yes. If you think I was arguing the opposite, then I failed to communicate clearly and I apologize.
Actually, I didn't interpret your message like that, but as I had already seen that proposal (to suppress string formatting), I thought it would be the right time to react ;)
Well, I totally agree. I think it could be nice to both: - introduce positional formatting : "%1", "%2"... - make type specification optional, since Python can figure out the type by itself and use the right method; you would only specify the type when you want to have a different formatting (for example, for floats, you could use "%g2" instead of "%2" which would be equivalent to "%f2") Regards Antoine. -- « On dit que pétrir c'est modeler, Moi je dis que péter c'est démolir. » Stupéflip

Reinhold Birkenfeld wrote:
Does it have to be a function? I'd expect it to be a method, like string.Template. E.g
BTW, I'm quite happy with the current string formatting format. I certainly haven't "taken issue with the trailing s in %(myvar)s". If it wasn't there, when it is for %(count)i and %(ratio)f, I'd probably wonder why. STeVe -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy

I have to agree with Barry, Paul, Fredrik, Reinhold, etc. Removing the "print" statement would immediately break at a fundamental level 15 years of tutorials, books, and examples, many of which start with
print "Hello, World!"
Of course, maybe that's the idea -- this is not your father's Python! (Though that slogan apparently didn't work out so well for Oldsmobile...) Is there a syntax trick here? Suppose start-of-the-line function names not followed by an open-paren, but followed by comma-separated lists of expressions, were treated as if the rest of the line were arguments to a function. That is, suppose print "foo", 3, dir(sys) was automagically converted to print ("foo", 3, dir(sys)) Not sure I like this kind of trickyness, though. Though it might be useful for "assert", "raise", maybe "exec", too. I also don't quite see the point of adding new top-level reserved words or built-in functions like "write". It clutters the namespace without being much of an improvement over "sys.stdout.write", IMO. Some kind of printf would be nice to have, but with Python's forgiving syntax is easy enough to add yourself.
Maybe the syntax used in the string.Template class is the way to go?
If you'd consider extending the Template syntax to positional parameters ($1, $2, etc.), then perhaps "print" could be modified to use the template for formatting, if it occurs as the first argument: print string.Template("arg $1, arg $2"), arg1, arg2 with an alternate form printf "arg $1, arg $2", arg1, arg2 where the first arg is required to be a template pattern string. This is a nice improvement over C printf in that you can re-use arguments. What happens to Template() when the string module goes away? Do we write "arg $1, arg $2".Template() instead? Bill

And good riddance! The print statement harks back to ABC and even (unvisual) Basic. Out with it!
Guido, After reviewing the PEP 3000 notes, I can find no justification there for removing "print" other than your statement here -- that it has served honorably and well in many programming languages for many years, a curious reason for abandoning it. There's a pointer to Python Regrets, but that document contains no justification for the change. (Actually, using pointers to Powerpoint slides to explain/justify anything is, er... -- what's a polite euphemism for "a sign of a weak mind"? :-) I agree that "print" is already a bit peculiar, but so what? If we wanted Scheme, we'd be programming in Scheme, not Python. The only other parts of PEP 3000 I take issue with are the removal of "reduce" (a little) and "lambda" (a bit more seriously). I use reduce a lot, but it's easy enough to cobble together oneself, given the changes in Python over the last 10 years. Bill

Bill Janssen <janssen@parc.com> wrote:
And good riddance! The print statement harks back to ABC and even (unvisual) Basic. Out with it!
I'm with Guido on this, BTW.
After reviewing the PEP 3000 notes, I can find no justification there for removing "print"
Well, how about the fact that basically all of Python's statements are for implementing logic (if, while, etc), controlling flow (return, yield, try, etc), and defining structure (def, class, etc). `print` stands pretty much alone as a statement which does none of these things -- in fact, it does nothing for the program but merely has the interesting side-effect of writing to stdout. It's an anomaly. It stands out in the language as a sore thumb waiting for Guido's hammer. Charles -- ----------------------------------------------------------------------- Charles Cazabon <python@discworld.dyndns.org> GPL'ed software available at: http://pyropus.ca/software/ -----------------------------------------------------------------------

On Thu, Sep 01, 2005 at 11:12:57PM +0200, Fredrik Lundh wrote:
I'd say: yeah, real programmers don't generate output _to stdout_ sockets, GUI widgets, buffers? sure. stdout? Almost never. Most of these don't have write() methods so I've never had a reason to use the "print >>" syntax. -jackdied

On Sep 1, 2005, at 2:27 PM, Jack Diederich wrote:
That is absolutely true, print is becoming less and less useful in the context of GUI or web applications. Even in Just Debugging scenarios, you're probably better off using something with more flexibility, such as the logging module. Additionally, the fact that sys.stdout is for bytes and not a text (unicode) makes it even more complicated. You can, of course, replace sys.stdout with an encoding-aware wrapper via codecs.getwriter (), but that's often inconvenient. -bob

On Thu, 2005-09-01 at 17:49, Bob Ippolito wrote:
That is absolutely true, print is becoming less and less useful in the context of GUI or web applications.
I know we're dinosaurs, but some of us still write console apps in Python!
The logging module is great, but logging and debugging are two different things (although that fact is obscured when you don't have a console). print is useful in scenarios other than debugging. And while I do occasionally use it, I wouldn't be too heartbroken if the trailing comma form were lost. I /would/ mourn the loss of print>> though -- not necessarily the syntax, which was clearly a compromise, but the functionality. If we could have spelled it "print to sys.stderr" we would have. -Barry

On Thu, 1 Sep 2005, Jack Diederich wrote:
Almost every program I write produces its output mainly to stdout. And I probably use print half the time to produce this output (the rest is done mostly with csv). GUI widgets? Who needs 'em? -- Michael Hoffman <hoffman@ebi.ac.uk> European Bioinformatics Institute

Fredrik Lundh <fredrik@pythonware.com> wrote:
That wasn't quite my point - I meant that the rest of Python's statements (to a one) all have a quite fundamental impact on what the code in question means. `print` doesn't. I write data filters in Python all the time -- but I virtually never use `print`. stdout.write() is more consistent /and/ parallel to stdin.read(). `print` should go away, at least as a statement. Charles -- ----------------------------------------------------------------------- Charles Cazabon <python@discworld.dyndns.org> GPL'ed software available at: http://pyropus.ca/software/ -----------------------------------------------------------------------

On 01/09/05, Guido van Rossum <guido@python.org> wrote:
And good riddance! The print statement harks back to ABC and even (unvisual) Basic. Out with it!
I disagree strongly. I can't count the number of times I've been p*ssed having to write something like System.out.println("point(" + this.x + "," + this.y +")") in Java. (Strangely though, I don't object to having printf() in C, but I know it doesn't work any other way). This is what I liked about Python, it offered a no-frills way to get the job done (TSOOWTDI and the like). I agree it's mostly used for debugging purposes, to do quick-and dirty calculations, etc. Nothing can beat it. We don't want the language to be pure, we want it to be useful. Isn't "Practicality beats purity" in the Zen of Python? Last time I checked (2.4.1) it was there, and updating Zen isn't in PEP 3000 ;) -1 on removal of print.

OK. Now that we've got the emotions under control somewhat, maybe a few folks can go off and write up a PEP for a print-replacement. I nominate Barry and Nick since they seem to be motivated; anyone who thinks their view is important and won't be taken into account enough by those two ought to speak up now and volunteer as a co-author. I suggest the wiki as a place for working out drafts. I'm pulling out of the discussion until I see a draft PEP. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On 9/1/05, Guido van Rossum <guido@python.org> wrote:
There is a lot of debate over this issue, obviously. Now, I think getting rid of the print statement can lead to ugly code, because a write function would be called as an expression, so where we'd once have prints on their own lines, that wouldn't be the case anymore, and things could get ugly. But, print is a little too inflexible. What about adding a special name __print__, which the print statement would call? It should be looked up as a local first, then global. Thus, different parts of a program can define their own __print__, without changing everyone else's stdout. The Python web people would love that.

On 9/5/05, Calvin Spealman <ironfroggy@gmail.com> wrote:
Sounds like FUD to me. Lots of functions/methods exist that *could* be embedded in expressions, and never are. Or if they are, there's actually a good reason, and then being a mere function (instead of a statement) would actually be helpful. Anyway, why would it be important that prints are on their own line where so many other important actions don't have that privilege?
Too many underscores; __print__ screams "internal use, don't mess" at you. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On 9/6/05, Guido van Rossum <guido@python.org> wrote:
For the same reason any statement is not an expression. Python doesn't allow assignments as expression, even though it has been implemented. Nor imports or function and class definitions. Readability is key. On the other hand, I actually don't like there being a print statement at all. We don't live in the days were console software rules and any other form of interface is an after thought. First-class printing to standard out seems to make a statement (no pun intended) that the language is intended for Unix-emulating operating systems (even Windows does, to some extent) and that anything you don't pipe through stdout or pull from stdin is something extra tossed in for a special crowd. Interface equality and neutrality would be a good thing in the language. But, I guess what I'm getting at is that if you do give special case to anything, give it special case properly. If text console IO is going to be only through functions and not directly in the language syntax, should it even be a built-in? Bring it to the level of any other interface API or keep it at its own status, but any middle ground seems half-hearted.

Reinhold Birkenfeld wrote:
The trailing comma is convenient, but I don't think it's that big of a deal to have two methods. ui.write() ui.writeln() # or ui.print() I'm +1 on making it a method of a "user interface object". Not just a function. I want to be able to import an interface, then communicate to it in a consistent way even though it may look quite different on the screen. Having a set of standard io methods moves in that direction I think. import console ui = console() ui.write("Hello World\n") howami = ui.input("How are you today? %s") import popup ui = popup('YesNo') # Create a 'YesNo' popup. ok = ui.input('Ok to proceed?') # Open it and wait for it. ok2 = ui.input('Are you sure?') # Reopen it and reuse it. if ok == ok2 == 'Yes': ... Some possible common methods... ui.write(data) # non blocking print/output, doesn't wait ui.send() # non echo write; passwords, config, etc.. ui.input(prompt) # output something and wait for return value ui.get() # non echo wait for value, or io.next() ui.read() # non blocking get As for functions without '()'s. (Just a thought) You could use '<<' or '<<<' (or other symbol) as a way to move data between objects. ui.write <<< 'Hello World/n' # ui.write('Hello World/n') ui.writeln <<< counter # ui.writeln(counter.next()) ok = ui.input <<< 'press a key:' # ok = ui.input('press a key:') The requirement could be that the item on the left is a callable, and the item on the right is a sequence or generator. Cheers, Ron

Reinhold Birkenfeld wrote:
But you'd still have to rewrite old code to work with it, in which case you might as well change it to whatever the new way is in 3.0. -- Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg.ewing@canterbury.ac.nz +--------------------------------------+

On 8/31/05, Oren Tirosh <oren.tirosh@gmail.com> wrote:
Note we can ease this process a little by making a copy without removing, e.g., adding compile to sys now without removing it. As programs support only Python 2.5+, they could use sys.compile and wouldn't need to resort to the try/except above. I realize this is only a marginal improvement. However, if we don't start making changes, we will be stuck maintain suboptimal behaviour forever. n

Oren Tirosh wrote:
I think it's because those are the most obvious things right now. The really radical stuff won't come up until active development on Python 3000 actually starts. And it will, so any "common subset" will probably not be very large. IMO, if we are going to restrict Python 3000 enough to protect that "common subset," then there's not enough payoff to justify breaking *any* backwards compatibility. If my current codebase[1] isn't going to be supported in Python 3000, I'm going to want the Python developers to use that opportunity to the fullest advantage to make a better language. [1] By which I mean the sum total of the code that I use not just code that I've personally written. I am a library-whore. -- Robert Kern rkern@ucsd.edu "In the fields of hell where the grass grows high Are the graves of dreams allowed to die." -- Richard Harter

On Aug 31, 2005, at 5:00 PM, Robert Kern wrote:
I disagree fully. As a maintainer in the Twisted project I very much hope that it is possible to adapt the code such that it will work on Python 3 while still maintaining compatibility with Python 2.X. Otherwise, it will be impossible to make the transition to Python 3 without either maintaining two forks of the codebase (I doubt that'll happen) or abandoning all users still on Python 2. And that surely won't happen either, for a while. Maybe by the time Python 3.1 or 3.2 comes out it'll be possible to completely abandon Python 2. I'm perfectly happy to see backwards-incompatible changes in Python 3, as long as they do not make it completely impossible to write code that can run on both Python 3 and Python 2.X. This suggests a few things to me: a) new features should be added to the python 2.x series first wherever possible. b) 3.0 should by and large by simply a feature-removal release, removing support for features already marked as going away by the end of the 2.x series and which have replacements. c) don't make any radical syntax changes which make it impossible to write code that can even parse in both versions. d) for all backwards-incompatible-change proposals, have a section dedicated to compatibility and migration of old code that explains both how to modify old code to do things purely the new way, _and_ how to modify code to work under both the old and new ways. Strive to make this as simple as possible, but if totally necessary, it may be reasonable to suggest writing a wrapper function which changes behavior based on python version/existence of new methods. James

On 9/1/05, Robert Kern <rkern@ucsd.edu> wrote:
Static typing is radical stuff and doesn't hurt the common subset since it's optional. Making unicode the default is pretty radical and can be done without breaking the common subset (with the help of little tweaks like allowing str() to return unicode now like int() can return longs). Iterators and new-style classes were pretty radical changes that were managed elegantly and meet an an even stronger requirement than the common subset - they were achieved with full backward compatibility. Python 3 will most probably make big changes in the internal implementation and the C API. Perhaps it will even be generated from PyPy. I don't think keeping the common subset will really stand in the way of making big improvements. The proposed 3.x changes that break it seem more like nitpicking to me than significant improvements. Python is terrific. I find nothing I really want to change. Remove old cruft and add some brand new stuff, yes. But nothing to change. Oren

Oren Tirosh wrote:
Don't you think the current Python 3 "visions" becomes rather pointless with the raise of PyPy and interpreter extensions that are developed polymorphically? If the distinction between a user defined package and a language extension becomes more or less irrelevant who needs a language design committee for it's control? If someone takes the Python core in order to implement static typing it might be happen and run in a separate object space. But than, I'm almost sure, it won't be an ill-defined concept like "optional static typing" but Hindley-Milnor ( or a generalization ) which restricts dynamicity but enables type safety and static control otherwise. The idea of forking a language with a new release and thereby deevaluating older code seems somewhat archaic to me. Or the other way round: archaic materials and media like papyrus and scripture enabled communication across centurys changing slightly evolutionary and continously. Form this point of view PL development is still in a state of modernistic, youthfull irresponsibility.
So it seems. Kay

On Thu, Sep 01, 2005 at 08:55:48AM +0200, Kay Schluehr wrote:
I mostly agree with that. For me personally, one of the big reasons for jumping ship from perl to python (a considerable investment in time and effort) was to avoid perl 6. Its been clear for a long time that perl 6 will be completely different to perl 5, thus making perl 5 an evolutionary dead end. Yes I know about the perl 5 on perl 6 stuff - but who wants to program in a dead language? I'm all for removing the cruft in python 3, and giving it a bit of a spring clean, but please, please don't make it feel like a different language otherwise the users will be deserting in droves (no-one likes to be told that they've been using the wrong language for all these years). If come python 3, there is a 99% accurate program which can turn your python 2.x into python 3 code, then that would ease the transition greatly. -- Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

On 9/1/05, Nick Craig-Wood <nick@craig-wood.com> wrote:
IMO it won't feel like a different language; syntactically, the most far-fetched change is probably dropping the print statement (on which I just opened a new thread).
That might not be so easy given the desire to change most list-returning functions and methods into iterator-returning ones. This means that *most* places where you use keys() your code will still run, but *some* places you'll have to write list(d.keys()). How is the translator going to know? Worse, there's a common idiom: L = D.keys() L.sort() that should be replaced by L = sorted(D) how is the translator going to recognize that (given that there are all sorts of variations)? -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Oren Tirosh wrote:
Just had a weird thought. What if you could write from sys or __builtin__ import compile which would be equivalent to try: from sys import compile except ImportError: from __builtin__ import compile Greg

Oren Tirosh wrote:
* Replacing print with write/writeln
I still hope to see this change to "make print a builtin instead of a statement". I'd hate to lose the one-line hello world example due to cruft like "from sys import stdout". Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com

>> I still hope to see this change to "make print a builtin instead of a >> statement". I'd hate to lose the one-line hello world example due to >> cruft like "from sys import stdout". Barry> I agree. You can't get much simpler to explain or use than the Barry> current print statement. Then why remove it at all? Skip

Oren Tirosh <oren.tirosh@gmail.com> wrote:
Perhaps py3k could have a py2compat module. Importing it could have the effect of (for instance) putting compile, id, and intern into the global namespace, making print an alias for writeln, alias the standard library namespace, ... ? Charles -- ----------------------------------------------------------------------- Charles Cazabon <python@discworld.dyndns.org> GPL'ed software available at: http://pyropus.ca/software/ -----------------------------------------------------------------------

Collin Winter wrote:
If we ever get the ast-branch finished, then keeping a copy of the final 2.x parser around that targets the Python AST should actually be feasible, too. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com

[Charles Cazabon]
[Greg Ewing]
[Reinhold Birkenfeld]
You'd have to enclose print arguments in parentheses. Of course, the "trailing comma" form would be lost.
And good riddance! The print statement harks back to ABC and even (unvisual) Basic. Out with it! A transitional strategy could be to start designing the new API and introduce it in Python 2.x. Here's my strawman: (1) Add two new methods the the stream (file) API and extend write(): stream.write(a1, a2, ...) -- equivalent to map(stream.write, map(str, [a1, a2, ...])) stream.writeln(a1, a2, ...) -- equivalent to stream.write(a1, a2, ..., "\n") stream.writef(fmt, a1, a2, ...) -- equivalent to stream.write(fmt % (a1, a2, ...)) (2) Add builtin functions write(), writeln(), writef() that call the corresponding method on sys.stdout. (Note: these should not just be the bound methods; assignment to sys.stdout should immediately affect those, just like for print. There's an important use case for this.) -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Thu, 2005-09-01 at 10:58, Guido van Rossum wrote:
I have to strongly disagree. The print statement is simple, easy to understand, and easy to use. For use cases like debugging or the interactive interpreter, and even for some more complicated use cases like print>>, I think it's hard to beat the useability of print with a write() function, even if builtin. -Barry

On 9/1/05, Barry Warsaw <barry@python.org> wrote:
I agree with Barry. In particular, the behaviour of adding spaces between items is something I find very useful, and it's missing from the functional forms. print greeting, name feels much more natural to me than write(greeting, " ", name) or writef("%s %s", greeting, name) And that's even worse if the original used a literal "Hello", and only later migrated to a variable greeting - remembering to get the spaces in the right place is a pain: print "Hello", name ==> print greeting, name write("Hello ", name) ==> write(greeting, name) # oops, forgot the space or write(greeting, " ", name) # non-obvious translation OK, it's a minor thing, but what's the benefit? I've used print functions a lot in things like VBScript and Javascript, and hated them every time... Paul.

[Guido van Rossum]
And good riddance! The print statement harks back to ABC and even (unvisual) Basic. Out with it!
[Barry Warsaw]
I have to strongly disagree. The print statement is simple, easy to understand, and easy to use.
[Paul Moore]
While I agree that mostly the print statement is "simple, easy to understand, and easy to use", I've seen the trailing-comma version cause confusion for a lot of newbies. I wouldn't mind at all if the trailing-comma version disappeared in Python 3.0 -- if you need this kind of complicated output, you can always use sys.stdout.write and/or string formatting. The spaces-between-items point that Paul Moore makes is IMHO the best argument against the proposed write*() functions. I think we *do* need a statement or function of some sort that does the most basic task: writing a line to sys.stdout that calls str() on each of the elements and joins them with spaces. That is, I think we need to keep *something* with functionality like: def XXX(*args): sys.stdout.write('%s\n' % ' '.join(str(a) for a in args)) Note that this would keep the Hello World example simple: XXX(greeting, name) STeVe -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy

Steven Bethard wrote:
Hypertalk (the programming language of Apple's Hypercard) had an interesting way of doing this. There were two string concatenation operators: a regular one, and a "concatenate with a space between" operator. Using these, you could build up strings for output quite nicely. It helped somewhat that Hypertalk really only had strings as a data type. A Python version of this operator would need to be willing to convert either or both operands to strings. -- Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg.ewing@canterbury.ac.nz +--------------------------------------+

Steven Bethard wrote:
... as proposed, but ...
... the trailing-comma version is indeed BASIC voodoo of ancient heritage, and not something I'd personally miss.
Of course, for Python 3.0 if we lose the keyword there's nothing to stop us calling the convenience function "print". With the removal of the trailing-comma functionality we'd only have to add parentheses to 2.X print statements to have them work :-) Next question: could the function have a sensible return value, or is None the best possible result? hesitating-to-suggest-minus-one-ly y'rs - steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/

>> And good riddance! The print statement harks back to ABC and even >> (unvisual) Basic. Out with it! Barry> I have to strongly disagree. The print statement is simple, easy Barry> to understand, and easy to use. I'm with Barry. Even for non-debug use the print statement is suitable for the majority of my output. Skip

skip@pobox.com wrote:
99.9% of my Python code is test harnesses to run low-level hardware control interface tests, for which printing to stdout works perfectly. Maybe one day I'll stick a GUI on the front end of them, but even then I will probably just be using subprocess to invoke the command line versions behind the scenes. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com

I like the present print statement because parentheses are inconvenient to type compared to lowercase letters, and it looks less cluttered without them. The parentheses in writeln("hello world") don't add any more meaning than a terminating semicolon would, so why are they necessary? Why not instead change the language so as to allow any function call to be written without parentheses (when this is unambiguous)? This could make Python more convenient for creating imperative-style DSLs (though I'm not sure this is a goal). In any case, I think "write" would be better than "print", because it is easier to type (at least for me; reaching for 'w' and than 'r' goes much faster than reaching for 'p'). I don't like "writeln" though, as in 9 of 10 cases I want the line break to be there. I'd rather have write add the line break, and "writeraw" or somesuch exclude it. By the way, if print has to go, then what about the assert, raise, and import statements? Should these be changed to use function call syntax as well? (By the way, assert and raise could be methods: ZeroDivisionError.assert(denom != 0). Surprising that Java doesn't do this ;-) Fredrik

On 9/1/05, Fredrik Johansson <fredrik.johansson@gmail.com> wrote:
Given all the other syntax it would be too ambiguous. If you really want this, please sit down and design a grammar. If you can't do that, just believe me that it would be too nasty (with too many exceptional cases) to bother.
Yuck. Also, write() and writeln() have a long history going back to Pascal. Java has print() and println(). Plus stream.write("abc") already has a meaning, and the elegance of my proposal is that that meaning remains unchanged.
It can't work for import because it defines a new name; if import were a function, then import(foo) would necessarily mean to evaluate foo first, which isn't what you want. It could work for raise (and even for break and continue) but I'd rather keep control flow as statements; you never know what the compiler could do with the information that a particular block doesn't contain a raise statement. It can't work for assert because you don't want the argument to be evaluated in -O mode. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
Here I have to agree with Barry. print is very handy, and print>> is, too. I'd rather see exec and assert becoming a function.
Do we really need writef()? It seems to be not much better than its %-formatting equivalent.
If write* is introduced, this is absolutely necessary. Reinhold -- Mail address is perfectly valid!

Actually, formatting needs to become a function. The overloading of the arithmetic mod operator has proven to be unfortunate (if only because of precedence issues). Also, the format coding scheme itself needs to be revisited. There is no shortage of people who have taken issue with the trailing s in %(myvar)s. Raymond

On 9/1/05, Raymond Hettinger <raymond.hettinger@verizon.net> wrote:
For me, it's not so much the precedence, but the fact that "%s" % x doesn't work as expected if x is a tuple; you'd have to write "%s" % (x,) which is tedious.
Maybe the syntax used in the string.Template class is the way to go? -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Right. That too.
string.Template is a bit too simplified. But perhaps it can be adapted. We still want some way to express %r, %6.2f, etc. Since string formatting has been around since Tim was in diapers, we should probably start by looking at the solutions used by other languages. With Py3.0, we have a real opportunity to break-away from doing things the way C does it. Raymond

On 9/1/05, Raymond Hettinger <raymond.hettinger@verizon.net> wrote:
Hrm. Most other languages these days do floating point formatting the way C does it. I'm happy to look for other ways to invoke the thing, but I think that we shouldn't tinker with %6.2f. (In fact, the major complaint is about the one place where I *did* tinker with it -- %(boo)s.) Maybe the ${boo} form can be extended to allow ${boo%6.2f} ??? Unfortunately that would prevent a different extension of ${boo}: %{boo+far}. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
May I also suggest the following shortcut for creating and evaluating a string template. (Ever since I thought of this, I've actually used this in code without thinking... it's just too natural): message = $"Hello, $name!" Shane

Shane Hathaway wrote:
As I recall, this has been considered before, and rejected on the grounds that it's too visually confusing having $ signs both inside and outside the quotes. -- Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg.ewing@canterbury.ac.nz +--------------------------------------+

[Raymond Hettinger]
[Guido van Rossum]
[Raymond Hettinger]
I was curious about what kind of options there were, so I googled around a bit. Here's what I found: Java[1] uses syntax like: %[argument_index$][flags][width][.precision]conversion which is basically the same as that of C, with positional argument specifiers. Some examples: String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c); System.out.format("Local time: %tT", Calendar.getInstance()); formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d") Classes can customize formatting for the 's' specifier by implementing the Formattable interface, which provides a method: formatTo(Formatter fmt, int f, int width, int precision) You can get formatted objects by calling: * The format() methods on Formatter objects * The format() methods on Strings * The format() methods on System.out, System.err, etc. .Net[2] uses syntax like: {index[,alignment][:formatString]} with examples like: String.Format("{0:dddd MMMM}", DateTime.Now) Console.WriteLine("{0:C}", MyInt) String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}", myName, DateTime.Now) Classes can customize formatting for any specifier by implementing the ICustomFormatter interface: Format(string format, object arg, IFormatProvider formatProvider); or the IFormattable interface: ToString(string format, IFormatProvider formatProvider); You can get formatted objects by calling: * The ToString method of an IFormattable instance * The Format on Strings * The Write and WriteLine methods of Console, TextWriter, StreamWriter, etc. objects I also briefly looked at Tcl/Tk[3], Common Dylan[4], OCaml[5] and Ruby[6][7], which all appear to use C-style (or similar) formatting. I believe that Ruby, in addition to having printf and sprintf, also uses the % operator like Python does. This was a pretty small sample of languages (just the first few that showed up in google), and I didn't really look at any of them other than Java and .Net in much depth, so I've may have misunderstood some of it. That said, I think it's probably pretty reasonable to conclude that C-style formatting is the choice of a lot of other languages. (Not to imply that it therefore needs to be the choice of Python.) I understand one of the complaints about string formatting in Python is having to write the "s" on things like "%(key)s". I was hoping to get some ideas for alternatives here, but I wasn't able to find any dict-style insertion like in Python. There were a few languages (Java, Tcl) with the N$ positional-style insertion, but I don't think that helps us much. People have also been discussing a builtin format() function to replace the current % operator. Translating into Python the location of the formatting operations in the languages above suggests the following possibilities: * Have all __str__() methods take additonal formatting arguments * Add a format() builtin * Add format() methods on str and unicode objects * Add format() methods on all Python streams (files, sys.stdin, etc.) Of course, these possibilities aren't mutually exclusive, but TOOWTDI suggests that we probably shouldn't have too many of them. If people know of other languages that have a different approach to string formatting, it might be useful to see them. BTW, I intentionally didn't go into Perl's string formatting because I don't know it that well, and figured there are people on this list much more qualified than myself to present it. [1]http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html [2]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm... [3]http://www.tcl.tk/man/tcl8.0/TclCmd/format.htm [4]http://gauss.gwydiondylan.org/books/drm/drm_57.html [5]http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html [6]http://www.rubycentral.com/book/ref_c_string.html#String._pc [7]http://www.rubycentral.com/book/ref_m_kernel.html#Kernel.sprintf Steve -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy

If people know of other languages that have a different approach to string formatting, it might be useful to see them.
Common Lisp has something broadly C-like but bigger and hairier. It includes powerful-but-confusing looping and conditional features, letting you say things like (format t "~{~^, ~A~}" 1 2 3 "wombat") which produces 1, 2, 3, wombat or -- you may wish to be sitting down before reading further -- (format t "~#[nothing~;~S~;~S and ~S~:;~@{~#[~; and~] ~S~^ ,~}~]." 1 2 3 "wombat") which produces 1, 2, 3, and wombat and also does the Right Thing with 0, 1 or 2 items. (The first argument to FORMAT, in case you were wondering, determines where the output should go. Feeding in T, as here, sends it to stdout. You can also give it an arbitrary stream, or NIL to return the formatted result as a string.) For the impressive and horrifying full story, see http://www.lisp.org/HyperSpec/Body/sec_22-3.html Most of the features of CL's formatted output are probably, shall we say, inappropriate for Python. It might still be worth a look, to see if there's anything under the rococo exterior that would fit. * Some languages have "picture" formats, where the structure of the format string more closely mimics that of the desired output. (This is true, e.g., of some Basics and of one variety of Perl output.) The trouble with this is that it limits how much information you can provide about *how* each value is to be formatted within the available space. * C++'s << operator represents another way to do formatted output. I regard it as an object lesson in bad design. -- g

I wrote:
C++'s << operator represents another way to do formatted output. I regard it as an object lesson in bad design.
... and should add: Of course it's usually seen as being about output more than about formatting, but in fact if you want to do what Python does with "%", C with "sprintf" and Common Lisp with (format nil ...) then the Right Thing in C++ (in so far as that exists) is usually to use << with a string stream. -- g

Le lundi 05 septembre 2005 à 16:52 +0100, Gareth McCaughan a écrit :
Uh, what about internationalization (i18n) ? In i18n you can't avoid the need for parameterized strings. For example I want to write : _("The file '%s' is read only") % filename not : _("The file") + " '" + filename + "' " + _("is read only") because the splitting in the second form will not translate correctly into other languages. You *have* to supply the whole non-splitted sentence to the translators. The bottom line, IMHO, is that there are frequent uses that mandate a nice and easy to use formatting operator. Python has it, let's not remove it. Regards Antoine.

On Mon, 2005-09-05 at 12:07, Antoine Pitrou wrote:
Actually, this was part of the motivation behind PEP 292 and Template strings, because what you really want is named parameters, not positional parameters: 'The file $filename in directory $dir is read only' There are a few techniques for getting full i18n for Template strings. -Barry

[Barry Warsaw]
'The file $filename in directory $dir is read only'
There are a few techniques for getting full i18n for Template strings.
Yet, "The file %(filename)s in directory %(dir)s is read only" % vars() is already usable. The need being already filled without Template strings, it could hardly be presented as a motivation for them. :-) -- François Pinard http://pinard.progiciels-bpi.ca

On Monday 2005-09-05 17:07, Antoine Pitrou wrote:
Yes. If you think I was arguing the opposite, then I failed to communicate clearly and I apologize.
It's clear (I think) that a good way of formatting strings is necessary. It's less clear what the best way is. Python's % is pretty good; perhaps it's possible to do even better. For instance, take your I18N example. Not all languages have the same word order, as you've observed. When there's more than one parameter, Python's %-interpolation isn't enough in general; you'd need something that can reorder the parameters. I don't know whether this is worth complicating string formatting for, but it's not obvious that it isn't. -- g

Yes. If you think I was arguing the opposite, then I failed to communicate clearly and I apologize.
Actually, I didn't interpret your message like that, but as I had already seen that proposal (to suppress string formatting), I thought it would be the right time to react ;)
Well, I totally agree. I think it could be nice to both: - introduce positional formatting : "%1", "%2"... - make type specification optional, since Python can figure out the type by itself and use the right method; you would only specify the type when you want to have a different formatting (for example, for floats, you could use "%g2" instead of "%2" which would be equivalent to "%f2") Regards Antoine. -- « On dit que pétrir c'est modeler, Moi je dis que péter c'est démolir. » Stupéflip

Reinhold Birkenfeld wrote:
Does it have to be a function? I'd expect it to be a method, like string.Template. E.g
BTW, I'm quite happy with the current string formatting format. I certainly haven't "taken issue with the trailing s in %(myvar)s". If it wasn't there, when it is for %(count)i and %(ratio)f, I'd probably wonder why. STeVe -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy

I have to agree with Barry, Paul, Fredrik, Reinhold, etc. Removing the "print" statement would immediately break at a fundamental level 15 years of tutorials, books, and examples, many of which start with
print "Hello, World!"
Of course, maybe that's the idea -- this is not your father's Python! (Though that slogan apparently didn't work out so well for Oldsmobile...) Is there a syntax trick here? Suppose start-of-the-line function names not followed by an open-paren, but followed by comma-separated lists of expressions, were treated as if the rest of the line were arguments to a function. That is, suppose print "foo", 3, dir(sys) was automagically converted to print ("foo", 3, dir(sys)) Not sure I like this kind of trickyness, though. Though it might be useful for "assert", "raise", maybe "exec", too. I also don't quite see the point of adding new top-level reserved words or built-in functions like "write". It clutters the namespace without being much of an improvement over "sys.stdout.write", IMO. Some kind of printf would be nice to have, but with Python's forgiving syntax is easy enough to add yourself.
Maybe the syntax used in the string.Template class is the way to go?
If you'd consider extending the Template syntax to positional parameters ($1, $2, etc.), then perhaps "print" could be modified to use the template for formatting, if it occurs as the first argument: print string.Template("arg $1, arg $2"), arg1, arg2 with an alternate form printf "arg $1, arg $2", arg1, arg2 where the first arg is required to be a template pattern string. This is a nice improvement over C printf in that you can re-use arguments. What happens to Template() when the string module goes away? Do we write "arg $1, arg $2".Template() instead? Bill

And good riddance! The print statement harks back to ABC and even (unvisual) Basic. Out with it!
Guido, After reviewing the PEP 3000 notes, I can find no justification there for removing "print" other than your statement here -- that it has served honorably and well in many programming languages for many years, a curious reason for abandoning it. There's a pointer to Python Regrets, but that document contains no justification for the change. (Actually, using pointers to Powerpoint slides to explain/justify anything is, er... -- what's a polite euphemism for "a sign of a weak mind"? :-) I agree that "print" is already a bit peculiar, but so what? If we wanted Scheme, we'd be programming in Scheme, not Python. The only other parts of PEP 3000 I take issue with are the removal of "reduce" (a little) and "lambda" (a bit more seriously). I use reduce a lot, but it's easy enough to cobble together oneself, given the changes in Python over the last 10 years. Bill

Bill Janssen <janssen@parc.com> wrote:
And good riddance! The print statement harks back to ABC and even (unvisual) Basic. Out with it!
I'm with Guido on this, BTW.
After reviewing the PEP 3000 notes, I can find no justification there for removing "print"
Well, how about the fact that basically all of Python's statements are for implementing logic (if, while, etc), controlling flow (return, yield, try, etc), and defining structure (def, class, etc). `print` stands pretty much alone as a statement which does none of these things -- in fact, it does nothing for the program but merely has the interesting side-effect of writing to stdout. It's an anomaly. It stands out in the language as a sore thumb waiting for Guido's hammer. Charles -- ----------------------------------------------------------------------- Charles Cazabon <python@discworld.dyndns.org> GPL'ed software available at: http://pyropus.ca/software/ -----------------------------------------------------------------------

On Thu, Sep 01, 2005 at 11:12:57PM +0200, Fredrik Lundh wrote:
I'd say: yeah, real programmers don't generate output _to stdout_ sockets, GUI widgets, buffers? sure. stdout? Almost never. Most of these don't have write() methods so I've never had a reason to use the "print >>" syntax. -jackdied

On Sep 1, 2005, at 2:27 PM, Jack Diederich wrote:
That is absolutely true, print is becoming less and less useful in the context of GUI or web applications. Even in Just Debugging scenarios, you're probably better off using something with more flexibility, such as the logging module. Additionally, the fact that sys.stdout is for bytes and not a text (unicode) makes it even more complicated. You can, of course, replace sys.stdout with an encoding-aware wrapper via codecs.getwriter (), but that's often inconvenient. -bob

On Thu, 2005-09-01 at 17:49, Bob Ippolito wrote:
That is absolutely true, print is becoming less and less useful in the context of GUI or web applications.
I know we're dinosaurs, but some of us still write console apps in Python!
The logging module is great, but logging and debugging are two different things (although that fact is obscured when you don't have a console). print is useful in scenarios other than debugging. And while I do occasionally use it, I wouldn't be too heartbroken if the trailing comma form were lost. I /would/ mourn the loss of print>> though -- not necessarily the syntax, which was clearly a compromise, but the functionality. If we could have spelled it "print to sys.stderr" we would have. -Barry
participants (35)
-
Antoine
-
Antoine Pitrou
-
Barry Warsaw
-
Bill Janssen
-
Bob Ippolito
-
Calvin Spealman
-
Charles Cazabon
-
Collin Winter
-
François Pinard
-
Fred L. Drake, Jr.
-
Fredrik Johansson
-
Fredrik Lundh
-
Gareth McCaughan
-
Greg Ewing
-
Guido van Rossum
-
Jack Diederich
-
James Y Knight
-
JustFillBug
-
Kay Schluehr
-
Krzysztof Zych
-
Michael Hoffman
-
Neal Norwitz
-
Nick Coghlan
-
Nick Craig-Wood
-
Oren Tirosh
-
Oren Tirosh
-
Paul Moore
-
Raymond Hettinger
-
Reinhold Birkenfeld
-
Robert Kern
-
Ron Adam
-
Shane Hathaway
-
skip@pobox.com
-
Steve Holden
-
Steven Bethard