From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,b87849933931bc93 X-Google-Attributes: gidfac41,public X-Google-Thread: 109fba,b87849933931bc93 X-Google-Attributes: gid109fba,public X-Google-Thread: 1111a3,5ee869da42505971 X-Google-Attributes: gid1111a3,public X-Google-Thread: f5d71,7639803758efa1ea,start X-Google-Attributes: gidf5d71,public X-Google-Thread: 103376,b87849933931bc93 X-Google-Attributes: gid103376,public X-Google-Thread: 114809,b87849933931bc93 X-Google-Attributes: gid114809,public X-Google-Thread: 1108a1,b87849933931bc93 X-Google-Attributes: gid1108a1,public From: shang@corp.mot.com (David L. Shang) Subject: Re: Combining dynamic and static typing Date: 1997/01/29 Message-ID: <1997Jan29.165358.16783@schbbs.mot.com> X-Deja-AN: 213013179 sender: news@schbbs.mot.com (SCHBBS News Account) references: <5cloqm$9kn@csugrad.cs.vt.edu> organization: MOTOROLA reply-to: shang@corp.mot.com newsgroups: comp.lang.eiffel,comp.lang.ada,comp.lang.c++,comp.lang.smalltalk,comp.lang.objective-c,comp.lang.java,comp.object Date: 1997-01-29T00:00:00+00:00 List-Id: In article <5cloqm$9kn@csugrad.cs.vt.edu> nurban@csugrad.cs.vt.edu (Nathan M. Urban) writes: > In article <1997Jan28.160420.28915@schbbs.mot.com>, shang@corp.mot.com wrote: > > > The advantage of static type checking is type error prevention: > > to prevent type errors before it can happen. > > > Therefore, Objective-C cannot give the benefit of a static typing > > system. Objective-C detects the type errors such as "Not a String" > > at run-time. It does detection, not prevention! Detection is usually > > not a solution to a problem. It is like an irresponsible doctor saying: > > "Now I find what is wrong with you, it's your responsibility to figure > > how to fix it. Want my suggetion? -- peace die -- crash!" > > Compile-time detection _is_ prevention. If you get build errors all > over the place, you fix them. Now, there are circumstances under which > you need to generate method dispatches at runtime -- which C++ cannot > do -- that can't be detected at compile-time. Objective-C gives you > the power to do that, and if you send a bad message, you can trap the > exception and do something with it. You can even check to see if an > object responds to a message before you send it, if you don't want to > trap it. This is a better solution than not being able to have that > power at all. Programs don't have to crash on a runtime exception. > > If you want total safety without the possibility of generating a > runtime exception, then if you don't need dynamic message generation in > your program, it is trivial to write code that does not generate method > dispatches at runtime, just like C++; if you don't need the extra power > of Objective-C, then you don't have to write your code to use it. > There are some confusions about run-time type check or dynamic dispatch with static type safety. They are not contradictory. When a language uses run-time type check or allows dynamic dispatch, the language does not necessariy have to report type errors at run-time. A language should use run-time type check for type-error prevention. But unfortunately, most dynamic languages use run-time type check for error detection only. Objective-C is among them. "type error" is a kind of soft definition to human beings. When a type check fails, is that a type error? some people would say yes, some people would say no. Consider a example. Suppose we select oranges from a heterogeneous fruit bag: take out a fruit, check whetehr it is an orange, if it is, accept it. If it is not, throw it away. When the orange- type check fails, is it a type error? No! It is an expected situation. Consider another example. Imagine we want to put an orange into a fruit box that accept orange. Now we got a box with a lable telling us that it is a fruit box. Since an orange is a fruit, of cause we can put the orange in. But it happens to be a box accept apples only. Is this a type error? Yes! It is an unexpected event. Fortunately, we have a formal definition for what is a type error. A type error is such an incorrect binding of an object to a name that the type of the object does not conform to the declared type of the name. With this definition, let's review the above two examples: 1. Selecting Orange (in Transframe): fruit_bag: bag of Fruit; orange_bag: bag of Orange; foreach (fruit in fruit_bag) { inspect (typeof(fruit)) { case Orange: orange_bag.put(fruit); default: // do nothing } } The above code uses run-time type check, but should not raise a run-time type error. 2. Put Orange (in Java): Fruit[] fruit_box; Orange orange; if (some_condition) fruit_box = new Apple[100]; ... fruit_box[0] = orange; The above code will raise a run-time type error. The problem is that "Apple[100]" is not a subtype of "Fruit[]": Fruit[]: an array whose elements can be any kinds of fruits Apple[]: an array whose elements can be apples only Think for a while. You'll find even by your intuitive logic, Apple[] should not be a subtype of Fruit[]! (Perhaps Java designers have a uncommon logic than our ordinary people). If I ask my 7-year old daugther to bring me a box that can hold any kinds of fruit, she would certainly not bring me the box that can hold apples only! In Transframe, the code fruit_box: Fruit[] ; Orange orange; if (some_condition) fruit_box := Apple[100](); ... fruit_box[0] := orange; cannot get compiled, because the binding: fruit_box := Apple[100](); is invalid. It is definitely (even my 7-year old daugther can judge) a wrong binding. So where can we get the array polymorphism? Transframe allows correct array polymorphism only. Consider the following (in Transframe): fruit_box: array #(ElementType: type of Fruit); orange: Orange; apple: Apple; new_kind_of_fruit: Fruit; if (some_condition2) fruit_box := Apple[100] (); else if (some_condition2) fruit_box := Orange[100] (); else fruit_box := Fruit[100] (); inspect (typeof(fruit_box).ElementType) { case Orange: fruit_box[0]:= orange; case Apple: fruit_box[0]:= apple; case Fruit: fruit_box[0]:= new_kind_of_fruit; fruit_box[1]:= orange; fruit_box[2]:= apple; } The above code is correct. "fruit_box" is a polymorphic array variable. It can represent a fruit_box that contains oranges only, or a fruit_box that contains apples only, or a fruit_box that contains any kinds of apples. When you put an orange into the fruit box, you have to check whether the fruit box accept an orange or not! It is the basic requirement! If you have a 7-year old kid, make a test. Tell him or her that there are some fruit boxes, some may contain apples only, some may contain orange only. And ask him or her to put an orange into on of the fruit boxes. See whether she or he check the contents of the box before puting the orange in. David Shang