The Artima Developer Community
Sponsored Link

Agile Buzz Forum
Smalltalk compared

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
James Robertson

Posts: 29924
Nickname: jarober61
Registered: Jun, 2003

David Buck, Smalltalker at large
Smalltalk compared Posted: Jan 1, 2006 2:31 PM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by James Robertson.
Original Post: Smalltalk compared
Feed Title: Cincom Smalltalk Blog - Smalltalk with Rants
Feed URL: http://www.cincomsmalltalk.com/rssBlog/rssBlogView.xml
Feed Description: James Robertson comments on Cincom Smalltalk, the Smalltalk development community, and IT trends and issues in general.
Latest Agile Buzz Posts
Latest Agile Buzz Posts by James Robertson
Latest Posts From Cincom Smalltalk Blog - Smalltalk with Rants

Advertisement

Alan Lovejoy pointed me at a page that compares Java and Ruby, and suggested that I provide Smalltalk examples. The Smalltalk is going to be a lot like the Ruby code - both are dynamic languages with what people now call "duck typing".

The page sets up a simple example with a pair of classes - Word and Definition:

Class Definitions

You can go to the linked site to see the Java and Ruby classes - here are the class definitions in Smalltalk:

 

Smalltalk.Words defineClass: #Word
	superclass: #{Core.Object}
	indexedType: #none
	private: false
	instanceVariableNames: 'spelling partOfSpeech definitions synonyms
'
	classInstanceVariableNames: ''
	imports: ''
	category: 'Words'

Smalltalk.Words defineClass: #Definition
	superclass: #{Core.Object}
	indexedType: #none
	private: false
	instanceVariableNames: 'word definition exampleSentence '
	classInstanceVariableNames: ''
	imports: ''
	category: 'Words'


In Ruby, it looks like you can define getters/setters in the class definition. In Cincom Smalltalk, the environment does the same thing for you, offering to define getters/setters (and a default initializer) as part of creating the class. So in step one, we get a small bit further than Ruby, due to the tools we have. As to the methods, let's start with the initiazers - I had to modify the default initializer so that it matched the code in the example page - first Definition, then Word:

 


initialize
	"Initialize a newly created instance. This method must answer the
receiver."

   word := nil.
	definition := nil.
	exampleSentence := Set new.

initialize
	"Initialize a newly created instance. This method must answer the
receiver."

   spelling := nil.
	partOfSpeech := nil.
	definitions := Set new.
	synonyms := Set new.


So on to the meat - the tools mostly created what I needed, and I just had to modify the defaults. The class definitions have a lot of things we don't need to worry about right now - I created them via the class creation wizard, seen below:

Smalltalk Class Defining

That wizard removes a lot of the typing drudgery of class creation - mind you, old hands (like me) can still do it the "old fashioned way" in the browser. Let's define the #addDefinition: and #addSynonym: methods now - they auto-check for duplicates by being Set objects:

 

addDefinition: definitionString
	self definitions add: definitionString.

addSynonym: synonymString
	self synonyms add: synonymString.


Now creating a new instance is easy - we create a class side convenience method for creating new words::

 

newWord: wordString partOfSpeech: partOfSpeechString
	^self new
	       spelling: wordString;
	       partOfSpeech: partOfSpeechString.


Some explanation - the #new method creates the new object and the #spelling: setter is immediately sent to that. The semi-colon is a cascade, which allows us to send the #partOfSpeech: setter to the same object as the first message went to. Note the name of the method: #newWord:partOfSpeec:. It's self describing. Instead of #new, we can create our own class creation protocol that is self explanatory. Now to use it:

 

"Create a Word"
word := Word newWord: 'ebullient' partOfSpeech: 'adjective'.
word addDefinition: 'Overflowing with Enthusiasm'.
word addDefinition: 'Boiling up or over'.


Notice how clear that is - and how much clearer it is than the Java example on that page (IMHO, it's clearer than Ruby, simply because of the keyword message). Keyword messages make it possible to make your code very intention revealing - which is a good thing. This is part of why Smalltalkers tend to send you to the source instead of to some doc - because the source (if done decently) is documentation. Yes, you can write bad Smalltalk, and I've done plenty of that myself :)

If you look at the explanation of collection protocol on that page, everything he says about Ruby's collections applies to Smalltalk. We can add things into the collections without fear of them blowing up. In fact, if we make sure that the things we add are polymorphically (i.e., message signature) identical to each other, it doesn't matter what they are at all. I take great advantage of that in BottomFeeder.

Moving past the example, the linked page goes into Ruby iteration. We have the same power in Smalltalk - we can iterate over any kind of collection like this:


someCollection do: [:each | each doSomethingHere]. 

The [ ] syntax is for a closure - the first place you'll find them in Smalltalk is in the logical operations (ifTrue/ifFalse, etc). They provide a lot more power though, and the fact that they are used to define the common operations (doWhile, et. al.) is telling - those operations are not reserved word syntax in Smalltalk - they are messages. Which means that you can define your own versions. I've seen plenty of people add #do: to class Object so that any object can be treated like a collection, for instance.

The entire discussion of duck typing applies to Smalltalk as well. Rather than formal interfaces, Smalltalkers worry about polymorphic equivalence. You can implement a matching protocol between any kind of objects that make sense, and then use them together. A common example used in intro classes is a FinancialInstrument - without regard to inheritance, just define a financial protocol amongst all the objects, and then use it - for instance, a #currentValue method might determine what an instrument is worth right now - and be very different for various objects that share little else. Even so, they can all be placed in a collection, and current worth calculated like this:


instruments inject: 0 into: [:subTotal :next | subTotal + next currentValue].

The comment for #inject:into:, since it may not be clear to non-Smalltalkers:

Accumulate a running value associated with evaluating the argument, binaryBlock, with the current value and the receiver as block arguments. The initial value is the value of the argument, thisValue.

That pretty much covers what the IBM page went into. The main difference you're going to see in Smalltalk is that it's not file-oriented. You work in an image, and you create code in a browser. You can save packages out into loadable modules though (we call them parcels here at Cincom) - and this server is fired up exactly that way. I have a basic image which starts, grabs a set of parcels, loads them, configures itself as a set of post-load actions, and then goes. Interested? Grab the Cincom Smalltalk non-commercial here.

Read: Smalltalk compared

Topic: Revolution ready for production? Previous Topic   Next Topic Topic: Blog Spam for all

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use