
Why I love Smalltalk - mordaroso
http://pupeno.com/blog/why-i-love-smalltalk/
======
hboon
It covers some of the minimal syntax of Smalltalk but didn't touch on
Smalltalk images, which is a major signature of Smalltalk.

A Smalltalk image contains every Smalltalk object. This includes classes
(which are Smalltalk objects), instances of the classes, source code, the
current running state, everything. You work within the image and interact with
it.

Think of the image as a copy of your IDE, along with the compiler, your
current project's source code, the compiled classes, methods, everything. You
can save your image (state) at any time, not unlike the sleep feature of
Windows and Mac. It's a live environment. During a programming session, you
edit and save the code of class (it's automatically compiled) and every
instance of that class is updated. This sounds like what you commonly have in
many dynamic languages, but Smalltalk takes it to an extreme. You can re-
configure your "IDE" as you go along since they are running in the same image,
all the classes and objects are accessible. Or you can set breakpoints and
step through code, changing code on the fly and resuming, all without stopping
the "program" and starting again. Not unlike a graphical REPL.

Does anyone know if there's a similar tool utilizing the same concept other
than Self?

~~~
pupeno
I consider the image an implementation detail of Squeak or the original
Smalltalk-implementation. You can implement Smalltalk the language without the
image: <http://smalltalk.gnu.org/>

------
draegtun
_The syntax is quite unique to Smalltalk. The message, otherwise known as
“method call” in other languages, is called show: (including the colon) and it
takes an argument._

 _self_ also uses this method call syntax. However this syntax can get quite
confusing, see this example from
<http://en.wikipedia.org/wiki/Self_(programming_language)>

    
    
      valid: base bottom between: ligature bottom + height and: base top / scale factor.
    

Smalltalk version provided gets even more verbose:

    
    
      valid := self base bottom between: self ligature bottom + self height and: self base top / self scale factor.
    

Personally I prefer Io message syntax because it has far less ambiguity. See
_Why not use an infix message syntax like Smalltalk?_ in the FAQ -
<http://iolanguage.com/about/faq/>

~~~
eterps
So, what would the syntax be in Io? Like this?

    
    
      valid := base bottom between(ligature bottom + height, base top / scale factor)

~~~
draegtun
Yes, unless I've totally misunderstood that Self/Smalltalk code!

Also instead of _between_ method with two args you could also create an _and_
message/method:

    
    
      valid := base bottom between(ligature bottom + height) and(base top / scale factor)

------
JoachimSchipper
Copy of the text, since it's hard to reach the site itself [any layout errors
should be assumed to be mine]:

This post was extracted from a small talk I gave at Simplificator, where I
work, titled “Why I love Smalltalk and Lisp”. There should be another post,
“Why I love Lisp” following this one.

After I learned my basic coding skill in more or less traditional languages,
like C, C++, Python, there were four languages that really tought me something
new. Those languages changed my way of thinking and even if I never use them,
they were worth learning. They are:

* Smalltalk

* Lisp

* Erlang

* Haskell

You can probably add Prolog to that list, but I never learned Prolog. This
post is about Smalltalk.

My goal is not to teach Smalltalk but to show things that you can do with
Smalltalk that you can’t do with any other language (disclaimer: surely other
languages can do it, and we’ll call them Smalltalk dialects). Nevertheless I
need to show you some basics of the language to be able to show you the good
stuff, so here we go, a first program:

    
    
        1 + 1
    

That of course, evaluates to 2. If we want to store it in a variable:

    
    
        m := 1 + 1
    

Statements are finished by a period, like this:

    
    
        m := 1.
        m := m + 1
    

In Squeak, a Smalltalk implementation, there’s an object called Transcript and
you can send messages to it to be displayed on the screen. It’s more or less
like a log window. It works like this:

    
    
        Transcript show: 'Hello world'
    

and it looks like this:

[Squeak transcript showing the result of Transcript show: 'Hello World']

The syntax is quite unique to Smalltalk. The message, otherwise known as
“method call” in other languages, is called show: (including the colon) and it
takes an argument. We can run it 10 times in a row with the following snippet:

    
    
        10 timesRepeat: [
          Transcript show: 'Hello world'
        ]
    

There you can start to see how Smalltalk is special. I’m sending the message
timesRepeat: to the object 10, an Integer. Doing something N times repeatedly
is handled by the Integer class, which if you think about it, makes sense.

The second interesting part, is the block. The part inside squared brackets.
You might thing that’s the equivalent of other language’s block syntax, like
in this Java example:

    
    
        for(int i=1; i<11; i++) {
          System.out.println("Hello world");
        }
    

but Smalltalk version’s is a bit more powerful. It’s a real closure. Look at
this:

    
    
        t := [
          Transcript show: 'Hello world'
        ]
    

Now I have a variable named t, of type BlockClosure, and I can do anything I
want with that variable. If I send it the class message it’ll return it’s
class:

    
    
        t class
    

and if I sed it the value message, it’ll execute and leave a “Hello World” in
the transcript:

    
    
        t value
    

Let’s see some more code. A message without any arguments:

    
    
        10 printString
    

a message with one argument:

    
    
        10 printStringBase: 2
    

and a message with two arguments:

    
    
        10 printStringBase: 2 nDigits: 10
    

Isn’t it cute? That method is called printStringBase:nDigits:. I never seen
that syntax anywhere else; well, except in Objective-C, which copied it from
Smalltalk.

Enough toying around, let’s start building serious stuff. Let’s create a
class:

    
    
        Object subclass: #MyClass
               instanceVariableNames: ''
               classVariableNames: ''
               poolDictionaries: ''
               category: 'Pupeno'
    

Notice that a class is created by sending a message to another class telling
it to subclass itself with the name and a few other arguments. It’s a message,
a method call like any other. Object is a class, classes are objects. The
object model of Smalltalk is a beauty but that’s a subject for another post.

Now that we have a class, let’s create a method called greet: in that class.

    
    
        greet: name
          "Greets the user named name"
         
          | message |
         
          message := 'Hello ', name.
          Transcript show: message.
    

In that method definition first we have a comment for the method, then the
list of local variables within pipes (“|”), and then the implementation, which
sets the variable message to contain “Hello ” and the comma concatenates name
to it. Then we just send it to the transcript.

It looks like this:

    
    
        MyClass greet method
    

Ok, let’s use it:

    
    
        m := MyClass new.
        m greet: 'Pupeno'
    

To create an object of class MyClass, we send the new message to that class.
There’s no new keyword like in Java. new is just a method. You can read it’s
code, override it, etc. Don’t mess with it unless you really know what you are
doing.

Actually, if you think about it, we haven’t seen a single keyword. Look all
the code we wrote without having to memorize any keywords! What’s even more
important is that by now you essentially now Smalltalk. That’s all there is,
but like LEGO bricks, this simple and small building blocks allow you to build
whatever you want.

Yes, that’s it, that’s all there is to it. We already saw that Smalltalk
doesn’t need loops, it has integers and that class implements the timesRepeat:
message which allows you to do something N times. There are many other looping
methods here and there.

What about the if keyword you ask? Surely Smalltalk has an if? Well, no, it
doesn’t. What you can recognize as an if is actually implemented in Smalltalk
using the same mechanism of classes and message passing you saw already. Just
for fun let’s re-implement it.

We starte by creating the class PBoolean and then two classes inheriting from
it, PTrue and PFalse.

    
    
        Object subclass: #PBoolean
               instanceVariableNames: ''
               classVariableNames: ''
               poolDictionaries: ''
               category: 'Pupeno'
     
        PBoolean subclass: #PTrue
               instanceVariableNames: ''
               classVariableNames: ''
               poolDictionaries: ''
               category: 'Pupeno'
     
        PBoolean subclass: #PTrue
               instanceVariableNames: ''
               classVariableNames: ''
               poolDictionaries: ''
               category: 'Pupeno'
    

For the class we created before, MyClass, we define a equals: method that will
return either true or false, or rather, PTrue or PFalse.

    
    
        equals: other
          ^ PTrue new
    

The little hat, ^, means return. For now, just a hardcoded true. Now we can do
this in the workspace:

    
    
        m1 := MyClass new.
        m2 := MyClass new.
        m1 equals: m2
    

and get true, that is PTrue, as a result. We are getting close but no if yet.
How should if look like? It’ll look like something like this:

    
    
        m1 := MyClass new.
        m2 := MyClass new.
        (m1 equals: m2) ifTrue: [
          Transcript show: 'They are equal'; cr
        ] else: [
          Transcript show: 'They are false'; cr
        ]
    

and you can start to imagine how to implement it. In PTrue we add the method:

    
    
        ifTrue: do else: notdo
          ^ do value
    

That method basically takes two parameters, evaluates the first one and
ignores the second one. For PFalse we create the oposite:

    
    
        ifTrue: notdo else: do
          ^ do value
    

and that’s it. A working if! If you ask me, I think this is truly amazing. And
if you check Squeak itself, you’ll find the if is actually implemented this
way:

    
    
        True's ifTrue:ifFalse:
    

If your programming language allows you to create something as basic as the if
conditional, then it allows you to create anything you want.

~~~
mbrzuzy
Appreciated :)

I'm unable to access the site at all right now. HN traffic might have brought
it down.

~~~
pupeno
Indeed it has! My server is smoking :P

------
redxaxder

      equals: other
      ^ PTrue new
    

The implementation of ifTrue isn't done. The branching was just deferred to
the equals function, which has to somehow choose between PTrue and PFalse.

Will it take advantage of the ifTrue function you're building? Will it resort
to some nasty arithmetic? Will it call some baked-in feature of smalltalk?
Without an answer here, the "implementation" of _if_ is just an illusion.

~~~
gjm11
I don't think that's fair. Being able to implement _if_ doesn't mean that the
entire remainder of the system is built without any conditional instructions
anywhere in its implementation. (The point, after all, isn't some sort of
mystical purity; it's that if you can implement _if_ then you can probably
also implement whatever other control structures you happen to fancy. Which
you can.)

~~~
redxaxder
To implement a usable _if_ , you need to tie it to some form of logical
branching. Haskell can tie it to pattern matches. C compiles them to
conditional jumps in asm. The asm jump instructions are implemented in
hardware. The meat of the _if_ definition lies in how you tie it to whatever
form of conditional behavior your language has. This is missing from the
article.

Smalltalk (presumably) has a form of logical branching in it somewhere. To
finish the _if_ , just pick one.

For a satisfying conclusion, you want to use one that doesn't already look
like an _if_ statement.

~~~
more_original
> Smalltalk (presumably) has a form of logical branching in it somewhere. To
> finish the if, just pick one.

It uses dynamic binding.

In Java it would look like something this (but it's less useful without proper
closures):

    
    
      abstract class Bool {
        void ifTrue(Runnable f, Runnable g); 
      }
    
      class True extends Bool {
        void ifTrue(Function f, Function g) {
          f.run();
        }
      }
    
      class False extends Bool {
        void ifTrue(Function f, Function g) {
          g.run();
        }
      }
    

Then, given a variable

    
    
      Bool b;
    

the if-then-else becomes

    
    
      b.ifTrue(new Runnable() {
          public void run() {
             System.out.println("It's true!");
          }
        }
      , new Runnable() {
          public void run() {
             System.out.println("Not true!");
          }
        }
      );

It's a bit more verbose, though...

~~~
more_original
s/Function/Runnable/g

------
xradionut
I like Smalltalk, but like Forth and Lisp it's just not practical in most of
my computing tasks, career or hobby-wise. It's a shame that Smalltalk didn't
evolve enough to challenge Java in the '90s. But my buds that knew it well and
also had some C chops are in demand as Objective C coders.

~~~
Xurinos
The word you were looking for was "popular", not "practical". Our industry is
largely internally rife with fads, marketing, and anecdotal discussion, rather
than objective analysis and scientific measurement.

And then, this statement is just blaming the tools rather than the developers.
"C chops" means less than "has good logical thinking skills and exposure to
many programming approaches/patterns".

~~~
pupeno
I disagree. Every time I tried to put together an app with any of Common Lisp,
Scheme or Smalltalk I found myself fighting idiosyncrasies unrelated to my
app. Obviously it can be done, but the advantage of using those languages
start to diminish. It's not about popularity, it's about practicality. I found
making Java web applications unpractical in a similar way although I haven't
tried enough.

~~~
Xurinos
This is an example of an anecdotal piece of evidence, and without a close
examination of the "idiosyncrasies" and your definition of "practical", it is
difficult to have a discussion. I recognize, though, that people have
different opinions on what language is most familiar/useful to them, and at
the end of the day, people get work done and make money, whatever they use.

~~~
pupeno
Yes, it's only anecdotal, but it's not that someone didn't allow me to use the
language because it's name didn't start with "J" and ended with "ava". I tried
and failed. Other people had similar experience. There are some things to
point out that many people mention as problematic, like Squeak's image.

