471,337 Members | 944 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,337 software developers and data experts.

Zope 3.0, and why I won't use it

Hello all,

So Zope still lives, yay. Well, I like that they use Python.

<rant>

What amazed me is they write that they "added types to the variables
and hope that it will be added to the Python project too". Really.
ROFL.

And instead of working on the engine they should have put more work
into examples. Simple tutorials. Downloadable executables for
Windows that you can click and install. But most of all simple and
good examples: webapplications like
- a wiki in zope
- a forum in zope, with agenda and calendar
- a game like http://216.199.69.100/war/ in zope

They have a nice free webhosting thing for zope, but to expect new
users to do everything from scratch...
The "examples" I found were very disappointing.

</rant>
Jul 18 '05 #1
47 2306
> Guido has repeatedly stated that a future version of Python will include static type support. The Zope project has driven numerous past changes to Python. What's funny about this?

It sounds very "unpythonic" :) A link or two to some site that
explains a little more what "static type support" means to Python
would be nice.

--
mvh Björn
Jul 18 '05 #2
Will Stuyvesant wrote:
And instead of working on the engine they should have put more work
into examples. Simple tutorials.


What has been released is not Zope 3
but Zope X3 where the X stands for eXperimental.

The way I understood it they want to showcase the
technology and system architecture. So don't knock
it for what is not meant to be.

Istvan.

ps. that being said I, after a few hours of fooling
around with it I found it to be more complicated
than ever ... and it was not clear what is it
that we gain from paying that price. We'll see how it
evolves.
Jul 18 '05 #3
Istvan Albert wrote:
Will Stuyvesant wrote:
And instead of working on the engine they should have put more work
into examples. Simple tutorials.

What has been released is not Zope 3
but Zope X3 where the X stands for eXperimental.

The way I understood it they want to showcase the
technology and system architecture. So don't knock
it for what is not meant to be.

Istvan.

ps. that being said I, after a few hours of fooling
around with it I found it to be more complicated
than ever ... and it was not clear what is it
that we gain from paying that price. We'll see how it
evolves.


You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination.

regards
Steve
--
http://www.holdenweb.com
http://pydish.holdenweb.com
Holden Web LLC +1 800 494 3119
Jul 18 '05 #4
Steve Holden wrote:
You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination.


I had no problems whatsoever ... on the other hand I
been using Zope 2.7 for a more than a year so
that might have helped me.

In Zope X3 they make a big deal out of interfaces,
everything seems to revolve around that.

http://dev.zope.org/Wikis/DevSite/Pr...nterfaces.html

then I looked at this,

http://dev.zope.org/Wikis/DevSite/Pr...Page/Zope3Book

totally overwhelming. But I have confidence in
the Zope developers. I have had good experience with Zope
in general, did not let me down yet ... in the way
a few years back for example Tomcat would crash
if one set a cookie value that had a newline character
in it.
Istvan.
Jul 18 '05 #5
Istvan Albert wrote:
Steve Holden wrote:
You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination.

I had no problems whatsoever ... on the other hand I
been using Zope 2.7 for a more than a year so
that might have helped me.

In Zope X3 they make a big deal out of interfaces,
everything seems to revolve around that.

http://dev.zope.org/Wikis/DevSite/Pr...nterfaces.html
then I looked at this,

http://dev.zope.org/Wikis/DevSite/Pr...Page/Zope3Book
totally overwhelming. But I have confidence in
the Zope developers. I have had good experience with Zope
in general, did not let me down yet ... in the way
a few years back for example Tomcat would crash
if one set a cookie value that had a newline character
in it.

Well indeed, the developers are a bunch of smart cookies (no pun
intended). But I still await a comprehensible description of how the
whole system works for 2.7, let alone X3 - how to put sites together,
and the best way to achieve various results, and so on.

Searching for information about Zope is a nightmare of broken links and
outdated content that makes it difficult to find one's way through to
the really useful stuff.

regards
Steve
--
http://www.holdenweb.com
http://pydish.holdenweb.com
Holden Web LLC +1 800 494 3119
Jul 18 '05 #6
Steve Holden wrote:
how to put sites together, and the best way to achieve
various results, and so on.
The entire Zope Book is available online:

http://www.zope.org/Documentation/Bo..._6Edition/view

I consider that as good of a startup documentation as it can
get. This covers 2.6 but as far as I could tell the only
major change that 2.7 introduced relates to the way
the zope sites are stored on the file system, they became
better separated (a much needed improvement BTW).
It is not an easy read though.
Searching for information about Zope is a nightmare of
broken links and outdated content


I did notice that too. In all fairness most of that content
is already in the Zope book and sometimes I wonder whether
it was the online availability of this latter was the
cause of it all.

Istvan.

PS. just noticed that they have a 2.7 edition of the Zope book
but it is being written:
http://www.plope.com/Books/2_7Edition
Jul 18 '05 #7
Will Stuyvesant wrote:
And instead of working on the engine they should have put more work
into examples. Simple tutorials. Downloadable executables for
Windows that you can click and install.
The gripe about Zope has allways been that it was too difficult for
developers.

The Zope developers had a pretty good idea as to why. So they developed
a new version of Zope that changed that. They have done a pretty fin job
too.

But most of all simple and
good examples: webapplications like
- a wiki in zope
- a forum in zope, with agenda and calendar
- a game like http://216.199.69.100/war/ in zope
You mean completely unlike:
http://svn.zope.org/book/trunk/messageboard/

They have a nice free webhosting thing for zope, but to expect new
users to do everything from scratch...
The "examples" I found were very disappointing.


Have you looked at Plone at all?

--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
Jul 18 '05 #8
Steve Holden wrote:
You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination.


Where you on Windows or Linux?

--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
Jul 18 '05 #9
- Will Stuyvesant :
Hello all,

So Zope still lives, yay. Well, I like that they use Python.

<rant>

What amazed me is they write that they "added types to the variables
and hope that it will be added to the Python project too". Really.
ROFL.
Sorry, probably I'm just tired (work to buy coffee <-> drink coffee to
work inifite loop, as usual :p), but I can't find where exactly they
made such a claim. I'm really interested in this because a friend of
mine (Volonghi) asked me exactly the same question... I think that
"someone - somewhere" misunderstood what interfaces are, but I'm not
sure. The only thing I'm sure is that I'm writing components for ZopeX3
in plain old good Python from milestone 3 :)
And instead of working on the engine they should have put more work
into examples. Simple tutorials.
What about the programmers tutorial (http://snipurl.com/amy9) and the
Developer Book (http://snipurl.com/amyb) ?
Downloadable executables for Windows that you can click and install.
Like the .exe here http://snipurl.com/amyd ? I'm not a Windows user,
sorry, can't really help here :)
But most of all simple and good examples: webapplications like
- a wiki in zope
http://snipurl.com/amyh
- a forum in zope, with agenda and calendar
Maybe the example of the developer book can help: Stephan explains the
main concepts of ZX3 by implementing a messageboard.
- a game like http://216.199.69.100/war/ in zope
Can't help here. BTW, I think that the zwiki, the bugtracker and all the
documentation is enought for now - I've seen too much ultrastable
software with a man page and an hello world called "documentation" to
complain the developers for that :)
They have a nice free webhosting thing for zope, but to expect new
users to do everything from scratch...
The "examples" I found were very disappointing.


Why ? ...

HAND,
ngw
Jul 18 '05 #10
Max M wrote:
Steve Holden wrote:
You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination.

Where you on Windows or Linux?

Windows.

regards
Steve
--
http://www.holdenweb.com
http://pydish.holdenweb.com
Holden Web LLC +1 800 494 3119
Jul 18 '05 #11
On Sun, 14 Nov 2004 19:41:13 -0500, Steve Holden <st***@holdenweb.com> wrote:
You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination. From time to time, I download Zope, try it a little bit, and uninstall

it. Perhaps I am too dumb for it (which may be the case) :-( ... but I
somehow feel that there is a problem, for I am not alone in this
feeling. For me, Zope lacks Python's inherent clarity; it seems that
it requires a 'mental mode' of its own. Many things are not obvious,
in the way they normally are when I am working with Python. This
places a lot of burden on the documentation, which - as said elsewhere
- is confusing. It's a shame.

(The best image that I can cast is of a rough gem. A good gem cutter
can see the finished gem through layers of dirty, and locate the
correct planes to cut. For others, even knowing that the gem is inside
there is not enough, for they can't see it until finished. For me Zope
looks like an still unfinished gem, and even if I know that there is a
beautiful gem inside, I can't just see it there.)

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #12
Carlos Ribeiro wrote:

feeling. For me, Zope lacks Python's inherent clarity; it seems that
it requires a 'mental mode' of its own. Many things are not obvious,
in the way they normally are when I am working with Python.


Web development in general is quite messy. Most of it
is spent on formatting the output and collecting
the parameters. There are no obvious choices and
there is no inherent clarity in the process.

Istvan.

Jul 18 '05 #13
Will Stuyvesant wrote:
So Zope still lives, yay. Well, I like that they use Python.

<rant>

What amazed me is they write that they "added types to the variables
and hope that it will be added to the Python project too". Really.
ROFL.
Admittedly this is not a very good description of what is done, but I
believe you lifted that out of an article on it on zdnet, so they can
hardly go into deep detail there.

What this actually talks about is the explicit interface notation. This
actually has a long long history in the Python world and the Zope
project has been involved in this discussion for as long as this
discussion exists. It goes back to Jim Fulton's straw man interface
proposal from, I think, 2000, and the discussions on the now-defunct
types-sig.

The interface system is also in use by Twisted. PyProtocols is another
large Python project that can make use of Zope 3 interfaces (and adds
ideas of its own).

So, while this may come across as arrogant from the Zope project, please
note the following:

* there's a long background on this of Python community discussion. It's
not something that the Zope project is suddenly dumping on you.

* it's unfair towards the Zope project and Zope corporation in
particular. They've funded a lot of core Python development over the years.
And instead of working on the engine they should have put more work
into examples.
Both need to be done. :)
Simple tutorials.
While I am sure they can be much improved, and the web presentation of
the Zope 3 project is not very ideal, I don't think the situation is as
dire as you suggest here. Witness the Zope 3 book:

http://dev.zope.org/Wikis/DevSite/Pr...Page/Zope3Book
Downloadable executables for
Windows that you can click and install.
Someone still has to sit down and do this, I think. They do exist in the
Zope 2 world, such as for Zope itself, Plone, and Silva.
But most of all simple and
good examples: webapplications like
- a wiki in zope
This exists, actually:

http://svn.zope.org/Zope3/trunk/src/zwiki
- a forum in zope, with agenda and calendar
- a game like http://216.199.69.100/war/ in zope

They have a nice free webhosting thing for zope, but to expect new
users to do everything from scratch...
The "examples" I found were very disappointing.


I'm not sure where you were looking. Concerning examples and tutorials,
Zope 3 is just in its beginning phase.

Regards,

Martijn
Jul 18 '05 #14
Steve Holden wrote:
[snip]
Well indeed, the developers are a bunch of smart cookies (no pun
intended). But I still await a comprehensible description of how the
whole system works for 2.7, let alone X3 - how to put sites together,
and the best way to achieve various results, and so on.


There's a lot of knowledge floating around in the Zope 2 community on
how to do it with Zope 2.x, but I don't know whether there's a book that
actually has it written all down, and the website is, as you mention, a
mess.

The Zope 3 website could use a lot of work as well; it's now rather
intimidating. I think however that a coherent story about Zope 3 is a
lot easier to write than a coherent story about Zope 2.x, with all its
years of evolution of code and changing insights. Zope 3 in a way *is* a
distillation of what Zope developers have learned from Zope 2.

I think one good community project would be a Zope 3 website project, to
make the Zope 3 web presence a lot more friendly. Zope 3 is actually
quite pythonic, and the new component architecture, while doubtless
intimidating at first, is very powerful while being a lot less likely to
shoot you in the foot than Zope 2's power is.

Zope 2 has the famous 'Z shaped learning curve'. It starts out really
eay, then it suddenly gets horribly complicated, you're confused for a
very long time, until after a long struggle you finally can do stuff
with it, while still swearing at unpythonic behavior.

Zope 3 has (we hope) a saner learning curve. Zope X3 in particular is
harder to start out with than Zope 2, as there's no friendly clicke-ty
click web interface. It takes a bit more programmer investment. It
should however a easier a lot faster than Zope 2, while remaining a lot
more Pythonic along the way.

I have personal experience with the Pythonic nature of Zope 3, as I'm
part of another project (Five) that managed to hack part of its
functionalities into Zope 2. That wouldn't have been possible if Zope 3
isn't a more accessible library of Python packages.

Regards,

Martijn
Jul 18 '05 #15
Carlos Ribeiro wrote:
On Sun, 14 Nov 2004 19:41:13 -0500, Steve Holden <st***@holdenweb.com> wrote:
You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination.

From time to time, I download Zope, try it a little bit, and uninstall
it. Perhaps I am too dumb for it (which may be the case) :-( ... but I
somehow feel that there is a problem, for I am not alone in this
feeling. For me, Zope lacks Python's inherent clarity; it seems that
it requires a 'mental mode' of its own. Many things are not obvious,
in the way they normally are when I am working with Python. This
places a lot of burden on the documentation, which - as said elsewhere
- is confusing. It's a shame.


I agree that this is the case (and I've been working with Zope for many
years). Zope 2 is many ways rather unpythonic. There's a lot of stuff
that could be a lot more clear and Pythonic.

On the other hand, Zope 2 suffers like any large framework does. While
they (hopefully) offer a lot of power, it is inevitable that parts of a
framework are not ideal, and it's also inevitable you have to invest
time on how to use it effectively. So in part I think this lack of
clarity is inherent to what it tries to be.

Zope 3 tries, and in most part succeeds, to be a lot more Pythonic than
Zope 2. That should help in part. Zope 3 is of course a large framework
as well -- it'll be inherently take time to get into it and use it
effectively. Nonetheless, Zope 3 also tries very hard through its
component architecture to be a framework that is a lot *easier* to
integrate with than Zope 2 ever was.

Regards,

Martijn
Jul 18 '05 #16
Carlos Ribeiro wrote:
On Sun, 14 Nov 2004 19:41:13 -0500, Steve Holden <st***@holdenweb.com> wrote:
You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination.

From time to time, I download Zope, try it a little bit, and uninstall
it. Perhaps I am too dumb for it (which may be the case) :-( ... but I
somehow feel that there is a problem, for I am not alone in this
feeling. For me, Zope lacks Python's inherent clarity; it seems that
it requires a 'mental mode' of its own. Many things are not obvious,
in the way they normally are when I am working with Python. This
places a lot of burden on the documentation, which - as said elsewhere
- is confusing. It's a shame.


I agree that this is the case (and I've been working with Zope for many
years). Zope 2 is many ways rather unpythonic. There's a lot of stuff
that could be a lot more clear and Pythonic.

On the other hand, Zope 2 suffers like any large framework does. While
they (hopefully) offer a lot of power, it is inevitable that parts of a
framework are not ideal, and it's also inevitable you have to invest
time on how to use it effectively. So in part I think this lack of
clarity is inherent to what it tries to be.

Zope 3 tries, and in most part succeeds, to be a lot more Pythonic than
Zope 2. That should help in part. Zope 3 is of course a large framework
as well -- it'll be inherently take time to get into it and use it
effectively. Nonetheless, Zope 3 also tries very hard through its
component architecture to be a framework that is a lot *easier* to
integrate with than Zope 2 ever was.

Regards,

Martijn
Jul 18 '05 #17
Nicholas Wieland wrote:
[snip]
Sorry, probably I'm just tired (work to buy coffee <-> drink coffee to
work inifite loop, as usual :p), but I can't find where exactly they
made such a claim. I'm really interested in this because a friend of
mine (Volonghi) asked me exactly the same question... I think that
"someone - somewhere" misunderstood what interfaces are, but I'm not
sure. The only thing I'm sure is that I'm writing components for ZopeX3
in plain old good Python from milestone 3 :)


This zdnet article made such a claim:

http://news.zdnet.co.uk/software/app...9173322,00.htm

I think it's just a case of a journalist trying to make comprehensible
with that Zope 3 interfaces do.

"""
Zope developers have also extended the Python programming language so
that variable types are specified, rather than being loosely typed, said
Richter. He hopes that these changes will eventually be given to the
Python project.
"""

That or Stephan Richter didn't explain it very well. :)

Interfaces are just annotations for classes and don't change the dynamic
typed nature of Python at all. Interfaces do allow for powerful
introspection (which the component architecture builds), and they also
function as API specification.

Regards,

Martijn
Jul 18 '05 #18
Steve Holden wrote:
Max M wrote:
Steve Holden wrote:
You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination.


Where you on Windows or Linux?

Windows.

I thought so :-)

I'm on Windows too, and Z3 the installer seems to be in a pretty sorrow
state there.

I think it is pretty simple to get it running. But stuff like scripts
being called "mkzopeinstane" instead of "mkzopeinstane.py" and there
being references to folders that don't exists in the Windows install, so
you need to guess which ones to use instead.

Minor things like that. But if you have no idea as to how the things
should be connected they get pretty major.

--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
Jul 18 '05 #19
[Max M]
Where you on Windows or Linux?

[Steve Holden] Windows.

[Max] I thought so :-)

I'm on Windows too, and Z3 the installer seems to be in a pretty sorrow
state there.
The Z3 Windows installer is exactly what you get if you:

1. Unpack the Linux Z3 tarball.
2. Run "install.py bdist_wininst" from its root, on a Windows box
with MSVC 6.0 installed.
3. Rename the installer that step generates to remove the blank
from its name.

IOW, it's a 100% vanilla distutils-based installer, by way of Zope's
zpkg, and should be equivalent to what gets created on Linux. If it's
not, that's a bug in distutils, or in zpkg, or in X3's zpkg config
files.
I think it is pretty simple to get it running. But stuff like scripts
being called "mkzopeinstane" instead of "mkzopeinstane.py"
That's a religious battle in distutils-land. At least half of
Linux-heads seem to think it's offensive to God to leave an extension
on an "executable" script, and since most contributors to open
software are Linux-heads, .py gets stripped on most such files.
There's no solution to this short of changing distutils to grow
platform-specific rules about retaining or stripping extensions.
and there being references to folders that don't exists in the Windows
install, so you need to guess which ones to use instead.


That's news to me. The entire X3 test suite (both unit and functional
tests) passes on Windows, when run from a Zope instance created from
what the installer installs, and that accesses virtually every part of
X3.

If you have more details about that, the zope3-dev list would be a
better place to reveal them.
Jul 18 '05 #20
Max M <ma**@mxm.dk> said :
You managed to get it to run? I found the whole load opaque beyond
belief, and removed it after an hour's examination.

Where you on Windows or Linux?

Windows.


I thought so :-)
I'm on Windows too, and Z3 the installer seems to be in a pretty sorrow
state there.
I think it is pretty simple to get it running. But stuff like scripts
being called "mkzopeinstane" instead of "mkzopeinstane.py" and there
being references to folders that don't exists in the Windows install, so
you need to guess which ones to use instead.


Thanks for the sanity check ! I though I was being really dumb there :-)
I've installed a few early Zope versions under Solaris and Linux some years
back, but had not used it since. When I saw X3 coming out with a Windows
installer, I though they'd made it really easy for once and wanted a quick
test run on my desktop. Ended up pretty nonplussed by all the stuff dumped
under site-packages and no really obvious way to launch the damn thing :)

--
YAFAP : http://www.multimania.com/fredp/
Jul 18 '05 #21
Tim Peters wrote:
and there being references to folders that don't exists in the Windows
install, so you need to guess which ones to use instead.


If you have more details about that, the zope3-dev list would be a
better place to reveal them.


Shure. I wasn't bitching. I just tried the Window installer yesterday
evening, so I haven't really had time to comment. But I crosspost this
to z3dev (via gmane), and vill continue the discussion there.

I tried to follow the instructions in the Zope3Book at:

http://dev.zope.org/Wikis/DevSite/Pr...tallzope3.html

Especially:

1.3.3 Creating a Zope Instance

It says:

"""
Creating a new instance is easy. Enter the Zope 3 directory and enter
the following command:

1 /bin/mkzopeinstance -u username:password -d path/to/instance
"""

First problem here is that there is no obvious "Zope 3" directory on the
windows installation.

Most of Z3 gets installed in site-packages, so I search that folder and
find a "mkzopeinstance.py" file in:

<PYTHON>\Lib\site-packages\zope\app\server

I run that, and nothing happens.

So I look on, and to my surprise i find a file called "mkzopeinstance" in:

<PYTHON>\Scripts

Which isn't exactly logical. It is in the root of my Python install, and
I didn't exactly remember that it wasn't there before ... I guess that
must be the Zope 3 folder on Windows ;-)

I look into it and check that it isn't a shell script, rename it to
"mkzopeinstance.py" and runs it. It creates an instance allright with
all the skeleton files.

Now I want to start the server and look into the <INSTANCE>/bin where
there is a "runzope" but no "runzope.bat". So I start to wonder if more
files are going to have missing extension, so that I will need to spend
the entire night appending ".py" to script in random order ;-)

So I gave up and went to bed, wanting to try again later when I had
better time.

So I guess I spend enough time to be confused, but not enough to make
constructive critiscism.
--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
Jul 18 '05 #22
[Max M]
Shure. I wasn't bitching. I just tried the Window installer yesterday
evening, so I haven't really had time to comment. But I crosspost this
to z3dev (via gmane), and vill continue the discussion there.

I tried to follow the instructions in the Zope3Book at:

....

Ya, I sure agree it's not obvious what to do on Windows! There have
been detailed Windows instructions since X3 alpha 1, but subsequent
release pages didn't point to them. I see Jim updated the 3.0.0-final
release page to include them now:

<http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/ZopeX3300>

Start from that next time, and it should go much easier.
Jul 18 '05 #23
ex*****@intarweb.us wrote:
On 14 Nov 2004 11:09:38 -0800, hw***@hotmail.com (Will Stuyvesant) wrote:
Hello all,
....What amazed me is they write that they "added types to the variables
and hope that it will be added to the Python project too".

We didn't say that. A reporter said that. As Martijn pointed out, this
was probably a missunderstanding of our work on interfaces.


Guido has repeatedly stated that a future version of Python will include static type support. The Zope project has driven numerous past changes to Python. What's funny about this?


For the record, I'm against static typing for Python, although,
if Guido decides he wants it, I have an open mind. :)

Jim
--
Jim Fulton mailto:ji*@zope.com Python Powered!
CTO (540) 361-1714 http://www.python.org
Zope Corporation http://www.zope.com http://www.zope.org

Jul 18 '05 #24
Jim Fulton <ji*@zope.com> wrote:
Guido has repeatedly stated that a future version of Python will
include static type support. The Zope project has driven numerous past
changes to Python. What's funny about this?
For the record, I'm against static typing for Python, although,
if Guido decides he wants it, I have an open mind. :)


Glad to hear that. As for me, I'd love it if function arguments, only,
could bear an 'as' clause (making 'as' a keyword is long overdue):

def x(y as foo, z as bar):
<body of x>

translating into:

def x(y, z):
y = adapt(y, foo)
z = adapt(z, bar):
<body of x>

where builtin 'adapt' does protocol adaptation. On the other hand, if
the semantics of those 'as' clauses were something like:

def x(y, z):
if type(y) is not foo: raise TypeError, 'y must be foo'
if type(z) is not bar: raise TypeError, 'z must be bar'
<body of x>

then that's the day I move to Ruby, or any other language that remained
halfway sensible (if any).

In other words, if the 'as' clause (or whatever absurd syntax ends up
being adopted in its place -- judging on recent performance, probably a
two-arguments version of splat, or a nice << to complement the just as
nice 'print>>bah,humbug' syntax -- good thing I don't really care about
syntax sugar;-) ends up being a way to ease *type-checking*, then, well,
I'll evaluate that as being on a par with easing alcohol abuse. What
the syntax supports, people will do more of, and we already know that
type-checking, like alcohol abuse, is a _very_ popular although
self-destructive practice.

Protocol adaptation is the polar opposite from type checking. I'd see
syntax that supports adaptation as being on a par with easing things
that are good for you, as well as pleasant, and yet are not widely
practiced -- yoga, aerobics, many other forms of exercise, healthy
nutrition -- the language gently encouraging you to do the right thing.
Alex
Jul 18 '05 #25
(Someone):
Guido has repeatedly stated that a future version of Python will
include static type support. The Zope project has driven numerous past
changes to Python. What's funny about this?


What is sad to me is that the reporter seems to have gotten it backwards.
To me, the point of interfaces and adapters is to support and extend the
notion of generic programming, not undermine it. After reading the
Programmers' Introduction referenced in a previous post, Zope 3 seems to
have made contributions in this regard that may well trickle into standard
Python.

Terry J. Reedy

Jul 18 '05 #26

al*****@yahoo.com (Alex Martelli) wrote:

Jim Fulton <ji*@zope.com> wrote:
Guido has repeatedly stated that a future version of Python will

include static type support. The Zope project has driven numerous past
changes to Python. What's funny about this?

For the record, I'm against static typing for Python, although,
if Guido decides he wants it, I have an open mind. :)


Glad to hear that. As for me, I'd love it if function arguments, only,
could bear an 'as' clause (making 'as' a keyword is long overdue):

def x(y as foo, z as bar):
<body of x>

translating into:

def x(y, z):
y = adapt(y, foo)
z = adapt(z, bar):
<body of x>

where builtin 'adapt' does protocol adaptation. On the other hand, if
the semantics of those 'as' clauses were something like:

def x(y, z):
if type(y) is not foo: raise TypeError, 'y must be foo'
if type(z) is not bar: raise TypeError, 'z must be bar'
<body of x>

then that's the day I move to Ruby, or any other language that remained
halfway sensible (if any).

In other words, if the 'as' clause (or whatever absurd syntax ends up
being adopted in its place -- judging on recent performance, probably a
two-arguments version of splat, or a nice << to complement the just as
nice 'print>>bah,humbug' syntax -- good thing I don't really care about
syntax sugar;-) ends up being a way to ease *type-checking*, then, well,
I'll evaluate that as being on a par with easing alcohol abuse. What
the syntax supports, people will do more of, and we already know that
type-checking, like alcohol abuse, is a _very_ popular although
self-destructive practice.

Protocol adaptation is the polar opposite from type checking. I'd see
syntax that supports adaptation as being on a par with easing things
that are good for you, as well as pleasant, and yet are not widely
practiced -- yoga, aerobics, many other forms of exercise, healthy
nutrition -- the language gently encouraging you to do the right thing.


Decorators to the rescue?

def d_adapt(t):
def f(a):
return adapt(a, t)
return f

def d_adaptors(*adaptors):
#some work necessary to make kwargs work
def f(fcn):
def f(*args):
return fcn(*[i(j) for i,j in zip(adaptors, args)])
return f
return f

@d_adaptors(d_adapt(foo), d_adapt(bar))
def x(y, z):
<body of x>
- Josiah

Jul 18 '05 #27
On Mon, 15 Nov 2004 17:50:12 -0800, Josiah Carlson <jc******@uci.edu>
wrote:
@d_adaptors(d_adapt(foo), d_adapt(bar))
def x(y, z):
<body of x>


First listing type coercions and then listing the variables
on which they're applied ? IMO this is worse than pre-ansi C.

I'd prefer explicit calls at the begin of the body rather
than that... it would be way more readable.

Andrea
Jul 18 '05 #28
Josiah Carlson <jc******@uci.edu> wrote:
def d_adapt(t):
def f(a):
return adapt(a, t)
return f

def d_adaptors(*adaptors):
#some work necessary to make kwargs work
def f(fcn):
def f(*args):
return fcn(*[i(j) for i,j in zip(adaptors, args)])
return f
return f

@d_adaptors(d_adapt(foo), d_adapt(bar))
def x(y, z):
<body of x>


Can do with less work:

def d_adap(*types):
def f(fcn):
def f(*args):
return fcn(*(adapt(i, j)
for i, j in izip(types, args)))
f.__name__ = fcn.__name__
return f
return f

@ d_adap(foo, bar)
def x(y, z):
<body of x>

but the point is whether, if and when 'optional static typing' _syntax_
gets it, it will have this semantics or that of inserting a lot of
typechecks... people can do typecheks or adaptation now, and neither
will go away -- but which, if either, should syntax facilitate? That,
as I see it, is key.
Alex
Jul 18 '05 #29

Andrea Griffini <ag****@tin.it> wrote:

On Mon, 15 Nov 2004 17:50:12 -0800, Josiah Carlson <jc******@uci.edu>
wrote:
@d_adaptors(d_adapt(foo), d_adapt(bar))
def x(y, z):
<body of x>
First listing type coercions and then listing the variables
on which they're applied ? IMO this is worse than pre-ansi C.


Since I didn't learn C (1999) until after the ANSI standard, if you
would care to explain that'd be great. Is it perhaps something like (I
can't remember the syntax I've seen, as I've only seen it a few times)...

int main(argc, argv)
(int argc, char[] argv)
{ /*body/* }

I'd prefer explicit calls at the begin of the body rather
than that... it would be way more readable.


So the trick is to ask yourself what is available now. Decorators are
available now (or in a month or two when 2.4 comes out), and are about
as close to what you want as is going to happen before Py3k, and even
then, it may have syntax you don't want.

Me, I'll just stick my type checking and coercions (if either are
necessary) in the function body where I always have.

- Josiah

Jul 18 '05 #30

al*****@yahoo.com (Alex Martelli) wrote:

[snip your better implementation]
but the point is whether, if and when 'optional static typing' _syntax_
gets it, it will have this semantics or that of inserting a lot of
typechecks... people can do typecheks or adaptation now, and neither
will go away -- but which, if either, should syntax facilitate? That,
as I see it, is key.


I guess it all depends.
"In the face of ambiguity, refuse the temptation to guess."
"Explicit is better than implicit."

With the requisite zens quoted, I'd say that there should be an explicit
way to do both, because guessing which one (but not both) is necessarily
the wrong thing to do.

With that said, type-based dispatch, checking and adaptation are
provided by decorators, which are explicit. They are not a syntax
per-se, but they will get the job done in the mean time (if placing type
checking and adaptations in the function body is not sufficient).

- Josiah

Jul 18 '05 #31
>>>>> "Alex" == Alex Martelli <al*****@yahoo.com> writes:

Alex> where builtin 'adapt' does protocol adaptation. On the
Alex> other hand, if the semantics of those 'as' clauses were
Alex> something like:

Alex> def x(y, z):
Alex> if type(y) is not foo: raise TypeError, 'y must be foo'
Alex> if type(z) is not bar: raise TypeError, 'z must be bar'
Alex> <body of x>

Alex> then that's the day I move to Ruby, or any other language
Alex> that remained halfway sensible (if any).

Even if it allowed portions of the code to be statically compiled to
reach "native" performance? Or if it allowed resolving ambiguous
situations in type inference? Type declarations would of course be
optional, and they could be a big win esp. for non-cpython
implementations of the language. Beats reverting to C#/whatever for
situations where you want good JITtability. In CPython "adaptation"
might be the way to go, of course, but that would still enable the
same code to run on different variants of Python.

Alex> syntax sugar;-) ends up being a way to ease *type-checking*,
Alex> then, well, I'll evaluate that as being on a par with easing
Alex> alcohol abuse. What

I don't think people have been too keen to get static type checking
into the language anyway. It might be an option in pychecker, but that
should be enough. Dynamic type checking, well, that's an obvious net
loss over adaptation.

--
Ville Vainio http://tinyurl.com/2prnb
Jul 18 '05 #32
Josiah Carlson <jc******@uci.edu> wrote:
but the point is whether, if and when 'optional static typing' _syntax_
gets it, it will have this semantics or that of inserting a lot of
typechecks... people can do typecheks or adaptation now, and neither
will go away -- but which, if either, should syntax facilitate? That,
as I see it, is key.
I guess it all depends.
"In the face of ambiguity, refuse the temptation to guess."
"Explicit is better than implicit."

With the requisite zens quoted, I'd say that there should be an explicit
way to do both, because guessing which one (but not both) is necessarily
the wrong thing to do.


Since the actual need for type-checking is extremely rare, I contend it
should not _at all_ be a candidate for a syntax to facilitate it. Since
the actual need for adaptation is much wider, I contend it's the one
obvious choice for the "nice syntax" if any.
With that said, type-based dispatch, checking and adaptation are
provided by decorators, which are explicit. They are not a syntax
per-se, but they will get the job done in the mean time (if placing type
checking and adaptations in the function body is not sufficient).


Type checking is ugly, so it's quite fitting that it be implemented in
ugly ways -- by boilerplate or user-coded splats. Adaptation is
beautiful, and beautiful is better than ugly (see, I can quote the zen
of Python too...), so it should have nice syntax (<var> 'as' <itf>).

Type-based dispatch is a little bit of a mess to implement with
decorators, IMHO. Consider the hypothetical code...:

class A(object):
@ dispatch(int)
def foo(x): ...

@ dispatch(float)
def foo(x): ...

class B(object):
@ dispatch(int)
def foo(x): ...

@ dispatch(str)
def foo(x): ...

Sure, dispatch can be a H**2OF which returns a dispatching-foo and
stashes somewhere a (say) foo__int, foo__float or whatever, but the
problem is, _WHAT_ 'somewhere'. dispatch isn't told what class body
it's being called from, so it can't easily stash stuff in the obvious
place, the class dictionary being built. Attributes of the
dispatching-foo don't seem good, because of the problem of getting at
the right previously-returned dispatching-foo object on successive calls
of dispatch from within the same class body (but not from separate class
bodies). Maybe some peek-into-the-stack black magic or custom
metaclass can help, but it does seem a little bit of a mess, unless I'm
overlooking something obvious. If the implementation is hard to
explain, it's a bad idea...
Alex
Jul 18 '05 #33
Ville Vainio <vi***@spammers.com> wrote:
>> "Alex" == Alex Martelli <al*****@yahoo.com> writes:

Alex> where builtin 'adapt' does protocol adaptation. On the
Alex> other hand, if the semantics of those 'as' clauses were
Alex> something like:

Alex> def x(y, z):
Alex> if type(y) is not foo: raise TypeError, 'y must be foo'
Alex> if type(z) is not bar: raise TypeError, 'z must be bar'
Alex> <body of x>

Alex> then that's the day I move to Ruby, or any other language
Alex> that remained halfway sensible (if any).

Even if it allowed portions of the code to be statically compiled to
reach "native" performance? Or if it allowed resolving ambiguous
situations in type inference? Type declarations would of course be
optional, and they could be a big win esp. for non-cpython


My prediction is that, once 'of course optional' type declaration gets
in, it will become the mandated approach in most new-to-Python shops, by
fallacious analogy with (say) VB and Perl's "optional" type declaration,
and by dint of managers' general liking for putting silly unjustified
restriction on professionals to hamper their productivity. That is
going to be a huge cost. What will it buy in exchange?

If typenames in a type declaration context can be statically resolved at
compile-time, then so can just about every other use of names, right?
After all, if the compiler can statically resolve what object 'foo' is
bound to in a clause 'x as bar.foo', it means it must somehow have
inferred that some 'class foo' statement will inevitably get executed
before then in module bar, or whatever other attribute assignment
produces that binding of name 'foo' within name 'bar'.

And of course the 'foo' type will generally be built up in another
module, so we're talking about a compiler that examines other modules in
order to be able to compile this one. Whole-program compilation with
compile-time inferred name-object bindings would be such a huge and
total revolution wrt today's Python that very little would stay the
same. OK, then, if that's the revolution that's in Python's future,
let's see it come _first_ -- there would be huge wins without requiring
any source code changes _IF_ name-to-object resolution could be
uniformly done at compile-time rather than at runtime, even across
modules. Though I've never seen any example of whole-program
compilation and optimization done right, in practice (with compile time
NOT growing faster than O(N) and soon becoming untenable for large
programs), I do know that _in theory_ it's feasible -- I'd just be
astonished if it was shown that Python, never having been designed for
it, "just happens" to be the right language to have it finally occur.

implementations of the language. Beats reverting to C#/whatever for
situations where you want good JITtability. In CPython "adaptation"
might be the way to go, of course, but that would still enable the
same code to run on different variants of Python.
If adaptation was a dialect-specific thing, it would hamper the ability
to move large frameworks and applications across dialects.

I don't see "falling back" to a lower-level language where you need one
as a disaster. Doesn't have to be _AS_ low-level as C# or Java or C, of
course; I think pyrex does a great job of showing how a restricted
Python dialect/variant which, among other things, includes optional
declarations, can make your life much easier. I don't see why there
couldn't be pyrex# or Jirex versions, or even languages inspired from
Python but farther from it than Pyrex is, such as Bobo.

Alex> syntax sugar;-) ends up being a way to ease *type-checking*,
Alex> then, well, I'll evaluate that as being on a par with easing
Alex> alcohol abuse. What

I don't think people have been too keen to get static type checking
into the language anyway. It might be an option in pychecker, but that
should be enough. Dynamic type checking, well, that's an obvious net
loss over adaptation.


I agree pychecker or the like might well have options to check on
everything under the sun -- no problem. For reasons that escape me,
shop rules such as "all programs will pass lint with this and that
option" seem to never stick. Shop rules such as "-Wall -pedantic on all
compilations and NEVER any commit of code with warnings" (a good idea,
actually) or "all VB programs must have option explicit" (maybe better
than nothing, given VB's typing mess, if you have to do VB) or "all perl
runs will always have -w" (probably a good idea), etc, etc, _are_
observed, in practice, to stick. And there are good rules for Python,
too, of course, ones that promote productivity, from 'we do not ever use
"exec"' to similar edicts against 'from x import *'. As long as control
freaks don't get an effective way to destroy Python's greatest strength,
namely signature-based polymorphism, I'm happy...
Alex
Jul 18 '05 #34
Tim Peters <ti********@gmail.com> said :
Ya, I sure agree it's not obvious what to do on Windows! There have
been detailed Windows instructions since X3 alpha 1, but subsequent
release pages didn't point to them. I see Jim updated the 3.0.0-final
release page to include them now:

<http://dev.zope.org/Wikis/DevSite/Pr...tecture/ZopeX3
<300>


Huh, thanks for that pointer ! Sure makes a lot more sense that way, and a
lot less to guess at, even for a developer release :)

If only the lower part of that page had figured in a prominent
WINDOWS_INSTALL_README.TXT or some such in the Windows installer, there'd
been much less bitchin' here :-)

--
YAFAP : http://www.multimania.com/fredp/
Jul 18 '05 #35
alex,

you've mentioned several times the concept of adapting parameters to a method. but i'm not able to understand your few
examples. can you go more into depth (and with simpler examples) on this topic?

thanks,

bryan
Jul 18 '05 #36
Bryan wrote:
alex,

you've mentioned several times the concept of adapting parameters to a
method. but i'm not able to understand your few examples. can you go
more into depth (and with simpler examples) on this topic?

thanks,

bryan


Bryan,

Thanks for asking this. You aren't alone in wanting to know more.

Jeremy
Jul 18 '05 #37
>>>>> "Alex" == Alex Martelli <al*****@yahoo.com> writes:
situations in type inference? Type declarations would of course be
optional, and they could be a big win esp. for non-cpython


Alex> My prediction is that, once 'of course optional' type
Alex> declaration gets in, it will become the mandated approach in
Alex> most new-to-Python shops, by

I don't think this has happened with Lisp either, so it doesn't
necessarily happen with Python. Python has a strong culture of dynamic
typing, it wouldn't disappear overnight. It's a matter of education,
mostly.

Alex> And of course the 'foo' type will generally be built up in
Alex> another module, so we're talking about a compiler that
Alex> examines other modules in order to be able to compile this
Alex> one. Whole-program compilation with compile-time inferred
Alex> name-object bindings would be such a huge and total
Alex> revolution wrt today's Python that very little would stay
Alex> the same. OK, then, if that's the revolution that's in
Alex> Python's future, let's see it come _first_ -- there would be
Alex> huge wins without requiring any source code changes _IF_
Alex> name-to-object resolution could be uniformly done at
Alex> compile-time rather than at runtime, even across modules.

Ok, let's :-).

I figure the concept of "frozen" modules would need to be introduced:

python -f a.py b.py c.py

=> a.pyf b.pyf c.pyf

It would now be impossible to introduce new names in the module global
area. All the classes introduced in the module would be immutable,
i.e. no rebinding of methods. Attributes would work through
__slots__. Imports would need to only address other frozen modules
(which would apply to most of the standard library at some point :-).

Granted, it's not the laissez-faire Python we all know and love, but
many problems could be solved by using that kind of programming style
alone. Several more "sophisticated" frameworks could be able to use a
lean, "frozen" subset of classes and functions.

Alex> I don't see "falling back" to a lower-level language where
Alex> you need one as a disaster. Doesn't have to be _AS_
Alex> low-level as C# or Java or C, of course; I think pyrex does
Alex> a great job of showing how a restricted Python
Alex> dialect/variant which, among other things, includes optional
Alex> declarations, can make your life much easier. I don't see

I admit that the concept of frozen modules is somewhere b/w an
additional lower level language and an extension to Python as an
idea.

Alex> couldn't be pyrex# or Jirex versions, or even languages
Alex> inspired from Python but farther from it than Pyrex is, such
Alex> as Bobo.

I assume you mean Boo here.

--
Ville Vainio http://tinyurl.com/2prnb
Jul 18 '05 #38
[Tim Peters]
Ya, I sure agree it's not obvious what to do on Windows! There have
been detailed Windows instructions since X3 alpha 1, but subsequent
release pages didn't point to them. I see Jim updated the 3.0.0-final
release page to include them now:
<http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/ZopeX3300>

[Fred Pacquier] Huh, thanks for that pointer ! Sure makes a lot more sense that way, and a
lot less to guess at, even for a developer release :)
Yup -- it's essential.
If only the lower part of that page had figured in a prominent
WINDOWS_INSTALL_README.TXT or some such in the Windows
installer, there'd been much less bitchin' here :-)


Ah, but where would you put this file? In a *tarball* distribution,
it's easy: you stick README_FILES_WITH_SCREAMING_NAMES in the root of
the distribution, and then they're easy to find.

But this is a Windows *installer*, and every file it installs is
"hiding" under some subdirectory of your pre-existing Windows Python
installation. Where could the X3 Windows installer put
WINDOWS_INSTALL_README.TXT where a new user is likely to find it?

I don't believe such a place exists. It would be anti-social to
clutter the root of the Python installation with package README files,
and I doubt most users would think to look there anyway. And that's
the "most obvious" place I can dream up.

Doing something other than that (for example, maybe popping up a
README file in Notepad at the end of installation) would require
changes to distutils, since X3's Windows installer is built by
distutils. The point of that isn't that changing distutils makes it
impossible, the point is that since distutils *today* doesn't have
such abilities, no distutils-built installer built today (whether X3's
or any other Python project's) can do such things.
Jul 18 '05 #39
On Tue, 16 Nov 2004 10:03:42 -0500, Jeremy Jones <za******@bellsouth.net> wrote:
Bryan wrote:
alex,

you've mentioned several times the concept of adapting parameters to a
method. but i'm not able to understand your few examples. can you go
more into depth (and with simpler examples) on this topic?

thanks,

bryan


Bryan,

Thanks for asking this. You aren't alone in wanting to know more.

Jeremy


Well, my name is not Alex, and my answer will probably fall short of a
comprehensive definition :-) But let's see if I can help here...

Adaptation is the act of taking one object and making it conform to a
given protocol (or interface). Adaptation is the key to make dynamic
code that takes parameters from arbitrary types work in a safe, well
behaved way.

The basic concept underlying adaptation is the "protocol", also called
"interface" in some implementations. For all purposes of this
discussion, and for simplicity reasons, we can safely assume that
protocols and interfaces are equivalent.

A protocol is a set of primitives that is supported by a given object.
For example: the iterator protocol defines the following primitives:
__iter__ and next() (as documented in
http://docs.python.org/lib/typeiter.html). Any object from any class
that implement these methods, regardless of its ancestors, is said to
support the iterator protocol.

Any object that supports the iterator protocol can be used whenever an
iterable is acceptable. This includes for loops and list
comprehensions. The biggest advantage of adaptation comes when one
realize how flexible this design is, specially when compared with
old-style type checking. In a old-style type checking environment,
parameters to a given routine must conform to the declared type of the
arguments. For iterators, it would mean that only objects descending
from some abstract class (let's say, "Iterable") would be accepted.
Now, even with multiple inheritance, this design is severely limited.

Now, back to Python world. In many situations, there is no need for
adaptation; the object itself supports the protocol, and can be
supplied directly. But there are situations when the object itself
can't be immediately used; it has to be adapted, or prepared, to
support the protocol. Another situation is when an object is passed to
a routine that *doesn't* support the required protocol; this is an
error, that can be catched by the adapt() framework in a superficially
similar but fundamentally different approach from type checking (and
that's whats Alex has been pointing out).

The adapt protocol (as presented on PEP246 -
http://www.python.org/peps/pep-0246.html) defines a very flexible
framework to adapt one object to a protocol. The result of the
adaptation (if possible) is an object that is guaranteed to support
the protocol. So, using adapt(), we can write code like this:

def myfunc(obj):
for item in adapt(obj, Iterable):
...

Finally, one may be wondering, is there any situation when an object
needs to be "adapted"? Why don't just check for the availability of
the interface? There are many reasons to use the adapt framework. The
protocol checking is one of the reasons -- it allows errors to be
catched much earlier, and at a better location. Another possible
reason is that complex objects may support several protocols, and
there may be name clashes between some of the methods. One such
situation is when an object support different *versions* of the same
protocol. All versions have the same method names, but semantics may
differ slightly. The adapt() call can build a new object with the
correct method names and signatures, for each protocol or version
supported by the object. Finally, the adaptation method can optionally
build an opaque "proxy" object, that hides details of the original
methods signature, and it's thus safer to pass around.

Well, that's a broad overview of the subject. There is a lot of stuff
to learn, and using adaptation properly is something that takes some
time. Hope it helps.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #40
Tim Peters <ti********@gmail.com> writes:
Doing something other than that (for example, maybe popping up a
README file in Notepad at the end of installation) would require
changes to distutils, since X3's Windows installer is built by
distutils. The point of that isn't that changing distutils makes it
impossible, the point is that since distutils *today* doesn't have
such abilities, no distutils-built installer built today (whether X3's
or any other Python project's) can do such things.


Recent distutils' bdist_wininst command has a post_install_script (or
something like that), which is run *after* the installation. It can do
anything that Python does, so os.startfile("readme.txt") or
os.startfile("readme.html") would be possible.

I do not know which Python version zope uses, and I'm not sure the
post_install_script stuff has been ported to 2.3. OTOH, there are
several ways to use 2.4's distutils with earlier Python releases.

(Although I'll doubt it would help at all - experience shows that nearly
nobody reads this stuff)

Thomas
Jul 18 '05 #41
Ville Vainio wrote:
>>"Alex" == Alex Martelli <al*****@yahoo.com> writes:

Alex> where builtin 'adapt' does protocol adaptation. On the
Alex> other hand, if the semantics of those 'as' clauses were
Alex> something like:

Alex> def x(y, z):
Alex> if type(y) is not foo: raise TypeError, 'y must be foo'
Alex> if type(z) is not bar: raise TypeError, 'z must be bar'
Alex> <body of x>

Alex> then that's the day I move to Ruby, or any other language
Alex> that remained halfway sensible (if any).

Even if it allowed portions of the code to be statically compiled to
reach "native" performance? Or if it allowed resolving ambiguous
situations in type inference? Type declarations would of course be
optional, and they could be a big win esp. for non-cpython
implementations of the language. Beats reverting to C#/whatever for
situations where you want good JITtability. In CPython "adaptation"
might be the way to go, of course, but that would still enable the
same code to run on different variants of Python.


I would think of it differently. I don't see a need for static typing
to deal with the outside world. There's always a bridge when
communicating with the outside world, and if that bridge is smart enough
it should be okay. You can annotate things (I think type annotation for
PyObjC was one of the motivations behind the decorator syntax), that's
different from static typing, and is just a guide for coercion.

And obviously foreign functions cannot take arbitrary arguments.
Nothing in Python can, there's always limits; though foreign functions
may not accept immitation objects (e.g., list subclasses), and that's
just part of the API. That's why people tend to create wrappers around
non-Python libraries.

I can see some performance advantages to static typing. I don't think
it would be worth it for any external interface, but for internal
interfaces it might be worth it, where there's less of a concern about
flexibility. In that case, decorators might be all that's necessary, e.g.:

@constrain_types(a=float, b=str, c=int:
def foo(a, b):
c = 1
...

Imagining an implementation of constrain_types that knew how to pick
apart a function's code, apply the type information and optimizations,
and put it back together. It really doesn't need pretty syntax, because
it's not a pretty operation (though the decorator syntax is actually
reasonably attractive). It would be nice if this applied both to
arguments and local variables.

Now, I could imagine this turning into a Cargo Cult programming
practice, where people mindlessly apply this type information despite
there being no reason or performance gain, thus adding weight to their
code and reducing flexibility. But then, I'd rather work under the
expectation that the programmer will do the right thing.

--
Ian Bicking / ia**@colorstudy.com / http://blog.ianbicking.org
Jul 18 '05 #42

al*****@yahoo.com (Alex Martelli) wrote:

Josiah Carlson <jc******@uci.edu> wrote:
but the point is whether, if and when 'optional static typing' _syntax_
gets it, it will have this semantics or that of inserting a lot of
typechecks... people can do typecheks or adaptation now, and neither
will go away -- but which, if either, should syntax facilitate? That,
as I see it, is key.
I guess it all depends.
"In the face of ambiguity, refuse the temptation to guess."
"Explicit is better than implicit."

With the requisite zens quoted, I'd say that there should be an explicit
way to do both, because guessing which one (but not both) is necessarily
the wrong thing to do.


Since the actual need for type-checking is extremely rare, I contend it
should not _at all_ be a candidate for a syntax to facilitate it. Since
the actual need for adaptation is much wider, I contend it's the one
obvious choice for the "nice syntax" if any.


Sounds reasonable, but there will be a group of people who will beg and
plead for type checking, because they want "static type checking on
function call and return".

With that said, type-based dispatch, checking and adaptation are
provided by decorators, which are explicit. They are not a syntax
per-se, but they will get the job done in the mean time (if placing type
checking and adaptations in the function body is not sufficient).


Type checking is ugly, so it's quite fitting that it be implemented in
ugly ways -- by boilerplate or user-coded splats. Adaptation is
beautiful, and beautiful is better than ugly (see, I can quote the zen
of Python too...), so it should have nice syntax (<var> 'as' <itf>).


Adaptation is quite nifty, but being that I am a rare user of either, it
probably isn't worth the effort to attempt to convince me that
adaptation is the one true way, especially considering that I've got
little to no pull in python-dev.

Type-based dispatch is a little bit of a mess to implement with
decorators, IMHO. Consider the hypothetical code...:

class A(object):
@ dispatch(int)
def foo(x): ...

@ dispatch(float)
def foo(x): ...

class B(object):
@ dispatch(int)
def foo(x): ...

@ dispatch(str)
def foo(x): ...

Sure, dispatch can be a H**2OF which returns a dispatching-foo and
stashes somewhere a (say) foo__int, foo__float or whatever, but the
problem is, _WHAT_ 'somewhere'. dispatch isn't told what class body
it's being called from, so it can't easily stash stuff in the obvious
place, the class dictionary being built. Attributes of the
dispatching-foo don't seem good, because of the problem of getting at
the right previously-returned dispatching-foo object on successive calls
of dispatch from within the same class body (but not from separate class
bodies). Maybe some peek-into-the-stack black magic or custom
metaclass can help, but it does seem a little bit of a mess, unless I'm
overlooking something obvious. If the implementation is hard to
explain, it's a bad idea...


It can be a mess, which is one reason why I haven't been using it, and
generally don't use it. But you know those C/C++ guys who are all like
"hey, where's my polymorphism?"

I agree that it would be best of one could place everything into the
class dict without frame hacks, but for simplicity in implementation's
sake, I would stick with a dispatch-factory and jam all of the requisite
dispatch information into the closure (or instance) that is generated.
Sure, you need to say 'hey, I'm going to do type-based dispatch here'
at the beginning of your desired non-overlapping namespaces, but it is
explicit what one would want in such a case. Heck, with a properly
defined metaclass or class decorator, a post-decoration pass could be
done to extract all of the dispatches and place them into foo__int, etc.

@ multi_dispatch_to_methods
class A(object):
dispatch = dispatch_factory()

@ dispatch(int)
def foo(x): ...

@ dispatch(float)
def foo(x): ...
It may have a couple warts, but it is implementable today.

- Josiah

Jul 18 '05 #43
>>>>> "Ian" == Ian Bicking <ia**@colorstudy.com> writes:

Ian> I would think of it differently. I don't see a need for
Ian> static typing to deal with the outside world. There's always
Ian> a bridge when communicating with the outside world, and if
Ian> that bridge is smart enough it should be okay. You can

With things like IronPython, there isn't necessarily any "outside
world". The compiler can look at the code, determine that it's "typed
enough" and compile it to a more static form of code that can be
JIT-compiled to native code.

Ian> it would be worth it for any external interface, but for
Ian> internal interfaces it might be worth it, where there's less
Ian> of a concern about flexibility. In that case, decorators
Ian> might be all that's necessary, e.g.:

Ian> @constrain_types(a=float, b=str, c=int:
Ian> def foo(a, b):
Ian> c = 1
Ian> ...

Guido has stated that we shouldn't jump all over decorator syntax for
function/method signatures, because type declarations will appear in
language syntax at some point. We'll see how that pans out - in the
meantime, perhaps having some kind of "standard" type declaration
(-ish) decorator in the standard library would be conductive to having
One Obvious Way of telling IDEs about the types.

--
Ville Vainio http://tinyurl.com/2prnb
Jul 18 '05 #44
Carlos Ribeiro <ca********@gmail.com> wrote:
...
Well, my name is not Alex, and my answer will probably fall short of a
comprehensive definition :-) But let's see if I can help here...
I think you did a great job! May I recommend some further reading...:

http://www.python.org/peps/pep-0246.html
http://www.aleax.it/os04_pydp.pdf
http://peak.telecommunity.com/protoc...protocols.html

Adaptation is the act of taking one object and making it conform to a
given protocol (or interface). Adaptation is the key to make dynamic
code that takes parameters from arbitrary types work in a safe, well
behaved way.
Hear, hear!
The basic concept underlying adaptation is the "protocol", also called
"interface" in some implementations. For all purposes of this
discussion, and for simplicity reasons, we can safely assume that
protocols and interfaces are equivalent.
Right, but, for the curious...: "Interface" mostly describes a certain
set of methods and their signatures; "Protocol" adds semantics and
pragmatics -- some level of conceptualization of what the methods _do_
and constraints on how they are used (e.g. "after calling .close(), no
other method can ever be called on the object any more"). This is a
reasonably popular use of the words in question, though far from
universal.

A protocol is a set of primitives that is supported by a given object.
For example: the iterator protocol defines the following primitives:
__iter__ and next() (as documented in
http://docs.python.org/lib/typeiter.html). Any object from any class
that implement these methods, regardless of its ancestors, is said to
support the iterator protocol.
....if the semantics and pragmatics are also respected, e.g.:
x.__iter__() is x

Any object that supports the iterator protocol can be used whenever an
iterable is acceptable. This includes for loops and list
comprehensions. The biggest advantage of adaptation comes when one
realize how flexible this design is, specially when compared with
old-style type checking. In a old-style type checking environment,
parameters to a given routine must conform to the declared type of the
arguments. For iterators, it would mean that only objects descending
from some abstract class (let's say, "Iterable") would be accepted.
Now, even with multiple inheritance, this design is severely limited.
In old-style Python, inheritance isn't really the issue (except for
exceptions, where inheritance does matter). Rather, a protocol is
defined by a given set of methods.

An iterable is an object supplying a special method __iter__ which,
called without arguments, returns an iterator (any object which respects
the iterator protocol). A sequence besides being iterable supports
__len__, AND __getitem__ with integer and slice arguments, and there is
a rich semantic and pragmatic web of mutual constraints between behavior
of __getitem__ and __len__ and iteration. A mutable sequence is a
sequence which also supports __setitem__ (again with specific
constraints wrt __getitem__, __len__...) and is also supposed to expose
a rich set of other methods such as pop, append, extend, etc, etc.

This IS great BUT limited by what the LANGUAGE designer(s) sanction(s)
as 'blessed protocols'. There are quite a few, but they're never enough
to cover the needs of an application or field of applications, of
course. With protocols based on certain special methods, you have a
great concept which however is not really extensible, nor flexible
enough to help the authors of large frameworks and applications.

Framework authors do define new protocols, of course -- they can't help
doing that. "X must be an object supplying methods 'foo' and 'bar' with
the following constraints...:". This is OK for somebody who's writing
an application using just one framework -- they can code their classes
to the framework's specifications.

The problem comes in when you're writing an application that uses two or
more frameworks... the two frameworks likely haven't heard of each
other... one wants objects supplying 'foo' and 'bar, the other supplies
objects supplying 'oof' and 'rab' instead, with subtly different
semantics and pragmatics. So, what do you do then? You write adapters:
wrappers over Y with its oof and rab which provide an X with its foo and
bar. Python is _great_ at that kind of job!

But, who applies the adapters, where, when? Well, unless we do get PEP
246 in... _you_, the application writer, are the only one who can.
You'd like to spend your time developing your application, with
frameworks to relieve you from some parts of the job, but to do that you
also need to develop adapters _and_ tediously, boilerplatishly, apply
them to every object from one framework that's going over to the other,
etc. Basically, you risk ending up with very *thick glue* (cfr Eric
Raymond's excellent "The Art of Unix Programming", great book also
available online for free) -- throughout your application, there will be
knowledge about the details of all frameworks you're using, spread in
thick layers of glue.

Now, back to Python world. In many situations, there is no need for
adaptation; the object itself supports the protocol, and can be
supplied directly. But there are situations when the object itself
can't be immediately used; it has to be adapted, or prepared, to
support the protocol. Another situation is when an object is passed to
a routine that *doesn't* support the required protocol; this is an
error, that can be catched by the adapt() framework in a superficially
similar but fundamentally different approach from type checking (and
that's whats Alex has been pointing out).
Oh yes, VERY different. Let me try an analogy...

A policeman's job is to ensure you respect the law. He does that by
trying to catch you violating the law, and punishing you for that.

A civics teacher's job is to ensure you respect the law. He does that
by teaching you the law, explaining its rationale, engaging you in
discussion to find instances where your spontaneous behavior might
violate the law, and working out together with you how to adapt your
behavior and your instincts so that the law gets respects.

Type checking is a policeman. Adaptation is a civics teacher.

The adapt protocol (as presented on PEP246 -
http://www.python.org/peps/pep-0246.html) defines a very flexible
framework to adapt one object to a protocol. The result of the
....and yet the text of PEP 246 is still missing the specs about
registering "third party adapters". Phil Eby's PyProtocols is much
better that way!!! (I promise I'll do something about PEP 246 updating:
just as soon as I'm done with the 2nd ed of the cookbook....!!!!).
adaptation (if possible) is an object that is guaranteed to support
the protocol. So, using adapt(), we can write code like this:

def myfunc(obj):
for item in adapt(obj, Iterable):
...
Hmmm, yes, we can. It's a standard protocol so not the best of
examples, but still, it may be meaningful.

Finally, one may be wondering, is there any situation when an object
needs to be "adapted"? Why don't just check for the availability of
the interface? There are many reasons to use the adapt framework. The
protocol checking is one of the reasons -- it allows errors to be
catched much earlier, and at a better location. Another possible
reason is that complex objects may support several protocols, and
there may be name clashes between some of the methods. One such
situation is when an object support different *versions* of the same
protocol. All versions have the same method names, but semantics may
differ slightly. The adapt() call can build a new object with the
correct method names and signatures, for each protocol or version
supported by the object. Finally, the adaptation method can optionally
build an opaque "proxy" object, that hides details of the original
methods signature, and it's thus safer to pass around.
The main motivation I'd give is that different frameworks not knowing
about each other may define [1] what the object supplies and [2] what
the object is REQUIRED to supply -- there are often discrepancies, and
an adapter in-between is gonna be required. With 246 (once suitably
updated;-) we can write the adapter ONCE, register it in a suitable
global registry, and 'adapt' will just find it. Oh bliss -- as long as
adapt DOES get called all over the place!-)

Well, that's a broad overview of the subject. There is a lot of stuff
to learn, and using adaptation properly is something that takes some
time. Hope it helps.


My compliments for your excellent presentation! I hope my enrichment of
it may have proved useful rather than distracting....
Alex
Jul 18 '05 #45
Josiah Carlson wrote:
Since the actual need for type-checking is extremely rare, I contend it
should not _at all_ be a candidate for a syntax to facilitate it. Since
the actual need for adaptation is much wider, I contend it's the one
obvious choice for the "nice syntax" if any.

Sounds reasonable, but there will be a group of people who will beg and
plead for type checking, because they want "static type checking on
function call and return".


Yes, but they've been begging for it for years. They seem insistant
that this Python Thing will never catch on without these important features.

Anyway, a much more general and useful feature would be contracts.
Which is just to say, a formal place to put constraints on input and
output for a function. Contracts could include type checking --
sometimes quite validly -- but not necessarily. There's no type that
can indicate "only valid username strings" or "only integers contrained
by some global variable".
@ multi_dispatch_to_methods
class A(object):
dispatch = dispatch_factory()

@ dispatch(int)
def foo(x): ...

@ dispatch(float)
def foo(x): ...
It may have a couple warts, but it is implementable today.


Phillip Eby just did this, in like the last week. It's very cool:

http://peak.telecommunity.com/DevCen...sitorRevisited
http://www.eby-sarna.com/pipermail/p...er/001916.html

It looks similar to what you were thinking:

class A(object):
@dispatch.on('x')
def foo(x):
"""This is a dummy function, for documentation purposes"""

@foo.when(int)
def foo(x): ...

@foo.when(float)
def foo(x): ...

Of course, you can use interfaces in addition to types, and you can also
use arbitrary expressions (e.g., @foo.when("x % 2") and @foo.when("not x
% 2") to dispatch odd and even numbers separately).

--
Ian Bicking / ia**@colorstudy.com / http://blog.ianbicking.org
Jul 18 '05 #46
On Tue, 16 Nov 2004 19:45:29 +0100, Alex Martelli <al*****@yahoo.com> wrote:
Carlos Ribeiro <ca********@gmail.com> wrote:
...
Well, my name is not Alex, and my answer will probably fall short of a
comprehensive definition :-) But let's see if I can help here...


I think you did a great job! May I recommend some further reading...:

http://www.python.org/peps/pep-0246.html
http://www.aleax.it/os04_pydp.pdf
http://peak.telecommunity.com/protoc...protocols.html

Adaptation is the act of taking one object and making it conform to a
given protocol (or interface). Adaptation is the key to make dynamic
code that takes parameters from arbitrary types work in a safe, well
behaved way.


Hear, hear!
The basic concept underlying adaptation is the "protocol", also called
"interface" in some implementations. For all purposes of this
discussion, and for simplicity reasons, we can safely assume that
protocols and interfaces are equivalent.


Right, but, for the curious...: "Interface" mostly describes a certain
set of methods and their signatures; "Protocol" adds semantics and
pragmatics -- some level of conceptualization of what the methods _do_
and constraints on how they are used (e.g. "after calling .close(), no
other method can ever be called on the object any more"). This is a
reasonably popular use of the words in question, though far from
universal.


Nice summary of the difference.
A protocol is a set of primitives that is supported by a given object.
For example: the iterator protocol defines the following primitives:
__iter__ and next() (as documented in
http://docs.python.org/lib/typeiter.html). Any object from any class
that implement these methods, regardless of its ancestors, is said to
support the iterator protocol.


...if the semantics and pragmatics are also respected, e.g.:
x.__iter__() is x

Any object that supports the iterator protocol can be used whenever an
iterable is acceptable. This includes for loops and list
comprehensions. The biggest advantage of adaptation comes when one
realize how flexible this design is, specially when compared with
old-style type checking. In a old-style type checking environment,
parameters to a given routine must conform to the declared type of the
arguments. For iterators, it would mean that only objects descending
from some abstract class (let's say, "Iterable") would be accepted.
Now, even with multiple inheritance, this design is severely limited.


In old-style Python, inheritance isn't really the issue (except for
exceptions, where inheritance does matter). Rather, a protocol is
defined by a given set of methods.

An iterable is an object supplying a special method __iter__ which,
called without arguments, returns an iterator (any object which respects
the iterator protocol). A sequence besides being iterable supports
__len__, AND __getitem__ with integer and slice arguments, and there is
a rich semantic and pragmatic web of mutual constraints between behavior
of __getitem__ and __len__ and iteration. A mutable sequence is a
sequence which also supports __setitem__ (again with specific
constraints wrt __getitem__, __len__...) and is also supposed to expose
a rich set of other methods such as pop, append, extend, etc, etc.

This IS great BUT limited by what the LANGUAGE designer(s) sanction(s)
as 'blessed protocols'. There are quite a few, but they're never enough
to cover the needs of an application or field of applications, of
course. With protocols based on certain special methods, you have a
great concept which however is not really extensible, nor flexible
enough to help the authors of large frameworks and applications.

Framework authors do define new protocols, of course -- they can't help
doing that. "X must be an object supplying methods 'foo' and 'bar' with
the following constraints...:". This is OK for somebody who's writing
an application using just one framework -- they can code their classes
to the framework's specifications.

The problem comes in when you're writing an application that uses two or
more frameworks... the two frameworks likely haven't heard of each
other... one wants objects supplying 'foo' and 'bar, the other supplies
objects supplying 'oof' and 'rab' instead, with subtly different
semantics and pragmatics. So, what do you do then? You write adapters:
wrappers over Y with its oof and rab which provide an X with its foo and
bar. Python is _great_ at that kind of job!

But, who applies the adapters, where, when? Well, unless we do get PEP
246 in... _you_, the application writer, are the only one who can.
You'd like to spend your time developing your application, with
frameworks to relieve you from some parts of the job, but to do that you
also need to develop adapters _and_ tediously, boilerplatishly, apply
them to every object from one framework that's going over to the other,
etc. Basically, you risk ending up with very *thick glue* (cfr Eric
Raymond's excellent "The Art of Unix Programming", great book also
available online for free) -- throughout your application, there will be
knowledge about the details of all frameworks you're using, spread in
thick layers of glue.
Now, back to Python world. In many situations, there is no need for
adaptation; the object itself supports the protocol, and can be
supplied directly. But there are situations when the object itself
can't be immediately used; it has to be adapted, or prepared, to
support the protocol. Another situation is when an object is passed to
a routine that *doesn't* support the required protocol; this is an
error, that can be catched by the adapt() framework in a superficially
similar but fundamentally different approach from type checking (and
that's whats Alex has been pointing out).


Oh yes, VERY different. Let me try an analogy...

A policeman's job is to ensure you respect the law. He does that by
trying to catch you violating the law, and punishing you for that.

A civics teacher's job is to ensure you respect the law. He does that
by teaching you the law, explaining its rationale, engaging you in
discussion to find instances where your spontaneous behavior might
violate the law, and working out together with you how to adapt your
behavior and your instincts so that the law gets respects.

Type checking is a policeman. Adaptation is a civics teacher.


Good example. I have my own take on this: type checking is about being
strict (to the point of intolerance). Adaptation is about being
flexible.
The adapt protocol (as presented on PEP246 -
http://www.python.org/peps/pep-0246.html) defines a very flexible
framework to adapt one object to a protocol. The result of the


...and yet the text of PEP 246 is still missing the specs about
registering "third party adapters". Phil Eby's PyProtocols is much
better that way!!! (I promise I'll do something about PEP 246 updating:
just as soon as I'm done with the 2nd ed of the cookbook....!!!!).


That's another thing that I thought about including... but I was
afraid of broadening the scope too much. But at least a pointer to
PyProtocols is needed, if this small intro is to be turned out into a
'what is adaptation' tutorial of sorts.
adaptation (if possible) is an object that is guaranteed to support
the protocol. So, using adapt(), we can write code like this:

def myfunc(obj):
for item in adapt(obj, Iterable):
...


Hmmm, yes, we can. It's a standard protocol so not the best of
examples, but still, it may be meaningful.


I thought that it was a good example to show what adapt() does... for
someone who never thought about it before.
Finally, one may be wondering, is there any situation when an object
needs to be "adapted"? Why don't just check for the availability of
the interface? There are many reasons to use the adapt framework. The
protocol checking is one of the reasons -- it allows errors to be
catched much earlier, and at a better location. Another possible
reason is that complex objects may support several protocols, and
there may be name clashes between some of the methods. One such
situation is when an object support different *versions* of the same
protocol. All versions have the same method names, but semantics may
differ slightly. The adapt() call can build a new object with the
correct method names and signatures, for each protocol or version
supported by the object. Finally, the adaptation method can optionally
build an opaque "proxy" object, that hides details of the original
methods signature, and it's thus safer to pass around.


The main motivation I'd give is that different frameworks not knowing
about each other may define [1] what the object supplies and [2] what
the object is REQUIRED to supply -- there are often discrepancies, and
an adapter in-between is gonna be required. With 246 (once suitably
updated;-) we can write the adapter ONCE, register it in a suitable
global registry, and 'adapt' will just find it. Oh bliss -- as long as
adapt DOES get called all over the place!-)


I was not entirely satisfied with this part of my explanation, but I
was afraid of taking too many things at once. If I was to rewrite it
now I would probably restructure it, and include a few considerations
about the case with similar (but slightly and annoyingly different)
frameworks.
Well, that's a broad overview of the subject. There is a lot of stuff
to learn, and using adaptation properly is something that takes some
time. Hope it helps.


My compliments for your excellent presentation! I hope my enrichment of
it may have proved useful rather than distracting....
Alex
--
http://mail.python.org/mailman/listinfo/python-list

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #47
Alex Martelli wrote:
Jim Fulton <ji*@zope.com> wrote:

Guido has repeatedly stated that a future version of Python will


include static type support. The Zope project has driven numerous past
changes to Python. What's funny about this?
For the record, I'm against static typing for Python, although,
if Guido decides he wants it, I have an open mind. :)

Glad to hear that. As for me, I'd love it if function arguments, only,
could bear an 'as' clause (making 'as' a keyword is long overdue):

def x(y as foo, z as bar):
<body of x>

I know many people here already know about this, but you can use this
syntax in boo:

def foo(y as int, z as bool) as bool:
<body returns a boolean>

You can also use attributes (similar to decorators):

def foo([required(value > 3)] value as int):
pass

http://boo.codehaus.org/

If anyone here familiar with Zope, mod_python, etc. ever tries out boo
and ASP.NET (or Mono's XSP/mod_mono), I'd appreciate you sharing any
notes about it on the boo mailing list to help others getting started.
Jul 18 '05 #48

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Sig | last post: by
2 posts views Thread by mxlplx | last post: by
1 post views Thread by Lukasz Indyk | last post: by
4 posts views Thread by Jochen Demuth | last post: by
9 posts views Thread by john | last post: by
4 posts views Thread by Avery Warren | last post: by
21 posts views Thread by godwin | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.