What is good about Prothon?

has has.temp2 at virgin.net
Wed Apr 28 11:22:40 EDT 2004


"Mark Hahn" <mark at prothon.org> wrote in message news:<oiCjc.9622$Qy.6230 at fed1read04>...
> has wrote:
> 
> > (Note: scripts are compiled, so you'll need a Mac to view source.)
> 
> Can you at least make a screen snapshot available or something for the "rest
> of us"?

Eh, I'll see what I can do. Here's a short example to get you started:


on makeStack()
    script
        property class : "Stack"
        property _linkedList : missing value
        -------
        on push(val)
            script node
                property nval : val
                property chain : _linkedList
            end script
            set _linkedList to node
            return
        end push
        --
        on top()
            if _linkedList is missing value then error "Can't get top:
stack is empty." number -1728
            return _linkedList's nval
        end top
        --
        on pop()
            if _linkedList is missing value then error "Can't pop:
stack is empty." number -1728
            set val to get _linkedList's nval
            set _linkedList to get _linkedList's chain
            return val
        end pop
        --
        on isEmpty()
            return (_linkedList is missing value)
        end isEmpty
    end script
end makeStack

-- TEST

set foo to makeStack()
foo's push(3)
foo's push(5)
log foo's pop() --> 5
log foo's pop() --> 3



In AS, every compiled script is itself a script object. Scripts can be
loaded into other scripts using the 'load script' command; this
provides the foundation for library-based design. Script objects can
also be declared within other script objects and handlers (aka
procedures) using the 'script [identifier]...end script' block. This,
along with their support for delegation via the 'parent' property,
allows you to do prototype-based OOP. Incidentally, because script
objects have first-class syntactic support, they also support modular
design within a single file, sectioning off parts as separate
namespaces without having to move code off into separate files as
you'd do in Python; e.g.:

----- begin script (global namespace) -----

property foo : 0

script Sub_Namespace1
   -- properties and handlers here
end

script Sub_Namespace2
   -- properties and handlers here
end

on bar()
    ...
end bar

----- end script -----

(e.g. This ability makes for a very handy halfway stage when
refactoring one file into several or vice-versa.)

Thus a single, very generic type (script) can perform all the roles
that it takes Python several specialised and largely
non-interchangeable types (classobj, instance, module) to do. It's
such a clean, simple and extremely flexible way to do encapsulation
that, though I can understand why more static languages might require
the extra layers and complexity, I've never understood why languages
like Python, Smalltalk, etc. feel such need to erect all these extra
hurdles for themselves. Maybe they just like making work for
themselves? Of course, greater freedom also implies greater
responsibility and a better understanding of what you're trying to
achieve, which might freak some folk from the BDSM school of
programming, but that's their problem - and loss.



Other nice stuff: while AS allows only a single delegate per object,
the ability to compose object behaviour at runtime makes it much more
powerful than class-based single inheritance, and less of a PITA to
use than MI. Just create and delegate-chain together the objects you
want as and when you need them.

e.g. I used this approach in my original HTMLTemplate library to
construct the various template objects - see
<http://freespace.virgin.net/hamish.sanderson/TemplateConstructors.rtf>
for the relevant module (forgive the nasty source code-munging bit in
the middle, but one of AS's limitations is an inability to add/remove
slots once an object is created*). Compare this with the Python port
where I had to use MI to compose behaviour
<http://freespace.virgin.net/hamish.sanderson/htmltemplate.html> -
particularly the older 0.3.2 release where I managed to spaghetti the
inheritance tree something awful on my first attempt (I had no such
problems designing the AS version where composing objects was a
no-brainer).

[* Python shouldn't feel too smug, however, seeing as I had no better
luck trying to dynamically attach property objects to class instances,
and had to resort to sticking nodes into a private dict accessed via
__getattr__ and __setattr__.]



Obviously, there's some things about the AS implementation that don't
translate well to a more Python-like language design: e.g. its use of
object-centric Smalltalk/Obj-C-style message passing instead of
Python-style bound functions make callbacks a bit of a chore (you have
to pass the entire script object around rather than just a function
object/pointer), and its lexical/dynamic variable scoping is a bit of
a disaster area (though that may simply be down to poor implementation
than fundamental design limitation).

What's important is just to note the extreme simplicity and total lack
of "sophistication" in its script object system; it may be a little
_too_ simple for an industrial-size language, but it's a heck of a lot
easier to start with an overly simple but clean and coherent model and
build upward than begin with something that's over-complex and muddled
and try to clean it up. Good programmers know how to add features;
great ones know how NOT to.



More information about the Python-list mailing list