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

'for every' and 'for any'

0 views
Skip to first unread message

Oren Tirosh

unread,
May 26, 2002, 6:59:44 AM5/26/02
to
Here's an idea for a possible language enhancement. I'd like to hear your
comments about it. It's inspired by list comprehensions and I think the
examples are pretty self-explanatory:

if not isinstance(x, str) for any x in args:
raise TypeError, "arguments must be of type str"

valid = i>0 for every i in vector

if dict2.has_key(k) for any k in dict1:
...

The words 'any' and 'every' can be non-reserved keywords (like the word 'as'
in "import foo as bar"). They are valid only after the keyword 'for' when
it's used in a non-statement context.

Oren

Peter Hansen

unread,
May 26, 2002, 9:33:23 AM5/26/02
to
Oren Tirosh wrote:
>
> Here's an idea for a possible language enhancement. I'd like to hear your
> comments about it. It's inspired by list comprehensions and I think the
> examples are pretty self-explanatory:
>
> if not isinstance(x, str) for any x in args:
> raise TypeError, "arguments must be of type str"

for x in args:
if not isinstance(x, str):


raise TypeError, "arguments must be of type str"

> valid = i>0 for every i in vector

valid = True
for i in vector:
if i <= 0:
valid = False
break

> if dict2.has_key(k) for any k in dict1:
> ...

for k in dict1:
if dict2.has_key(k):
break

Other than saving a few lines at the expense of code that is "denser"
and (I believe) harder to understand at a glance, what advantage
do these constructs have? Can you post an example where the improvement
is clear and overwhelmingly convincing?

-Peter

jep...@unpythonic.net

unread,
May 26, 2002, 10:17:47 AM5/26/02
to
On Sun, May 26, 2002 at 01:59:44PM +0300, Oren Tirosh wrote:
> Here's an idea for a possible language enhancement. I'd like to hear your
> comments about it. It's inspired by list comprehensions and I think the
> examples are pretty self-explanatory:
>
> if not isinstance(x, str) for any x in args:
> raise TypeError, "arguments must be of type str"

this is equivalent to
bool([None for x in args if not isinstance(x, str)])


>
> valid = i>0 for every i in vector

This is equivalent to
not [None for i in vector if not i > 0]
(i>0 for every i in vector <==> not (not i > 0 for any i in vector))
.. a little more cumbersome. You could also write
[i for i in vector if i > 0] == vector
or
len([i for i in vector if i > 0]) == len(vector)
depending how much like a sequence (i.e., not an iterator) vector is.

> if dict2.has_key(k) for any k in dict1:
> ...

bool([None for k in dict1 if k in dict2])

> The words 'any' and 'every' can be non-reserved keywords (like the word 'as'
> in "import foo as bar"). They are valid only after the keyword 'for' when
> it's used in a non-statement context.

The other issues to work out would include the precedence of operators. Is
it
not (isinstance(x,str) for any x in args)
or
(not isinstance(x,str)) for any x in args
?

I'm not 100% sure that you can even implement this in the Python parser.
After all, if just having 'for..in' later on in the expression could give
you a generator, then we wouldn't need the silly brackets ..
l = x for x in range(1000) if isprime(x)

Jeff


Andrew Dalke

unread,
May 26, 2002, 3:00:11 PM5/26/02
to
jep...@unpythonic.net:

>this is equivalent to
> bool([None for x in args if not isinstance(x, str)])

Not quite the same as the original poster's request, which
raises a TypeError, and raises it at the first error location
without continuing to scan the rest of the args. It's also
harder to understand this as a list comprehension. Jeff's
style, of

for x in args:
if not isinstance(x, str):


raise TypeError, "arguments must be of type str"

is what I consider to tbe the prefered style, except I think the
exception should be raised

raise TypeError("arguments must be of type str")

(That preferred change occured, I believe, in Python 1.4.)

>> valid = i>0 for every i in vector
>
>This is equivalent to
> not [None for i in vector if not i > 0]

Jeff's equivalent also stopped at the firt match while yours scans
everything. That may or may not be part of the consideration of
the original poster.

Oren Tirosh:


>> The words 'any' and 'every' can be non-reserved keywords (like the word
'as'
>> in "import foo as bar"). They are valid only after the keyword 'for'
when
>> it's used in a non-statement context.

Jython supports something like this, to allow "print" as a method name.
This is important because there are a lot of Java classes with that name,
as it isn't a keyword in Java. As I recall, this came up recently in
python-dev and Guido was against implementing it for CPython, because
he didn't want a word which was a keyword in places and a variable in
others. This change won't happen.

Andrew
da...@dalkescientific.com

Hans Nowak

unread,
May 26, 2002, 7:20:02 PM5/26/02
to

Interesting. I don't know enough about the language internals
to judge whether this is doable or not, or whether it's a good
idea or not. I do think that these constructs can be emulated
though, and we don't even need too much hackery.

Let's start with defining the 'any' and 'every' functions:

>>> every = lambda a, b: a and b
>>> any = lambda a, b: a or b

> if not isinstance(x, str) for any x in args:
> raise TypeError, "arguments must be of type str"

# error condition met: not everything's a string
>>> reduce(any, [not isinstance(x, str) for x in [23, 33, "foo"]])
1

# no error condition:
>>> reduce(any, [not isinstance(x, str) for x in ["foo", "bar"]])
0

> valid = i>0 for every i in vector

# not everything's > 0:
>>> reduce(every, [i>0 for i in [0, 1, 2]])
0

# but here it is:
>>> reduce(every, [i>0 for i in [4, 5, 6]])
1

> if dict2.has_key(k) for any k in dict1:

>>> d1 = {1:2, 3:4, 5:6}
>>> d2 = {1:3, 6:6}
>>> d3 = {0:2, 9:3}
# yes, there are some mutual keys
>>> reduce(any, [d2.has_key(k) for k in d1.keys()])
1
# not here though
>>> reduce(any, [d2.has_key(k) for k in d3.keys()])
0

It can be done even simpler:

>>> def Any(lst):
return reduce(lambda a, b: a or b, lst)

>>> def Every(lst):
return reduce(lambda a, b: a and b, lst)

# every number > 0
>>> Every([i>0 for i in [4, 5, 6]])
1
# not here though:
>>> Every([i>0 for i in [0, -2, 4]])
0
# yes, there are any numbers > 0
>>> Any([i>0 for i in [-2, 0, 2]])
1

(Disclaimer: I haven't these constructs extensively,
but they seem to work.)

Cheers,

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

Oren Tirosh

unread,
May 28, 2002, 2:33:11 AM5/28/02
to
On Sun, May 26, 2002 at 09:17:47AM -0500, jep...@unpythonic.net wrote:

> On Sun, May 26, 2002 at 01:59:44PM +0300, Oren Tirosh wrote:
> > Here's an idea for a possible language enhancement. I'd like to hear your
> > comments about it. It's inspired by list comprehensions and I think the
> > examples are pretty self-explanatory:
> >
> > if not isinstance(x, str) for any x in args:
> > raise TypeError, "arguments must be of type str"
>
> this is equivalent to
> bool([None for x in args if not isinstance(x, str)])

Sure, and the list comprehension


[None for x in args if not isinstance(x, str)]

Is equivalent to
map(lambda x: None, filter(lambda x: isinstance(x, str), args))

But which one is more readable?

List comprehensions were introduced into the language because they make
the code much more readable and English-like. I consider this an important
feature of the language.

I often use Python to write specifications. Python is great for this task
because it can be written in a way that is very compact and very readable
even for someone who has never seen Python source before. Python list
comprehensions are one of the things that make this possible. I use Python
as a language for writing specifications that also happen to be an executable
reference implementation. The poor souls that later have to implement the
specification in C++ often write write 10-20 times as much code as the
Python implementation and have a much harder harder time debugging it :-)

Anyway, the common task of checking if all or any of the items of a list
match a certain predicate is implemented in a large variety of ways. Just
in the replies to my message I got implementations that use break
statements, exceptions to break of of the loop, flags, checking for empty
lists, comparing list length to the original list and reduce with lambdas.
I've also seen a lot of code that uses the return statement as a kind of
break to achieve this effect.

The fact that there is no simple, common idiom to express this operation
seems to suggest that this part of the language is not as natural as it
could be. Most common ways to express this operation make use control flow
statements rather than expressions which makes them more awkward to use.
An expression is easy to use in an if statement where you get an else
clause. Using combinations of break makes it harder to use both the positive
and negative case. I often find myself rearranging my code and sometimes
inverting tests just to get what I want. That's not what programming is all
about. I'd rather concentrate on the task at hand than on how to express it.

Oren

Quinn Dunkan

unread,
May 28, 2002, 12:01:40 PM5/28/02
to
On Tue, 28 May 2002 02:33:11 -0400, Oren Tirosh <oren...@hishome.net> wrote:
>On Sun, May 26, 2002 at 09:17:47AM -0500, jep...@unpythonic.net wrote:
>> On Sun, May 26, 2002 at 01:59:44PM +0300, Oren Tirosh wrote:
>> > Here's an idea for a possible language enhancement. I'd like to hear your
>> > comments about it. It's inspired by list comprehensions and I think the
>> > examples are pretty self-explanatory:
>> >
>> > if not isinstance(x, str) for any x in args:
>> > raise TypeError, "arguments must be of type str"
...

>Anyway, the common task of checking if all or any of the items of a list
>match a certain predicate is implemented in a large variety of ways. Just
>in the replies to my message I got implementations that use break
>statements, exceptions to break of of the loop, flags, checking for empty
>lists, comparing list length to the original list and reduce with lambdas.
>I've also seen a lot of code that uses the return statement as a kind of
>break to achieve this effect.

The standard lisp functions EVERY and SOME are easily written in python:

def every(f, seq):
for e in seq:
if not f(e):
return 0
else:
return 1
def some(f, seq):
for e in seq:
if f(e):
return 1
else:
return 0

Then the above becomes:

if not every(is_string, args):
raise TypeError('why is that "brick" so "bleck"?')

where:

def is_string(o):
'checking for stringp is more complicated if you include unicode'
# if you want backward compatibility, it's even more complicated
return some(lambda t: isinstance(o, t), types.StringTypes)

>The fact that there is no simple, common idiom to express this operation
>seems to suggest that this part of the language is not as natural as it
>could be. Most common ways to express this operation make use control flow
>statements rather than expressions which makes them more awkward to use.

The above functions are how I would solve the problem at first glance
(though I'd probably call them "any" and "all" after haskell). They're not
builtin to python but are standard in many other languages. Any any case, it
seems quite simple and natural to me (as well as being an expression).

The fact that I don't have them in my util library probably means I don't need
them very often and when I do I find it easier to write three lines of loop.
Probably because the loop is so easy, and if you take the any/all route you
soon find yourself writing curry() and before you know it you're generating
thunks to foil eager evaluation and then you realize you're well down the
slipperly slope and made a big mess of things by writing non-pythonic python.

>An expression is easy to use in an if statement where you get an else
>clause. Using combinations of break makes it harder to use both the positive
>and negative case. I often find myself rearranging my code and sometimes
>inverting tests just to get what I want. That's not what programming is all
>about. I'd rather concentrate on the task at hand than on how to express it.

Then drop those functions into your personal utility library and use 'em
as often as you want :)

As an aside, I'm sure you know this and your example was just a silly example,
but explicitly checking types is usually bad form in python.

Tim Peters

unread,
May 28, 2002, 12:20:19 PM5/28/02
to
ABC had existential and universal quantifiers in its flavor of Boolean
expressions, and they were quite Pythonic. I can't make time now to write
up the details, but have written them up several times before. The most
recent seems to be this brief summary:

http://aspn.activestate.com/ASPN/Mail/Message/679408

Oren Tirosh

unread,
May 29, 2002, 3:46:01 AM5/29/02
to
On Tue, May 28, 2002 at 04:01:40PM +0000, Quinn Dunkan wrote:
> >An expression is easy to use in an if statement where you get an else
> >clause. Using combinations of break makes it harder to use both the positive
> >and negative case. I often find myself rearranging my code and sometimes
> >inverting tests just to get what I want. That's not what programming is all
> >about. I'd rather concentrate on the task at hand than on how to express it.
>
> Then drop those functions into your personal utility library and use 'em
> as often as you want :)

I don't have a personal utility library. It's on purpose. I don't have
personalized key bindings. I try to avoid customization. Customization is
a big part of what makes one programmer's code difficult to maintain by
another programmer, what makes on programmers's workstation unusable by
another and makes combining code from several sources difficult.

Just one little example: I hate it when different parts of the code use
their own customized constants for ints from specific sizes. Is it
u_int32_t, uint32_t or guint32? I hate it when a big project starts and the
programmers all start to waste their time on writing a yet another library
with all this stuff.

One of the things I like about Python is that it comes with everything in
the box.

Oren


Quinn Dunkan

unread,
May 29, 2002, 4:48:33 PM5/29/02
to
On Wed, 29 May 2002 03:46:01 -0400, Oren Tirosh <oren...@hishome.net> wrote:
>On Tue, May 28, 2002 at 04:01:40PM +0000, Quinn Dunkan wrote:
>> >An expression is easy to use in an if statement where you get an else
>> >clause. Using combinations of break makes it harder to use both the positive
>> >and negative case. I often find myself rearranging my code and sometimes
>> >inverting tests just to get what I want. That's not what programming is all
>> >about. I'd rather concentrate on the task at hand than on how to express it.
>>
>> Then drop those functions into your personal utility library and use 'em
>> as often as you want :)
>
>I don't have a personal utility library. It's on purpose. I don't have
>personalized key bindings. I try to avoid customization. Customization is
>a big part of what makes one programmer's code difficult to maintain by
>another programmer, what makes on programmers's workstation unusable by
>another and makes combining code from several sources difficult.

Um, customizing your workstation is only going to cause problems for other
people if they use your account. I'm hoping they don't do that? No one can
use my wacky setup but they don't need to because I log out when I'm done.

All of the good programmers I've seen working have idiosyncratic setups. I've
never heard of any problems because of it as long as they can edit text and run
cvs or whatever, but I've seen plenty of problems suffered by people who
exclusively use poorly chosen defaults.

And if you're writing code with another programmer, yes, you both need to use
the same libraries. You should also use the same language :)

Of the hard-to-maintain code I've looked at, it's always been not enough
abstraction, rather than too much. People who are used to C and Pascal seem to
be especially used to reinventing common operations, probably because
non-polymorphic static languages make it hard to write generic anything.

>Just one little example: I hate it when different parts of the code use
>their own customized constants for ints from specific sizes. Is it
>u_int32_t, uint32_t or guint32? I hate it when a big project starts and the
>programmers all start to waste their time on writing a yet another library
>with all this stuff.

That's a complaint about C's type system, and is not relevant to the issue.

The question of C programmers re-writing a utility library is also not
relevant because the question is not re-writing vs. re-using a utility
library, but using one vs. not using one. There seems to be some kind of
cultural thing where C programmers like to reinvent stuff. Or something.
I'm not really a C programmer so I don't know.

Would you avoid certain abstraction mechanisms in C because it led to a mess
when you tried it in FORTRAN 30 years ago?

>One of the things I like about Python is that it comes with everything in
>the box.

The way I see it, one of the major advantages of dynamic flexible languages
like python and lisp is the ability to program "bottom up" (to use graham's
terminology) by writing a lot of little generic interoperable parts that can be
stacked up later. No language can come with everything in the box, and an
attempt to make it so is trouble because everyone's needs are different.

I agree that programming is not rearranging loops but about expressing the
problem as directly as possible. The chances are slim that you'll be able to
directly express your problem in "pure syntax".

Anyway, obviously you're free to follow whatever convention you wish. I'm just
saying that I don't agree with it so I don't go for the "but I can't use this
solution because my religion forbids it" line.

Delaney, Timothy

unread,
May 29, 2002, 7:09:39 PM5/29/02
to
> From: Oren Tirosh [mailto:oren...@hishome.net]

>
> I don't have a personal utility library. It's on purpose. I don't have
> personalized key bindings. I try to avoid customization.
> Customization is
> a big part of what makes one programmer's code difficult to
> maintain by
> another programmer, what makes on programmers's workstation
> unusable by
> another and makes combining code from several sources difficult.

What? You mean you write everything from scratch every time? Guess you don't
use any third-party libraries either. Oh - and I guess you don't use modules
- everything must be in a single file.

Oh - you do? Where are your modules stored? Wow - looks like a personal
library to me ...

Tim Delaney


Kragen Sitaker

unread,
May 29, 2002, 10:20:04 PM5/29/02
to
qu...@regurgitate.ugcs.caltech.edu (Quinn Dunkan) writes:
> Um, customizing your workstation is only going to cause problems for other
> people if they use your account. I'm hoping they don't do that? No one can
> use my wacky setup but they don't need to because I log out when I'm done.

Other people use my account when we are sitting at the machine together.

> Of the hard-to-maintain code I've looked at, it's always been not enough
> abstraction, rather than too much.

I've seen quite a bit of both. Code that's either not abstract enough
or too abstract can be ten times the size of the ideal code; modifying
a 20 000 line program is a lot harder than modifying a 2 000 line
program that does the same thing.

> People who are used to C and Pascal seem to be especially used to
> reinventing common operations, probably because non-polymorphic
> static languages make it hard to write generic anything.

When I work in C, it's usually for one of two reasons:
1. I feel like reinventing the wheel for fun, so I do.
2. I need (or, anyway, want) the performance, so I tend to reinvent
common operations so they're optimized for my application.

David LeBlanc

unread,
May 29, 2002, 10:56:40 PM5/29/02
to
Then you shrink it down to 200 lines of dense Perl and it's impossible to
modify!

David LeBlanc
Seattle, WA USA

> --
> http://mail.python.org/mailman/listinfo/python-list

Oren Tirosh

unread,
May 30, 2002, 8:26:47 AM5/30/02
to
On Thu, May 30, 2002 at 09:09:39AM +1000, Delaney, Timothy wrote:
> > From: Oren Tirosh [mailto:oren...@hishome.net]
> >
> > I don't have a personal utility library. It's on purpose. I don't have
> > personalized key bindings. I try to avoid customization.
> > Customization is
> > a big part of what makes one programmer's code difficult to
> > maintain by
> > another programmer, what makes on programmers's workstation
> > unusable by
> > another and makes combining code from several sources difficult.
>
> What? You mean you write everything from scratch every time? Guess you don't
> use any third-party libraries either. Oh - and I guess you don't use modules
> - everything must be in a single file.

Aww... leave that poor little strawman alone. Sure, I have code I have
collected over the years for various specific purposes and I reuse code
written by others. What I don't have is a personal library with lots of
unrelated little tricks and idiosyncracies of questionable value that might
make me feel a bit more comfortable but only makes the code feel alien when
it's read by someone else.

For some reason, reading Python code almost always feels familiar
regardless of who wrote that code. This is definitely not true of C, C++
or Perl.

Oren

Oren Tirosh

unread,
May 30, 2002, 9:09:38 AM5/30/02
to
On Wed, May 29, 2002 at 08:48:33PM +0000, Quinn Dunkan wrote:
> >I don't have a personal utility library. It's on purpose. I don't have
> >personalized key bindings. I try to avoid customization. Customization is
> >a big part of what makes one programmer's code difficult to maintain by
> >another programmer, what makes on programmers's workstation unusable by
> >another and makes combining code from several sources difficult.
>
> Um, customizing your workstation is only going to cause problems for other
> people if they use your account. I'm hoping they don't do that? No one can
> use my wacky setup but they don't need to because I log out when I'm done.

Nobody else ever uses my workstation but if I customize it too much I will
feel crippled whenever I ssh or install a new machine somewhere. So I ask
myself whether I really need it.

> All of the good programmers I've seen working have idiosyncratic setups.

And they spend ridiculous amounts of time fine-tuning their setup that could
not possibly be justified by the alleged efficiency gained. I used to do
that too. It's fun, but it is not rational activity. Python is one of the
things that helped me stop it. It's just good enough as it is. I only need
a nice editor (vi will do if I'm on an alien machine) and Python which comes
installed by default more and more often.

> Of the hard-to-maintain code I've looked at, it's always been not enough
> abstraction, rather than too much. People who are used to C and Pascal

It has nothing to do with abstraction. I'm talking about the part of the
learning curve called "making youself feel at home". If the environment is
not powerful enough and makes you jump through hoops for common tasks
it encourages gratuitous customization until you feel comfortable.

> library, but using one vs. not using one. There seems to be some kind of
> cultural thing where C programmers like to reinvent stuff. Or something.

I think they hate reinventing stuff, but C is just not powerful enough as
it is when you finish the installation. I am not talking about theoretical
Turing-equivalence, I'm talking about the power of sitting down and just
writing what you want without too much fuss. So they customize and search
for the right generic utility library or write their own. And it's never
the *same* utility library, of course.

> stacked up later. No language can come with everything in the box, and an
> attempt to make it so is trouble because everyone's needs are different.

Python comes close. It answers more people's needs with less things to learn
and keep in your mind. Languages are not all born equal. Some of them have
Dutch ancestry :-)

Oren

Quinn Dunkan

unread,
May 30, 2002, 4:57:37 PM5/30/02
to
On Thu, 30 May 2002 09:09:38 -0400, Oren Tirosh <oren...@hishome.net> wrote:
>On Wed, May 29, 2002 at 08:48:33PM +0000, Quinn Dunkan wrote:
>> >I don't have a personal utility library. It's on purpose. I don't have
>> >personalized key bindings. I try to avoid customization. Customization is
>> >a big part of what makes one programmer's code difficult to maintain by
>> >another programmer, what makes on programmers's workstation unusable by
>> >another and makes combining code from several sources difficult.
>>
>> Um, customizing your workstation is only going to cause problems for other
>> people if they use your account. I'm hoping they don't do that? No one can
>> use my wacky setup but they don't need to because I log out when I'm done.
>
>Nobody else ever uses my workstation but if I customize it too much I will
>feel crippled whenever I ssh or install a new machine somewhere. So I ask
>myself whether I really need it.

Ok, I can understand that. I have to know qwerty because I use public access
terminals. For everything else, I haven't had a problem because either my home
directory is NFSed, or I untar my little wad of dotfiles and static binaries.

No, I don't "really need it", since I could do everything under windows with
notepad. I might not even be that much slower, since I spend most of my time
making mistakes and then thinking about the mistakes I just made. I'd have
a lot less fun, though.

>> All of the good programmers I've seen working have idiosyncratic setups.
>
>And they spend ridiculous amounts of time fine-tuning their setup that could
>not possibly be justified by the alleged efficiency gained. I used to do

Well, I can't speak for anyone else, especially not "good programmers", but my
wacky setup hasn't changed significantly since high school. Occaisionally I
find some new way of doing things that bypasses some old annoyance I'd gotten
used to, and I don't know if it actually makes me any "faster", but it makes
life noticably more pleasant.

>that too. It's fun, but it is not rational activity. Python is one of the
>things that helped me stop it. It's just good enough as it is. I only need
>a nice editor (vi will do if I'm on an alien machine) and Python which comes
>installed by default more and more often.

I guess my computing lifestyle is sedentary enough that I can afford to settle
down and decorate the place to taste. The analogy doesn't hold because
untarring a 600K blob is easier than unpacking 1,000 knick-knacks and I can't
NFS mount my room.

I think there's a continuum between taking advantage of configurability to make
the system conform to your personal taste vs. leaving it all alone because
"standard is better than better". The other dimension is that of genuinely
useful modification vs. the occaisionally cathartic pleasure of poking at
minutiae.

Anyway, this subject is not adequately analogous to the utility function
question so I'll leave it alone :)

>> Of the hard-to-maintain code I've looked at, it's always been not enough
>> abstraction, rather than too much. People who are used to C and Pascal
>
>It has nothing to do with abstraction. I'm talking about the part of the
>learning curve called "making youself feel at home". If the environment is
>not powerful enough and makes you jump through hoops for common tasks
>it encourages gratuitous customization until you feel comfortable.

Ok. I guess I just don't consider defining and then calling functions to be
"jumping through hoops". Your usage of "power" seems to be kind of like the
"capability baseline". C has such a low baseline that to do anything useful
you usually need to build it up quite a bit. Higher level languages have a
high enough baseline that you can get quite a bit done with built in data
structures and operations. If I'm interpreting you correctly, then "jumping
through hoops" is "building up the baseline".

To me, that's "abstraction". Logging debugging information is a very common
task, but python doesn't have it built in. I don't write 'if debug >=
whatever: print blah' all the time and blame python for forcing me to jump
through hoops, I write util.dprint(). I don't have to complain about its not
being built in or wait for 2.3 or 2.2.2 or whatever, since I can have exactly
what I want right now.

Working with timed events and lazily evaluated data structures are other common
tasks (for me) that python doesn't have built in. I don't care that it's "not
powerful enough" to express them directly (generators help some) because it is
powerful enough to write some utility classes which express them as directly as
I want (though possibly not as directly as a real concurrent language).

I could be annoyed about having to type awkward nested combinations of
multiple-value-bind, and destructuring-bind and let in some heavily
pattern-matching oriented lisp, but I'd be better off writing a macro
specifically designed to express the kind of matching and binding I'm
interested in.

I don't think of it as gratuitous, and I do think my comfort is important. My
definition of "power" is not so much "how much is built in" but closer to "how
much can I express in a natural way (as if it were built in)".

anyway, that's enough handwaving on that subject :)

Stephen J. Turnbull

unread,
Jun 3, 2002, 2:35:45 AM6/3/02
to
>>>>> "Quinn" == Quinn Dunkan <qu...@regurgitate.ugcs.caltech.edu> writes:

Quinn> To me, that's "abstraction". Logging debugging information
Quinn> is a very common task, but python doesn't have it built in.
Quinn> I don't write 'if debug >= whatever: print blah' all the
Quinn> time and blame python for forcing me to jump through hoops,
Quinn> I write util.dprint(). I don't have to complain about its
Quinn> not being built in or wait for 2.3 or 2.2.2 or whatever,
Quinn> since I can have exactly what I want right now.

Picking an example that suits the point: this is exactly what
PEP-something-or-other (282, in this case) is about. Understood,
_you_ don't have to wait, and you maybe don't want to.

As I understand it, Oren's point is precisely that you rarely have to
wait very long (at the current stage of Python development) for the
appropriate PEP-something-or-other to show up -- and it's usually
pretty well thought out and will work for most people.

Furthermore, PEPs are strongly encouraged (maybe required?) to provide
an implementation early. This means that you can use them now, with a
pretty good shot at forward compatibility.


--
Institute of Policy and Planning Sciences http://turnbull.sk.tsukuba.ac.jp
University of Tsukuba Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
My nostalgia for Icon makes me forget about any of the bad things. I don't
have much nostalgia for Perl, so its faults I remember. Scott Gilbert c.l.py

Andrae Muys

unread,
Jun 3, 2002, 8:36:46 PM6/3/02
to
Oren Tirosh <oren...@hishome.net> wrote in message news:<mailman.1022658469...@python.org>...

> I don't have a personal utility library. It's on purpose. I don't have
> personalized key bindings. I try to avoid customization. Customization is
> a big part of what makes one programmer's code difficult to maintain by
> another programmer, what makes on programmers's workstation unusable by
> another and makes combining code from several sources difficult.
>
> Just one little example: I hate it when different parts of the code use
> their own customized constants for ints from specific sizes. Is it
> u_int32_t, uint32_t or guint32? I hate it when a big project starts and the
> programmers all start to waste their time on writing a yet another library
> with all this stuff.
>

Now I just don't understand how this position can possibly make sense?
C dosn't have any 32-bit int types standardised, so what do _you_ use
when you need one? Please don't tell me you don't use int, or I'll
have to hunt you down and put you out of your misery ;). I personally
have absolutely no problem with any of the 3 examples you gave above:

sometimes-the-word-length-is-important-ly yours
Andrae Muys

Martin Sjögren

unread,
Jun 4, 2002, 3:24:37 AM6/4/02
to
On Mon, Jun 03, 2002 at 05:36:46PM -0700, Andrae Muys wrote:
>
> Now I just don't understand how this position can possibly make sense?
> C dosn't have any 32-bit int types standardised, so what do _you_ use
> when you need one? Please don't tell me you don't use int, or I'll
> have to hunt you down and put you out of your misery ;). I personally
> have absolutely no problem with any of the 3 examples you gave above:

Doesn't C99 specify <stdint.h>? With int8_t, int16_t, ..., uint8_t,
uint16_t, ...


Martin

--
Martin Sjögren
mar...@strakt.com ICQ : 41245059
Phone: +46 (0)31 7710870 Cell: +46 (0)739 169191
GPG key: http://www.strakt.com/~martin/gpg.html


Gerhard Häring

unread,
Jun 4, 2002, 3:48:51 AM6/4/02
to
* Andrae Muys <am...@shortech.com.au> [2002-06-03 17:36 -0700]:

> C dosn't have any 32-bit int types standardised, so what do _you_ use
> when you need one?

Do you need 32 bit ints or >= 32 bit ints?

I only know that Ada 95 and C++ with Boost can guarantee a certain bit length
for ints. Dunno if that's what you wanted to hear :)

Does Python run on any machine where ints are 16 bits long at all?

Gerhard
--
This sig powered by Python!
Außentemperatur in München: 18.7 °C Wind: 2.0 m/s


Tim Peters

unread,
Jun 4, 2002, 7:50:17 PM6/4/02
to
[Andrae Muys]

> Now I just don't understand how this position can possibly make sense?
> C dosn't have any 32-bit int types standardised, so what do _you_ use
> when you need one? Please don't tell me you don't use int, or I'll
> have to hunt you down and put you out of your misery ;).

[Martin Sjögren]


> Doesn't C99 specify <stdint.h>?

Yes.

> With int8_t, int16_t, ..., uint8_t, uint16_t, ...

Not necessarily. All of the exact-size stdint gimmicks are optional -- an
implementation need not supply any of them. This simply reflects reality.
There's a slew of other names, like int_least8_t and int_least32_t, that are
required, and those guarantee to resolve to an integer type *at least* big
enough.

In the Python source, we spell int_least32_t "long", since even C89 required
that the platform long hold at least 32 bits' worth of stuff. People who
think they need a type exactly N bits wide are people who've never thought
about it, or are missing some neurons <wink -- but >= N is easy to live with
provided you're not trying to optimize for space, or relying on woefully
unportable casting tricks).

Well, OK, the Python source does assume in several places that "a byte" is
an 8-bit thingie. The saving grace there is that any platform on which
that's false will never get popular enough to attract a significant user
base.

19-bit-microcomputers-are-a-thing-of-the-past-ly y'rs - tim


Andrae Muys

unread,
Jun 4, 2002, 8:40:41 PM6/4/02
to
Gerhard =?unknown-8bit?Q?H=E4ring?= <gh_pyt...@gmx.de> wrote in message news:<mailman.1023177066...@python.org>...

> * Andrae Muys <am...@shortech.com.au> [2002-06-03 17:36 -0700]:
> > C dosn't have any 32-bit int types standardised, so what do _you_ use
> > when you need one?
>
> Do you need 32 bit ints or >= 32 bit ints?
>
Normally >=32, but in that case anyone using anything other than
standard int or long had better be using a domain specific alias
(size_t, time_t, etc). However when messing with binary data in it's
various forms (network packets, filesystems, executable formats, just
to name a few personal favourates) there are times when you most
definately want N bits *exactly*. Naturally sometimes N == 32. :)

True, if this integer type is likely to leak into the specific modules
interface I'll generally alias it myself, but internally I usually
won't bother.

Andrae

James T. Dennis

unread,
Jun 10, 2002, 5:10:53 PM6/10/02
to
Oren Tirosh <oren...@hishome.net> wrote:

>> Then drop those functions into your personal utility library and use 'em
>> as often as you want :)

> I don't have a personal utility library. It's on purpose. I don't have
> personalized key bindings. I try to avoid customization. Customization is
> a big part of what makes one programmer's code difficult to maintain by
> another programmer, what makes on programmers's workstation unusable by
> another and makes combining code from several sources difficult.

...

> One of the things I like about Python is that it comes with everything in
> the box.

> Oren

Yet, this very discussion proves that "everything" is not already in
the box. I'll grant that Python includes a very large set of batteries
--- but I'd still say that there are many useful functions and classes
that can still be added.

Those should start as personal "utility" libraries, be discussed here
and in PEPs, and (when their general utility is established) added to
appropriate (standard or optional) libraries.

Obviously you don't re-invent the wheel for each project that you join;
you are re-using some code that you've used before, even if it's from
"finger macros." I can see the argument in favor of adapting your
functions to conform to local conventions and every programming team has
to collaborate to find compatible conventions and standards for their
projects. Any non-trivial project (non-trivial, in this case meaning
"requires a *team* of programmers (> 3)) is going to find some elements
of their project that go beyond established coding conventions. The
alternative to "building a (domain/application specific) library" is
to eschew code re-use.

In this particular case the all() and every() functions that were
presented are elegant and seem useful. As others have pointed out the
implementations are trivial; so the questions become: "does it 'pollute
the namespace' to add them to the core library?" and (if so) "where would
we put them?"

Personally I think that a language that support containers as first order
data types should also include a reasonably comprehensive set of
functions to operate on and/or support them. The in operator is good,
the iteration protocol is great, the map(),zip(), and filter() functions
are good. Notably zip() and filter() can be done with map() (trivially
in most cases). I'd say that the inclusion of zip() and filter()
argue *for* the (eventual/future) inclusion of (every() or all()) and
(any() or some()).

M.-A. Lemburg

unread,
Jun 11, 2002, 10:26:13 AM6/11/02
to

You might want to check out mxTools which has quite a few
of these gimmicks implemented in C.

--
Marc-Andre Lemburg
CEO eGenix.com Software GmbH
______________________________________________________________________
Company & Consulting: http://www.egenix.com/
Python Software: http://www.egenix.com/files/python/
Meet us at EuroPython 2002: http://www.europython.org/

0 new messages