On and off the last couple of weeks I have ported PetitParser to GNU Smalltalk. I am still a Smalltalk newbie and it was a nice learning experience and it helped me to improve the way I code on GNU Smalltalk and to learn more about GNU Smalltalk and ANSI Smalltalk.
To load the PetitParser.star one can type:
gst-package http://smalltalk.gnu.org/project/petitparser/package.xml
To load the PetitParser.star into the image do:
PackageLoader fileInPackage: 'PetitParser'
There are some differences between the real PetitParser and this port. GNU Smalltalk does not support binary selectors that have more than two charachters. This means that ==> and >=> had to be mapped to something else. I have picked => and >< for now.
This weekend I created a public Amazon Machine Image (AMI) setup as a Smalltalk web server with a Linux SqueakVM, a Pharo 1.1 Smalltalk image and the Apache2 web server. Anyone can use this AMI as a robust and scalable runtime platform for their Seaside applications.
In this article I will try to explain how you can you can use and customize this image. First their are some prerequisites:
Using EC2 is not free, you have to pay for each hour the server runs and you have to pay for storage and bandwidth. Seaside runs fine on the smallest 32bit AMI that costs $0,085 cents per hour. Bandwidth is $0,15 per GB (the first GB is free). You can get a discount on the costs per hour if you reserve you AMI’s beforehand.
The AMI is based on a 32bit Ubuntu 10.04 server AMI. The Ubuntu server is a very minimal install, I have added Apache2 and the SqueakVM. I have also setup a Pharo image with the Seaside runtime packages and Apache2 is configured in such a way that all requests are forwarded to Seaside.
How can you start using this AMI?
Start an EC2 instance using the public AMI ami-0800ea61 (ubuntu-10.04-i386-smalltalk-server-v01). The AMI is available in the US East region. This is the cheapest region
When you start the image you have to select a security group. This defines the firewall rules for the AMI. You can select the default group or some other group that allows TCP connections for the ports 22 and 80.
When the image is started it should have a generated a public DNS name. When you enter this name in the address bar of your browser, you should see something similar to http://ec2demo.doit.st If the web page is shown it means that everything is running OK.
You can connect to the running AMI instance using ssh. You should login with the userid ubuntu. No password is required because a private key is used for authentication. The Pharo image that runs on the AMI includes RFB, a VNC server implementation. With a VNC client we can remotely control the Smalltalk image. The best way to do this is to tunnel the VNC connection (port 5900) through ssh:
ssh -i id_rsa-gsg-keypair -L 5900:localhost:5900 ubuntu@ec2demo.doit.st
Now you can connect to the image using a VNC client use display number 0 and the password is seaside. Note that you have to keep port 5900 closed for direct access otherwise this would be very unsecure.
Through the VNC client you have access to the Smalltalk image. You should see a workspace. I used the code in this workspace to build the image from a standard PharoCore 1.1 image. Note that I only loaded the runtime parts of Seaside and some small examples. This image is used for hosting an application and not for development so it is probably safer and more efficient to leave out the development packages.
If the image suits your needs you can just load your packages through Monticello. There is no config web application to configure your Seaside components. You can do this via the workspace or better, make a class side initialize method that does this automatically when the package is loaded. I used the the Apache2 configuration described in the Seaside book (the non-clustered setup for now). You can read the Deployment chapter for more details. You should have you app running within a few minutes.
If the Smalltalk image does not suit your needs you can replace it with another Squeak or Pharo image. The image is stored in the directory /srv/seaside If your new image has a different name you need to update the run script in the same directory.
Of course you can also install more Ubuntu packages. You could install a local database system like MySQL or PostgreSQL. But if you are really into cloud computing you probably don’t want to maintain a database yourself. Instead you can use RDS, an AWS managed MySQL service or SimpleDB. SimpleDB is a key-value store with a simple API and great scalability. You can use the Cloudfork ActiveItem Smalltalk library to persist your Smalltalk objects to SimpleDB.
To setup a nice domain name for your app (like ec2demo.doit.st) you should reserve a static IP using the AWS Console. You can then go to your domain name registrar and update the name servers to point to this IP number.
Ok, this is about it. If you have questions or ideas on how to improve the Smalltalk AMI please let me now. I think the current AMI can be used as a production environment for Seaside apps.
The base of the CouchDB interface is my wrapper around an external C-library doing the JSON parsing stuff. The JSON parser/checker can be found in the MSKJSONWrapper App application (by the way: all source code is available at vastgoodies).
As I mentioned in my earlier posting about this wrapper – the c-library is pretty ANSI C and can be compiled quite easily. It’s a very good example to show the usage of a callback to Smalltalk.
The main use of this library is to parse JSON strings and get a Dictionary-like object (with the help of the external C library) or to create from a Dictionary a JSON string representation (without external C support).
In most of the time you will use the MSKJSONParser and on the class side you may find several small helper methods:
MSKJSONParser class>>newChecking
This method returns a new instance of the parser and you may use this instance to check the valid syntax of the JSON string. Please be aware, that you must release the external sources in the C library ! How this is done can be seen in
MSKJSONParser class>>newCheckingParserParsingOnce: aString.
You may use this method to check a valid JSON string representation and the result is returned to the caller (in error case an instance of AbtError with more information what is wrong with the string). After checking the string, the external resources are released.
All the other methods are used to build Dictionary-like Smalltalk objects from JSON string representations.
MSKJSONParser class >>newParser: aJSONConfig
The is the lowest level instance creation method. The configuration values for the newly parser are stored in an instance of MSKJSONConfig. The parser can be used several times – and be aware, that you have to release all external memory. How the instance of MSKJSONCOnfig can be configured can be seen in the next method:
MSKJSONParser class>>newDefaultBuildParser
This method is more or less the parser method newChecking (introduced above). A new parser is created and configured and you may use this parser several times. Also here: be aware to release all external resources.
MSKJSONParser class>>newDefaultBuildParserParsingOnce: aString
The next helper method, which does everything. Parsing and build an instance of the class MSKJSONObject – a subclass of dictionary. If you want to let the parser create an instance of a user defined class, that you should create a subclass of MSKJSONObject and then you call:
MSKJSONParser class>>newDefaultBuildParserParsingOnce: aString buildClass: aClass
The method is heavily used in the CouchDB interface.
For the other way (create a JSON string representation from a Dictionary like instance) the following small code sequence shows, how it can be done:
aStream := WriteStream on: String new.
aDictionary storeAsJSONOn: aStream.
jsonRepresentationString := aStream contents
Well, that shpuld give you enough informations to start with this wrapper. As I mentioned, the needed library is available from my site and can easily be compiled using a normal C compiler. The Watcom C project is included in the download.
Whether one likes the TIOBE Index or not, this is bad news for us Smalltalk enthusiasts:
TIOBE Programming Community Index for August 2010
August Headline: Dinosaur Smalltalk falls off top 50
Smalltalk, the first pure object-oriented programming language ever, lost its position in the TIOBE top 50 this month. The same happened to the other well-known pure object-oriented language Eiffel a couple of months ago. This is probably part of the trend that languages are becoming more and more multiparadigm: both object-oriented and procedural with a functional flavor.
I took action and created this blog. Hope it helps somewhat.
How should Google respond to the lawsuit filed by Oracle about Java?
In my opinion Google should take the chance and replace the surface language of Android by something more modern and dynamic. They already replaced the Java VM. They can easily do it with the language as well.
They have the know-how to do that. Lars Bak, one of the leading engineers behind the Google V8 JavaScript VM, is a great language designer. He implemented Beta, Smalltalk, Strongtalk, Self, Java, OOVM, and JavaScript.
If I were them, I would bring in Gilad Bracha, who worked with Lars Bak at Animorphic and Sun, and use his Newspeak language as the basis for Android. That would make a great language for the Android platform.
Apparently, while I wasn't looking, some Very Smart People finally ported Pier to new Seaside, which I've been waiting for as a prerequisite to cutting www.stonehenge.com over to Seaside and away from Perl. It's a bit tricky to get it all installed, but I have this magical set of incantations that can bring it in as needed:
(Installer ss project: 'MetacelloRepository') install: 'ConfigurationOfMetacello'; install: 'ConfigurationOfPier2'!
ConfigurationOfMetacello loadLatestVersion!
ConfigurationOfMetacello project latestVersion load: #('UI')!
ConfigurationOfPier2 load!
(Installer ss project: 'MetacelloRepository') install: 'ConfigurationOfPier2'!
ConfigurationOfPier2 load!
Pat Maddox a “Beach bum yuppy programmer” and “Ruby dude” is giving a talk entitled Takin’ the railway down to the seaside at the the upcoming Ruby|Web conference. Recently Pat Eyler, interviewed Pat giving us a preview of his talk:
Photo by http://www.flickr.com/photos/ankor2/4820229669/ / CC BY-NC 2.0
This year’s ESUG conference will host the 6th annual Innovation Technology Awards. The top 3 teams with the most innovative software will receive, respectively, €500, €300 and €200 during an awards ceremony at the conference. Developers of any Smalltalk-based software are welcome to compete, and, for the first time, this year entrants are asked to provide a 3-5min video explaining each entry.
There are lots of interesting projects up for the competition, based on Squeak, Pharo, VisualWorks, and Smalltalk/X. You can find out more about the competition at http://www.esug.org/Conferences/2010/Innovation+Technology+Awards, and of course, you’ll be able to see them for yourself at the conference. See you there!
In an interview with Pad Maddox, he remarks:
It's nice that he's going to be presenting Seaside with such enthusiasm at a Rails Conference. Yeay.Okay as for what's so interesting to me about Seaside... it's 50% the framework and 50% the Pharo environment. Seaside itself represents a step forward in web development similar to how Rails did. Rails takes care of a lot of the plumbing for you - you don't have to parse query params, set up response headers, manage the session (unless you want to of course). Seaside does all that of course but also manages application state for you. So you don't have to worry about putting stuff into a database, then pulling it back out and operating on it. I can't do it justice in a few sentences, but that's why I'll be showing lots of examples at the conference! :) At any rate, that same feeling you get when you code Rails for the first time and see how much easier things are, you get that same feeling with Seaside. It's not a replacement for Rails by any means - Rails definitely has a sweet spot, particularly when it comes to RESTful websites and interoperability with the unix ecosystem - but for the things that Seaside is strong at (which for me so far has been complex and/or configurable workflows), it runs circles around everything else.
An excellent article by Hannes Hirzel. Quoted with permission.
I would like to comment on the trigger word “competition” which Pavel has brought up in connection with Squeak / Etoys / Pharo and Cuis. Andreas is advocating a discussion which actually promotes the work and I support this.
1) There is competition – sure – but as a whole it is just a sign of a healthy eco-system to have Squeak / Etoys / Scratch / Pharo and Cuis around. I have written this earlier this year when we were asked to fill in a questionnaire. In fact as a user of a Squeak based Smalltalk “distribution” or “fork” I am happy that there are alternatives. The use of these alternatives may vary though.
2) It is probably more precise to speak of coopetition.
Coopetition or Co-opetition (sometimes spelled “coopertition” or “co-opertition”) is a neologism coined to describe cooperative competition. Coopetition occurs when companies work together for parts of their business where they do not believe they have competitive advantage and where they believe they can share common costs.
Or maybe we should speak of a ‘distributed’ development approach or just having different distributions which share ideas / concepts / strategies / code snippets and packages. This is reuse on all levels (analysis, design, implementation, package, methods). A recent example is the WebClient and the release announcment of Pharo 1.1 for example states (http://www.pharo-project.org/pharo-download/release-1-1).
StandardFilestream now performs read-buffering, dramatically speeding up some operations like “Object compileAll” (2x improvement) as well as various other operations (scanning change lists etc). This change was taken from Squeak.
and further down
A new general cleanup protocol has been added. The cleanUp protocol takes an optional argument to indicate whether we’re doing an aggressive cleanup (which involves deleting projects, change sets, and possibly other destructive actions) or a more gentle cleanup that’s only supposed to clean out transient caches. This change was taken from Squeak.
3) Squeak, Etoys, Pharo, Scratch and Cuis have different “missions” so to say. Or we could say “different customer groups”.
As a reminder for the goals of Squeak I would like to mention the article “Personal Dynamic Media” written in 1977 which is to be found on http://www.scribd.com/doc/454106/Personal-Dynamic-Media. It is amazing what was there at that time.
The problem in the past was that Squeak development did not scale in terms of developers working together and going for forks was the only reasonable thing to do at that time. But this does not mean that new approaches are not feasible. Scratch so to say was ‘silent’ fork. And at the same time a very successful one. It did not create much noise on this list. Maybe we should call it an application. In the area of Squeak these borders are blurred (intentionally) and this might be part of the causes for these kinds of discussions.
4) Going for a minimal kernel with loadable packages maintained by various people is actually meant to stimulate “competition”. People will be encouraged to take the minimal kernel and load all kinds of things on it and distribute the result and create communities around it.
5) For this to work the kernel has to be minimal in a sense that it can be managed by a small team. This is the aspect Cuis strongly promotes and we want to adapt for Squeak. Actually this is not new at all. It has been a long standing goal. But for many reasons about which we have pondered many times it had not been achieved so far. Juan has given the real-life proof that it is possible to maintain his own fork as a single person while at the same time adapting important changes from elsewhere. In addition he has contributed back to the main-line Squeak development. From this point of view we should really de-emphasise the negative aspects of competition.
6) This time we have Andreas, Pavel and Juan for the core, Eliot on the VM side and Bert for the Etoys link working together. Others are working on various aspects improving the system. I think this is an opportunity and there is a real chance of success.
7) As an illustration I did a sketch. (see attached PNG file). I think the overlap of the distributions is considerable. As a follow up it would be nice to have some simple statistics like no. of classes per distribution. Number of classes with identical names across distributions. As the picture is very rough somebody might post a more accurate one.
Cheers
Hannes
P.S. Please note that in the meeting report this thread is about Randal says that he wants to contact the other Squeak based projects to talk about a minimal core.
I just came back from the Scheme and Functional Programming Workshop at Montréal, hosted by Marc Feeley and an excellent organisation team. It’s been a fun couple of days putting faces to emails and IRC nicks and attending a handful of pretty interesting talks. Here’s a quick report.
My favourites were the two invited papers. The first day, Olin Shivers presented a pretty cool hack in a delicious talk consisting in actually writing the code he was explaining. Under the title Eager parsing and user interaction with call/cc, he showed us how call/cc is not just an academic toy, but can be put to good use in writing a self-correcting reader for s-expressions on top of the host scheme read (or any other parser, for that matter). He started from the very basics, explaining how input handling and buffering is usually delegated to the terminal driver, which offers a rather dumb, line-oriented service. Wouldn’t it be nice if, as soon as you typed an invalid character (say, a misplaced close paren) the reader complained, before waiting for the whole line to be submitted to read? Well, all we need to do is to implement the input driver in scheme, and he proceeded to show us how. As you know, reading s-expressions is a recursive task, meaning that when you detect invalid input in the middle of a partial s-expression, or want to delete a character, you might find yourself somewhere deep inside a stack of recursive calls and you’ll need to backtrack to a previous checkpoint. That’s an almost canonical use case for call/cc, provided you use it intelligently. Let me tell you that Olin is quite capable of using call/cc as it’s meant to be used, as he immediately demonstrated. I’m skipping the details in the hope that a paper will be available any time soon. As i mentioned, his talk was a beautiful example of live coding: he showed us the skeleton of the implementation and filled it up as he explained how it should work. Olin does know how to write good code, and it was a pleasure (and a lesson) seeing him doing just that. It was all so schemish: a terminal and emacs in the venerable twm: that’s all you need to create beauty.
The second invited talk was by Robby Findler, who gave us a tour of Racket’s contract system, how to use it and the subtleties of implementing it properly. The basic idea dates back to Meyer’s design by contract methodology of the early nineties, and was subsequently explored further by several authors, including Robby. Simple as they sound at first sight, good contracts are not trivial to implement. For instance, it’s vital to assign blame where’s blame is due, and Robby gave examples of how tricky that can get (and how Racket’s contracts do the right thing). Another subtlety arises when you try to write contracts assessing a property of an input data structure (say, you want to ensure that an argument is actually a binary search tree). The problem here is that checking the contract can alter the asymptotic complexity of the wrapped function (e.g., you can go from O(log n) to O(n) in a lookup, an exponential degradation). Racket provides an ingenious fix for that problem, by means of lazy contracts that are checked as the input is traversed by the “real” function.
There was also real-time scheme in Robby’s talk, although in a much more sophisticated way, thanks to Slideshow’s magic, which lets you embed code files and snippets in a presentation, evaluate them and show the results in the same or a new slide. Very elegant. He also used DrRacket a bit during the introductory part of his talk, and i’m starting to understand why some people are so happy with Racket’s IDE: it definitely felt, in his hands, professional and productive. And also kind of fun.
There were also lightning talks. I’m of course biased, but the one i enjoyed most was Andy Wingo’s Guile is OK!, where he showed us how Guile has overcome the problems, perceptual and real, of its first dozen years. For instance, he reminded us how Guile was traditionally a “defmacro scheme”, and he himself a “defmacro guy”… until he studied in earnest Dyvbig’s work and ported his syntax-case implementation to Guile, to become a “syntax-case man” as Guile gained full syntax-case support (i hope i’ll reach that nirvana some day; i still find syntax-case too complex and plagued by unintuitive corner cases (one of them was showed by Aaron Hsu in another lightning talk, where apparently none of us was able to correctly interpret 10 lines of scheme) that make me uneasy; but that’s surely just ignorance on my part). There are many other things that make Guile a respectable citizen of the Scheme Underground, which were also listed in Andy’s talk: i’ll ask him for a PDF, but in the meantime you can just try Guile and see :).
Although this time we didn’t have a talk by Will Clinger, to me it’s always a pleasure to listen to what he has to say, even if only as comments to other people’s talks. For instance, i enjoyed his introduction to Alex Shinn’s R7RS progress report. Will showed us three one dollar coins, of the same size and shape, but different, as he described, in almost everything else. And yet, all three were useful and recognised as (invalid) dollars by the Canadian vending machines at the entrance. He thinks that says something about standards, but he left to us to decide exactly what.
Finally, let me mention that this workshop has alleviated all my quibbles with what i’ve sometimes perceived as a fragmented, almost dysfunctional, community, made up of separate factions following their own path in relative isolation. My feeling during the workshop was nothing of the sort; rather, i’m back with the conviction that there’s much more uniting us that breaking us apart, and that there’s such a thing as a scheme underground ready to take over the world. Some day.
Gofer new
squeaksource: 'MetacelloRepository';
package: 'ConfigurationOfWebTester';
load.
(ConfigurationOfAutotest project version:'1.1') load.
|tester searchButton searchField|
tester := WtSeleniumWebTester new.
tester
appRoot: 'http://pharo-project.org';
browserType: '*firefox';
start;
openUrl: '/'.
searchField := tester textFieldById: 'searchfield'.
self assert: searchField isPresent.
searchButton := tester buttonByXPath: '//input[@title=''Search'']'.
self assert: searchButton isPresent.
searchField text: 'screencasts'.
searchButton click.
tester waitForPageToLoad.
self assert: (tester isTextPresent:'pharocasts').
tester stop.
Gofer new
squeaksource: 'MetacelloRepository';
package: 'ConfigurationOfXMLSupport';
load.
ConfigurationOfXMLSupport load.
|xmlStream xmlDoc photos builder|
xmlStream := 'http://picasaweb.google.com/data/feed/api/all?q=miles+davis&max-results=10' asUrl retrieveContents contentStream.
xmlDoc := XMLDOMParser parseDocumentFrom: xmlStream.
photos := OrderedCollection new.
xmlDoc tagsNamed: #entry do:
[:entry| |title photoUrl|
title := (entry firstTagNamed: #title) characterData.
photoUrl := (entry firstTagNamed: #content) attributeAt: #src.
photos add: (PicasaPhoto new
title: title;
photoUrl: photoUrl)].
builder := UITheme builder.
(builder
newRow: (photos collect:
[:aPhoto|
builder newColumn: {
builder newImage: aPhoto asForm size: 128@128.
builder newLabel: aPhoto title.}]))
extent: 500@400;
wrapDirection: #topToBottom;
openInWindow.
| xmlStream xmlDoc photos builder clickBlock |
xmlStream := 'http://api.flickr.com/services/feeds/photos_public.gne?id=12018791@N06&lang=en-us&format=rss_200' asUrl retrieveContents contentStream.
xmlDoc := XMLDOMParser parseDocumentFrom: xmlStream.
photos := OrderedCollection new.
xmlDoc tagsNamed: #item do:
[:item| | title thumbUrl photoUrl |
title := (item firstTagNamed: #title) characterData.
thumbUrl := ((item firstTagNamed: #media:thumbnail) attributeAt: #url) asUrl.
photoUrl := ((item firstTagNamed: #media:content) attributeAt: #url) asUrl.
photos add: title -> (Form fromBinaryStream: thumbUrl retrieveContents contentStream) -> photoUrl].
clickBlock := [:url :title | | scrollPane |
scrollPane := GeneralScrollPane new
scrollTarget: (builder
newImage: (Form fromBinaryStream: url retrieveContents contentStream)).
scrollPane openInWindow
setLabel: title;
extent: 600@400.
scrollPane color: Color transparent].
builder := UITheme builder.
((builder
newRow: (photos collect:
[:aPhoto|
(builder
newButtonFor: clickBlock
getState: nil
action: #value:value:
arguments: {aPhoto value. aPhoto key key}
getEnabled: nil
label: ((builder newColumn: {
builder newImage: aPhoto key value.
builder newLabel: aPhoto key key})
cellPositioning: #center;
layoutInset: 10)
help: nil)]))
wrapDirection: #topToBottom;
openInWindow)
setLabel: (xmlDoc firstTagNamed: #title) characterData;
extent: 700@680.
I started work of an interface to the CouchDB (MSKCouchDB) – a document/json oriented database from the Apache project. You may get further information about CouchDB at CouchDB at Apache.
In addition to this early interface I updated the JSON wrapper to produce correct string representations of JSON objects.
The software is available at vastgoodies as usual.
And as usual – this is work in progress and it will change between the version, but the code gives you the ability to play with that database.
Almost full house today. Only Chris was missing because he is on vacation. We had a good meeting and discussed many issues.
Money transfers to SFC. Andreas has been extremely busy at work, but will be able to pick it up again now.
Squeak 4.2 release: Date and Scope. Setting up the infrastructure for Community Supported Packages and start picking them. We currently don’t have an active Release Team. If somebody steps up to work on this, we can start planning. Please volunteer!
Documentation. The community has previously shown interest in having a Documentation Team, so Jecel will post to squeak-dev to check up on the current volunteers and seek out new ones.
Randal suggested doing a wide survey on usage of Squeak and Squeak derivatives to help in planning and decision making. This would include Pharo, Etoys, Cobalt, Scratch, Cuis and others. We’d need input from groups and organizations that are not members of the squeak-dev list. Therefore we need to approach members of those groups and organizations for coordination. We’ll also need cooperation from everybody to get all users of Squeak and derivatives to be aware of this effort, and to consider answering the survey. Randal will start contacting some of these groups for coordinating.
Bert will attend to Esug 2010 partly on behalf of the Squeak Board as a Squeak PR activity. We decided to financially support his trip.
Andreas and Juan would like to find a way to leverage the work done to reduce Cuis for Squeak. Ideally, Squeak would become a smaller kernel, about the size of Cuis, and everything else would be in optional packages that would be unloadable. Comments, suggestions, volunteers, are all welcome!

Andreas Raab noted on the Squeak-dev mailing list and on his blog that Teleplace have decided that Squeak 4.1 is sufficiently stable to use as the basis for their commercial software. They made the massive leap from 3.8 all the way to Squeak 4.1 in this release of their Teleplace Enterprise Server 3.5, which is used to host online collaboration environments.
It appears to have been a painless and successful activity, and is a massive vote of confidence in the ongoing changes to Squeak. If you want to see the new product in action, there’s a free trial version available at http://www.teleplace.com/trial/signup.php.