[squeak-dev] Re: talk on Newspeak online

Igor Stasenko siguctua at gmail.com
Thu May 8 23:50:40 UTC 2008


2008/5/9 Vassili Bykov <smalltalkbigot at gmail.com>:
> 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?
>

Point taken. :)

> 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
>

I very like the above, especially how NewSpeak provides a ways to hide
details from user but still there are subtleties which not covered
well.
In given example i assumed that ExternalInterface is basic abstract
class, which provides common interface,
while different subclasses providing specialization for each separate platform.

So, as far as i understood, the only constructor which can be used for
ExternalInterface is one which is sit in declaration:
 class ExternalInterface platform: platform

If this correct, then given the rule, that direct subclasses should
use this and only this constructor to initialize superclass, then how
subclass declaration would look like and why it would need to pass
'platform' again to superclass, which is already used in #new to
determine subclass and no more required?

I know, there can be a way around of this, by declaring it like following:

class ExternalInterface platform: platform = (
   | platformName = platform platformName. |)
 (
    private class BasicInterface  = ...
    private class MacOSExternalInterface  = BasicInterface ...   " not
sure if this notation is correct. i mean that MacOSExternalInterface
is subclasss of BasicInterface here"
)

But then this not better than having utility method (which chooses
appropriate specialization) in any other place not bound to any
specific class.
Also, suppose i loaded a module(package) which provides me the classes
above. Now, how i can create own XXXXOSExternalInterface, but place it
in my separate module, but still taken in account by ExternalInterface
if my module is loaded?
So, that ExternalInterface platform: XXXX should return an instance of my class.

----------
Also, there was a more important question, not answered.
The question sounds like following: And finally, who told that,
ultimately, only classes can create instances?

Is it possible to implement something like this
http://www.russell-allen.com/squeak/prototypes/ in NewSpeak?
And if yes, please show some code snippets.

> 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.
>

True, but all cases need to be wighted before cutting.
If language enforcing X, it should provide an alternative how people
can implement Y (which being cut down) without much stress.

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

I see a class chain as a set of objects which sharing same virtual
space. So, there is no need to draw hard borders between them and
there is no problem with initialization.
But of course, if classes are kind of mixins NewSpeak, then you are correct.

> 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.
>

I think you are familiar with following, which is one of the razors:

If it looks like a duck, walks like a duck, and quacks like a duck -
it's a duck.

Going back to my question concerning classes and they sole role as
instance factories, it can sound like:

If it looks like a class, walks like a class, and quacks like a class
- it's a class.

And Prototypes using this principle quite well :)

> Cheers,
>
> --Vassili
>
>



-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list