I'm very new to Smalltalk and would like to understand a few things and confirm others (in order to see if I'm getting the idea or not):

1) In Smalltalk variables are untyped?

2) The only "type check" in Smalltalk occurs when a message is sent and the inheritance hierarchy is climbed up in order to bind the message to a method? And in case the class Object is reached it throws a run time error because the method doesn't exist?

3) There are no coercions because there are no types...?

4) Is it possible to overload methods or operators?

5) Is there some kind of Genericity? I mean, parametric polymorphism?

6) Is there some kind of compatibility/equivalence check for arguments when a message is sent? or when a variable is assigned?

Most questions probably have very short answers (If I'm in the right direction).

有帮助吗?

解决方案

1) Variables have no declared types. They are all implicitly references to objects. The objects know what kind they are.

2) There is no implicit type check but you can do explicit checks if you like. Check out the methods isMemberOf: and isKindOf:.

3) Correct. There is no concept of coercion.

4) Operators are just messages. Any object can implement any method so, yes it has overloading.

5) Smalltalk is the ultimate in generic. Variables and collections can contain any object. Languages that have "generics" make the variables and collections more specific. Go figure. Polymorphism is based on the class of the receiver. To do multiple polymorphism use double dispatching.

6) There are no implicit checks. You can add your own explicit checks as needed.

其他提示

Answer 3) you can change the type of an object using messages like #changeClassTo:, #changeClassToThatOf:, and #adoptInstance:. There are, of course caveats on what can be converted to what. See the method comments.

For the sake of completion, an example from the Squeak image:

Integer>>+ aNumber
    "Refer to the comment in Number + "
    aNumber isInteger ifTrue:
        [self negative == aNumber negative
            ifTrue: [^ (self digitAdd: aNumber) normalize]
            ifFalse: [^ self digitSubtract: aNumber]].
    aNumber isFraction ifTrue:
        [^Fraction numerator: self * aNumber denominator + aNumber  numerator denominator: aNumber denominator].
    ^ aNumber adaptToInteger: self andSend: #+

This shows:

  1. that classes work as some kind of 'practical typing', effectively differentiating things that can be summed (see below).
  2. a case of explicitly checking for Type/Class. Of course, if the parameter is not an Integer or Fraction, and does_not_understand #adaptToInteger:andSend:, it will raise a DNU (doesNotUnderstand see below).
  3. some kind of 'coercion' going on, but not implicitly. The last line:

    ^aNumber adaptToInteger: self andSend: #+

asks the argument to the method to do the appropriate thing to add himself to an integer. This can involve asking the original receiver to return, say, a version of himself as a Float.

  1. (doesn't really show, but insinuates) that #+ is defined in more than one class. Operators are defined as regular methods, they're called binary methods. The difference is some Smalltalk dialects limit them up to two chars length, and their precedence.
  2. an example of dispatching on the type of the receiver and the argument. It uses double dispatch (see 3).
  3. an explicit check where it's needed. Object can be seen as having types (classes), but variables are not. They just hold references to any object, as Smalltalk is dynamically typed.

This also shows that much of Smalltalk is implemented in Smalltalk itself, so the image is always a good place to look for this kind of things.

About DNU errors, they are actually a bit more involved:

When the search reaches the top class in the inheritance chain (presumably ProtoObject) and the method is not found, a #doesNotUndertand: message is sent to the object, with the message not understood as parameter) in case it wants to handle the miss. If #doesNotUnderstand: is not implemented, the lookup once again climbs up to Object, where its implementation is to throw an error.

Note: I'm not sure about the equivalence between Classes and Types, so I tried to be careful about that point.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top