mdrutenberg (12/08/82)
Don - I have been reading over some of your messages and I want to try to clear up some of the things you were saying about Smalltalk. While I am not a language expert in general, I have used Smalltalk-80 and know some things about it. So, here is a little stuff to think about until I finish exams and have more time for real discussions. First I want to start off with a general note that Smalltalk-80 is not @i(just) a language but is also an integrated computing environment. I think there are some very interesting ideas in both of these which are 'new' in that they haven't really shown up cleanly built into a programming language and/or environment before. There are also refinements to some things which have been around for some time. So here we go... First I think it would be helpful to give some examples for people to think about. You mention the example of "sqrt(5)" in your last message. What we ideally want to do, as you indicate, is to specify @i(what) you want to do rather than @i(how) exactly to do it. You mention that Pascal's "sqrt(5)" says that we want to calculate the square root of 5 but does not indicate how it is done. I would disagree that this, in Pascal, is not specifying how it is being done, since for example I can't say "sqrt(numb)" where numb is a variable of type "extended precision integer" which I have defined. The compiler will choke and tell me that it must be of type real. I will instead have to create my own function, possibly called 'longIntSqrt', which can find the square roots of long integers and in doing so I am specifying @i(how) I do things rather than just what I want to do. As a real live example in Smalltalk-80, consider the following class hierarchy (I hope everyone has nonproportional fonts so this looks ok): Object / \ / <<other classes>> / Magnitude / \ / <<other classes such as date, time>> / Number / | \ / | \ / | \ Fraction Float Integer If I want to calculate the function 2 sin x foo(x) = e for any number x, I want to be able to say foo(x) or similar, and have it give me the right result for @i(any) type of x. In Smalltalk I would put the following definition in class Number: foo "calculate the well known foo function" ^ (self sin * 2) exp At this point, @i(any) of the numbers in the chart above can now calculate it's foo value and each type of number will use this same piece of code since all numbers inherit behaviour from class Number. Also - If last Saturday night I got fed up with those short little @i(n) digit reals I'm given by every computer manufacturer, and I created a type of number called LargeFloat which responds to all the standard messages that a Float does and provides me with 1000+ digits, one of those numbers also can tell me it's foo value with no extra work done by me, again using this same piece of code. <<note: In Smalltalk, 'self' refers to the receiver of the message>>. Another interesting things occurs with routines like factorial. For some background, which you will (almost?) never need to know: 65536 65536 Integers in the system have a range -10 to 10 Because most integers are quite close to zero, there is a special class called SmallInteger for these which is specially handled (i.e. is fast), but from the outside they look @i(just) like any other integer. If, for example, we multiply two SmallIntegers together, and the product is out of range for a SmallInteger, then we are instead returned a LargeInteger which has the correct value. When using system, you have only the idea of "integers". Back to the example of factorial - Consider a routine to find the factorial of an integer as follows: factorial "Return my factorial, which is the product of all the positive integers less than or equal to myself" self > 0 ifTrue: [^self * (self - 1) factorial]. self = 0 ifTrue: [^1]. "0! = 1" self error: 'One can''t take the factorial of a negative number' We know from experience that the factorial of an integer is usually quite large. We can (and should if we program computers) ask ourselves then - "What will happen when I ask a reasonably large integer, say one hundred or one thousand, what it's factorial is?". Well... at least in Smalltalk we will get the right answer! If we ask what 100! is, we will recurse and the start multiplying. At some point, the product of the intermediate result, (self - 1) factorial, and the current number, self, will exceed the range of SmallIntegers. The correct result of the multiply will be returned in spite of this in the form of a LargeInteger, and your program just keeps on working. I have used this to find the number of zeroes in 1000! and if there is popular demand, I'll include this in my next message. Mike Rutenberg a.k.a. Arpanet: decvax!watmath!mdrutenberg@berkeley Usenet: ...!decvax!watmath!mdrutenberg P.S. It should be noted that some of this stuff can be done in other languages, like (?) Generic Procedures in Ada or (?) Bignums in Interlisp. I would love to see what these examples would look like in <<what you use>>. If you'll mail them to me, I will collect them together and post it.