A declarative model of Smalltalk (was Re: [DOCS] SUnit tests)

Nevin Pratt nevin at smalltalkpro.com
Sat Feb 22 20:21:51 UTC 2003

Over the years I have read Allen's papers (and read his posts) 
concerning a declarative Smalltalk, and I've tried to weigh in and form 
my own opinion.  Over all of those years, Allen has not convinced me of 
the value of the declarative approach, but then again, I have not been 
convinced he is wrong either.  I am simply undecided.

However, I *do* take issue to the implied assertion that the current 
imperative approach used by the major Smalltalk's  necessitates any less 
(or even any more) reproducable "programs" than the declarative 
approach.  But let me briefly introduce some definitions of the 
components of a declarative "program" before I attempt to defend the belief:

1. A "word" is a sequence of non-white space tokens within the 
declaration of the "program" (and "white space" has the classic 
definition we are all used to).

2. A "vocabulary" is a unique set of words.

3. A "language" is a vocabulary coupled with a unique meaning of each 
word of that vocabulary.

4. Any program declaration is necessarily written in a "language", as 
defined above.

Since above I said a vocabulary is a *unique* set of words, this means 
that adding or removing a word to or from the vocabulary creates a new 
language, per the above definitions.

Since above I said a language is a vocabulary coupled with a *unique* 
meaning of each word, this means that changing the meaning of a given 
word creates a new language, per the above definitions.

Given the above definitions, then, one of the first things we discover 
is that the act of programming is the same thing as the act of "language 
designing".  You are extending an existing language in a domain-specific 
direction (i.e., introducing new words to the vocabulary, whether they 
are functions, prodedures, methods, or whatever), and in so doing, you 
are creating a new language as a side-effect, for the simple reason that 
your "new" language has a greater (and sometimes lessor) set of words 
than what you started with, and you may have even altered the "meanings" 
of some of the existing words in the process.  Either of these acts 
result in a new "language" (using the definition of "language" from 
above), even though you may be starting from a given base language when 
you do it.  Your existing "base" language might be the native 
instruction set understood by the CPU you are programming on, or on some 
Virtual Machine, or any other form of a "language", but you will always 
be building on a base language of some sort.

Now, as we know, many languages differentiate intrinsic words within the 
vocabulary of the language from the programmer-defined words.  But many 
languages (such as Smalltalk) do not differentiate them.  

Given the above definitions, a Smalltalk "program" (or any other program 
in any language) consists of *every* word of the vocabulary of the 
"program", coupled with the meaning of every word.  And because 
Smalltalk does not differentiate *who* introduced the word into the 
vocabulary (intrinisic or programmer defined), it is irrelevent whether 
"Programmer A" introduced the word to the vocabulary, or "Programmer B". 
 Likewise, it is irrelevent whether "Company A" introduced it, or 
"Company B".  Thus, a complete "program" necessarily has to either (1) 
include *every* word of the vocabulary of the program, and the 
definitions of those words, or (2) assume that such a program is merely 
an extension of an existing language (or program).  Actually, two 
paragraphs above I argued that you will always be building on a base 
language, which would mean that #1 isn't even possible, and that your 
only option is to assume that such a program is merely an extension of 
an existing language (or program).  But I won't actually make that 
assertion (yet).

Now, if such a "program" includes every word of the vocabulary of the 
program (assuming that it is even possible to do this, and I suggested 
above that this option isn't even possible), together with the 
definitions of those words, I personally don't see any advantages (or 
disadvantages) of comparing this with an image-based approach, since 
everything has to be included anyway.

And, if it is just an extension of an existing language, then it 
necessarily has the same "initial state sensitivity" that the imperative 
approach has, because it is expecting to extend a known, existing (i.e., 
"static" and unchanging) base language.  If the base language that it is 
extending is different from that which it was designed to extend, you 
have exactly the same state-related problems that you see with the 
imperative approach.  And, in the imperative approach, if you start from 
a known base "language", then a known sequence of expressions applied to 
that base *will* reliably reproduce the "program", just as the 
declarative approach will.

When merely "extending" an existing base language, both approaches 
require that you know where you are starting from, consequently neither 
approach results in any theoretical advantage towards program 
reproducability.  That's my opinion.

I could say more, but suffice it to say that I remain unconvinced that 
any declarative approach has any theoretically advantage (or 
disadvantage) over the classic Smalltalk imperitave approach.


Allen Wirfs-Brock wrote:

> At 04:00 AM 2/22/2003 -0500, Jeff Read wrote:
>> When the compiler and parser are tightly integrated with the runtime 
>> of the language, instructing the language to add program parts to its 
>> currently running program often becomes the norm, rather than 
>> crafting everything declaratively in an editor and then running it 
>> through a compiler.
> I think you half get and half miss the point.  Using a declarative 
> approach to Smalltalk in no way implies using an editor to create 
> source files. As I previously mentioned, Smalltalk browsers generally 
> present a declarative model of Smalltalk programs to the programmer 
> who creates and views class and method definitions/declarations (a 
> class definition is (partially) presented as a message expression but 
> to most users  that's just  syntax  which is  treated  as a 
> declaration). The issue is more related to what happens when the user 
> clicks "accept".  In a classic Smalltalk-80 system the browser uses 
> the declaration to imperatively side-effect the  running system and 
> then essentially forgets the declaration. In a declarative Smalltalk 
> environment the  browser records the declaration  as a  primary 
> archival artifact and then (perhaps optionally) side-effects the 
> running system.
> The two most widely used "team" Smalltalk development environments 
> during the "golden age" of commercial Smalltalk were Digitalk's 
> VSE(Team/V) and OTI's Envy. While OTI was less overt about it, both  
> systems were  essentially  declarative  in nature. Yet both presented  
> a complete, browser-based, interactive, incremental, reflective, 
> "Smalltalk-style" development experience.
> The issue is really all about reproducibility of programs. If I create 
> a program I need to be able to hand it to you with  the expectation 
> that you will receive the exact same program.  I need to be able to 
> take that program and run it with a future version of the runtime 
> system and know that it will still get the exact same results. I need 
> to combine independently development "modules" into a common program 
> and know  that each module  remains as originally defined.  I need to 
> retrieve an old, archived version of a program and reconstruct it in 
> its exact original form. To reliably do these things you need a 
> declarative definition of the  program or a module rather than a 
> sequence of state sensitive imperative operations. BTW, it is the 
> initial  state  sensitivity that is the real killer.  That's why 
> "file-outs" often  don't work when they  are "filed-in" and that's why 
> you have to worry about the load order of change sets.
> (I also take issue with the implied assertion that the 
> Smalltalk/Squeak compiler is tightly integrated with the runtime 
> system.  Removing  the compiler is quite simple.  Most commercial 
> Smalltalk products have included the capability  (or even the 
> requirement) to deploy applications without including the compiler.  
> Similarly, it is  quite possible to build a runtime compiler for Java 
> that is capable of taking a  source code class declaration and 
> dynamically loading it into a running application.)
>> Smalltalk appears to borrow a lot from LISP in this regard, at least 
>> in terms of philosophy if not implementation. In Scheme, for 
>> instance, the keyword define means "Add this symbol to your currently 
>> running global environment, and bind it to the following value..." 
>> LISPers tend to see this as an advantage.
> Not when  they want to create a maintainable, reproducible, deployable 
> application. In that situation they create archival source code 
> definitions that can reproducibly create the  runable  application.
>> The difference, if I surmise correctly, is that every Scheme knows 
>> what define means; the base semantics for the keyword are 
>> standardized -- whereas each Smalltalk has a different protocol for 
>> creation of classes and adding methods to the
>> The Smalltalk situation is rather unfortunate, but I see not what 
>> having a separate declarative syntax for Smalltalk affords us; with a 
>> standardized imperative protocol for creation of classes, methods, 
>> and variables, the declarative syntax comes for free.
> It's not just an issue of protocol standardization. It's  more an 
> issue of initial state  dependencies  and polymorphism. Syntactically 
> you can use Smalltalk message syntax if you want.  However, if you 
> want reproducibility, their semantic interpretation can't be dependent 
> upon the happenstance  state  of the running system.  As you say, it 
> isn't the syntax that is important.  However, a standard semantics is 
> essential. ANSI Smalltalk doesn't even bother to define a concrete 
> syntax for class declarations.  It just says that no matter what you 
> use  for  a concrete  syntax, here is what it means.
> Allen Wirfs-Brock
>> -- 
>> Jeffrey T. Read
>> "I fight not for me but the blind babe Justice!" --Galford

More information about the Squeak-dev mailing list