Feeds:
Posts
Comments

Archive for the ‘Squeak’ Category

A few weeks ago I discovered the Code Kata website. Working through a few of these exercises may help me improve my very basic squeak which I have wanted to learn properly for a while. As a recovering perler, the first kata that really appeals is kata 4 (data munging).

I started with the following:

  1. Damien Cassou’s fantastic Squeak development image with code completion, syntax highlighting and much more. That is available here.
  2. A pure smalltalk regex package. If you download this mcz and drag it and drop it onto your image you are good to go.
  3. The Terse guide to Squeak

After working through the problems the first time in the workspace, I wanted to come up with a more generic solution. The obvious one is to have a stream method that iterates over lines. There are a number of ways of doing this. With some inspiration from the STL algorithm library here is a class with a single class method:

StreamAlgorithms>>class

on: aStream eachLine: aBlock
	| line |
	aStream position: 0.
	[ (line := aStream nextLine) isNil ] whileFalse: [
		aBlock value: line
	]

This is used as following (actual solution to the Kata elided):

| fp |
Transcript clear.
fp := CrLfFileStream readOnlyFileNamed: 'c:/dev/weather.dat'.
StreamAlgorithms
       on: fp
       eachLine: [ :line | Transcript show: ('[', line, ']') ; cr ].
fp close.

Alternatively, here is a class that wraps a stream.

Object subclass: #ExtendedStream
	instanceVariableNames: 'stream'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Katas'

These are the instance methods

stream
	^ stream

stream: anObject
	stream := anObject

eachLine: aBlock
	| line |
	self stream position: 0.
	[ (line := self stream nextLine) isNil ] whileFalse: [
		aBlock value: line
	]

And the class methods…

ExtendedStream>>class

"'Constructor'"
on: aStream
	^ (self new) stream: aStream

"I liked this class method from StreamAlgorithms"
on: aStream eachLine: aBlock
	| line |
	aStream position: 0.
	[ (line := aStream nextLine) isNil ] whileFalse: [
		aBlock value: line
	]

The client code for this is:

Transcript clear.
fp := ExtendedStream on: (CrLfFileStream readOnlyFileNamed: 'c:/dev/weather.dat').
fp eachLine: [ :line | Transcript show: ('[', line, ']') ; cr ].
fp close.

Possibly the best way is to put eachLine: as an instance method on the stream class but I’m not comfortable messing with the core libraries just yet.

Read Full Post »

Learning Squeak

Despite the recent articles on Scheme / CGI, I’m still very interested in the Seaside web framework. I’ve worked through a couple of the tutorials up until the point at which I thought I was fairly comfortable. However, when I try to write my own app, I come unstuck right at the very beginning. I think I know why this is, and that is because my Smalltalk is far too weak. Seaside makes it easy to build a nice web-app, but you to have good enough Smalltalk to be able to implement your model.

One of the features that I found very interesting me when I started reading about Smalltalk was the extremely small number of keywords and the complete lack of precedence rules (amongst other things). This convinced me that I didn’t need to spend any effort in actually learning Smalltalk itself – I would be able to pick it up while learning Seaside. However, initially, the learning curve of Smalltalk is steeper, not shallower than other environments.

In most languages, you can learn the language, then the libraries and then start picking up the idioms and there is a fairly smooth progression. In Squeak, you have to learn the different editor windows and various ways of importing code into the image. The fact that loops and conditional is implemented in the libraries obviously doesn’t mean that you don’t need to learn about loops and conditionals. You just need to learn more of the libraries to get started than in other languages.

There are some excellent resources on learning Smalltalk the language plus the appropriate libraries of course. I chose the A Little Smalltalk book and am slowly making my way through it. My next plan is to start making a Smalltalk cheatsheet.

Read Full Post »

Is Squeak Smalltalk Slow?

This is a question I’m currently interested in knowing the answer to. I don’t know much about Smalltalk or Squeak unfortunately, but from what I do know, it seems like a good fit for the latest idea I have. The primary advantage over other environments I know, is that the image is available at all times. If an image receives a message it can’t handle because of a programming error, it can enter the debugger and wait for me to come along and debug it. I think that a decent Common Lisp implementation will offer me similar functionality.

Unfortunately, playing around with a new language for a couple of days gives a very limited idea of what it will be like to use it to develop a medium-sized application. For me, during the initial stage of investigation, it is very important to know whether it is worth taking the time with very quickly so that as little time is wasted as possible. Unfortunately, Squeak is a little harder to get to grips with than most languages I am familiar with as it is necessary to learn the IDE at the same time as the language. It is not possible (as far as I know) to simply enter a hello world program into a textfile and execute it.

The first script I entered into the Workspace (which is kind of a scratchpad for exploring new ideas) displayed the numbers from 1 to 200 on to the transcript, which is a kind of logging window. Here is the code to do that along with a timing method. If you highlight thecode and select “print it” from the menu, it tells you how long it took to run.

Time millisecondsToRun: [1 to: 200 do: [:i | Transcript show: i ; cr]]

This was the response: 10335

Ouch! 10 seconds. This is by far the worst performance I’ve ever seen in any language including BBC BASIC on a 2MHz machine. I was certain I must be doing something wrong so I asked on the Squeak beginners list. Unfortunately, it seems that it really is that slow. No-one has made any effort to tune the performance. Here is the comment from the Transcripter class:

"Transcripter is a dog-simple scrolling stream with display.  It is intended to operate with no
support from MVC or color in a minimal, or headless version of Squeak.  No attention has been
paid to appearance or performance."

Okay. Well that is a pity – it is one of the first parts of the Squeak people will see and I would have thought that it would put a few people off. Anyway, the “everything is an image” is still selling me so I try to see how long it takes to write 10,000 numbers to a file.

| myFile ios |
ios := ReadWriteStream on: ''.

Transcript show: 'Populate Buffer: ',
        (Time millisecondsToRun: [
                1 to: 10000 do: [
                        :i | ios nextPutAll: ((i asString) , String crlf)
                        ]]) asString , ' millseconds' ; cr.

MessageTally spyOn: [
 	1 to: 10000 do: [
 		:i | ios nextPutAll: ((i asString) , String crlf)]].

Transcript show: 'Position: ', (ios position) asString ; cr.

myFile := StandardFileStream fileNamed: 'c:/test.txt'.

Transcript show: 'Output Buffer: ',
                    (Time millisecondsToRun: [
        myFile nextPutAll: (ios contents)]) asString,
     ' milliseconds' ; cr.

myFile close.

The MessageTally spyOn: is a nice profiler to see where it is spending its time – it is not really part of the initial test.

This produced the following output on the Transcript:

Populate Buffer: 275 millseconds
Position: 58894
Output Buffer: 9 milliseconds

Hmmm… is 275 milliseconds good or bad? I wrote a quick perl script and ran it with Cygwin.

use strict;open (FH, "> t3.txt") || die "Error: Can't write to file";
 for (my $i = 0; $i < 10000; ++$i) {
     print FH "$irn";
 }
 close FH;

It ran in 0.061s – more than 4 times faster than the Squeak. Well, this is not very good at all. MzScheme and Chicken Scheme both produced results similar to the Perl. Asking on the mailing list again, it seems that the integer to string conversion is implemented in Squeak for flexibility whereas [it is suspected that] all the other languages use C libraries.

Now, I’m not the sort of person who is in favour of premature optimisation, but if all the primitives are 4 times slower than Perl for reasons of flexibility that seems like a huge performance hit. It seems like it is harder to drop into C from Squeak than it would be from other scripting languages and Perl speed is about as slow as I like to go normally anyway. Maybe further investigation would reveal that the Transcript and integer to string comparisons are unusually slow. However, I have to balance the time spent investigating new programming languages is time I’m not spending developing my application.

Read Full Post »

Follow

Get every new post delivered to your Inbox.