[comp.lang.misc] OBJ2 and Smalltalk

rentsch@unc.UUCP (01/30/87)

In article <4196@utah-cs.UUCP> shebs@utah-cs.UUCP (Stanley Shebs) writes:
> [aren't you glad I didn't include the article?]

Because my opposite seems more interested in scoring debate points
than shedding light on the subject, I have taken the time to read
the OBJ2 paper ["Principles of OBJ2", 12th POPL, January 1985,
pp52-66].  I will here try to answer some the relevant questions
about OBJ2 and Smalltalk.

Before we begin, let us be clear on what is being discussed.  The
issue is how are OBJ2 and Smalltalk different (or similar).  Please
note that the issue is NOT either (1) which is better, or (2) which
is more (or less) representative of its respective methodology (ADT
for OBJ2, OOP for Smalltalk).  If someone is interested in
discussing these issues, fine, except that arguing in response to
this posting is not the right way to do that.  [There are some
excerpts which might be construed as making points on issue (2).
Those excerpts were not included for that reason, I assure you.]

For reference:  text in double quotes is an excerpt from the OBJ2
paper.  Questions in single quotes are my own, to be asked of both
languages, with my answers provided.  The neutral term 'type' is
used instead of 'sort' in the case of OBJ2, 'class' in the case of
Smalltalk.  The term 'type-specification' is used for text
associated with variable declarations which allows type checking.

The answers in the OBJ2 case are my best understanding based on my
reading of the OBJ2 paper; however, there is no guarantee that those
answers are correct.  Factual corrections (arguments are not
necessary, but give reasons, please!)  are appreciated.  

The answers in the Smalltalk case are based on my experience with
several Smalltalk system.  

So, onward!

Q: 'Do variables have type-specifications?'
OBJ2: yes.  Smalltalk: no.

Q: 'Can the value of a variable be an object of any type at any time?'
OBJ2: no.  Smalltalk: yes.

Q: 'Is inheritance supported?'
OBJ2: yes.  Smalltalk: yes.

Q: 'Is multiple inheritance supported?'
OBJ2: yes.  "Multiple inheritance in the sense of object-oriented
  programming permits one sort to be a subsort of two (or more)
  others ..."
Smalltalk: kind of.  (There is a supplied multiple inheritance
  mechanism, but none of the standard system code uses it.  I have
  never used it myself, nor have I seen any examples of its use;
  but I believe there are some.)

Q: 'Is the language type checked?  (i.e., when the source code is
  read, not at run time)'
OBJ2: yes.  Smalltalk: no.

Q: 'Is the language strongly typed?'
OBJ2: yes.  Smalltalk: no.
"OBJ2 is strongly typed."

Q: 'Can polymorphic procedures be written?'
OBJ2: yes.  Smalltalk: yes.

Q: 'Can polymorphic procedures be written without subtypes and
  without parameterized types?'
OBJ2: no.
Smalltalk: yes.  (Note also the question following.)

Q: 'Does the language have parameterized types?'
OBJ2: yes.  Smalltalk: no.

Q: 'Can Stack( arbitrary type ) be written?'
OBJ2: yes, using parameterized types.  Smalltalk: yes.

Q: 'Can Stack( mixed types ) be written, without using either
  subtypes or parameterized types?'
OBJ2: no.  Smalltalk: yes.

Q: 'Are procedure calls checked against their specifications (i.e.,
  when the source code is read, not at run time)?' 
OBJ2:  yes, type checking.  Smalltalk:  no.  

Q: 'What are the formal theoretical foundations for the language?'
OBJ2: term rewriting and initial algebra semantics.  
Smalltalk: none.

Q: 'Is the language compiled?'
OBJ2: no.  Smalltalk: yes.

Q: 'Is the language suitable for direct (compiled) execution on a
  more-or-less conventional computer architecture?'
OBJ2: no.  Smalltalk: yes.
COMMENT:  Obviously these answers are not purely factual but
represent my opinion somewhat.  I defend these as follows:

Smalltalk:  Two smalltalk machines (one in Japan, and SOAR) have
been designed and either have been or are about to be built.
Another design is under way (the Caltech Object Machine).

OBJ2:  The equality predicates of initial algebra semantics require
in the worst case unbounded computing time.  (At least, I think they
do, and I think that OBJ2 allows as much expressive power in its
equality predicates.)  Certainly hardware could be built to execute
these 'directly', but I argue that any machine instruction which may
not terminate is not 'more-or-less conventional computer
architecture'.  Can anyone cite a counter-example instruction on any
standard architecture of today?  (Note that termination by failure or
error is still termination.)  
    Note also these quotes:  

      "...  lead us to regard OBJ as an ultra high level programming
       programming language that can be executed ...  on suitable
       architectures, and that is especially suitable for 
       'fifth generation' applications ... ".  

      "OBJ is a 'logic programming' language ..."  

      "Although we originally thought of OBJ as a vehicle for testing
       algebraic ADT specifications, we soon came to think of it as a
       general purpose executable specification language ..."  


I hope this has shed some light on the subject.  My conclusion, for
those of you who haven't guessed it, is that OBJ2 is significantly
different from Smalltalk.

cheers,

Tim

shebs@utah-cs.UUCP (01/31/87)

In article <741@unc.unc.UUCP> rentsch@unc.UUCP (Tim Rentsch) writes:

>Because my opposite seems more interested in scoring debate points
>than shedding light on the subject,

I really shouldn't respond to articles prefaced with ad hominem remarks,
but I don't feel like working today...

>Q: 'Do variables have type-specifications?'
>OBJ2: yes.  Smalltalk: no.

>Q: 'Can the value of a variable be an object of any type at any time?'
>OBJ2: no.  Smalltalk: yes.

I mentioned previously that the existence of a universal sort makes the
question of the type of a variable uninteresting.  Here's a quote:
"... to be implemented soon are: a `universal' sort U -- this will give
a tremendous flexibility in programming style, since it supports arbitrary
mixtures of typed and *untyped* code; ..." (emphasis mine).  Theoretical
works seem to be split on the desirability of a universal type, but I think
programming practice demands it.

>Q: 'Is the language compiled?'
>OBJ2: no.  Smalltalk: yes.

Do you mean to say there are no Smalltalk interpreters?  I still don't
understand what compilation has to do with language design...  Compilation
is an optimization - part of the implementor's bag of tricks!

>Q: 'Is the language suitable for direct (compiled) execution on a
>  more-or-less conventional computer architecture?'
>OBJ2: no.  Smalltalk: yes.

People used to say that Lisp was not suitable for compiled execution,
at least until Lisp compilers met or bettered procedural language compilers.
(See Brooks' compiler paper in last summer's Lisp conference, and the
Orbit compiler paper in the last compiler conference for recent examples.)
Prolog is another language that is obviously unsuitable for conventional
machines, but David Warren's compiler was written ten years ago, and it
achieved performance that has rarely been matched since.  Don't bet on
what kind of compilers for rewrite systems will be written in the next ten
years (may try my hand at it myself, once this thesis is out of the way).

Smalltalk is suitable for conventional machines because the lowest levels
of semantics (within a method) are basically procedural.

>OBJ2:  The equality predicates of initial algebra semantics require
>in the worst case unbounded computing time.  (At least, I think they
>do, and I think that OBJ2 allows as much expressive power in its
>equality predicates.)  Certainly hardware could be built to execute
>these 'directly', but I argue that any machine instruction which may
>not terminate is not 'more-or-less conventional computer
>architecture'.

"Nontermination of rewriting" is a red herring.  It just means that it
is possible to write infinite loops in rewrite systems.  The theoreticians
are unhappy about it because they would like guarantees that infinite
loops can't happen, but of course the theoreticians also tell us that
it is impossible to detect all infinite loops!  A compiler for a rewrite
system will most likely compile a rule into a collection of instructions,
in much the same way that a Warren-style Prolog compiler works.  You don't
have to assume broadly powerful instructions, just an adequate compiler
algorithm.

>My conclusion, for
>those of you who haven't guessed it, is that OBJ2 is significantly
>different from Smalltalk.

This reminds me a lot of functional language vs Lisp debates.  As a Lisper
I always end up taking the moral low ground, while David Turner publishes
memorable but scurrilous quotes to the effect that Lisp has held back
functional programming by at least ten years.  ADT vs OOP has the same 
flavor - ADT languages have formal semantics, while Smalltalk and Simula
have operational definitions; ADT languages are hard to use and not
practical for programming, while OOP languages are designed to meet
the needs of the moment and are eminently usable.  Like Lisp and its
purely functional brethren, although OOP and ADT languages share a common
foundation, the adherents of each contend over matters that seem totally
trivial to nonspecialists.  I find the disagreements distasteful, particularly
when attempts at reconciliation are themselves reviled as supporting the other
side.  So this is my last article on the subject.

>Tim

							stan shebs

asente@figaro.UUCP (02/03/87)

In article <741@unc.unc.UUCP> rentsch@unc.UUCP (Tim Rentsch) writes:
>Q: 'Can Stack( mixed types ) be written, without using either
>  subtypes or parameterized types?'
>OBJ2: no.  Smalltalk: yes.

This has been bothering me for some time.  In addition to claiming the
ease of programming without having to specify types, advocates of
totally untyped systems (like Smalltalk) always dredge up the example of
having a queue (or stack or list...) that allows arbitrarily mixed
data to be enqueued.  In all my years of programming I have never wanted
to do anything like this.  I'd be interested in hearing from

   1) anyone who had needed to do this or something similar
   2) anyone who thinks doing this is good programming style, or
   3) anyone who can come up with a better example of why unconstrained
      polymorphism is a good thing in a language.

	-paul asente

shebs@utah-cs.UUCP (02/03/87)

In article <277@figaro.STANFORD.EDU> asente@figaro.UUCP (Paul Asente) writes:

>... advocates of
>totally untyped systems (like Smalltalk) always dredge up the example of
>having a queue (or stack or list...) that allows arbitrarily mixed
>data to be enqueued.  In all my years of programming I have never wanted
>to do anything like this.

If you've ever used a variant record in Pascal or pointer tricks in C or
equivalences in Fortran, you've wanted polymorphism.  If you've ever used
numbers in specified ranges as tokens with various meanings, you've wanted
polymorphism ("0-3 means a disk channel, while larger numbers are ttys."
"Negative numbers indicate error conditions, while positive ones are
answers.").

A couple situations extracted from recent programming tasks:

Writing an machine-independent assembler, I needed to flag certain addresses
as relocatable, others as references to functions, and so forth, to be
recognized by the object file writer.  The buffer passed between the assembler
and the writer contains mostly numbers, but also more complicated structures
to indicate what to do about addresses.

My new formatter for Lisp programs has a main function (that users invoke)
which can take several kinds of arguments.  It can take a single file name
(a string), a list of file names, or a "system" (a symbol designating an
aggregate of files, actions, etc - something like a makefile).  In the Unix/C
world, all command line arguments are strings, and if any represent something
else (such as a number), the program must do all of its own processing.
Makes me sad to think of all the hours spent on such low-level tasks...

Most code is not polymorphic.  It doesn't usually make sense to divide
strings or capitalize numbers.  But in those cases where it is desirable,
the right language makes polymorphism natural and easy to use, while low-level
languages require the re-invention of tagged data types, symbols, storage
reclamation, and all the other things builtin (and probably more efficiently)
in languages like Lisp, Prolog, and Smalltalk.

>	-paul asente

							stan shebs

asente@figaro.UUCP (02/04/87)

In article <4255@utah-cs.UUCP> shebs@utah-cs.UUCP (Stanley Shebs) writes:
>In article <277@figaro.STANFORD.EDU> asente@figaro.UUCP (Paul Asente) writes:
>
>>... advocates of
>>totally untyped systems (like Smalltalk) always dredge up the example of
>>having a queue (or stack or list...) that allows arbitrarily mixed
>>data to be enqueued.  In all my years of programming I have never wanted
>>to do anything like this.
>
>If you've ever used a variant record in Pascal or pointer tricks in C or
>equivalences in Fortran, you've wanted polymorphism.  If you've ever used
>numbers in specified ranges as tokens with various meanings, you've wanted
>polymorphism

...following are many good examples of why you want polymorphism.

In case it wasn't clear from my original posting, it is not polymorphism
that I find questionable, it's unbounded polymorphism.  In each of the
examples in Stanley Shebs' article, you are chosing a type out of
a limited set that you know beforehand.  Even Simula allows that, and
it can be appropriately type-checked.  What I find of dubious usefulness
and even more dubious stylistic practice even if it were useful is
creating a data structure having no idea of what goes into it.  Can
you actually think of an example where you would want a queue that
allowed you to enqueue absolutely anything?  If you know what's going in,
it may be more convenient to program it with no element type checking
than to set up subtypes of the queue elements for the types you know
are going in, but is it really good style?

Of course, "style" is about the vaguest word you can use to describe
a program.  What I mean by style is the degree that the program can
be understood and modified by someone unfamiliar with it.  This of
course may well be the author, two years later.

One final point...if you REALLY need a queue with anything in it,
languages like CLU allow you to sidestep the type system by using
a predefined type that is the union of all types.  But you don't
have to sacrifice the advantages of compile-time type checking
for this one obscure instance.

	-paul asente

shebs@utah-cs.UUCP (02/10/87)

In article <278@figaro.STANFORD.EDU> asente@figaro.UUCP (Paul Asente) writes:
>...it is not polymorphism
>that I find questionable, it's unbounded polymorphism.
>...What I find of dubious usefulness
>and even more dubious stylistic practice even if it were useful is
>creating a data structure having no idea of what goes into it.  Can
>you actually think of an example where you would want a queue that
>allowed you to enqueue absolutely anything?  If you know what's going in,
>it may be more convenient to program it with no element type checking
>than to set up subtypes of the queue elements for the types you know
>are going in, but is it really good style?

I was using examples from heavily engineered production software;  in those
circumstances I agree that there is little use for "unbounded" polymorphism
(is there a technical term for that?).  In ten years of looking at "real"
software, I have not seen any cases where unbounded polymorphism was either 
used or where it would have been the right thing.

On the other hand, unbounded polymorphism is essential to a good development
environment.  It's an extremely important abstraction tool - my just-written
procedure will take anything as an argument and pass it on somewhere else;
I can wait till later to decide what kinds of things actually pass through.
If I need to make a change, only the actual generators and consumers of an
object must be hacked.  Ultimately I may determine that only numbers appear
in a given context, at which point (at least in Common Lisp) I can add
appropriate declarations.  It's a straightforward tradeoff between constraint
and flexibility.  Even after development, Lisp and Smalltalk programmers tend
to avoid sacrificing flexibility, so as to ease maintenance and enhancement.
Stylistically, I don't think there's a problem, because the whole point of
style is to facilitate reading, and I find it easier to read code if the types
of most entities in the program are irrelevant to its correct behavior.
(On aptitude tests, I scored very very low in "clerical skills").

>	-paul asente

								stan shebs

stevev@tekchips.UUCP (02/13/87)

In article <277@figaro.STANFORD.EDU>, asente@figaro.STANFORD.EDU (Paul Asente) writes:
> 
> This has been bothering me for some time.  In addition to claiming the
> ease of programming without having to specify types, advocates of
> totally untyped systems (like Smalltalk) always dredge up the example of
> having a queue (or stack or list...) that allows arbitrarily mixed
> data to be enqueued.  In all my years of programming I have never wanted
> to do anything like this.  I'd be interested in hearing from
> 
>    1) anyone who had needed to do this or something similar
>    2) anyone who thinks doing this is good programming style, or
>    3) anyone who can come up with a better example of why unconstrained
>       polymorphism is a good thing in a language.

I'm not a particular fan of unconstrained polymorphism, but one application
in which it has been useful in Smalltalk is in writing out descriptions
of a data structure to a file so that they can later be read back in.  Since
such structures might be circular, you have to keep track of what you've
already seen.  Having one data structure in which  I can keep track of
everything (regardless of class), rather than having a different Set for
each class, made life quite a bit easier.

A similar application is that of copying (possibly circular) structures.
For each object that you've already seen, you want a data structure that
keeps track of the mapping between "old" objects and "new" objects.

		Steve Vegdahl
		Computer Research Lab
		Tektronix Labs
		Beaverton, Oregon