Dreaming of new generation IDE

3 views
Skip to first unread message

Vladimir Ignatov

unread,
Feb 3, 2010, 6:10:21 AM2/3/10
to pytho...@python.org
Hello,

I am sitting here for quite some time, but usually keep silent ;-) I
use Python since 2003 both "professionally" and for my hobby projects
and love it a much.
I notice however, that "maintaining" existing/older python code is may
be not so enjoyable task. It may be even harder than supporting old
code written in some type of "static" languages (like Java or C++).
Surely "dynamic" nature of python comes with price.

Finally I develop a feeling that strong instrumentation / tools can
bring us the best of two worlds. That I am dreaming on is an absolute
new type/class of IDE suitable for Python and potentially for other
dynamic-type languages. Instead of current text-oriented IDEs, it
should be a database-centric and resemble current CAD systems instead
of being just "fancy text editor". Source text should be an output
product of that CAD and not a "source material" itself.

Well. I understand that it is a very ambitious and experimental stuff.
Great efforts and motivation needed even to get something "runnable".
So I am looking for someone to get in kind of "virtual partnership".
If someone interesting it that soft of stuff, I would like to talk and
discuss this system.

Vladimir Ignatov

Paul Rubin

unread,
Feb 3, 2010, 8:07:28 AM2/3/10
to
Vladimir Ignatov <kmi...@gmail.com> writes:
> I notice however, that "maintaining" existing/older python code is may
> be not so enjoyable task. It may be even harder than supporting old
> code written in some type of "static" languages (like Java or C++).
> Surely "dynamic" nature of python comes with price.

Yes, this is a well known drawback of dynamic typing. The usual remedy
is lots and lots of test automation (a full suite of unit and
integration tests that you run on every build, that check the properties
of basically every function in your program).

> Instead of current text-oriented IDEs, it
> should be a database-centric and resemble current CAD systems

I've never used a current CAD system, so I can't make any sense of this.
I don't see how databases would help.

Stefan Behnel

unread,
Feb 3, 2010, 8:16:45 AM2/3/10
to
Paul Rubin, 03.02.2010 14:07:

>> Instead of current text-oriented IDEs, it
>> should be a database-centric and resemble current CAD systems
>
> I've never used a current CAD system, so I can't make any sense of this.
> I don't see how databases would help.

Just like they help in current IDEs to index the source code.

Stefan

Adam Tauno Williams

unread,
Feb 3, 2010, 8:18:40 AM2/3/10
to pytho...@python.org
On Wed, 2010-02-03 at 14:10 +0300, Vladimir Ignatov wrote:
> Hello,
> I am sitting here for quite some time, but usually keep silent ;-) I
> use Python since 2003 both "professionally" and for my hobby projects
> and love it a much.
> I notice however, that "maintaining" existing/older python code is may
> be not so enjoyable task. It may be even harder than supporting old
> code written in some type of "static" languages (like Java or C++).
> Surely "dynamic" nature of python comes with price.

Yes, it certainly does. Not that you'll get many Pythonistas to confess
to that fact. Somehow those who brag about the readability and
expressiveness of source code just cannot admit that:

class.method(sting name, int count)

- is *obviously* more expressive than -

class.method(name, count)

Oh, well.

This is obvious even in the Python documentation itself where one
frequently asks oneself "Uhh... so what is parameter X supposed to be...
a string... a list... ?"

Not knocking Python; Python is great. I maintain a rapidly growing
Python code base. But the above is almost comically funny sometimes
[sand.insert_head(pythonista)].

> Finally I develop a feeling that strong instrumentation / tools can
> bring us the best of two worlds. That I am dreaming on is an absolute
> new type/class of IDE suitable for Python and potentially for other
> dynamic-type languages. Instead of current text-oriented IDEs, it
> should be a database-centric and resemble current CAD systems instead
> of being just "fancy text editor". Source text should be an output
> product of that CAD and not a "source material" itself.

Ugh, please NO! This has been attempted many many times in many
environments - it always fails *terribly*.

Stefan Behnel

unread,
Feb 3, 2010, 8:35:41 AM2/3/10
to
Adam Tauno Williams, 03.02.2010 14:18:

> This is obvious even in the Python documentation itself where one
> frequently asks oneself "Uhh... so what is parameter X supposed to be...
> a string... a list... ?"
>
> Not knocking Python; Python is great. I maintain a rapidly growing
> Python code base. But the above is almost comically funny sometimes
> [sand.insert_head(pythonista)].

So, what's "pythonista" in the above? A dummy?

Stefan

Jean-Michel Pichavant

unread,
Feb 3, 2010, 8:51:46 AM2/3/10
to Adam Tauno Williams, pytho...@python.org
Adam Tauno Williams wrote:
> Yes, it certainly does. Not that you'll get many Pythonistas to confess
> to that fact. Somehow those who brag about the readability and
> expressiveness of source code just cannot admit that:
>
> class.method(sting name, int count)
>
> - is *obviously* more expressive than -
>
> class.method(name, count)
>
>
class.method(string name, int count):
"""Return the cap'tain's age.

name: a string giving the name of the cap'tain daughter
count: an int giving the number of fingers left in the cap'tain
right hand
"""

In python, attributes/parameters have no type (but you know that). By
specifying them in the method signature, you're just duplicating the
information hold in the docstring.

JM

Vladimir Ignatov

unread,
Feb 3, 2010, 8:54:26 AM2/3/10
to pytho...@python.org
> This is obvious even in the Python documentation itself where one
> frequently asks oneself "Uhh... so what is parameter X supposed to be...
> a string... a list... ?"

Exactly. Often I don't need to know the exact type, but to figure out
that "kind of type" it is.

>> should be a database-centric and resemble current CAD systems instead
>> of being just "fancy text editor". Source text should be an output
>> product of that CAD and not a "source material" itself.
>
> Ugh, please NO!  This has been attempted many many times in many
> environments - it always fails *terribly*.

Can you give some examples of such systems? (maybe just names for
googling for) I don't see anything dirt in storing some additional
meta-information about the code under development and using it later
for all kind of benefits (easy refactoring for example). As with your
example with "parameter x", some additional information can be
"attached" to this paramer. Later it can be used during
code-generation phase and placed as "comment" in source code or placed
in popup tag in html-style presentation.

Vladimir Ignatov

Marco Salden

unread,
Feb 3, 2010, 9:18:40 AM2/3/10
to

The maintenance thing may be true but for me that doesn't outweigh the
clear benefits I get from using Python i.s.o. e.g. C++: the fact that
I have much less code that is more compact and for me more directly
readable is a clear advantage when doing maintance on code I didnt
touch for a while. Documenting the essential parameters used with some
examples and some logging helps (for me at least...).

The type of IDE you are looking for is more something like Rational
Rose (e.g. RRT?) type of tooling perhaps? There you "CAD" components
and their statebehavior and the system generates C or C++ code.

Regards,
Marco

Paul Rubin

unread,
Feb 3, 2010, 9:42:52 AM2/3/10
to
Jean-Michel Pichavant <jeanm...@sequans.com> writes:
> class.method(string name, int count):
> """Return the cap'tain's age.
>
> name: a string giving the name of the cap'tain daughter
> count: an int giving the number of fingers left in the cap'tain
> right hand
> """
>
> In python, attributes/parameters have no type (but you know that). By
> specifying them in the method signature, you're just duplicating the
> information hold in the docstring.

It's not enough to just document (except as an aid to remembering) since
the compiler and runtime don't enforce the documentation. You have to
use static typing or write tests, to flag all the call sites if you
change the signature. One nice trick with static types is if you change
what the method does (even if its type signature doesn't change), you
can rename the method:

class.method2(string name, int count): # change 'method' to 'method2'

and recompile your codebase. Every place in the code that called
'method' now gets a compile time "undefined method" error that you can
examine to see if you need to update it. This is something you can't
catch with unit tests because the call sites can be in distant modules.

Vladimir Ignatov

unread,
Feb 3, 2010, 9:58:25 AM2/3/10
to pytho...@python.org
> The maintenance thing may be true but for me that doesn't outweigh the
> clear benefits I get from using Python i.s.o. e.g. C++: the fact that
> I have much less code that is more compact and for me more directly
> readable is a clear advantage when doing maintance on code I didnt
> touch for a while. Documenting the essential parameters used with some
> examples and some logging helps (for me at least...).

Python is very easy to write. But with code grow and time passes,
things get worse. Currently I tries to reanimate one of my old
freeware project and faced it again.

> The type of IDE you are looking for is more something like Rational
> Rose (e.g. RRT?) type of tooling perhaps? There you "CAD" components
> and their statebehavior and the system generates C or C++ code.

Perhaps. I newer use Rational Rose but hear about it. But I use some
other Rational* products and they scare me a lot. So maybe Rose can be
used for "inspiration" but not much more. Actually I don't want to
put programmer in GUI-fashioned env. with a lot of buttons and
switches. I think about "classic" text-like view but that actually
"understands" that are you doing (typing) on. So your types goes in
"datastore" first and then renders back as a text representation.
Something like this.

Vladimir Ignatov

David Cournapeau

unread,
Feb 3, 2010, 10:24:00 AM2/3/10
to Adam Tauno Williams, pytho...@python.org
On Wed, Feb 3, 2010 at 10:18 PM, Adam Tauno Williams
<awil...@opengroupware.us> wrote:

> On Wed, 2010-02-03 at 14:10 +0300, Vladimir Ignatov wrote:
>> Hello,
>> I am sitting here for quite some time, but usually keep silent ;-) I
>> use Python since 2003 both "professionally" and for my hobby projects
>> and love it a much.
>> I notice however, that "maintaining" existing/older python code is may
>> be not so enjoyable task. It may be even harder than supporting old
>> code written in some type of "static" languages (like Java or C++).
>> Surely "dynamic" nature of python comes with price.
>
> Yes, it certainly does.  Not that you'll get many Pythonistas to confess
> to that fact.  Somehow those who brag about the readability and
> expressiveness of source code just cannot admit that:

Static typing sounds "obviously" better only if you assume everything
else being equal. But the typing system also often goes in the way
when developing large codebases, when you need to refactor things,
etc... So if for a *given* codebase, you get type information, it is
almost certainly very helpful. But when you need to change this
codebase, maybe not so much.

There was a nice paper from people at Adobe which mentioned this very
aspect, focusing on how to maintain a significant codebase, from
prototype-kind of development to maintenance-kind of development:
http://www.ecmascript.org/es4/spec/evolutionary-programming-tutorial.pdf.
It strikes me as a good way to look at this tradeoff between static
and dynamic typing, where the dynamic typing for some "mostly frozen"
code areas has diminishing returns,

David

Adam Tauno Williams

unread,
Feb 3, 2010, 10:39:53 AM2/3/10
to pytho...@python.org
On Wed, 2010-02-03 at 16:23 +0100, Stef Mientki wrote:
> Yes, it certainly does. Not that you'll get many Pythonistas
> to confess
> to that fact. Somehow those who brag about the readability
> and
> expressiveness of source code just cannot admit that:
> class.method(sting name, int count)
> - is *obviously* more expressive than -
> class.method(name, count)
> Oh, well.

> This is obvious even in the Python documentation itself where
> one
> frequently asks oneself "Uhh... so what is parameter X
> supposed to be...
> a string... a list... ?"

> But I thought that was the one of beauties of Python, you don't need
> to know if the input parameter is a list or a string.

You don't need to know; unless of course you want the expected result.

Vladimir Ignatov

unread,
Feb 3, 2010, 10:48:12 AM2/3/10
to pytho...@python.org
> I don't see what the advantage of the use of a database is in a fairly
> linear hierarchical structure like python objects and modules.

Imagine simple operation like "method renaming" in a simple "dumb"
environment like text editor + grep. Now imagine how simple it can be
if system "knows" all your identifiers and just regenerates relevant
portions of text from internal database-alike representation.

> You mean something like LabView ?

No, I don't think so. I never use LabView but imagine it something
very "graphical-oriented". No, I think about more "classic" text view.
But back-ended with "smart" underlying system - not just obvious
"text".

Vladimir Ignatov

Stef Mientki

unread,
Feb 3, 2010, 10:52:52 AM2/3/10
to pytho...@python.org
On 03-02-2010 16:48, Vladimir Ignatov wrote:
>> I don't see what the advantage of the use of a database is in a fairly
>> linear hierarchical structure like python objects and modules.
>>
> Imagine simple operation like "method renaming" in a simple "dumb"
> environment like text editor + grep. Now imagine how simple it can be
> if system "knows" all your identifiers and just regenerates relevant
> portions of text from internal database-alike representation.
>
I think every IDE (not older than 20 years) does that already.
cheers,
Stef

banibra...@gmail.com

unread,
Feb 3, 2010, 10:50:16 AM2/3/10
to pytho...@python.org
-----Original Message-----
From: Vladimir Ignatov
Sent: 03/02/2010 7:24:26 pm
Subject: Re: Dreaming of new generation IDE

> This is obvious even in the Python documentation itself where one
> frequently asks oneself "Uhh... so what is parameter X supposed to be...
> a string... a list... ?"

Exactly. Often I don't need to know the exact type, but to figure out


that "kind of type" it is.

>> should be a database-centric and resemble current CAD systems instead


>> of being just "fancy text editor". Source text should be an output
>> product of that CAD and not a "source material" itself.
>

> Ugh, please NO!  This has been attempted many many times in many
> environments - it always fails *terribly*.

Can you give some examples of such systems? (maybe just names for
googling for) I don't see anything dirt in storing some additional
meta-information about the code under development and using it later
for all kind of benefits (easy refactoring for example). As with your
example with "parameter x", some additional information can be
"attached" to this paramer. Later it can be used during
code-generation phase and placed as "comment" in source code or placed
in popup tag in html-style presentation.

BD> probably close to Java annotations perhaps? And as for the CAD approach, would a UML reverse engg tool help ? If yes, perhaps you could give BOUML a shot.

Regards,
Banibrata

Vladimir Ignatov

unread,
Feb 3, 2010, 12:21:20 PM2/3/10
to pytho...@python.org
>> Imagine simple operation like "method renaming" in a simple "dumb"
>> environment like text editor + grep. Now imagine how simple it can be
>> if system "knows" all your identifiers and just regenerates relevant
>> portions of text from internal database-alike representation.
>>
>
> I think every IDE (not older than 20 years) does that already.

And fix every reference to it in all files? For python? I don't think
so. I even don't think this is possible at all. That if several
different objects have a similar named method? How will IDE "classify"
calls and renames only some of calls and not others?

Vladimir Ignatov

Phlip

unread,
Feb 3, 2010, 1:05:30 PM2/3/10
to
On Feb 3, 3:10 am, Vladimir Ignatov <kmis...@gmail.com> wrote:

> Finally I develop a feeling that strong instrumentation / tools can
> bring us the best of two worlds. That I am dreaming on is an absolute
> new type/class of IDE suitable for Python and potentially for other
> dynamic-type languages. Instead of current text-oriented IDEs, it
> should be a database-centric and resemble current CAD systems instead
> of being just "fancy text editor". Source text should be an output
> product of that CAD and not a "source material" itself.

That's fine so long as I can also treat the source as source, at need.

You may have just reinvented Smalltalk's Squeak editor (reputedly the
testbed for all of modern GUIs...).

Current editors suck because they can't see into the code and browse
it - unless it's so statically typed it's painful.

That's why I wrote this:

http://www.oreillynet.com/onlamp/blog/2008/05/dynamic_languages_vs_editors.html

John Bokma

unread,
Feb 3, 2010, 1:24:43 PM2/3/10
to
Vladimir Ignatov <kmi...@gmail.com> writes:

> Finally I develop a feeling that strong instrumentation / tools can
> bring us the best of two worlds. That I am dreaming on is an absolute
> new type/class of IDE suitable for Python and potentially for other
> dynamic-type languages. Instead of current text-oriented IDEs, it
> should be a database-centric and resemble current CAD systems instead
> of being just "fancy text editor". Source text should be an output
> product of that CAD and not a "source material" itself.

Your idea is certainly not new. Moreover, I've been using such an IDE
and implemented support for a (small) language in it:

Programs are hierarchical compositions of formulae satisfying
structural and extra-structural relationships. A program editor can
use knowledge of such relationships to detect and provide immediate
feedback about violations of them. The Synthesizer Generator is a
tool for creating such editors from language descriptions. An editor
designer specifies the desired relationships and the feedback to be
given when they are violated, as well as a user interface; from the
specification, the Synthesizer Generator creates a full-screen editor
for manipulating programs in the language.

http://portal.acm.org/citation.cfm?id=390010.808247

It might be a good start to read as much as possible on the Synthesizer
Generator if you want to write such an IDE for Python. I am sure you
could write such an IDE in the Synthesizer Generator, but I have no idea
if it's still available. And back when I used it (at university) one had
to pay for it, and most likely was closed source as well.

See also: http://www.google.com/search?q=synthesizer%20generator

--
John Bokma j3b

Hacking & Hiking in Mexico - http://johnbokma.com/
http://castleamber.com/ - Perl & Python Development

Stef Mientki

unread,
Feb 3, 2010, 1:54:14 PM2/3/10
to pytho...@python.org
On 03-02-2010 18:21, Vladimir Ignatov wrote:
>>> Imagine simple operation like "method renaming" in a simple "dumb"
>>> environment like text editor + grep. Now imagine how simple it can be
>>> if system "knows" all your identifiers and just regenerates relevant
>>> portions of text from internal database-alike representation.
>>>
>>>
>> I think every IDE (not older than 20 years) does that already.
>>
> And fix every reference to it in all files? For python? I don't think
> so. I even don't think this is possible at all.
with tools like inspect it certainly should be possible

> That if several
> different objects have a similar named method? How will IDE "classify"
> calls and renames only some of calls and not others?
>
yep, you're right,
the IDE's I use have as the beste "search / select / rename".

But how often do you must/want to rename something (mature) ?

cheers,
Stef
> Vladimir Ignatov
>

Adam Tauno Williams

unread,
Feb 3, 2010, 1:57:51 PM2/3/10
to pytho...@python.org
On Wed, 2010-02-03 at 10:05 -0800, Phlip wrote:
> On Feb 3, 3:10 am, Vladimir Ignatov <kmis...@gmail.com> wrote:
> > Finally I develop a feeling that strong instrumentation / tools can
> > bring us the best of two worlds. That I am dreaming on is an absolute
> > new type/class of IDE suitable for Python and potentially for other
> > dynamic-type languages. Instead of current text-oriented IDEs, it
> > should be a database-centric and resemble current CAD systems instead
> > of being just "fancy text editor". Source text should be an output
> > product of that CAD and not a "source material" itself.
> That's fine so long as I can also treat the source as source, at need.
> You may have just reinvented Smalltalk's Squeak editor (reputedly the
> testbed for all of modern GUIs...).
> Current editors suck because they can't see into the code and browse
> it - unless it's so statically typed it's painful.

? I edit Python in MonoDevelop 2.2; and I can browse my file,
classes, etc... So I don't know what you mean by "can't see into the
code". It works pretty well.

Of course it can't tell that I've set x = {an integer}, as that only
happens at runtime.

Phlip

unread,
Feb 3, 2010, 2:38:57 PM2/3/10
to
On Feb 3, 10:57 am, Adam Tauno Williams <awill...@opengroupware.us>
wrote:

> > Current editors suck because they can't see into the code and browse
> > it - unless it's so statically typed it's painful.
>
> ?  I edit Python in MonoDevelop  2.2;  and I can browse my file,
> classes, etc...  So I don't know what you mean by "can't see into the
> code".  It works pretty well.
>
> Of course it can't tell that I've set x = {an integer}, as that only
> happens at runtime.
>
> > That's why I wrote this:
> > http://www.oreillynet.com/onlamp/blog/2008/05/dynamic_languages_vs_editors.html

You just said that your code browsing "works pretty well, except when
it doesn't".

Hence my blog entry. If your editor analyzed your code at runtime,
instead of just static analysis, then it could see that x = an
integer, or an object, no matter how dynamic your language.

--
Phlip
http://zeekland.zeroplayer.com/Uncle_Wiggilys_Travels/1

John Bokma

unread,
Feb 3, 2010, 3:08:35 PM2/3/10
to
Phlip <phli...@gmail.com> writes:

In Perl:

my $x = ( 5, "hello", sub {}, [], {} )[ int rand 5 ];

what's $x? The answer is: it depends.

Moreover, even if your editor analyzes your code at runtime (which is
certainly not always desirable) it might not be able to find out what
the type is of x, simply because it would take too much time to find it
out. (It sounds like you want an editor that solves the halting problem
;-) )

I agree with you that to /some extent/ and editor can do analyses, if it
does compilation as well (and even runs the code, but the latter is not
always desirable). I mentioned the Synthesizer Generator before, which
can do compilation on the fly, if you implement it (or if it has been
implemented for the language you edit with it). I've written a very
simple assembler in it, ages ago, which did assembling on the fly.

Robert

unread,
Feb 3, 2010, 3:40:51 PM2/3/10
to
Vladimir Ignatov wrote:
> dynamic-type languages. Instead of current text-oriented IDEs, it
> should be a database-centric and resemble current CAD systems instead
> of being just "fancy text editor". Source text should be an output
> product of that CAD and not a "source material" itself.

can you sketch an example/use case more concretely?


Robert

Phlip

unread,
Feb 3, 2010, 3:44:05 PM2/3/10
to
John Bokma wrote:

> my $x = ( 5, "hello", sub {}, [], {} )[ int rand 5 ];
>
> what's $x? The answer is: it depends.

That's why my blog post advocated (as usual for me) developer tests.
Then you either mock the rand, like all developers should, or you get
what you pay for, and Principle of Least Surprise still applies...

Over the past decade, teams discovered that developer tests more than
made up for the lack of rigor in dynamic languages. A dynamic language
with tests can be more productive than a static language, even with
its runtime type checks AND with its tests.

However, our editors must catch up to us. When I test, I am statically
declaring a set of types, even if the language would prefer to
dynamically fling them hither and yon. We should leverage that.

--
Phlip

John Bokma

unread,
Feb 3, 2010, 4:02:33 PM2/3/10
to
Phlip <phli...@gmail.com> writes:

> John Bokma wrote:
>
>> my $x = ( 5, "hello", sub {}, [], {} )[ int rand 5 ];
>>
>> what's $x? The answer is: it depends.
>
> That's why my blog post advocated (as usual for me) developer tests.
> Then you either mock the rand, like all developers should, or you get
> what you pay for, and Principle of Least Surprise still applies...

Yup, I agree with you that (to some extent) an IDE should be able to
determine types, especially if programmers don't reuse variables, like
(again Perl):

my $result = .... # int
:
:
if ( ... ) {

$result = .... # string
}

# $result can be still an int, or either a string, depending on the
# test.

> Over the past decade, teams discovered that developer tests more than
> made up for the lack of rigor in dynamic languages. A dynamic language
> with tests can be more productive than a static language, even with
> its runtime type checks AND with its tests.

Yup, this matches up with my experience. I can't recall that I ever
bumped into an issue in Perl (the dynamic language I've been using
the most for the past years). Not saying that it hasn't happened, but I
just can't recall. Probably also the reason why a "new" language I am
learning is also dynamic: Python ;-)

> However, our editors must catch up to us. When I test, I am statically
> declaring a set of types, even if the language would prefer to
> dynamically fling them hither and yon. We should leverage that.

I am all for testing, but it should IMO not get into the way. I am quite
happy with Emacs as an editor (I "recently" switched), it satisfies most
(if not all) of the items on the check list.

John Bokma

unread,
Feb 3, 2010, 4:10:56 PM2/3/10
to
Robert <no-...@non-existing.invalid> writes:

I guess Vladimir means what's called a structure editor. The (by me)
aforementioned Synthesizer Generator is an example of such an editor
(environment).

http://en.wikipedia.org/wiki/Structure_editor
http://portal.acm.org/citation.cfm?doid=358746.358755

Vladimir Ignatov

unread,
Feb 3, 2010, 4:24:30 PM2/3/10
to pytho...@python.org
> can you sketch an example/use case more concretely?

Sorry, I don't have anything written down. I just have some rough idea
of implementation and some concrete features I would like to see in
such system. For example:

1) Instant refactoring. No more needs for manual
search/inspect/rename. Since system knows exactly that is going on,
the refactoring will be fully automatic.
2) Show "xref table" for each function. How often this function used?
Where is it used? (code snippets of calls) What functionality is
supported by this function?
3) Extended statistics. How many objects this object/function
interacts with? Popular functions, dead/unused functions.
4) Code smell detector - too long functions, too much interaction with
other objects, global objects, etc.
...

Vladimir Ignatov

Robert Kern

unread,
Feb 3, 2010, 4:27:48 PM2/3/10
to pytho...@python.org

I believe that Smalltalk came pretty close to what Vladimir is asking for. You
wrote the methods as linear plain text, but you used the GUI three pane class
browser to define and navigate classes. You could export class definitions to a
text file and read them back in, but in Vladimir's terms, the text files were
not the "source material" themselves.

http://www.cosc.canterbury.ac.nz/wolfgang.kreutzer/cosc205/smalltalk1.html

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Vladimir Ignatov

unread,
Feb 3, 2010, 4:36:05 PM2/3/10
to pytho...@python.org
> I guess Vladimir means what's called a structure editor. The (by me)
> aforementioned Synthesizer Generator is an example of such an editor
> (environment).

Maybe. Yes, it kind of "generator". It has (entered somehow) internal
representation of target program. Then it generates code out of this
internal data. Yes, it is imaginable system, I don't have any working
prototype yet. But about to start making it. For prototype I choose
python 2.x as implementation language, sqlite as internal database and
Django as UI.

Vladimir Ignatov

Steven D'Aprano

unread,
Feb 3, 2010, 4:37:55 PM2/3/10
to
On Wed, 03 Feb 2010 08:18:40 -0500, Adam Tauno Williams wrote:

> On Wed, 2010-02-03 at 14:10 +0300, Vladimir Ignatov wrote:
>> Hello,
>> I am sitting here for quite some time, but usually keep silent ;-) I
>> use Python since 2003 both "professionally" and for my hobby projects
>> and love it a much.
>> I notice however, that "maintaining" existing/older python code is may
>> be not so enjoyable task. It may be even harder than supporting old
>> code written in some type of "static" languages (like Java or C++).
>> Surely "dynamic" nature of python comes with price.
>

> Yes, it certainly does. Not that you'll get many Pythonistas to confess
> to that fact. Somehow those who brag about the readability and
> expressiveness of source code just cannot admit that:
>
> class.method(sting name, int count)
>
> - is *obviously* more expressive than -
>
> class.method(name, count)


Obviously? I don't know about that. Being told that "count" is an int
doesn't really help me -- it's obvious just from the name. In a well-
written API, what else could it be?

And surely count should be positive or zero but not negative? Saying it's
an int is misleading. Or perhaps count can be negative, in which case
maybe negative counts have some special meaning that isn't obvious from
the function signature. Can I pass None to get the default behaviour?
Either way, I need to read the docs, so the supposed added expressiveness
doesn't actually add much.

And why is count limited to an actual int type, rather than anything
which is integer-like? Why can't I pass 3.0 or Decimal(3)? If you have a
good reason for that limitation, great, but if it's just there to satisfy
the compiler, then boo hiss to you.

I cheerfully admit that *sometimes* there are type restrictions which
make sense, and of course we know that there are sometimes useful
performance gains to be made with static typing. Any compiler which
requires types to be declared is far too 1970s though -- a good modern
static language should use type inference to reduce the number of
declarations needed.

As for Pythonistas refusing to accept this, how do you explain function
annotations then?

Quoting Guido:

"Optional static typing has long been requested as a Python feature."

http://www.artima.com/weblogs/viewpost.jsp?thread=85551


More on function annotations and type inference for Python:

http://lambda-the-ultimate.org/node/1519
http://www.python.org/dev/peps/pep-3107/

http://www.python.org/workshops/2000-01/proceedings/papers/aycock/aycock.html

> This is obvious even in the Python documentation itself where one
> frequently asks oneself "Uhh... so what is parameter X supposed to be...
> a string... a list... ?"

The answer is usually "both, and anything else that obeys some subset of
the sequence or iterable protocols".

--
Steven

Steven D'Aprano

unread,
Feb 3, 2010, 4:40:53 PM2/3/10
to
On Wed, 03 Feb 2010 06:42:52 -0800, Paul Rubin wrote:

> One nice trick with static types is if you change
> what the method does (even if its type signature doesn't change), you
> can rename the method:
>
> class.method2(string name, int count): # change 'method' to
> 'method2'
>
> and recompile your codebase. Every place in the code that called
> 'method' now gets a compile time "undefined method" error that you can
> examine to see if you need to update it. This is something you can't
> catch with unit tests because the call sites can be in distant modules.


I don't understand why that won't work with unit tests. If you change the
name of a method, surely your unit tests will now start failing with
AttributeError?


--
Steven

Steven D'Aprano

unread,
Feb 3, 2010, 4:42:26 PM2/3/10
to
On Wed, 03 Feb 2010 18:48:12 +0300, Vladimir Ignatov wrote:


> Imagine simple operation like "method renaming" in a simple "dumb"
> environment like text editor + grep. Now imagine how simple it can be if
> system "knows" all your identifiers and just regenerates relevant
> portions of text from internal database-alike representation.

Something like Bicycle Repair Man then:

http://bicyclerepair.sourceforge.net/

--
Steven

Steven D'Aprano

unread,
Feb 3, 2010, 4:43:26 PM2/3/10
to


Says who? If you're free to assume the function requires a certain type,
we're free to assume the function is polymorphic and doesn't.


--
Steven

Paul Rubin

unread,
Feb 3, 2010, 5:00:42 PM2/3/10
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:
>> and recompile your codebase. Every place in the code that called
>> 'method' now gets a compile time "undefined method" error that you can
>> examine to see if you need to update it. This is something you can't
>> catch with unit tests because the call sites can be in distant modules.
>
> I don't understand why that won't work with unit tests. If you change the
> name of a method, surely your unit tests will now start failing with
> AttributeError?

Unit tests only test the code in the local module or package ("unit").
Obviously you also need other tests to exercise the interaction between
local and remote modules, but it's harder to be as thorough with those,
or write them as reflexively, in part because they're often written
by a separate group of programmers.

John Bokma

unread,
Feb 3, 2010, 5:24:05 PM2/3/10
to
Vladimir Ignatov <kmi...@gmail.com> writes:

You might check out articles that mention the Synthesizer Generator, etc.
http://citeseer.ist.psu.edu/cis?q=synthesizer+generator&cs=1
http://citeseer.ist.psu.edu/cis?q=structure+editor&cs=1

The idea is not new (at least 30 years old), and those articles might
help you.

Terry Reedy

unread,
Feb 3, 2010, 5:24:50 PM2/3/10
to pytho...@python.org
On 2/3/2010 8:18 AM, Adam Tauno Williams wrote:

> class.method(sting name, int count)
>
> - is *obviously* more expressive than -
>
> class.method(name, count)

So write

class.method(name:str, count:int)->return_type # 3.x

if you really prefer.

In spite of you disparagement of 'pythonistas', it seems that the head
pythonista *did* admit that some people, at least, would prefer such
annotations.

3.0 also added abstract base classes so one can better specify object
classes without losing duck-typing.

import numbers
class.method(name:str, count:numbers.Integral)->return_type

Now one is documenting that count should be an integral value that acts
like an integer even if it is not an int per se. Of course, this is too
broad as it allows (presumably invalid) negative values.

Terry Jan Reedy

Robert Kern

unread,
Feb 3, 2010, 5:27:43 PM2/3/10
to pytho...@python.org

Let's say we have class "A" with a method named "foo" that we change to "bar".
We have another class "B" with a method that accepts and A() instance and calls
the .foo() method on it. It is perfectly reasonable (and often necessary) for
the unit test of class B to use a mock object instead of a real A() instance.
The unit test for class B will fail to catch the renaming of A.foo() to A.bar()
because it never tries to call .foo() on a real A instance.

Of course, in a static language, it's much harder to make mock objects to do
this kind of (very useful!) testing to begin with.

Robert Kern

unread,
Feb 3, 2010, 5:38:21 PM2/3/10
to pytho...@python.org
On 2010-02-03 15:37 PM, Steven D'Aprano wrote:
> On Wed, 03 Feb 2010 08:18:40 -0500, Adam Tauno Williams wrote:
>
>> On Wed, 2010-02-03 at 14:10 +0300, Vladimir Ignatov wrote:
>>> Hello,
>>> I am sitting here for quite some time, but usually keep silent ;-) I
>>> use Python since 2003 both "professionally" and for my hobby projects
>>> and love it a much.
>>> I notice however, that "maintaining" existing/older python code is may
>>> be not so enjoyable task. It may be even harder than supporting old
>>> code written in some type of "static" languages (like Java or C++).
>>> Surely "dynamic" nature of python comes with price.
>>
>> Yes, it certainly does. Not that you'll get many Pythonistas to confess
>> to that fact. Somehow those who brag about the readability and
>> expressiveness of source code just cannot admit that:
>>
>> class.method(sting name, int count)
>>
>> - is *obviously* more expressive than -
>>
>> class.method(name, count)
>
> Obviously? I don't know about that. Being told that "count" is an int
> doesn't really help me -- it's obvious just from the name. In a well-
> written API, what else could it be?

A bool. As in telling the method whether or not it should count something.

That said, I agree with your later point that this kind of information is better
provided by the docstring, not the call signature. Not least because the "type"
may be something wishy-washy and ad-hoc like "sequence" or "string or list of
strings". I do wish that people would document their parameters with this
information a little more consistently, though.

Steven D'Aprano

unread,
Feb 3, 2010, 7:01:06 PM2/3/10
to
On Wed, 03 Feb 2010 16:38:21 -0600, Robert Kern wrote:

>>> class.method(name, count)
>>
>> Obviously? I don't know about that. Being told that "count" is an int
>> doesn't really help me -- it's obvious just from the name. In a well-
>> written API, what else could it be?
>
> A bool. As in telling the method whether or not it should count
> something.

Ha ha, good point. I question that this is a well-written API: such flags
to change the behaviour of a function/method are generally poor design.
If method behaves differently depending on whether or not you want it to
count something, then it is usually better design to have two methods,
one that counts and one that doesn't.

In any case, yes, the weakness of naming conventions is that there are
always odd-corner cases of natural language. Perhaps `name` is also a
flag telling the method whether or not to name something.

But then, one can write crappy APIs in any language.

--
Steven

Robert Kern

unread,
Feb 3, 2010, 7:49:58 PM2/3/10
to pytho...@python.org
On 2010-02-03 18:01 PM, Steven D'Aprano wrote:
> On Wed, 03 Feb 2010 16:38:21 -0600, Robert Kern wrote:
>
>>>> class.method(name, count)
>>>
>>> Obviously? I don't know about that. Being told that "count" is an int
>>> doesn't really help me -- it's obvious just from the name. In a well-
>>> written API, what else could it be?
>>
>> A bool. As in telling the method whether or not it should count
>> something.
>
> Ha ha, good point. I question that this is a well-written API: such flags
> to change the behaviour of a function/method are generally poor design.
> If method behaves differently depending on whether or not you want it to
> count something, then it is usually better design to have two methods,
> one that counts and one that doesn't.

I prefer Guido's formulation (which, naturally, I can't find a direct quote for
right now): if you expect that a boolean argument is only going to take
*literal* True or False, then it should be split into two functions. There is a
use case for a boolean argument like this when you can expect to pass around a
variable between multiple functions.

Of course, this also might be the private API that the public API (with two
distinct methods for each case) uses internally in order to avoid code
duplication. Private APIs need to be documented, too.

> In any case, yes, the weakness of naming conventions is that there are
> always odd-corner cases of natural language. Perhaps `name` is also a
> flag telling the method whether or not to name something.
>
> But then, one can write crappy APIs in any language.

Well, I'm not trying to make Paul's point that other languages are better in
this regard. I think that type documentation is quite helpful, but requiring
static type declaration to get that documentation is an undesirable tradeoff for
most of the code that I want to write. I do think it is worthwhile to recognize
that the tradeoff does cut the other way, too. It just so happens that Python
has docstrings and argument annotations to document argument types without the
burden of static typing.

Not all good, clean APIs are always going to have argument names that clearly
inform the kind of type it expects. And what an author thinks is obviously
deducible while writing the API is often quite different from what a new user
thinks is obvious. There isn't much reason to place that cognitive burden on the
(many) readers of the code when the (single) author can put in a word or two
into the docstring (once) to describe what the parameter is expected to be.
Figuring out how to use an API to solve your real problem is hard enough without
having your brainpower nickled-and-dimed at every turn.

Steve Holden

unread,
Feb 3, 2010, 7:55:45 PM2/3/10
to pytho...@python.org
Vladimir Ignatov wrote:
>> can you sketch an example/use case more concretely?
>
> Sorry, I don't have anything written down. I just have some rough idea
> of implementation and some concrete features I would like to see in
> such system. For example:
>
> 1) Instant refactoring. No more needs for manual
> search/inspect/rename. Since system knows exactly that is going on,
> the refactoring will be fully automatic.

You'll probably want to take a look at "Bicycle Repair Man", which
offers Python refactoring functionality.

> 2) Show "xref table" for each function. How often this function used?
> Where is it used? (code snippets of calls) What functionality is
> supported by this function?

Bear in mind this information can only ever be partial, since functions
are first-class objects and aren't always referred to by their original
name.

> 3) Extended statistics. How many objects this object/function
> interacts with? Popular functions, dead/unused functions.
> 4) Code smell detector - too long functions, too much interaction with
> other objects, global objects, etc.
> ...
>

Also take a look at pylint and pychecker, which are already built to
perform that kind of check on Python code.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS: http://holdenweb.eventbrite.com/

alex23

unread,
Feb 3, 2010, 8:03:47 PM2/3/10
to
Adam Tauno Williams <awill...@opengroupware.us> wrote:
> This is obvious even in the Python documentation itself where one
> frequently asks oneself "Uhh... so what is parameter X supposed to be...
> a string... a list... ?"

Could you provide an actual example to support this?

The only places I tend to see 'x' as a parameter in the Python library
docs are where it's clearly a number, or the text immediately beneath
it explains exactly what it is.

random.seed([x])
Initialize the basic random number generator. Optional
argument x can be any hashable object.

Everywhere else, the docs seem to declare what the parameters should
be _and_ explains them in the text:

itertools.combinations(iterable, r)
Return r length subsequences of elements from
the input iterable.

If you're finding places in the docs where this isn't the case, I'd
treat them as a documentation bug and report them. If it's not obvious
to you what an iterable is, well, I'm sure you've got a disparaging
term for those of us who do...

Ben Finney

unread,
Feb 3, 2010, 8:46:27 PM2/3/10
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:

> On Wed, 03 Feb 2010 18:48:12 +0300, Vladimir Ignatov wrote:

> > […] system "knows" all your identifiers and just regenerates


> > relevant portions of text from internal database-alike
> > representation.

You will probably want to learn about “refactoring” to see if that's
related to what you mean <URL:http://www.refactoring.com/>.

> Something like Bicycle Repair Man then:

Bicycle Repair Man has not shown any development activity since 2004.
Which is a shame, because it's an awesomely appropriate name for what it
does :-)

The niche is now occupied by the Rope library and tools
<URL:http://rope.sourceforge.net/>.

--
\ “Holy knit one purl two, Batman!” —Robin |
`\ |
_o__) |
Ben Finney

Ben Finney

unread,
Feb 3, 2010, 8:57:18 PM2/3/10
to
Robert Kern <rober...@gmail.com> writes:

> It is perfectly reasonable (and often necessary) for the unit test of
> class B to use a mock object instead of a real A() instance. The unit
> test for class B will fail to catch the renaming of A.foo() to A.bar()
> because it never tries to call .foo() on a real A instance.

Right, which is one good reason why unit tests are *necessary* but not
*sufficient*. You also need so-called “integration” tests (make sure
modules work together as expected) and “system” tests (make sure the
whole running system behaves as expected).

This need for testing is true regardless of whether you're using a
statically-typed or dynamically-typed language, of course. (I hope
no-one here thinks that static typing obviates the need for integration
and system tests in the test suite.)

--
\ “It is far better to grasp the universe as it really is than to |
`\ persist in delusion, however satisfying and reassuring.” —Carl |
_o__) Sagan |
Ben Finney

Vladimir Ignatov

unread,
Feb 3, 2010, 11:13:18 PM2/3/10
to pytho...@python.org
>> > […] system "knows" all your identifiers and just regenerates
>> > relevant portions of text from internal database-alike
>> > representation.
>
> You will probably want to learn about “refactoring” to see if that's
> related to what you mean <URL:http://www.refactoring.com/>.

I mean if system actually "understands" your code (instead of try to
figure it out from existing text files with source code), then much
more complex refactoring is possible. My favorite refactoring is
"Replace Method with Method Object". It is hard to imagine "external"
tool that can provide such refactoring for python code.

>> Something like Bicycle Repair Man then:
> Bicycle Repair Man has not shown any development activity since 2004.
> Which is a shame, because it's an awesomely appropriate name for what it
> does :-)

I believe it still live under the hood of PyDev plugin. I use it
almost every day and need to say that it don't provide much more than
simple renaming (which works right in 80% of cases in recent version).


Vladimir Ignatov

David Cournapeau

unread,
Feb 4, 2010, 1:33:10 AM2/4/10
to Vladimir Ignatov, pytho...@python.org
On Thu, Feb 4, 2010 at 1:13 PM, Vladimir Ignatov <kmi...@gmail.com> wrote:
>>> > […] system "knows" all your identifiers and just regenerates
>>> > relevant portions of text from internal database-alike
>>> > representation.
>>
>> You will probably want to learn about “refactoring” to see if that's
>> related to what you mean <URL:http://www.refactoring.com/>.
>
> I mean if system actually "understands" your code (instead of try to
> figure it out from existing text files with source code), then much
> more complex refactoring is possible. My favorite refactoring is
> "Replace Method with Method Object". It is hard to imagine "external"
> tool that can provide such refactoring for python code.

You may be interested by this project, then:

http://sourceforge.net/mailarchive/message.php?msg_name=9c768dc61001121642t5bd...@mail.gmail.com

It seems limited to Jython implementation unfortunately,

cheers,

David

purui

unread,
Feb 4, 2010, 3:52:55 AM2/4/10
to

> This is obvious even in the Python documentation itself where one
> frequently asks oneself "Uhh... so what is parameter X supposed to be...
> a string... a list... ?"
>

That is partially why I created this search engine for python, to see
what parameters other people feed in.
http://nullege.com/

Vladimir Ignatov

unread,
Feb 4, 2010, 4:41:03 AM2/4/10
to pytho...@python.org
> That is partially why I created this search engine for python, to see
> what parameters other people feed in.
> http://nullege.com/

Thank you for excellent effort! I found it very useful and start using
it on almost everyday basis. It's much simple to learn from real live
examples.

Vladimir Ignatov

Vladimir Ignatov

unread,
Feb 4, 2010, 5:54:58 AM2/4/10
to pytho...@python.org
> http://sourceforge.net/mailarchive/message.php?msg_name=9c768dc61001121642t5bd...@mail.gmail.com

Thanks a lot! That is a great reference (a must read for everybody
interested). Reading just this: "Internally at Google we have a
language-neutral representation shared by all our language analyzers,"
make me jumping ;-) Googlers can't be wrong.

Vladimir Ignatov

Arnaud Delobelle

unread,
Feb 5, 2010, 12:23:51 PM2/5/10
to
Robert Kern <rober...@gmail.com> writes:

> I prefer Guido's formulation (which, naturally, I can't find a direct
> quote for right now): if you expect that a boolean argument is only
> going to take *literal* True or False, then it should be split into
> two functions.

So rather than three boolean arguments, would you have eight functions?

--
Arnaud

Steve Holden

unread,
Feb 5, 2010, 2:55:25 PM2/5/10
to pytho...@python.org
If there's genuinely a need for that functionality, yes.

I statement that calls one of two functions depending on the value of a
Boolean is normally considered to be better coupling than calling a
single function with the Boolean as an argument.

As with everything else you have to apply a certain amount of common sense.

bartc

unread,
Feb 5, 2010, 5:22:39 PM2/5/10
to

"Steve Holden" <st...@holdenweb.com> wrote in message
news:mailman.1998.1265399...@python.org...

> Arnaud Delobelle wrote:
>> Robert Kern <rober...@gmail.com> writes:
>>
>>> I prefer Guido's formulation (which, naturally, I can't find a direct
>>> quote for right now): if you expect that a boolean argument is only
>>> going to take *literal* True or False, then it should be split into
>>> two functions.
>>
>> So rather than three boolean arguments, would you have eight functions?
>>
> If there's genuinely a need for that functionality, yes.

So you want a function such as drawtext(s, bold=true, italic=false,
underline=true) to be split into:

drawtext(s)
drawtextb(s)
drawtexti(s)
drawtextu(s)
drawtextbi(s)
drawtextbu(s)
drawtextiu(s)
drawtextbiu(s)

Which of course is going to be fun if the bold/italic/underline values are
not constants; instead of writing:

drawtext(s,b,i,u)

you have to say:

if b==0 and i==0 and u==0:
drawtext(s)
elif b==1 and i==0 and u==0:
drawtextb(s)

and so on. With half-a-dozen or more booleans, this becomes completely
impractical.

--
Bartc

Robert Kern

unread,
Feb 5, 2010, 5:45:38 PM2/5/10
to pytho...@python.org

Then you refactor to

drawtext(s, font)

Steve Holden

unread,
Feb 5, 2010, 6:11:04 PM2/5/10
to pytho...@python.org
bartc wrote:
>
> "Steve Holden" <st...@holdenweb.com> wrote in message
> news:mailman.1998.1265399...@python.org...
>> Arnaud Delobelle wrote:
>>> Robert Kern <rober...@gmail.com> writes:
>>>
>>>> I prefer Guido's formulation (which, naturally, I can't find a direct
>>>> quote for right now): if you expect that a boolean argument is only
>>>> going to take *literal* True or False, then it should be split into
>>>> two functions.
>>>
>>> So rather than three boolean arguments, would you have eight functions?
>>>
>> If there's genuinely a need for that functionality, yes.
>
> So you want a function such as drawtext(s, bold=true, italic=false,
> underline=true) to be split into:
>
> drawtext(s)
> drawtextb(s)
> drawtexti(s)
> drawtextu(s)
> drawtextbi(s)
> drawtextbu(s)
> drawtextiu(s)
> drawtextbiu(s)
>
The case I was discussing was where the function was required to
implement significantly different logic flow for the two different
values of the Boolean.

> Which of course is going to be fun if the bold/italic/underline values
> are not constants; instead of writing:
>
> drawtext(s,b,i,u)
>
> you have to say:
>
> if b==0 and i==0 and u==0:
> drawtext(s)
> elif b==1 and i==0 and u==0:
> drawtextb(s)
>
> and so on. With half-a-dozen or more booleans, this becomes completely
> impractical.
>

It's completely impractical the way you've written it anyway, since the
drawtext function shouldn't be required to know whether it's printing
bold, italic, etc. - those properties should be attributes of the font.

Steven D'Aprano

unread,
Feb 5, 2010, 6:29:10 PM2/5/10
to
On Fri, 05 Feb 2010 22:22:39 +0000, bartc wrote:

> "Steve Holden" <st...@holdenweb.com> wrote in message
> news:mailman.1998.1265399...@python.org...
>> Arnaud Delobelle wrote:
>>> Robert Kern <rober...@gmail.com> writes:
>>>
>>>> I prefer Guido's formulation (which, naturally, I can't find a direct
>>>> quote for right now): if you expect that a boolean argument is only
>>>> going to take *literal* True or False, then it should be split into
>>>> two functions.
>>>
>>> So rather than three boolean arguments, would you have eight
>>> functions?
>>>
>> If there's genuinely a need for that functionality, yes.
>
> So you want a function such as drawtext(s, bold=true, italic=false,
> underline=true) to be split into:
>
> drawtext(s)
> drawtextb(s)
> drawtexti(s)
> drawtextu(s)
> drawtextbi(s)
> drawtextbu(s)
> drawtextiu(s)
> drawtextbiu(s)


No, of course not. But one might prefer a function with an alternate API,
such as:

style = TextStyle(bold=True, underline=True, size=12, font='helvetica')
drawtext(s, style)
style.italic = True
drawtext(s, style)

Other alternatives might be to pass the style information as a string
"BU" (bold underline) or a numeric flag (BOLD & UNDERLINE).

In general, if your implementation looks like this:


def function(args, flag):
if flag:
do_this()
else:
do_that()


then this is a good candidate for splitting into multiple functions.

Likewise:

def function(args, flag):
result = do_this()
if flag:
result = modify(result)
return result

or similar.

The point is that such a function uses the flag to select between two
different semantics. From a API perspective, it is generally better to
make each behaviour an independent function (perhaps calling a third,
private, function implementing any common behaviour). For example,
instead of:

def extreme(sequence, biggest=True):
"""Return the extreme value from sequence.

If biggest is a true value, return the maximum value, otherwise
return the smallest.
"""
pass # implementation left as an exercise


have two functions, max and min.

--
Steven

Gabriel Genellina

unread,
Feb 6, 2010, 12:19:22 AM2/6/10
to pytho...@python.org
En Fri, 05 Feb 2010 19:22:39 -0300, bartc <ba...@freeuk.com> escribiᅵ:

> "Steve Holden" <st...@holdenweb.com> wrote in message
> news:mailman.1998.1265399...@python.org...
>> Arnaud Delobelle wrote:
>>> Robert Kern <rober...@gmail.com> writes:
>>>
>>>> I prefer Guido's formulation (which, naturally, I can't find a direct
>>>> quote for right now): if you expect that a boolean argument is only
>>>> going to take *literal* True or False, then it should be split into
^^^^^^^^^^^^^^^^^^^^^^^

>>>> two functions.
>>>
>>> So rather than three boolean arguments, would you have eight functions?
>>>
>> If there's genuinely a need for that functionality, yes.
>
> So you want a function such as drawtext(s, bold=true, italic=false,
> underline=true) to be split into:
>
> drawtext(s)
> drawtextb(s)
> drawtexti(s)
> drawtextu(s)
> drawtextbi(s)
> drawtextbu(s)
> drawtextiu(s)
> drawtextbiu(s)

Note the *literal* part. If you (the programmer) is likely to know the
parameter value when writing the code, then the function is actually two
separate functions.
By example, foo.get_path(absolute=True) should be written as
foo.get_absolute_path() and foo.get_relative_path()
It gets worse when one parameter alters the type of the returned value, or
even the number of returned values. This is an actual example:

def build_image(self, zone=-1, return_sizes=False):
...
if return_size:
return img, sizes
else:
return img

image = foo.build_image(3)
but:
image, sizes = foo.build_image(3, True)

It should be split onto two separate functions; in this particular case,
computing 'sizes' required actually drawing the image, so the solution was
to make those 'sizes' attributes of the returned image.

--
Gabriel Genellina

Arnaud Delobelle

unread,
Feb 6, 2010, 5:22:47 PM2/6/10
to
"Gabriel Genellina" <gags...@yahoo.com.ar> writes:

Thanks, I understand what Steve Holden meant now.

--
Arnaud

bartc

unread,
Feb 6, 2010, 8:34:14 PM2/6/10
to
"Arnaud Delobelle" <arn...@googlemail.com> wrote in message
news:m28wb6y...@googlemail.com...

I've just noticed that 'literal' part. But I think I still disagree.

For a real-world example, it means instead of having a room with a
light-switch in it, if I *know* I want the light on or off, I should have
two rooms: one with the light permanently on, and one with it permanently
off, and just walk into the right one.

--
Bartc


Steven D'Aprano

unread,
Feb 6, 2010, 8:57:24 PM2/6/10
to
On Sun, 07 Feb 2010 01:34:14 +0000, bartc wrote:

> For a real-world example, it means instead of having a room with a
> light-switch in it, if I *know* I want the light on or off, I should
> have two rooms: one with the light permanently on, and one with it
> permanently off, and just walk into the right one.

I don't think you can apply real-world analogies to software in that way.
They're too different.

Think of the objections to having two rooms, one permanently lit up, the
other permanently not:

(1) Having two rooms is expensive and wasteful of physical space, which
is in short supply.

(2) You typically use rooms for storing things (furniture and smaller
objects), having two rooms mean you would need to clone every object
inside it and somehow keep them in perfect synchronisation.

(3) the light that is always on will use electricity 24 hours a day,
regardless of whether you are inside it or not.

But none of those objections apply to functions:

(1) Functions are cheap and live in memory, which is not in short supply
unless you're programming for an embedded device.

(1a) Even if you are programming in a device that is short of memory, the
overhead of a second function is minimal. There's little difference
between:

def func(flag):
if flag:
blockA
else:
blockB


and


def funcA():
blockA

def funcB():
blockB


for any non-trivial code blocks, particularly if any common code is
factored out into another function which you call.

(2) Functions aren't typically used for storage, and when they need
external data, it is easy to have them access a common data store.

(3) Functions don't use CPU cycles just by existing.

--
Steven

Alf P. Steinbach

unread,
Feb 6, 2010, 10:04:03 PM2/6/10
to
* Steven D'Aprano:

I agree with your reasoning :-), but it's not either/or.

Consider, sometimes one wants to do

switch.off()

and sometimes one wants to do

original_switch_state = switch.state()
switch.off()
# ... Do things that are best done in utter darkness.
switch.set_state( original_switch_state )

E.g. the "switch" might be the enabled/disabled state of some GUI widget.

So IMHO it depends.

Sometimes one wants both kinds of "protocols".

Cheers,

- Alf

Gabriel Genellina

unread,
Feb 7, 2010, 2:52:18 AM2/7/10