> Smalltalk’s key advantage as a productive language and learning tool is that it strips away most, if not all, of the cognitive stress in mainstream object-oriented languages such as Java… It simply gets out of your way so that you can focus all your attention on the problem or application at hand…
That's the magic of Lisp, and specifically, Common LISP and it's object library give me.
Smalltalk has some large drawbacks compared to CL, that have made me hate maintaining programs written in it.
For the older Smalltalk the company was using: variables all being global, and also sharing function namespace.
That was truly hell in a dynamic language.
I would also say that Smalltalk comes with some really annoying reserved syntax you have to keep in mind, that I don't appreciate when it creeps into modern languages.
Namely:
* Shared vars must begin with uppercase
* Local vars must begin with lowercase
Due to it's dynamic nature, this may not cause any errors immediately. Thankfully preserved state can let you rollback easily enough, if you weren't running in production.
I also don't find the syntax as quick for my brain to parse as C, Lisp or something like Ruby.
m := FileLocator home / 'Music'.
m exists.
m isDirectory.
m allChildrenMatching: '.mp3'.
It is readable.
But my mind gets caught up trying to predict the flow: It has to if-like statements in this example, exists and ifDirectory, where does the flow get handled?
Two examples, just with a different syntax, that I find easier:
m = FileLocator(home / 'Music');
if(exists(m) && isDirectory(m)) {
return allChildrenMatching(m, '.mp3));
}
}
(define m
(FileLocator home / 'music'))
(if (exists m)
(if (isDirectory m)
(allChildrenMatching '.mp3')))
In short, Smalltalk has a bad history to overcome, whilst offering few benefits over other languages that share the same competing space.
Bias: 12 months working with a 1980s Smalltalk powering scientific equipment.
For most Smalltalks I am familiar with, using uppercase for globals and pool variables and lowercase for local variables is just a convention.
The Smalltalk and C code are not equivalent. The C code version of the Smalltalk would be:
m = FileLocator(home / 'Music');
exists(m);
isDirectory(m);
return allChildrenMatching(m, '.mp3');
while the Smalltalk version of your C code would be:
m := FileLocator home / 'Music'.
(m exists and: [m isDirectory]) ifTrue: [ ^ m allChildrenMatching: '.mp3']
The use of the keyword syntax for control structure does make things look backwards compared to other languages, but the semantics are the same. So you can have exists and isDirectory be functions that return booleans in both C and Smalltalk or have them be some kind of filtering/setter operation in both languages.
I don't have enough experience with Smalltalk to directly comment on your criticisms. I have experimented with Squeak and Pharo, but nothing earlier. Do you know if the more modern Smalltalks suffer from the same weaknesses you see in the 1980s Smalltalk you had to deal with?
Squeak kinda does, as it doesn't allow for locals within blocks.
Basically a variable is either shared or local. Locals were usually unimplemented or poorly implemented in the past.
As to sharing variables with functions in a namespace, that's implementation defined. A Smalltalk without a longer history probably doesn't do this,because the author/s are usually familiar with languages that don't.
>Squeak kinda does, as it doesn't allow for locals within blocks.
All Smalltalks allow this by putting the variable names in a pair of "|" after the "[" starting a zero-arg block or the "|" terminating its argument names:
> Basically a variable is either shared or local. Locals were usually unimplemented or poorly implemented in the past.
Traditionally block argument and block local vars shared the same "temp frame" with the method they were defined in, meaning that while indeed local, they were only local to their method, not the block itself. But Squeak, Pharo, Gemstone, VW, all have compilers and VMs that support real closures, where each block introduces a new scope and blocks can be written to evaluate recursively.
That's the magic of Lisp, and specifically, Common LISP and it's object library give me.
Smalltalk has some large drawbacks compared to CL, that have made me hate maintaining programs written in it.
For the older Smalltalk the company was using: variables all being global, and also sharing function namespace.
That was truly hell in a dynamic language.
I would also say that Smalltalk comes with some really annoying reserved syntax you have to keep in mind, that I don't appreciate when it creeps into modern languages.
Namely:
* Shared vars must begin with uppercase
* Local vars must begin with lowercase
Due to it's dynamic nature, this may not cause any errors immediately. Thankfully preserved state can let you rollback easily enough, if you weren't running in production.
I also don't find the syntax as quick for my brain to parse as C, Lisp or something like Ruby.
It is readable.But my mind gets caught up trying to predict the flow: It has to if-like statements in this example, exists and ifDirectory, where does the flow get handled?
Two examples, just with a different syntax, that I find easier:
In short, Smalltalk has a bad history to overcome, whilst offering few benefits over other languages that share the same competing space.Bias: 12 months working with a 1980s Smalltalk powering scientific equipment.