[squeak-dev] Re: [Pharo-project] A point a.k.a excuse to you

Keith Hodges keith_hodges at yahoo.co.uk
Tue Mar 3 01:06:09 UTC 2009


Michael Roberts wrote:
> Keith, your email implies that you believe Pharo should be backwards
> compatible at some level with Squeak.  Part of the Pharo manifesto is
> not to be compatible.  So if you want to write code or have apis that
> work in a backwards direction from Pharo to Squeak, that's great.  I
> don't believe it's a goal for Pharo though.  The pharo process doesn't
> need a rethink at all as far as I'm concerned.
>
> thanks,
>
> Mike
>   
No that is not what I am saying at all. Perhaps examples would help.

Take Rio. Rio was designed from ground up to be a replacement for a the
present non-modular kernel facility FileDirectory. It is a discrete
loadable module.

Wild and horrible uses of FileDirectory are spread around the image in
lots of places, so one thing that Rio tries to do is to anticipate use
cases, so that the users of Rio dont have to implement File handling
code in their stuff, and so we help to keep the module boundary clear.
For example you can ask Rio to get you the next version of a file -
'myfile.2.txt' asFile nextVersion = 'myFile.3.txt. That facility in
itself potentially lightens SmalltalkImage.  If you want to read Xml
files, you can subclass File, with FileXML, define the #validExtensions
that it handles, and implement contents/contents: This means that your
code only needs to send, 'myfile.xml' asFile contents, to get the model.
There are all sorts of things like that.

With Rio as a front end to File and Socket streams it is perfectly
possible to innovate on them without users of Rio being any the wiser.
If I do 'myFile.3.txt' asFile contents, it wouldn't care whether it was
Squeak streams Nile or Flow behind the scenes. 'http://www.google.com'
asFile contents, now means that I dont have to care about whether
HttpSocket is doing the work with a RWBinaryOrTextStream in 3.7 or
HTTPClient returning a MultiByteStream thingy in 3.8 or some other new
facility.

So, Rio demonstrates that it is possible to innovate, on a kernel
module, and you dont need to break anything to do it. Secondly by
thinking about APIs and module interface abstractions in this way, you
can define specific interfaces and bottlenecks, that potentially turn
the ball of tangled string into something designed and architected.
There are perhaps hundreds of other modules that could use the same
treatment.

Rio loads into all squeak images I have tried it in, so this then means
that any of my file handling code will work in all images. This benefit
comes from managing Rio as module external to the main image. Rio also
comes in two sizes, a Rio-Kernel, and a Rio-Base, with smaller images in
mind.

Having done this, the question of moving the kernel over to make use of
the new code arises, this also can be achieved without breaking anything
for users that have had Rio available for 2 years in every image that
their code was running in. I.e. Sophie, Croquet, Seaside, Gjallar,
Magma, Etoys, can all migrate their file handling code to the new Rio
API now, even if they are using Squeak 3.7/3.8, without having to
upgrade to the latest squeak. When they do update, they will be pleased
to find that their file handling code works, as well as their
gzipping/archiving/remote file handling/and website accessing code.

Installer follows the same principles, abstracting an api, freeing the
backend to be either old code or new code. If you dont have Universes
loaded, then defining Installer>>#universes to call #sake as a fall back
would use Sake/Packages and get identical results, your users would be
none the wiser. If you dont have SqueakMap loaded, then defining
Installer>>#squeakmap to call #websqueakmap instead, would again give
your users identical results. and you thought that Installer was just
for loading things. Edgar has pointed out that you could use CodeLoader
for that, but thats not the point of installer, Installer is providing a
DSL for loading things that provides an architectural layer of
isolation, and thus both inherrent forward and backward compatibility. I
expect my image building scripts to work identically with Monticello2 in
squeak 3.16 as they do now with Monticello 1.5 in Squeak 3.7.

Scripter (who here even knows that Scripter exists?) does the same, if
you want to write code to close or tile all the windows, after the
installing process has left a mess. Scripter can be the interface to
whatever backend GUI there happens to be whether it is
ToolBuilder/Tweak/Morphic.

Same again with Logging, is a front end abstraction to all of the three+
logging backends out there. I can remove the hardwired calls to
Transcript that scatter the image and replace them with a single api to
multiple backends, both past (Transcript) present (Syslog) and future
(seaside per-user session logging framework).

Oh, and again with Sake/Packages.... why does Sake/Packages define class
tasks? You can write a task that depends upon a task which removes
certain method selectors. You could just call Behaviour direct. Its
another  architectural layer, that frees up the back end to be old or
new code as far as Sake task writers are concerned. I can write a task
that says, "if you find this Class with a method categorised as so, then
it needs to be recategorised as such", in such a way as this task would
run in all images.

Oh and again SystemEditor... another layer of abstraction for compiling
and loading code atomically.

So if you think about it, those who know about the compiler could be
considering how to write their stuff, so that it logs to the Kernel
Logging API (which is valid even if Logging isnt Loaded). They might
consider connecting to SystemEditor in preference to providing a direct
api, and another abstracted pluggable Module is needed to handle source
code files (replacing RemoteString/ChangeSets etc), with Rio as the
local/remote file API. 

Do you get the idea now?

For the same treatment to be available for more significant chunks of
squeak, we would need atomic loading to work. Now the code to provide
atomic loading for everyone has been available for over a year, and it
works if you dont use traits. So where is the expertise to really get it
working for everyone with traits?

The only difficulty with this approach is that you might need slightly
different bits to make your NEW code load into older images. This
problem is reasonably easily addressed with Installer-Scripts
(LevelPlayingField+) and Sake/Packages.

I fully agree with Matthew about core packages like Collections. BUT and
this is the big but. If you are going to do that kind of thing, you need
to think about it, plan it, and create and participate in a process that
supports everyone is diverse images using and testing that package. From
what I have seen there is only one person on the Pharo team that
understands what LevelPlayingField is for, and how to use it.

The biggest risk to this approach is if some other folks decide to fork
some significant architectural component in a completely incompatible
manner, without thinking about any bigger picture at all.

Matthew's comment about how our tools are only just getting there isnt
that relevant to the point that I am making. I didnt need a test and
build server to innovate Rio for everyone rather than just for the image
I am using (trouble was I was using 3 different images), all I needed
was an inclusive attitude rather than an exclusive attitude.

cheers

Keith












More information about the Squeak-dev mailing list