Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

I'm coming from Tcl-world ...

1 view
Skip to first unread message

Andreas Leitgeb

unread,
Aug 2, 2002, 9:36:52 AM8/2/02
to
Hello pythonians!
I'm somewhat experienced in Tcl-scripting, and I generally still like
Tcl, but there are some nasty edges in Tcl, which is the reason
why I had a look at Python.
I bought a small intro-book about python (it deals with 2.0 to 2.2 with
some prospects to 3.0), which I've now almost read through, and now there
are some goodies in Tcl, which I'm sure have their counterparts in Python,
but I didn't find them so far. (This may also be due to the shortness of
the book). These are:

1.) A 'for'-loop like in Tcl or in C, where you have separate
Init-, condition and increment-blocks, that control the loop.
(Of course, there's while, which can emulate all, but with that,
getting "continue" straight (that is: jump to the "increment-part"
of the body) is probably some hassle ...)

2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but which
evaluates its expression only once ... and then does all the comparisons.

3.) event-based scripting. (like 'fileevent','after',... in Tcl)
I've read somewhere, that with tkinter I get access to tcl's event-stuff,
But I was more after something that also works without Gui and without
actually using Tcl through Python. Is there a builtin module that
wraps the select() or poll() systemcall, and invokes the registered
functions if "their" respective channel becomes readable/writable
or a timer runs out ?

4.) "calls by reference": maybe I'm totally misunderstanding pythons
function-call-concepts. I want to pass a non-global variable to
a subroutine, have it changed there, and find that variable
changed in the calling context:
something like
def f( x ) : x=42
f(y); print y
of course doesn't work out the way I'm looking for. So what's the
easiest, and (if different) what's the python'iest way to do it ?
(apart from returning a tuple that contains the changed copy of the
object)

PS:
during playing around (stress-testing) I created a string object z
that contained 1 MB of zero-characters, then I did the following:
len(str(map(ord,z)))
with Python 1.5 I stopped it after an hour, when it still wasn't
finished, whereas in Python 2.2 (on a different, little slower, but
more recently installed) machine this took less than 10 seconds (iirc).
On a third machine (about double fast than the other two) with
Python 2.0 it also seems to take ages.
Is this a bug in old versions, or has something severely changed from
2.0 to 2.2 that affects performance so much ? Or is this just one of
many reasons to upgrade to 2.2.1 on all the machines ?-)

PPS: python'ing on linux I currently am.
--
Newsflash: Sproingy made it to the ground !
read more ... <http://avl.enemy.org/sproingy/>

Cameron Laird

unread,
Aug 2, 2002, 10:49:54 AM8/2/02
to
In article <slrnakl3mb.c05....@pc7499.gud.siemens.at>,
Andreas Leitgeb <a...@logic.at> wrote:
.
.
.

>1.) A 'for'-loop like in Tcl or in C, where you have separate
> Init-, condition and increment-blocks, that control the loop.
> (Of course, there's while, which can emulate all, but with that,
> getting "continue" straight (that is: jump to the "increment-part"
> of the body) is probably some hassle ...)
.
.
.
Andreas, you'd probably like Dave Beazley's *Python
Essential Reference*.

The specific answer in this case is, use while, and
in fact the continue will do just what it should.
When in doubt, Python inclines to minimalism. A C-
like "for (;;)" isn't really necessary, and Python
doesn't go to the trouble of cluttering itself up
with this and other superfluities.
--

Cameron Laird <Cam...@Lairds.com>
Business: http://www.Phaseit.net
Personal: http://starbase.neosoft.com/~claird/home.html

Cameron Laird

unread,
Aug 2, 2002, 10:53:39 AM8/2/02
to
In article <slrnakl3mb.c05....@pc7499.gud.siemens.at>,
Andreas Leitgeb <a...@logic.at> wrote:
.
.
.
>2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but which
> evaluates its expression only once ... and then does all the comparisons.
.
.
.
You're far from the first to ask about it. I
confess I occasionally ache from its absence.

The Python attitude, though, is that a LOT of
switches are bogus; they're better handled as
type resolution (switching between what amount
to different classes) or dictionary look-up.

Cameron Laird

unread,
Aug 2, 2002, 10:56:17 AM8/2/02
to
In article <slrnakl3mb.c05....@pc7499.gud.siemens.at>,
Andreas Leitgeb <a...@logic.at> wrote:
.
.
.
>3.) event-based scripting. (like 'fileevent','after',... in Tcl)
> I've read somewhere, that with tkinter I get access to tcl's event-stuff,
> But I was more after something that also works without Gui and without
> actually using Tcl through Python. Is there a builtin module that
> wraps the select() or poll() systemcall, and invokes the registered
> functions if "their" respective channel becomes readable/writable
> or a timer runs out ?
.
.
.
Yes. You'll want to read about the select and asyncore modules.

Also, Pythoneers do much more multi-threading (at a scripting
level) than is typical for Tcl.

Daniel Fackrell

unread,
Aug 2, 2002, 10:25:37 AM8/2/02
to
"Andreas Leitgeb" <Andreas...@siemens.at> wrote in message
news:slrnakl3mb.c05....@pc7499.gud.siemens.at...

> Hello pythonians!
> I'm somewhat experienced in Tcl-scripting, and I generally still like
> Tcl, but there are some nasty edges in Tcl, which is the reason
> why I had a look at Python.

Welcome!

> I bought a small intro-book about python (it deals with 2.0 to 2.2 with
> some prospects to 3.0), which I've now almost read through, and now there
> are some goodies in Tcl, which I'm sure have their counterparts in Python,
> but I didn't find them so far. (This may also be due to the shortness of
> the book). These are:
>
> 1.) A 'for'-loop like in Tcl or in C, where you have separate
> Init-, condition and increment-blocks, that control the loop.
> (Of course, there's while, which can emulate all, but with that,
> getting "continue" straight (that is: jump to the "increment-part"
> of the body) is probably some hassle ...)

Someone else can probably help you better with this point. All I can say is
that I'm actually glad of the lack of a C-style 'for' loop in Python, as it
tends to be difficult to read and understand what it is doing unless you do
a lot of it.

For a better answer, try posting an example of the Tcl code that you'd like
to translate into Python, and a specific answer can be given which may bring
much enlightenment. There are a few of us around that know a little Tcl.

> 2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but which
> evaluates its expression only once ... and then does all the
comparisons.

I'm not sure what the proper idiom for this is, but I'd suspect that the
better Python users here have an awesome way of handling it, and that their
way makes one wonder why other languages ever bothered with a 'switch'- or
'select/case'-type statement.

> 3.) event-based scripting. (like 'fileevent','after',... in Tcl)
> I've read somewhere, that with tkinter I get access to tcl's
event-stuff,
> But I was more after something that also works without Gui and without
> actually using Tcl through Python. Is there a builtin module that
> wraps the select() or poll() systemcall, and invokes the registered
> functions if "their" respective channel becomes readable/writable
> or a timer runs out ?

Someone else will have to answer this one, too.

> 4.) "calls by reference": maybe I'm totally misunderstanding pythons
> function-call-concepts. I want to pass a non-global variable to
> a subroutine, have it changed there, and find that variable
> changed in the calling context:
> something like
> def f( x ) : x=42
> f(y); print y
> of course doesn't work out the way I'm looking for. So what's the
> easiest, and (if different) what's the python'iest way to do it ?
> (apart from returning a tuple that contains the changed copy of the
> object)

You can do this by putting the item to change in a list, dict, or instance
object rather easily (list case shown):

def incr(x):
x[0] += 1

x=[0]
print x[0]
incr(x)
print x[0]

This will output:
0
1

As always, keep in mind that it should be clear in some way exactly what the
side-effects of a call will be. Careful choice of names for
functions/methods will help greatly in this.

--
Daniel Fackrell (unle...@learn2think.org)
When we attempt the impossible, we can experience true growth.


geek

unread,
Aug 2, 2002, 10:33:13 AM8/2/02
to
> 2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but
> which evaluates its expression only once ... and then does all the
> comparisons.

I'm one of those weirdos that would use a dictionary for this. Here's
a very poor example:

#!/usr/bin/env python

import sys

def yes():
print 'yes'
return

def no():
print 'no'
return

options = {'-y': yes,
'-n': no,
}

for o in sys.argv[1:]:
try:
options[o]()
except:
print 'Unknown command line arguement'

Martin v. Löwis

unread,
Aug 2, 2002, 10:49:10 AM8/2/02
to
Andreas...@siemens.at (Andreas Leitgeb) writes:

> 1.) A 'for'-loop like in Tcl or in C, where you have separate
> Init-, condition and increment-blocks, that control the loop.
> (Of course, there's while, which can emulate all, but with that,
> getting "continue" straight (that is: jump to the "increment-part"
> of the body) is probably some hassle ...)

I think you'll find that you rarely need those, since you usually
iterate over some sequence. In those cases where you do need this
construct - yes, a while loop is the idiom you'll use.

> 2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but
> which evaluates its expression only once ... and then does all the
> comparisons.

PEP 275 proposes to include such a thing. You are encouraged to
comment on the PEP, either in this group, or by contacting the PEP
author:

http://www.python.org/peps/pep-0275.html

> 3.) event-based scripting. (like 'fileevent','after',... in Tcl)
> I've read somewhere, that with tkinter I get access to tcl's event-stuff,
> But I was more after something that also works without Gui and without
> actually using Tcl through Python. Is there a builtin module that
> wraps the select() or poll() systemcall, and invokes the registered
> functions if "their" respective channel becomes readable/writable
> or a timer runs out ?

I think the asyncore module is closest to that - although it is really
common to use select/poll explicitly, or to use threads.

>
> 4.) "calls by reference": maybe I'm totally misunderstanding pythons
> function-call-concepts. I want to pass a non-global variable to
> a subroutine, have it changed there, and find that variable
> changed in the calling context:

[...]


> of course doesn't work out the way I'm looking for. So what's the
> easiest, and (if different) what's the python'iest way to do it ?

The common approach is to mutate mutable objects. E.g.

class Counter:
pass

def count(o):
o.value += 1

p = Counter()
p.value = 0
count(p)
print p.value

Of course, for this application, you use proper methods:

class Counter:
def __init__(self):
self.value = 0
def count(self):
self.value += 1

p = Counter()
p.count()

> Is this a bug in old versions, or has something severely changed from
> 2.0 to 2.2 that affects performance so much ? Or is this just one of
> many reasons to upgrade to 2.2.1 on all the machines ?-)

I think this might be an improvement in the list.append
implementation: the map() call will add elements one-by-one, which
used to be quadratic, but isn't anymore.

Regards,
Martin

Tim Daneliuk

unread,
Aug 2, 2002, 11:40:03 AM8/2/02
to
Cameron Laird wrote:
> In article <slrnakl3mb.c05....@pc7499.gud.siemens.at>,
> Andreas Leitgeb <a...@logic.at> wrote:
> .
> .
> .
>
>>2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but which
>> evaluates its expression only once ... and then does all the comparisons.
>
> .
> .
> .
> You're far from the first to ask about it. I
> confess I occasionally ache from its absence.
>
> The Python attitude, though, is that a LOT of
> switches are bogus; they're better handled as
> type resolution (switching between what amount
> to different classes) or dictionary look-up.

Python *does* have this ability, it just isn't called a "case" - it's
a *dictionary* lookup. Suppose you want to switch on the values 1, 2, and
3, and have them return, "red", "green", and "blue". Here is a case-like
approach implemented in Python:


def case1():
print "red"

def case2():
print "green"

def case3():
print "blue"

switch-table={}
switch-table[1]=case1
switch-table[2]=case2
switch-table[3]=case3

... do something to get the the value to switch on into, say, a variable called 'SwiTch'

# Here is your whole switch/case implementation as a one-liner

switch-table[SwiTch]()


Python's beauty is that you can use this sort of thing to "switch" on pretty much
*anything", not just an integer like in C, because the index into a dictionary can
be an integer, string, or pretty much *any* object.

My quick-n-dirty budgeting program (which is more a Python tutorial than
a really useful application) makes extensive use of this sort of thing
to implement a table-driven command interpreter. Here the "switch" is on
user input. If interested, have a look at:

http://www.tundraware.com/Software/hb/

--
------------------------------------------------------------------------------
Tim Daneliuk
tun...@tundraware.com

Tim Daneliuk

unread,
Aug 2, 2002, 11:50:03 AM8/2/02
to
Martin v. Löwis wrote:

>>2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but
>>which evaluates its expression only once ... and then does all the
>>comparisons.
>
>
> PEP 275 proposes to include such a thing. You are encouraged to
> comment on the PEP, either in this group, or by contacting the PEP
> author:
>
> http://www.python.org/peps/pep-0275.html
>

This seems to me to just be syntactic sugar and thus unneeded. Switch/Case
like constructs are trivially, and more richly, implemented using
dictionaries to associate a switch value with a particular behavior or
result.

Andreas Leitgeb

unread,
Aug 2, 2002, 12:48:27 PM8/2/02
to
Andreas Leitgeb <Andreas...@siemens.at> wrote:
> Hello pythonians!
thank for all the responses. Because there were so many of them,
each answering only some parts of the post, I do a followup on my own
post ...

Unfortunately many of the given answers yet failed to make me happy :(

> 1.) A 'for'-loop like in Tcl or in C, where you have separate
> Init-, condition and increment-blocks, that control the loop.
> (Of course, there's while, which can emulate all, but with that,
> getting "continue" straight (that is: jump to the "increment-part"
> of the body) is probably some hassle ...)

[common answer: for(;;) is rubbish, use "while" or "for ... in" instead.]

Here, I think, I didn't make my concern clear enough:
in C/C++ (and similar in Tcl) I can do the following:
for (int i=0,string s="*" ; i<42 ; i++,s+=s) {
...
if (...) continue;
...
}
More and better examples of where a simple range/list/dictionary-
traversal just won't do it, surely exist.

Now, the transscription to while in C/C++ would be:
int i=0; string s="*";
while (i<42) {
...
if (...) goto increment;
...
increment:
i++; s+=s;
}

now, Python has no goto (rightly, so), thus by what shall I
replace the "continue", so I run through the incrementing part ?

How could python tell the increment-part from the rest of the body ?
the previous continue might be arbitrarily widely nested inside
some hierarchy of if's ...


> 2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but which
> evaluates its expression only once ... and then does all the comparisons.

[common answer: use dictionaries with functions as values ...]

coming from Tcl, dictionaries are not new to me, and even in Tcl,
I could start out like:
set switch(42) {puts 42}
set switch(666) {puts devil}
eval $switch($myvalue); # $myvalue being the switch-expression.
However, this has some impediments:
First: Only exact matches are possible with dictionaries, whereas
I'd have expected from a Python-switch to be able to specify a
comparison-function along, defaulting to exact match/identity.
Second: I want it all in the same scope; I want to set variables
in each "switch-branch" that are still valid outside,
and I don't want to clutter the namespace with a function for
each switch-branch. (yes, I know, I could reuse function-names after
placing the function-object into the dictionary, but...)

I'll have a look at the PEP-url given; thanks.


> 3.) event-based scripting. (like 'fileevent','after',... in Tcl)

[common answer: yes, there are modules: asyncore and select]
Thanks a lot, I'll have a look at them.

> 4.) "calls by reference":

> def f( x ) : x=42

[common answer: use mutable containers instead, e.g.: ]
[ def f(x): x[0]=42 ]
[ x= a list, containing my object as first (and perhaps only) element ]
[ f(x); then, x[0] outside of f is still 42 ]
It's not exactly what I fancied, but near enough :-)


> PS: [performance comparison among versions 1.5, 2.0 and 2.2 of python]
[answer: yes, there was a change in memory-allocation when appending
to lists]
That explains it :-)
Thus, whenever I intend to handle large data, I'd better upgrade
to a version at least 2.2 or so.

btw. the last attempt (on version 2.0) has taken 200 cpu-minutes so far
and still running on a 900MHz, with a job that took about 10 seconds
with 2.2 on a 300Mhz-machine. :-)

bru...@tbye.com

unread,
Aug 2, 2002, 1:32:33 PM8/2/02
to
On Fri, 2 Aug 2002, Tim Daneliuk wrote:

> Martin v. Löwis wrote:
>
> >>2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but
> >>which evaluates its expression only once ... and then does all the
> >>comparisons.
> >
> >
> > PEP 275 proposes to include such a thing. You are encouraged to
> > comment on the PEP, either in this group, or by contacting the PEP
> > author:
> >
> > http://www.python.org/peps/pep-0275.html
> >
>
> This seems to me to just be syntactic sugar and thus unneeded.

[snip]

Yeah, but being syntactic sugar doesn't necessarily make something a bad
idea. That's like saying you don't need for-loops since we have
while-loops. Heck, since we have operator.mul we don't need '*' anymore.
;-)


Fearless Freep

unread,
Aug 2, 2002, 3:17:06 PM8/2/02
to
cla...@starbase.neosoft.com (Cameron Laird) wrote in message news:<387A5DEC052156FC.360D7A97...@lp.airnews.net>...

> In article <slrnakl3mb.c05....@pc7499.gud.siemens.at>,
> Andreas Leitgeb <a...@logic.at> wrote:
> .
> .
> .
> >2.) A 'switch'-thing: like a big if-elif-elif-elif-...-else but which
> > evaluates its expression only once ... and then does all the comparisons.

> The Python attitude, though, is that a LOT of


> switches are bogus; they're better handled as
> type resolution (switching between what amount
> to different classes) or dictionary look-up.


I confess, coming from a Smalltalk background, I had been using Python
for about eight months before I even wondered if it had a switch
construct or not

Jay O'Connor
http://www.r4h.org/r4hsoftware

Heiko Wundram

unread,
Aug 2, 2002, 8:17:25 PM8/2/02
to
Hi Andreas!

On Fri, 2002-08-02 at 18:48, Andreas Leitgeb wrote:
> Here, I think, I didn't make my concern clear enough:
> in C/C++ (and similar in Tcl) I can do the following:
> for (int i=0,string s="*" ; i<42 ; i++,s+=s) {
> ...
> if (...) continue;
> ...
> }

There is no way to do anything like that in Python, there just isn't.
The only thing a for loop does is create an iterator on the object you
pass in after the "in" clause, and that iterator's next() method is
called until the iterator raises a StopIteration exception.

Why I'm telling you this is because there are (simple) ways to specify
functions that return iterators for your own types (classes are types in
Python).

The above code in Python would look something of the following:

for x in range(0,42):
s *= 2

<blah>

if <more blah>:
continue

<even more blah>

Doesn't look all the more complicated, does it? Just loop over one
variable, and specify all that extra stuff in the loop itself... :) You
can always rewrite any loop to loop over one variable only.

> now, Python has no goto (rightly, so), thus by what shall I
> replace the "continue", so I run through the incrementing part ?

Python has a continue statement, working just as you'd expect it to.

> First: Only exact matches are possible with dictionaries, whereas
> I'd have expected from a Python-switch to be able to specify a
> comparison-function along, defaulting to exact match/identity.

Of course, a switch statement only makes exact matches possible anyway.
Specifying the comparison function would only clobber the syntax (IMHO).

You can just as well do something of the following:

my_val = <switch expression>

if my_val == 1:
<blah>
elif 2 < my_val < 5:
<more blah>
elif my_val in range(6,25):
<some other blah>
else:
<default blah>

Looks almost like a switch statement, doesn't it?

> Second: I want it all in the same scope; I want to set variables
> in each "switch-branch" that are still valid outside,
> and I don't want to clutter the namespace with a function for
> each switch-branch. (yes, I know, I could reuse function-names after
> placing the function-object into the dictionary, but...)

Dictionaries aren't functions as they are in Tcl, but rather they are
builtin types. So you don't clobber any namespace when you try to look
up a dictonary key. You just write something like

my_switch_expr = 1
a = {1:"hello",2:"world"}

print a[my_switch_expr]

which would output hello in this case.

You'll only have a variable a running around which contains the
dictionary.

And by the way: Normally (at least at the moment) there are only two
namespaces in Python: Global and Local. Global means for the whole file
and local means local to the current function.

Global names are declared at module level, and local names at function
level. When you nest functions, these functions will share a common
namespace. (This doesn't mean that they will share namespace if you do a
recursive call or the like!)

If you need to access a global name from within a function, you'll have
to declare that name to be global directly after the function
declaration by saying "global <varname>".

Short example.

x = 3

def change_x_1():
x = 4

def change_x_2():
global x

x = 4

print x
change_x_1()
print x
change_x_2()
print x

will print:

3
3
4

as in the first function x isn't declared to be in the global namespace
(but rather assigned in the internal namespace), whereas in the second
case you explicitly state that when you refer to x you refer to the
global name called x.

> > 3.) event-based scripting. (like 'fileevent','after',... in Tcl)
> [common answer: yes, there are modules: asyncore and select]
> Thanks a lot, I'll have a look at them.

I'm sure those two modules answer all you need.

> [common answer: use mutable containers instead, e.g.: ]
> [ def f(x): x[0]=42 ]
> [ x= a list, containing my object as first (and perhaps only) element ]
> [ f(x); then, x[0] outside of f is still 42 ]
> It's not exactly what I fancied, but near enough :-)

This is based on the concept that Python always passes variables by
reference, and that there are some types that are simply not mutable
(such as tuples, integers, floats). This makes the language cleaner, as
you don't have all that mess you have in C/C++ where you have to watch
out about pointers, and the like.

I've never had any problems; what my functions simply always did was
return the values that needed to be changed in the calling function;
that way you don't have to mess about with putting a single argument in
a list just to be able to change it internal to the function...

Simple example:

x = 1

def inc(my_val):
return my_val+1, my_val+2

x,x_one_more = inc(x)

You can pass out more than one argument just by wrapping it in a tuple.

Well, hope this makes you look a little more favorable at Python than
what was suggested by your post. ;)

someone-put-me-on-python-advocacy-'ly yours,

and also

immitating-tim-peters-'ly yours, ;)

Heiko Wundram.


Tim Daneliuk

unread,
Aug 2, 2002, 9:00:02 PM8/2/02
to

Clearly, minimalism can be taken to a ridiculous extreme. But, I still fail
to see what problem adding switch-case syntax fixes. It is certainly not
more compact than a dictionary approach AFAIKT, and it is (arguably) no clearer,
so why add more sugar here?

(Then again, I am fond of table (dictionary)-driven constructs because
they are, IMHO, much more maintainable and clear than the equivalent
in-line implementations... I'm a wee bit biased)

Hans Nowak

unread,
Aug 2, 2002, 9:22:09 PM8/2/02
to
Andreas Leitgeb wrote:
> Andreas Leitgeb <Andreas...@siemens.at> wrote:
>
>>Hello pythonians!
>
> thank for all the responses. Because there were so many of them,
> each answering only some parts of the post, I do a followup on my own
> post ...
>
> Unfortunately many of the given answers yet failed to make me happy :(

That is understandable, coming from another language and being used to
different idioms. But bear in mind that Python is not just a different
language... it's a different philosophy, and idioms that are common in other
languages may not be the Right Thing here.

[for loop]


> Here, I think, I didn't make my concern clear enough:
> in C/C++ (and similar in Tcl) I can do the following:
> for (int i=0,string s="*" ; i<42 ; i++,s+=s) {
> ...
> if (...) continue;
> ...
> }

This type of loop is very flexible; it's also hard to understand for someone
not familiar with this construction. I'm not unfamiliar with C and C++, but it
took me a while to figure out what exactly it was doing, and I'm still not sure
what happens at the continue.

> More and better examples of where a simple range/list/dictionary-
> traversal just won't do it, surely exist.
>
> Now, the transscription to while in C/C++ would be:
> int i=0; string s="*";
> while (i<42) {
> ...
> if (...) goto increment;
> ...
> increment:
> i++; s+=s;
> }
>
> now, Python has no goto (rightly, so), thus by what shall I
> replace the "continue", so I run through the incrementing part ?

Why not:

i, s = 0, "*"
while i < 42:
...
if not ...:
...
i += 1
s += s

[switch]


> However, this has some impediments:
> First: Only exact matches are possible with dictionaries, whereas
> I'd have expected from a Python-switch to be able to specify a
> comparison-function along, defaulting to exact match/identity.
> Second: I want it all in the same scope; I want to set variables
> in each "switch-branch" that are still valid outside,
> and I don't want to clutter the namespace with a function for
> each switch-branch. (yes, I know, I could reuse function-names after
> placing the function-object into the dictionary, but...)

The common if-elif-elif-... construct allows for all this flexibility. I know
you were looking for a different construct besides this, but as it is, Python
currently doesn't have one.

>>4.) "calls by reference":
>> def f( x ) : x=42
>
> [common answer: use mutable containers instead, e.g.: ]
> [ def f(x): x[0]=42 ]
> [ x= a list, containing my object as first (and perhaps only) element ]
> [ f(x); then, x[0] outside of f is still 42 ]
> It's not exactly what I fancied, but near enough :-)

Call by reference is something that is often used in other languages, but which
doesn't make all that much sense in Python. Such side effects are generally
frowned upon, because they make code less clear, among other things. Usually
there are better constructs. A function that returns the new value is one.

I don't know which book you used to learn Python, but it seems it taught you
the right things and common "Pythonic" idioms. It's only natural that you want
to find ways of doing it that are closer to what you're used to, but eventually
you may find yourself using the other constructs anyway, because they "feel
better". Just give them a try.

HTH,

--
Hans (base64.decodestring('d3VybXlAZWFydGhsaW5rLm5ldA=='))
# decode for email address ;-)
The Pythonic Quarter:: http://www.awaretek.com/nowak/

Cameron Hutchison

unread,
Aug 2, 2002, 9:25:16 PM8/2/02
to
On Sat, 03 Aug 2002 10:17:25 +1000, Heiko Wundram wrote:

> Hi Andreas!
>
> On Fri, 2002-08-02 at 18:48, Andreas Leitgeb wrote:
>> Here, I think, I didn't make my concern clear enough:
>> in C/C++ (and similar in Tcl) I can do the following:
>> for (int i=0,string s="*" ; i<42 ; i++,s+=s) {
>> ...
>> if (...) continue;
>> ...
>> }
>
> There is no way to do anything like that in Python, there just isn't.

You should be able to do something like:

i = 0
s = "*"
while i < 42:
try:
...
if ...: continue
...
finally:


i += 1
s += s

But thats just really a direct translation, rather than looking for the
pythonic way of doing it.

--
Cameron Hutchison (cam...@xdna.net) | Onward To Mars

holger krekel

unread,
Aug 3, 2002, 5:06:49 AM8/3/02
to
Heiko Wundram wrote:
> Hi Andreas!
>
> On Fri, 2002-08-02 at 18:48, Andreas Leitgeb wrote:
> > Here, I think, I didn't make my concern clear enough:
> > in C/C++ (and similar in Tcl) I can do the following:
> > for (int i=0,string s="*" ; i<42 ; i++,s+=s) {
> > ...
> > if (...) continue;
> > ...
> > }
>
> There is no way to do anything like that in Python, there just isn't.

Huh? Maybe you mean there isn't this exact syntax which is correct.

But it's not hard to translate the above *idea* into:

def counted_doubler(iterations, s):
for i in xrange(iterations):
yield i,s # yields a tuple one by one to the for-loop
s+=s

for i,s in counted_doubler(42,'*'):
...
if ...:
continue

Actually python kind of leads you into finding good
explicit names for your ideas. Syntactic sugar is relatively
minimal compared to other languages.

So my basic point is: Don't translate syntax, translate ideas!

have fun,

holger

Keith Dart

unread,
Aug 3, 2002, 6:24:01 AM8/3/02
to
In article <slrnakleti.c05....@pc7499.gud.siemens.at>,
"Andreas Leitgeb" <Andreas...@siemens.at> penned these words:

>> 3.) event-based scripting. (like 'fileevent','after',... in Tcl)
> [common answer: yes, there are modules: asyncore and select] Thanks a
> lot, I'll have a look at them.

YOu might also want to look at the asyncio module in the pyNMS package.

http://pynms.sourceforge.net/

This works like asyncore, but uses SIGIO. It only works on Linux,
however. And it needs a little more work....


>
>> 4.) "calls by reference":
>> def f( x ) : x=42
> [common answer: use mutable containers instead, e.g.: ] [ def f(x):
> x[0]=42 ]
> [ x= a list, containing my object as first (and perhaps only) element
> ] [ f(x); then, x[0] outside of f is still 42 ] It's not exactly
> what I fancied, but near enough :-)

I usually use an idiom like the following:

def inc(x):
return x+1

x = 1
x = inc(x)
x = inc(x)
etc...

That is, the function just returns the new value, and you reassign the
name. although, for this simple example, that is unnecessary snd slower.


-- ^
\/ \/
(O O)
-- --------------------oOOo~(_)~oOOo----------------------------------------
Keith Dart
<mailto:kd...@kdart.com>
<http://www.kdart.com/>
----------------------------------------------------------------------------
Public key ID: B08B9D2C Public key: <http://www.kdart.com/~kdart/public.key>
============================================================================

Robin Becker

unread,
Aug 3, 2002, 6:46:28 AM8/3/02
to
I've always thought it was a pity that Tcl's event driven file i/o
didn't catch on elsewhere. Python seems locked into an older world in
its low level i/o mechanisms although at higher levels it's very clean.
Polling feels inefficient, but I guess is very robust.
--
Robin Becker

Michael Hudson

unread,
Aug 3, 2002, 11:28:46 AM8/3/02
to
Tim Daneliuk <tun...@tundraware.com> writes:

> Martin v. Löwis wrote:
>
> > [PEP 275]


>
> This seems to me to just be syntactic sugar and thus unneeded.
> Switch/Case like constructs are trivially, and more richly,
> implemented using dictionaries to associate a switch value with a
> particular behavior or result.

Not really. Something like:

int a, b, c

switch (v) {
case 1:
a = 0
break;
case 1:
return b;
case 1:
c += 1
break;
}

would be tedious to do using dictionaries (i.e. where the different
cases need access to different bits of the local environment).

Cheers,
M.

--
On the other hand, the following areas are subject to boycott
in reaction to the rampant impurity of design or execution, as
determined after a period of study, in no particular order:
... http://www.naggum.no/profile.html

Cameron Laird

unread,
Aug 3, 2002, 12:41:49 PM8/3/02
to
In article <mailman.1028333946...@python.org>,
Heiko Wundram <hei...@ceosg.de> wrote:
.
.

.
>Of course, a switch statement only makes exact matches possible anyway.
>Specifying the comparison function would only clobber the syntax (IMHO).
In C, of course, and there only against
fundamental datatypes (another issue).
Part of the context of Andreas' questions
is that Tcl builds-in a [switch] with
several different comparisons possible.
.
.
.

>Dictionaries aren't functions as they are in Tcl, but rather they are
>builtin types. So you don't clobber any namespace when you try to look
? I don't get that Tcl dictionaries
are "functions". The part of Tcl that's
most dictionary-like is what Tcl calls
an "array", and it's as built-in as can
be.

Frederic Bonnet has extended Tcl's asso-
ciative array to a new type called
"dictionary" which can more conveniently
be passed by reference. It's not widely
used (yet?).
.
.

Oren Tirosh

unread,
Aug 3, 2002, 11:57:01 AM8/3/02
to
On Sat, Aug 03, 2002 at 02:57:22PM +0100, Robin Becker wrote:
> In message <20020803133...@hishome.net>, Oren Tirosh <oren-py-
> l...@hishome.net> writes
> >Have you tried asyncore?
> >
> > Oren
> >
> yes, it's quite a mess working out what's going on.

Yes, you're right. The asyncore documentation could be better. Actually it's
very simple to use:

Write an object with the following methods:

writable() - return true if you wish to get write events
readable() - return true if you wish to get read events

handle_error() - called on any errors
handle_write_event() - called on write event
handle_read_event() - called on read event
also called on EOF, in that case reading will return ''

set socket_map[fd] to point to this object (multiple objects, more likely)
call asyncore.loop(optional_timeout)
The loop will return either on timeout or when one of the handlers
raises the asyncore.ExitNow exception.

That's all.

Everything else is just predefined objects you can inherit that help you
handle the little details. The asyncore.dispatcher handles setting up the
socket, listening for incoming connections, etc. The dispatcher_with_send
has a buffered send function, file_dispatcher handles pipes and other
non-socket fds, the asynchat module helps you implement two-way stateful
protocols.

If you have any ideas how to make it easier to use I'd love to hear them,
whether they're tcl-inspired or not...

Oren


Robin Becker

unread,
Aug 3, 2002, 12:48:19 PM8/3/02
to
In message <2002080318...@hishome.net>, Oren Tirosh <oren-py-
l...@hishome.net> writes
.......

>> >Have you tried asyncore?
>> >
>> > Oren
>> >
>> yes, it's quite a mess working out what's going on.
>
>Yes, you're right. The asyncore documentation could be better. Actually it's
>very simple to use:
>
>Write an object with the following methods:
>
> writable() - return true if you wish to get write events
> readable() - return true if you wish to get read events
>
> handle_error() - called on any errors
> handle_write_event() - called on write event
> handle_read_event() - called on read event
> also called on EOF, in that case reading will return ''
>
>set socket_map[fd] to point to this object (multiple objects, more likely)
>call asyncore.loop(optional_timeout)
>The loop will return either on timeout or when one of the handlers
>raises the asyncore.ExitNow exception.
>
>That's all.
......
Inspired by Steve Holden in another thread I was just looking at
http://www.python.org/dev/doc/devel/lib/module-asyncore.html
and see no mention of the handle_write_event & handle_read_event
methods. I assume they're aliases for handle_write and handle_read.
--
Robin Becker

Oren Tirosh

unread,
Aug 3, 2002, 1:23:33 PM8/3/02
to
On Sat, Aug 03, 2002 at 05:48:19PM +0100, Robin Becker wrote:
> >Write an object with the following methods:
> >
> > writable() - return true if you wish to get write events
> > readable() - return true if you wish to get read events
> >
> > handle_error() - called on any errors
> > handle_write_event() - called on write event
> > handle_read_event() - called on read event
> > also called on EOF, in that case reading will return ''
> >
> >set socket_map[fd] to point to this object (multiple objects, more likely)
> >call asyncore.loop(optional_timeout)
> >The loop will return either on timeout or when one of the handlers
> >raises the asyncore.ExitNow exception.
> >
> >That's all.
> ......
> Inspired by Steve Holden in another thread I was just looking at
> http://www.python.org/dev/doc/devel/lib/module-asyncore.html
> and see no mention of the handle_write_event & handle_read_event
> methods. I assume they're aliases for handle_write and handle_read.

No. The methods handle_read_event and handle_write_event are the low
level methods that get called directly by the asyncore loop. That's
what I use when I implement my own dispatcher from scratch. The dispatcher
class in the asyncore module implements them for you and calls the
handle_read and handle_write methods that you're supposed to override.

Oren


Martin v. Loewis

unread,
Aug 3, 2002, 5:24:20 PM8/3/02
to
Robin Becker <ro...@jessikat.fsnet.co.uk> writes:

That kind of processing assumes that your language runtime owns a
mainloop. While this is a compromise that Tcl was willing to make, I
still think that must be left out of the programming language, and
should be part of libraries.

Regards,
Martin

Robert Amesz

unread,
Aug 3, 2002, 11:08:58 PM8/3/02
to
Andreas Leitgeb wrote:

> [common answer: for(;;) is rubbish, use "while" or "for ... in"
> instead.]
>
> Here, I think, I didn't make my concern clear enough:
> in C/C++ (and similar in Tcl) I can do the following:
> for (int i=0,string s="*" ; i<42 ; i++,s+=s) {
> ...
> if (...) continue;
> ...
> }
> More and better examples of where a simple range/list/dictionary-
> traversal just won't do it, surely exist.

As C-style goes this isn't a very pretty piece of code, especially
since you seem bent on building a string of 2**42 '*' characters. That
is a bit over the top, not to mention an exceedingly dull read. ;-)
Presumably you meant s += "*". That assumed, and also assuming you
don't modify i in the loop, here's the Python equivalent.

for i in range(42):
s = "*" * (i + 1)


...
if ...:
continue
...

BTW, using 'continue' is pretty rare, in my experience; 'break' is
_much_ more common.


>> 4.) "calls by reference": def f( x ) : x=42
> [common answer: use mutable containers instead, e.g.: ]
> [ def f(x): x[0]=42 ]
> [ x= a list, containing my object as first (and perhaps only)
> element ] [ f(x); then, x[0] outside of f is still 42 ]
> It's not exactly what I fancied, but near enough :-)

_Don't_ use a one element list: that's misleading to anyone (including
yourself) who reads that code later. If you don't wan't to use a full-
fledged class (including initializer function) just do:

class simple:
pass

If you really, _really_ need a mutable numeric type you could make one
yourself by imlementing a class which emulates a numeric type (see ch.
3.3.6 of the Python manual) but that shouldn't be necessary. More
importantly: please check _why_ you need a reference to an immutable
object. Usually you'll find that:

1 - That immutable object could/should be grouped with other ones to
form a proper class, or:

2 - The call-by-reference is needed because you need to have more than
one return value. Most languages have this limitation, but in Python
you can return as many values as you like, in a tuple. Then you'd get
something like:

def func(x):
...
x = 42
return (your_return_value, x)


x = 43
value, x = func(x)


- - -

The examples you give are typical ones if you try to emulate C-style in
Python. However, if you approach Python as Python you'll find nearly
all of those problems mysteriously and conveniently disappear. Well,
perhaps not that mysteriously: Python allows you to program at a much
higher level of abstraction than C, and with a lot fewer implementation
details worry about. Programming in Python is many times faster and a
lot less error prone than doing the same job in C, but if you approach
Python as C-with-a-strange-syntax you lose much of that advantage.

I'm not quite sure how Python compares to TCL as my experience with
that language is anything but extensive. The everything-is-a-string
paradigm is interesting and pretty unique, but also limiting. The
syntax seems to have been designed to help the interpreter rather than
the programmer, (IMHO, of course.) I suppose it will take a little
while for someone with that background to switch styles.


Robert Amesz

Andrae Muys

unread,
Aug 4, 2002, 9:24:21 PM8/4/02
to
Tim Daneliuk <tun...@tundraware.com> wrote in message news:<io9fia...@eskimo.tundraware.com>...

> bru...@tbye.com wrote:
> >
> > Yeah, but being syntactic sugar doesn't necessarily make something a bad
> > idea. That's like saying you don't need for-loops since we have
> > while-loops. Heck, since we have operator.mul we don't need '*' anymore.
> > ;-)
> >
> >
>
> Clearly, minimalism can be taken to a ridiculous extreme. But, I still fail
> to see what problem adding switch-case syntax fixes. It is certainly not
> more compact than a dictionary approach AFAIKT, and it is (arguably) no clearer,
> so why add more sugar here?

Agreed.

We already have polymorphic objects which provide a cleaner approach
to the vast majority of traditional switch statements. For the few
that remain, I find an indexed function table approach (generally
using dictionaries, sometimes lists) a far more elegant approach.

In the case of varying conditionals, an if/elif/else chain is hardly
less consise then a switch.

In other words, I don't perceive any advantage to be gained through
introducing a switch statement, except maybe to discourage the use of
cleaner approaches.

> (Then again, I am fond of table (dictionary)-driven constructs because
> they are, IMHO, much more maintainable and clear than the equivalent
> in-line implementations... I'm a wee bit biased)

Definately agreed.

Andrae Muys

Andreas Leitgeb

unread,
Aug 5, 2002, 7:21:41 AM8/5/02
to
Cameron Hutchison <cam...@xdna.net> wrote:
> On Sat, 03 Aug 2002 10:17:25 +1000, Heiko Wundram wrote:
>> On Fri, 2002-08-02 at 18:48, Andreas Leitgeb wrote:
>>> Here, I think, I didn't make my concern clear enough:
>>> in C/C++ (and similar in Tcl) I can do the following:
>>> [example of non-trivial for-loop snipped]

>> There is no way to do anything like that in Python, there just isn't.
> You should be able to do something like:
> [ while - try - continue - finally ]
The idea looked promising, but:
at least python2.0 chokes on it: (I've got no 2.2 at hand right now)
"SyntaxError: 'continue' not supported inside 'try' clause"
other errors in the block would be catched and left unhandled as well
sorry.

Please, see also my second self-followup (which I'm going to post after
answering individual points)

Andreas Leitgeb

unread,
Aug 5, 2002, 8:00:39 AM8/5/02
to
Heiko Wundram <hei...@ceosg.de> wrote:
> On Fri, 2002-08-02 at 18:48, Andreas Leitgeb wrote:
>> Here, I think, I didn't make my concern clear enough:
>> in C/C++ (and similar in Tcl) I can do the following:
>> [ non-trivial for-loop with continue snipped]

> There is no way to do anything like that in Python, there just isn't.
Although some other posters contradicted this statement, it seems
to be true.
There are some approximations, though, as I've learnt in this thread.

> for x in range(0,42):
> s *= 2 [\n> ...]
This is not the same:
C(and Tcl)-for's increment-part is executed _after_ the body, and
_before_ evaluating the condition. _And_ it is the point where
'continue' jumps to)
Placing the increment-part after the end of the body will cause it
to be skipped by a 'continue' which I'd need to prevent.
Using Iterators prohibits me of altering the loop-variables inside
the body, which is no good style anyway ;-)

> Dictionaries aren't functions as they are in Tcl

Dictionaries aren't functions in Tcl, either. But Tcl uses
paranthesis to access the values from a dictionary, so for a
non-Tcl'er it may have looked like function-calls :-)
$dict(key) in Tcl --> dict['key'] in Python, and
$dict($keyvar) in Tcl --> dict[keyvar] in Python.

What I was referring to with "cluttering namespace with functions" was,
that others had suggested the following:
def handle_this(...): ...
def handle_that(...): ...
table['this']=handle_this; table['that']=handle_that; ...
# and then:
table[switchvar]()
which would have required a separate function for each branch,
which sometimes happens anyway (if the switch-branches would have
called the functions), but is not always the right thing.

> If you need to access a global name from within a function,

I wasn't speaking about global vars, but vars in the caller's
context. (accessing them is an important idiom in Tcl to
get a "call by reference"), but sometimes it seemed to be
quite useful even apart from that idiom.

[ mutating arguments passed to a function ]


> This is based on the concept that Python always passes variables by
> reference, and that there are some types that are simply not mutable
> (such as tuples, integers, floats). This makes the language cleaner, as
> you don't have all that mess you have in C/C++ where you have to watch
> out about pointers, and the like.

I've meanwhile recognized python's "call-by-reference"-mechanism
to be similar to java's (and completele unlike C/C++'s)

Assignment to parameter-vars inside a function get lost, but
mutations on arguments are visible outside.
There are some inconsistencies between the builtin types, whether
+=, etc. will replace or mutate the object on its left-hand-side.

> You can pass out more than one argument just by wrapping it in a tuple.

I know, but I'd like to have the choice, especially when dealing with
list-objects containing >million entries :-) (even though the referenced
objects are shared, the list itself would need to be copied)

> Well, hope this makes you look a little more favorable at Python than
> what was suggested by your post. ;)

Currently I'm in the phase of getting to know, what I can do and
what I need to do differently.
Once I think I've got some idea, I'll try to translate some of
my scripts to python and see, whether they become clearer or
obfuscated'er :)

Anyway, Python has some bonus' that make me even accept some other
shortcomings.
But the same still holds for Tcl, and lotsa other langs (even perl),
too ;-)

> someone-put-me-on-python-advocacy-'ly yours,

Andreas Leitgeb

unread,
Aug 5, 2002, 8:15:30 AM8/5/02
to
Cameron Laird <cla...@starbase.neosoft.com> wrote:
> Part of the context of Andreas' questions
> is that Tcl builds-in a [switch] with
> several different comparisons possible.
Yes, Cameron knows me from comp.lang.tcl :-)

For tcl's switch, I can specify any of: exact-, glob- or regexp-match,
which is technically speaking, syntactic sugar for an if-elif*-else
construct, but really very good quality sugar, that I'm sorry to
miss here.

The quality of that sugar comes from not having to explicitely repeat
the comparison-function and common 'switchvar' argument.
Now that I write this, I suddenly see, how one can resemble a switch
almost cleanly with lambda-expressions and if-elif*-else:
switchvar=...
# "compare" could be regexp,glob,case-insensitive
case=lambda x: compare(x,switchvar)
if case('foo'):
...
elif case('foo*'):
...
you get the idea ...
I'm just curious about performance ...

Andreas Leitgeb

unread,
Aug 5, 2002, 8:43:24 AM8/5/02
to
Hans Nowak <wu...@earthlink.net> wrote:
> Andreas Leitgeb wrote:

> That is understandable, coming from another language and being used to
> different idioms.

Whenever I start to peek into a new language, I try to recognize
some abstract elements in it.
one of these "abstract elements" is described as such:
'A loop, whose body can directly and freely modify the
loop-var, thereby controlling the loop'
(one might for example want to step back one iteration eventually,
which seems unachievable with iterator-based loops)
('freely' means more than continue&break)
In C/C++/Java/perl/Tcl there is the for-loop that fulfills it.
Python lacks it.
Of course, one might question the usefulness of this feature,
but that's not in the scope of my original question.
Whether I really need it and whether and with what magic tricks I can
do without it, practise will show.

> Why not: [ replace continue with an if and make everything after
> the continue part of the if-block]
I wrote: the location of continue may be nested arbitrarily deep down
inside other if's.

> I don't know which book you used to learn Python, but it seems it taught you
> the right things and common "Pythonic" idioms.

It is the german translation of:
"Python Pocket Reference (2nd edition)" ("Python kurz&gut")

> you may find yourself using the other constructs anyway, because they "feel
> better". Just give them a try.

Yes, of course.
My intended question was not, how to program C/Tcl in python, but what
are Python's idioms for the mentioned "tasks".
The reason, this thread grew so fast, was that obviously I didn't
specify these "tasks" well enough.

Andreas Leitgeb

unread,
Aug 5, 2002, 8:58:49 AM8/5/02
to
holger krekel <py...@devel.trillke.net> wrote:

> Heiko Wundram wrote:
>> There is no way to do anything like that in Python, there just isn't.
> Huh? Maybe you mean there isn't this exact syntax which is correct.
As I already f'up'd to Heiko, I think he was right.

Using generators can solve my problem in most cases, but it
still is not as general & powerful as the loop I asked for.

It's not that I ask for adding one to Python, it's just
that now I know, whenever I'd have felt like using such
a for-loop I'd have to do it differently.

> def counted_doubler(...): ... yield(i,s) ...


> for i,s in counted_doubler(42,'*'):

while this shows how to use more than one loop-var parallel,
(which looks like a useful idiom: thanks) it's not
a complete replacement for other languages' "for".

> Syntactic sugar is relatively
> minimal compared to other languages.

I don't understand, why "Syntactic sugar" has such a negative
connotation in most language-newsgroups.
It's usually syntactic sugar, that makes a language pleasing to
work with.
Languages without sugar (such as lisp/scheme but also various
assembler-langs as far as I know them) are really abhorrent for me.

Python also does have it's portion of s.s., and it's good it does.

Andreas Leitgeb

unread,
Aug 5, 2002, 9:11:21 AM8/5/02
to
Keith Dart <kd...@kdart.com> wrote:
> "Andreas Leitgeb" <Andreas...@siemens.at> penned these words:
>> [common answer: yes, there are modules: asyncore and select] Thanks a
>> lot, I'll have a look at them.
>
> YOu might also want to look at the asyncio module in the pyNMS package.
> http://pynms.sourceforge.net/
> This works like asyncore, but uses SIGIO. It only works on Linux,
> however. And it needs a little more work....
Really only linux ? Or did you mean "only unix" ?
(sourceforge also mentions only linux)

While I mostly use linux myself, I'd feel more comfortable if my
python-scripts also ran on solaris and other unices at least.

Andreas Leitgeb

unread,
Aug 5, 2002, 10:12:31 AM8/5/02
to
Oren Tirosh <oren...@hishome.net> wrote:
> The asyncore documentation could be better.
I had a look at help("asyncore"), and it gave me headache :-(

> If you have any ideas how to make it easier to use I'd love to hear them,
> whether they're tcl-inspired or not...

yes, and I think it would be quite easy (up to details) to do
it in Python: (the following is python-like, but pseudo-code)
The implementations are missing, and could be based on asyncore.

module fileevents:
# register a channel for watching reads, writes or errors
# fd (a file-object or a numeric os-filedescriptor)
# cb (callback: a function object taking a few parameters
# defined later. Specifying Null here, will cancel
# a previously set up callback for that channel
# mode (what events to register for: readable,writable,error
# or more of them. If error is not registered for an fd
# at the time the internal select() returns one for the fd,
# then read- and/or write-callback will be called instead
# once and then the channel is automtically unregistered.)
# data (an arbitrary object, that will be passed to the
# callback as is)
def register(fd,cb,mode="read",data=None)
reg=register # alias :-)

# if a timer is set, the internally called select is called with
# an appropriate timeout, to awake at the first requested timer
# after the callback returns, select is automatically called again,
# with the time left until the next waiting timer.
def timer(seconds,cb,data=None,autoreset=0)

# unregister a channel:
unreg = lambda fd,mode,data=None: register(fd,None,mode,data)

# the main loop:
# calls select(), and when that finishes, calls all the
# registered callback-functions whose condition is met
# and/or all timer-callbacks. Exceptions thrown by callbacks
# are caught, and handled: (e.g. printed out, or some
# registered exception-handler called)
# If there is no timer and no registered fileevent left,
# or on some other condition (yet to be defined - perhaps a
# special exception, as in asyncore), loop() finishes.
def loop()

So much for the basic interface.
possible enhancements:
allow identifying & cancelling of timers

Some of the suggested features even go beyond Tcl's current
fileevents :-)

PS: this was a brainstorming, not yet a thought-out design.

Andreas Leitgeb

unread,
Aug 5, 2002, 10:16:33 AM8/5/02
to
Martin v. Loewis <mar...@v.loewis.de> wrote:
> That kind of processing assumes that your language runtime owns a
> mainloop. While this is a compromise that Tcl was willing to make, I
> still think that must be left out of the programming language, and
> should be part of libraries.
It has the big advantage, though, that it makes it easier for new
modules to fit into a central mainloop, than into decentral
mainloops of other modules.
e.g. GUI and asyncore

holger krekel

unread,
Aug 5, 2002, 10:58:08 AM8/5/02
to
Andreas Leitgeb wrote:
> [me]

> > Syntactic sugar is relatively
> > minimal compared to other languages.
> I don't understand, why "Syntactic sugar" has such a negative
> connotation in most language-newsgroups.

If you - like quite some people do - program with lots of
different languages in the scope of - say - five years
you realize that syntactic sugar usually doesn't cut it.

You wan't to be able to express ideas and give good names
to them so that you later can maintain it. For me, python
helps a lot here.

> It's usually syntactic sugar, that makes a language pleasing to
> work with.

up to a certain degree, yes. E.g. perl certainly goes too far for me.
I professionally worked with perl for two years, day in and out.
That's just two years ago and i can't remember even basic stuff
due to the high ratio of !`{$[%&/ characters in a line (called
line-noise). IIRC, TCL was better for me in this area.

cheers,

holger

holger krekel

unread,
Aug 5, 2002, 11:01:00 AM8/5/02
to
Andreas Leitgeb wrote:
> Oren Tirosh <oren...@hishome.net> wrote:
> > The asyncore documentation could be better.
> I had a look at help("asyncore"), and it gave me headache :-(

IIRC, it has been updated recently at

http://www.python.org/dev/doc/devel/lib/module-asyncore.html


Andreas Leitgeb

unread,
Aug 5, 2002, 11:31:05 AM8/5/02
to
Robert Amesz <sheer...@mailexpire.com> wrote:
> As C-style goes this isn't a very pretty piece of code, especially
> since you seem bent on building a string of 2**42 '*' characters.
Yes, that was just an example, and not meant to be actually run :-)
I like the number 42, and ord("*") being 42, this is even a beautiful
example. :)

The other comments about that example have appeared similarly in
other posts, and answered in their followups.

>>> 4.) "calls by reference": def f( x ) : x=42

> _Don't_ use a one element list: that's misleading to anyone (including
> yourself) who reads that code later.

since Python seems to keep all types as "first class objects", I thought
it would not matter whether I chose an integer or any other object for
the example.
Meanwhile I've recognized Python's "call-by-ref" to be similar to
Java's (probably because object-handling is similar between these
languages) and I can live with that.

Generally:
It depends on the context on whether it is better to
make use of call-by-ref or return a result.
If the object is a list of millions of entries, it is definitely
better to have a way of modifying the list in-place than returning
even a shallow copy of it.


> The examples you give are typical ones if you try to emulate C-style in
> Python.

I see this differently:
If you had to switch from Python to C (and you didn't know C yet),
you would most likely ask, how to create a dictionary, and how
to do lists of mixed typed objects.
Maybe you'd hack together a simple dictionary in C, so you could
continue to use this powerful tool.
I wouldn't call this "emulating Python-style" then.


> I'm not quite sure how Python compares to TCL as my experience with
> that language is anything but extensive.

What really counts for me is, what useful gadgets and idioms a language
provides me, to let me express the algorithms as concisely as
possible. Some simple things become quite complicated when
writing it in Tcl, others, easy in Tcl, seem to become difficult
in Python ...
perl, e.g. offers me a genious regexp-engine and -syntax (not only the
re-syntax itself, but also how it is embedded in perl: if (/bla.*/) ... ).
If I write something that uses lots of regexps, I use perl (which I
otherwise don't like that much)
Tcl offers me a powerful event-loop, direct access to any stackframe
up to global context, lets me view the bodies of previously defined
procedures, but unfortunately also has some over-sophisticated
builtins (e.g. exec) that are hard to work around, and some level of
obfuscation is needed to pass a list as separate args to a function.
Python offers me flexible function-handling (passing a dictionary as
arguments), lambda's, generators(yield), ... (and more to be discovered
by me), but lacks a general for-loop (as in C and others), lacks
an internal event-loop, and other things I've not yet come across.


[Roberts "IMHO"'s :) ]


> The everything-is-a-string paradigm is interesting and pretty unique,
> but also limiting.

Unique, yes, interesting: not all that much, limiting: nope.

> The syntax seems to have been designed to help the interpreter
> rather than the programmer,

Initially perhaps, but Tcl has developed far enough, so I don't
necessarily notice it from programmer's point of view.

Cameron Laird

unread,
Aug 5, 2002, 12:32:54 PM8/5/02
to
In article <Xns92602661...@amesz.demon.nl>,
Robert Amesz <rca...@dds.nl> wrote:
.
.
.

>that language is anything but extensive. The everything-is-a-string
>paradigm is interesting and pretty unique, but also limiting. The
See <URL: http://wiki.tcl.tk/everything > for
commentary on just this subject.

>syntax seems to have been designed to help the interpreter rather than
>the programmer, (IMHO, of course.) I suppose it will take a little
That's a valid and important criticism--of other
languages. Whether it applies to Tcl is less
certain. Perhaps it helps to regard Tcl's
syntax as degenerate; like Forth and Lisp, it's
not supposed to have a syntax.

Andres Rosado

unread,
Aug 5, 2002, 8:32:11 PM8/5/02
to
At 09:26 PM 8/2/2002 -0400, you wrote:
>Clearly, minimalism can be taken to a ridiculous extreme. But, I still fail
>to see what problem adding switch-case syntax fixes. It is certainly not
>more compact than a dictionary approach AFAIKT, and it is (arguably) no
>clearer,
>so why add more sugar here?
>
>(Then again, I am fond of table (dictionary)-driven constructs because
>they are, IMHO, much more maintainable and clear than the equivalent
>in-line implementations... I'm a wee bit biased)

I'm quite new to programming in Python and this puzzled me. Could you give
me an example of using dictionaries instead of switch?

Thank you very much!


-----------------------------------
Andres Rosado
Email: and...@despammed.com
ICQ: 66750646
Homepage: http://andres980.tripod.com/

"There is no choice before us. Either we must Succeed in providing
the rational coordination of impulses and guts, or for centuries
civilization will sink into a mere welter of minor excitements.
We must provide a Great Age or see the collapse of the upward
striving of the human race"
-- Alfred North Whitehead


0 new messages