[squeak-dev] Re: talk on Newspeak online

Vassili Bykov smalltalkbigot at gmail.com
Thu May 8 22:15:22 UTC 2008


First of all, I take none of this personally or as an offense so don't
worry about the language or what's being said. In fact, it was I who
first referenced "crappy languages", and we seem to agree on what
those are. :)

I'm not arguing against the general thesis that borrowing crappy
features from crappy languages produces crap. But the important
question is whether constructors are a crappy feature in C++ or Java
because the *idea* of disciplined object initialization is flawed, or
because its particular incarnation in those languages is bad. Also,
"borrowing" is a vague notion with an arbitrary attribution. What
makes you believe that Newspeak "borrows" the idea of disciplined
object initialization from C++ or Java and not, say, from CLOS or
Dylan? And what exactly is borrowed, besides the term?

Igor, from trying to follow this thread I got an impression that the
reason for your pushback may be an implicit assumption that Newspeak
"constructors" are the same thing as Java constructors. It's
understandable that anyone here may have misconceptions, and that's
the reason I'm responding in this thread. There is not much
information out there, not because of any secrecy, simply because it's
not written up. I'd be happy to answer any questions that help clarify
things.

Now, as an aside, it's hard to parse a day's worth of posts consisting
mostly of many levels of quoted text and a few lines of actual
content, so excuse me if I missed a prior question worth answering. I
did notice the question about MyExternalModule and how that would look
in Newspeak. There are several possible solutions. Here is one:

class ExternalInterface platform: platform = (
    | platformName = platform platformName. |)
(
    private class MacOSExternalInterface  = ...

    private class LinuxExternalInterface  = ...

    private class Win32ExternalInterface  = ...

    new = (
        platformName = 'MacOS' ifTrue: [^MacOSExternalExternalInterface new].
        platformName = 'Linux' ifTrue: [^LinuxExternalExternalInterface new].
        platformName = 'Win32' ifTrue: [^Win32ExternalExternalInterface new].
        error: 'unknown platform'.
    )
)

I took the liberty of replacing "Module" with "Interface" to avoid
confusion, as I'll be talking about modules in a different sense.

This snippet illustrates many Newspeak things at once: absense of
global state, nested classes and classes-as-modules, read-only slots,
and message privacy. The top-level class ExternalModule plays the role
of a module. The argument 'platform' is a platform object the module
user will provide at the time a module instance is created, for
example as:

    ExternalInterface platform: Smalltalk

The use of '=' in the 'platformName' slot definition identifies it as
a read-only slot: the class will include a getter for it but no
setter.

The three nested classes are private, which means the module will not
respond to messages such as #MacOSExternalInterface if they are sent
by other objects. It will respond to these messages sent from itself,
as in the #new method. And thanks to that #new method, the module is
also a factory that creates an interface instance appropriate for the
platform.

As a user of this, you would likely create an instance of the module
and store in a slot defined as something like (assuming that
ExternalInterface and Smalltalk have been bound to appropriate
objects):

    Interface = ExternalInterface platform: Smalltalk.

And then create instances in the code with "Interface new". To the
rest of the code, "Interface" is no different from a real instantiable
class.

If the classes nested in ExternalInterface were not qualified as
private, it would be possible to retrieve them by sending a getter
message to the module and instantiate directly:

    (ExternalInterface platform: Smalltalk) Win32ExternalInterface new

Some other points.

Regarding freedom vs restrictions and predefined mechanisms, you have
to realize that very often abstraction design is like cutting a
fractal border with a straight knife. No matter how you do it, by
imposing regularities you leave something unnecessary and cut off
something useful. This is why any example like "here is one case where
X is clearly better than the alternatives" never proves anything by
itself, being only an isolated case. It's all a matter of statistics
and priorities.

I'm not sure how "locality" as a positive quality and the ability to
skip superclass initialization as a useful feature go together.

Regarding constructors "implemented" in Smalltalk--it shows two things
at once. 1) there if enough reflection in Smalltalk to implement
something like this, and 2) there is not enough syntactic abstraction
to hide the boilerplate and make it usable. There is a similar issue
with providing list comprehensions within Smalltalk/Newspeak syntax.
It's easy to do the work, but it's impossible to hide all the exposed
wiring, avoid binding names more than once, etc. In the end, it's only
a proof of concept and not a *usable* feature.

And, I completely agree with Klaus about Occam's Razor sometimes being
cited indiscriminately. There might be a place somewhere in the Fifth
Circle where Occam's Razor abusers are implementing a Blue Book VM on
the Turing machine.

Cheers,

--Vassili



More information about the Squeak-dev mailing list