This post originated from an RSS feed registered with Python Buzz
by Ian Bicking.
Original Post: Initial thoughts on Prothon
Feed Title: Ian Bicking
Feed URL: http://www.ianbicking.org/feeds/atom.xml
Feed Description: Thoughts on Python and Programming.
Prothon uses whitespace for continuations, so if a line is indented
from the previous line it is considered a continuation of that line.
I have a really hard time keeping lines under 80 characters in width,
and \ and () always break up my coding -- the first is ugly,
and the second requires me to back up to the beginning of the line
once I realize I'm going over 80 characters.
This is purely syntactic, Python could also do this.
This is really at the heart of Prothon. This is actually my plan for
OO in PyLogo (except it's called TELL there). When you use
with var:, var becomes the "self" object (though Prothon
doesn't use the word "self").
This kind of scares me, though. My experience with DTML shows that
this is a horrible feature. Though, that said, I'm not sure if
with is quite as dangerous as dtml-with -- so long as it only
applies locally it's not too bad. The issue would be something like:
with File:
def .writeAll(*objs):
for ob in objs:
.write(CustString(ob))
def CustString(ob):
if .filename.endswith('.txt'):
ob = Str(obj)
else:
ob = Str(obj).encode('UTF-8')
I don't know, I'm kind of contriving that example. But the question
being, do you "inherit" the . (self) according to call order? Or
only statically? Eh, they probably do the right (static only) thing
here.
def with expressions
Or, more specifically, something like:
def Point.move(xofs, yofs): ...
In this case, adding a method move to Point. I like this,
it's very natural feeling. It is used to more effect in Prothon than
it would be in normal Python.
Variable naming
In Prothon, locals start with lower-case letters or the underscore,
and globals are capitalized. This is okay. I still like lower-case
functions, but I can live with upper-case functions.
I do not like all the prefixes they come up with. I think this is
clearly a case of starting with one or two prefixes, then it spiraling
out of control. Here's the prefixes:
Prefix
Meaning
.
.x is like self.x, kind of.
Problem: . can't be pronounced, and it's really small.
I still like self, though I can understand taking it out
of method signatures. I think they should make self a
keyword.
^
Like "super", though the exact equivalent in Python is
terribly confusing (the super() function). I'm used to
it from Smalltalk, and like the brevity compared to Python's
standard mechanism. A super keyword would still be
better (to go with a self keyword).
&
This is a closure variable -- a variable that is defined in
the parent scope. Anyone who has tried Scheme-style
closures in Python has probably known the suffering of
trying to figure out how scopes work. This makes it very
explicit, which actually makes it usable. I also imagine
it makes it easier to implement, since you actually know
which variables need to be kept with the closure. Horrible
punctuation, but a good idea.
@
Dynamic local variables. There's no equivalent in Python --
you'd have to open up the current frame object and look in
parent scopes. While it's expedient, I think it's also a
very bad idea to provide this. That kind of mucking about
with parent scopes is just asking for problems. I guess it
could be used to macro-like effect in some ways.
__init__ allows for more playing around than in Python -- you can
return an object besides self and effect the result of the
constructor. Of course, you've already constructed the object anyway,
so maybe __new__ really is called for, if you actually want to
avoid creating an object. (If you had to call ^__init__ to
construct the object, then it would be more general)
In the list of little tweaks, they also allow identifiers to contain
!, with the usual meaning (indicating the method mutates the
object). I always like that punctuation, so I like that it's in
there. It's much more useful than Python's convention of returning
None -- I can tell statically that a method name contains !, but I
can't do the same for returning None, and returning None is annoying.
Prothon also returns self by default, instead of returning None
(there's some conflicting information on this, so they might not be
doing this). I like ? in identifiers as well, but Prothon doesn't
add that.
There also seems to be a tendency to global methods, like
obj.chr() instead of str(obj). I'm not entirely clear about
this -- I think it falls out of the way builtins are defined. I
generally prefer Python's style with magic methods, purely from an
aesthetic point of view, though I can understand why some people would
prefer using methods for everything.
There's also some changes in generators, but I haven't used generators
enough to have an opinion on the subject. I think the change is
fairly significant, from a stylistic/usage point of view.
It's an interesting effort. There are some small aesthetic/syntactic
changes, some of which I like and some of which I don't. Then there's
the prototypes... which are something else entirely.
I actually wonder to what degree prototypes could be implemented in
Python with metaclasses. While some of the syntax would currently be
crufy with Python (e.g., you'd have to create a function, then assign
the function to an object), that's kind of a separate issue. The
basic object model in Python feels like it should be replaceable,
especially since we already have both new and old style classes. I
think it's still a bit hard to think about these with the syntax
getting in the way or otherwise being distracting, but feel like the
potential is in there somewhere.
If it could be hacked onto Python instead of developed entirely
separately from Python, it could make Prothon much more interesting
from the perspective of practical programming. Ultimately it would
probably have to be like Stackless -- a patch against Python
implementing some necessary changes to syntax. But that's a more
viable development effort, and one that's more likely to percolate
ideas into the main Python interpreter.