"is" and ==

J

Jerry Hill

And that your
insisting on ``c[:]()`` instead of just ``c()`` seems to indicate you want
a change that is quite surprising. It would mean that a slice of a list
returns an other type with the __call__ method implemented.

I am not insisting on anything. I use ``c[:]()`` as shorthand way of saying
"c() for c in d where d is a container"

The problem people are having with that is that c[:]() *already* means
something in python, and it doesn't mean "c() for c in d where d is a
container". In today's python c[:]() means "return a slice of object
c, then call that slice". Since most container objects don't have a
__call__() method, it doesn't do what you want, but it is currently
valid syntax.
 
W

Warren Stringer

Thanks, Dakz for taking the time to reply:
This discussion has gone in more circles than Earth has gone 'round
the Sun, but it seems you should consider the following:

Yes, I've been feeling a bit dizzy
1) Sequences and functions serve fundamentally different purposes in
Python. One is for containing objects, the other is for executing an
action. (And yes, I'm aware that these concepts can differ in other
contexts. But we're talking about Python.)

I guess I've been arguing for fewer semantics, not more
2) It seems--at least to me--a bit dubious to change an entire general
purpose programming language to suit a very limited--and frankly
strange--use case.
Agreed.

3) You'd probably be better off making a very simple and concise
domain specific language.

Hence: http://muse.com/tr3/Tr3 Overview.pdf

I'm going to take Steve Holden's advice and hang out at c.l.py

Cheers,

\~/
 
G

Grant Edwards

And that your insisting on ``c[:]()`` instead of just ``c()``
seems to indicate you want a change that is quite surprising.
It would mean that a slice of a list returns an other type
with the __call__ method implemented.

I am not insisting on anything. I use ``c[:]()`` as shorthand
way of saying "c() for c in d where d is a container"

Once again, that's gibberish. Where does "d" come from? c[:]()
and c() _ARE_THE_SAME_THING_. c[:]() is another way of saying
c() PERIOD. "d" doesn't enter into it, and by no stretch of
the imagination is c[:]() "shorthand" for c() since it's
_twice_as_long_.
Having c() support containers seems obvious to me.

Again, that sentence appears to me to be meaningless. "c()"
doesn't "support" anything. "c()" is just syntax that says to
invoke the __call__ method of the object to which the name "c"
is bound.
It jibes with duck typing.

To what does "it" refer?
Perhaps the title of this thread should have been: "Why don't
containers quack?"

I'm not sure where you're getting your vocabularly, but it
seems to be completely foreign.
A change is surprising only if it breaks something. I still
haven't seen any code that breaks by making such a change.
Seeing such code would teach a great deal.

If I show you some, will that make you happy?
 
G

Grant Edwards

Yes, I've been feeling a bit dizzy

No comment.
I guess I've been arguing for fewer semantics, not more

What does that mean? The words you type are English, and the
grammar is OK, but the sentences don't seem to _mean_ anything.
Hence: http://muse.com/tr3/Tr3 Overview.pdf

I'm going to take Steve Holden's advice and hang out at c.l.py

Oh, for Pete's sake, you ARE in c.l.py. [You may be reading it
via an e-mail gateway, but reading it via an NNTP server isn't
going to make any difference.]
 
G

Gabriel Genellina

I am not insisting on anything. I use ``c[:]()`` as shorthand way of
saying
"c() for c in d where d is a container"

I begin to think you are some kind of Eliza experiment with Python
pseudo-knowledge injected.

Anyway, the code below defines a simple "callable" list; it just calls
each contained item in turn. Don't bother to use [:], it won't work.

py> class CallableList(list):
.... def __call__(self):
.... for item in self:
.... item()
....
py> def a(): print "a"
....
py> def b(): return 4
....
py> def c(): pass
....
py> def d():
.... global z
.... z = 1
....
py> z="A"
py> x = CallableList([a,b,c,d])
py> x()
a
py> z
1
 
G

Grant Edwards

I am not insisting on anything. I use ``c[:]()`` as shorthand
way of saying "c() for c in d where d is a container"

I begin to think you are some kind of Eliza experiment with
Python pseudo-knowledge injected.

I wish I'd said that.
Anyway, the code below defines a simple "callable" list; it
just calls each contained item in turn. Don't bother to use
[:], it won't work.

py> class CallableList(list):
... def __call__(self):
... for item in self:
... item()

Now all we need are user-definable
matched-pair-delimiter-constructors for anonymous user-classed
objects. ;)
 
W

Warren Stringer

Gabriel said:
I begin to think you are some kind of Eliza experiment with Python
pseudo-knowledge injected.

Tell me more about your feelings that I am an Eliza experiment with Python
with pseudo knowledge injected.

Thanks for the code example.
 
A

Andre Engels

2007/6/1 said:
I am not insisting on anything. I use ``c[:]()`` as shorthand way of saying
"c() for c in d where d is a container"

Having c() support containers seems obvious to me. It jibes with duck
typing. Perhaps the title of this thread should have been: "Why don't
containers quack?"

A change is surprising only if it breaks something. I still haven't seen any
code that breaks by making such a change. Seeing such code would teach a
great deal.

I think it very much bites duck typing. Currently, if I try to execute
a string or a list or whatever, I get:

TypeError: 'str' object is not callable

But under your proposed semantics, suppose a is a list with some
executable and some non-executable elements. What should

a()

now give? It cannot be a TypeError, because a list (in your semantics)
is callable. Whatever error it gives, and whether or not the preceding
executables are executed first, it will not be an existing error
acting the way it normally does - there is no Python error for "you
cannot do this with this object, but you can do it with other objects
of the same type". And that does not seem to be a case of "We have
never needed it yet" - the join method seems to have been specifically
tailored so that no such error is needed.
 
B

Bruce Coram

I am a relative newbie to Python and certainly to this mailing list. I
have watched this thread with interest. After the first few exchanges I
thought it would prove interesting and it has.

Warren Stringer is one of two things:

A joker having some fun at your expense.

An intellectually pretentious person who is so self absorbed that he is
mentally incapable of seeing the hollowness of his ideas.

Either way it's probably not worth spending any more time on him. All
that needs to be said has been. This thread is bare.

Exit

Bruce Coram
I am not insisting on anything. I use ``c[:]()`` as shorthand way of saying
"c() for c in d where d is a container"

Having c() support containers seems obvious to me. It jibes with duck
typing. Perhaps the title of this thread should have been: "Why don't
containers quack?"

A change is surprising only if it breaks something. I still haven't seen any
code that breaks by making such a change. Seeing such code would teach a
great deal.

I think it very much bites duck typing. Currently, if I try to execute
a string or a list or whatever, I get:

TypeError: 'str' object is not callable

But under your proposed semantics, suppose a is a list with some
executable and some non-executable elements. What should

a()

now give? It cannot be a TypeError, because a list (in your semantics)
is callable. Whatever error it gives, and whether or not the preceding
executables are executed first, it will not be an existing error
acting the way it normally does - there is no Python error for "you
cannot do this with this object, but you can do it with other objects
of the same type". And that does not seem to be a case of "We have
never needed it yet" - the join method seems to have been specifically
tailored so that no such error is needed.
 
W

Warren Stringer

Andre said:
I am not insisting on anything. I use ``c[:]()`` as shorthand way of saying
"c() for c in d where d is a container"

Having c() support containers seems obvious to me. It jibes with duck
typing. Perhaps the title of this thread should have been: "Why don't
containers quack?"

A change is surprising only if it breaks something. I still haven't seen any
code that breaks by making such a change. Seeing such code would teach a
great deal.

I think it very much bites duck typing. Currently, if I try to execute
a string or a list or whatever, I get:

TypeError: 'str' object is not callable

But under your proposed semantics, suppose a is a list with some
executable and some non-executable elements. What should

a()

now give? It cannot be a TypeError, because a list (in your semantics)
is callable. Whatever error it gives, and whether or not the preceding
executables are executed first, it will not be an existing error
acting the way it normally does ...

Since `a()` translates to `a() for a in b` then the error would be the exact
same `TypeError: 'str' object is not callable`
- there is no Python error for "you
cannot do this with this object, but you can do it with other objects
of the same type".

Yes there is:

#------------------------
def yo(): print "yo"
def no(): print blah
yo()
no()

Starting Python debug run ...
yo
Traceback (most recent call last):...
NameError: global name 'blah' is not defined
#------------------------

And that does not seem to be a case of "We have
never needed it yet" - the join method seems to have been specifically
tailored so that no such error is needed.

The join example is pretty cool - I want to study it a bit more - maybe I'm
missing your point?

There are two domain discussions, here:

1) is c[:]() is a good idea for python
2) is c[:]() a good idea in general

Where c[:]() symbolizes [c() for c in a]

In my opinion:

1a) might break something in Python 2.x -
1b) may or may not be a good idea for Python 3K

2a) is a great idea for a specific range of applications
2b) should attempt to coincide with existing idioms

Pragmatically speaking:

I'm not interested in 1a because it may break something. There may be an
edge case where catching a `TypeError: 'str' object is not callable` may
change the behavior of existing code.

I am somewhat interested in 1b but intend to lurk on the python.ideas and
python3k lists before entering a discussion. I tend to shy away from
proposing changes from ignorance. This is QUITE DIFFERENT from asking WHY
something works a certain way. Consider people who ask dumb questions, like
me, to be an opportunity to discover what isn't obvious.

I am intensely interested in 2a. Specifically visual music performances over
the web. I have spent 7 full years and my life's savings on developing a
platform. This particular application will involve millions of simultaneous
events that get passed around as objects. Two of those years have been spent
on developing a domain specific language that needs a very fast `c[:]()` --
which relates to 1b.

I am very interested in 2b. The two most inspiring languages to me are
Python and Occam (a now defunct language Transputers) Both use lexical
indentation. Although I am building a domain specific language I want make
it seamlessly integrate with Python. So that a 12-year-old may start by
patching performances, but ultimately, she may become inspired in writing
python script.

So, this thread has been of keen interest to me, mostly because of 2b. 1b is
of interest because extending Python with C has historically required
separate distributions between various versions of 2.x

So, Andre, you and others have a point, in regards to 1a. I find your post
particularly interesting, because it points out some history with join,
which helps me better understand how to approach 2b.

It wasn't my intent to ruffle feathers, but that in its own regard is
instructive, both in the topic, at hand, and in regard to the Python
community.

Meanwhile, I have written very little code, in the last couple days. It
means that I've taken everyone's suggestions very seriously, often leading
me to blogs and blogs of blogs. Looking back, there have been a couple of
helpful suggestions that I didn't respond to directly. So, for them, my
apologies and thanks!

For now, I am out of here!

Cheers,

\~/
 
W

Warren Stringer

Oops, forgot to cut and paste the point, to this:
Yes there is:

#------------------------
def yo(): print "yo"
def no(): print blah
yo()
no()

Starting Python debug run ...
yo
Traceback (most recent call last):...
NameError: global name 'blah' is not defined
#------------------------

The point is that if the object is ill formed, then you get a traceback
regardless.

But, as this is an addendum to the other post, please read that first.

Now, I really am out of here.
 
S

Steven D'Aprano

Since `a()` translates to `a() for a in b` then the error would be the exact
same `TypeError: 'str' object is not callable`

Not in any language called Python I know of.

Supposedly 28 years programming experience, and you can't even see the
_serious_ problems with "a()" --> "a() for a in b". Well, that explains a
lot about the lousy state of so many programming projects.

What's b? Given "a()", how does the compiler identify which b is the one
to look at? How does the recursive reference to a() terminate?

[snip]
For now, I am out of here!

Please don't come back until you have a clue.
 
S

Stebanoid

I want to call every object in a tupple, like so:

#------------------------------------------
def a: print 'a'
def b: print 'b'
c = (a,b)

TypeError: 'tupple' object is not callable
c[0]() # expected a
c[:][0] # huh? a
[i() for i in c] # too long and ...huh?

a
b
[None,None]
#------------------------------------------

bla-bla-bla......


you can write:
I think that it is good idea to use "map()" function for doing
somethimg with each element of a sequence, if the order of a actions
not important.

it is easy to read and understandable.

P.S. sorry my bad English
 
M

Marc 'BlackJack' Rintsch

In <[email protected]>,
I want to call every object in a tupple, like so:

#------------------------------------------
def a: print 'a'
def b: print 'b'
c = (a,b)
c[:]() # i wanna

TypeError: 'tupple' object is not callable
c[0]() # expected a
c[:][0] # huh? a
[i() for i in c] # too long and ...huh?

a
b
[None,None]
#------------------------------------------

bla-bla-bla......


you can write:
I think that it is good idea to use "map()" function for doing
somethimg with each element of a sequence, if the order of a actions
not important.

it is easy to read and understandable.

And has the same issue as a list comprehension if all you want is the side
effect of the calls: a useless temporary list full of `None`\s is build.

Ciao,
Marc 'BlackJack' Rintsch
 
S

Stebanoid

And has the same issue as a list comprehension if all you want is the side
effect of the calls: a useless temporary list full of `None`\s is build.

Ciao,
Marc 'BlackJack' Rintsch

functoins can return a values, and you get it. I don't think that it
is bad side effect.
When you write simpleyou have side effect too - returning "None".
 
M

Marc 'BlackJack' Rintsch

In <[email protected]>,
[using `map()`]
And has the same issue as a list comprehension if all you want is the side
effect of the calls: a useless temporary list full of `None`\s is build.

functoins can return a values, and you get it. I don't think that it
is bad side effect.

I don't either. By definition it's not a side effect at all. Side effects
are the "things that happen" besides the return values.

Warren Stringer wanted to call the functions just for the side effects
without interest in the return values. So building a list of return
values which is immediately thrown away is a waste of time and memory.
When you write simple
you have side effect too - returning "None".

No, the side effect is the printing of 'From Russia with love.'

IMHO there's a difference between this single `None` that can't be
prevented and abusing a list comprehension or `map()` just for side
effects and not for building a list with meaningful content.

Ciao,
Marc 'BlackJack' Rintsch
 
W

Warren Stringer

Anyway, the code below defines a simple "callable" list; it just calls
each contained item in turn. Don't bother to use [:], it won't work.

py> class CallableList(list):
... def __call__(self):
... for item in self:
... item()
...
py> def a(): print "a"
...
py> def b(): return 4
...
py> def c(): pass
...
py> def d():
... global z
... z = 1
...
py> z="A"
py> x = CallableList([a,b,c,d])
py> x()
a
py> z
1

I just ran this example. I think the class is simpler than Mikael's example:

class CallableList(list):
def __call__(self,*args,**kwargs):
return [f(*args,**kwargs) for f in self]

def a(): return 'a called'
def b(): return 'b called'
c = CallableList([a,b])()

Though Mikael's returns a list containing all the returns of each item,
which comes in handy for some use cases. So, your examples with Mikael's
CallableList, yields a list [None,4,None,None]

Mikael's shows how such a construct could simplify homogenous lists. Yours
shows how it might obfuscate heterogeneous lists.

Your example is less of an edge condition than ["string", func], as these
are all funcs. It best shows why supporting a general case of c[:]() might
lead to more obscure code.

My use case is very homogenous. I am porting a C++ parsed script that
contain 1000's of calls with no return value. So, I'll probably be using a
cross between your version and Mikael's.

There is another incentive for a callable list. Much of my script has deep
nested namespaces, like a.b.c.d(). In C++, deep nesting is cheap, but in
python, it is expensive because each dot is, in its own right, a function
call to __getattr__. Collecting all the calls into list preprocesses all of
the dots.

Thanks for the example
I begin to think you are some kind of Eliza experiment with Python
pseudo-knowledge injected.

BTW, my favorite Eliza implementation of all time is the one written by
Strout, Eppler, and Higgins ... in Python, of course.
 
T

Terry Reedy

|| Warren Stringer wanted to call the functions just for the side effects
| without interest in the return values. So building a list of return
| values which is immediately thrown away is a waste of time and memory.

Also unnecessary: for f in callables: f()

tjr
 
W

Warren Stringer

Marc 'BlackJack' Rintsch said:
|| Warren Stringer wanted to call the functions just for the side effects
| without interest in the return values. So building a list of return
| values which is immediately thrown away is a waste of time and memory.

Also unnecessary: for f in callables: f()

What do you mean?

This is very relevant to what I need to implement now. I am converting a
domain specific language script into python statements. For debugging the
script gets parsed and generates a .py file. The final bypasses the
intermediate step; instead it parses the script and does something like
this:

code = compile(_call,"ParseCall",'exec')
for coname in code.co_names:
... cleanup goes here
exec code in self._dict

I am already worried about speed. There are about 2000 macro statements that
look like this:

demo4: demo.stop()
ball.smooth()
video.live()
preset.video.straight()
view.front3d()
luma.real()
seq[:]lock(1)

In this example, the preprocessor translates the statements into a list of
10 callable objects. That last `seq[:]lock(1)` statement generates 4 objects
on its own. All of the __getattr__ resolution is done in the preprocessor
step. For the sort term version are no return values. For the long term
version, there may be return statements, but prefer simplest, for now.

It sounds like list comprehension may be slower because it builds a list
that never gets used. I'm curious if eval statements are faster than def
statements? Any bytecode experts?

Sorry if I got sidetracked on philosophical discussion, earlier. The above
example is lifted from a working c++ version with a tweaked syntax. This is
a real problem that I need to get working in a couple weeks.

As an aside, the code base will be open source.

Much appreciated,

\~/
 
E

Erik Max Francis

Warren said:
demo4: demo.stop()
ball.smooth()
video.live()
preset.video.straight()
view.front3d()
luma.real()
seq[:]lock(1)

You're way off in la-la land, now.
It sounds like list comprehension may be slower because it builds a list
that never gets used. I'm curious if eval statements are faster than def
statements? Any bytecode experts?

Are you serious? Something that builds a list that never gets used is
exactly what you were proposing this whole time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top