dmg@ssc-vax.uucp (David M Geary) (04/03/91)
In article <7689:Mar2623:28:5091@kramden.acf.nyu.edu>> (Dan Bernstein) writes: >>In article <48805@nigel.ee.udel.edu> new@ee.udel.edu (Darren New) writes: >> Hmm... How about a window with a hetrogeneous collection of buttons, sliders, >> text displays, etc, all of which respond to "redraw" and "is the mouse >> over you"? >struct {any object; void (*redraw)(); int (*ismouseover)();} *whatsinwindow(); >Here ``any'' is a polymorphic type (e.g., void * in C), and *redraw >takes an ``any'' argument. Naturally, languages like C++ encapsulate the >above struct into a single ``class,'' but that's merely syntactic sugar. A void* is not a "polymorphic type", and C++ provides much more than "merely syntactic sugar". In article <25655:Mar2803:50:2491@kramden.acf.nyu.edu> (Dan Bernstein) writes: >In article <49087@nigel.ee.udel.edu> new@ee.udel.edu (Darren New) writes: >> Am I crazy, or isn't (void *) impossible to indirect? Don't you have >> to type-cast it first? Isn't this dynamic typing implemented on top of ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >> C? ^^^ >YES. People are tossing around the term ``dynamic typing'' as if it were >some truly important feature. ``Yeah, Bob, not only does the language >have *loops*, but it has *dynamic typing*!'' ``Wow! *Dynamic typing*? >Really?'' NO. This is *not* an example of dynamic typing implemented on top of C. > On the occasions when I want dynamically typed variables, I >can use them without trouble in C. No you cannot; C has no support whatsover for "dynamically typed variables." >Sure, this requires a void pointer type. SO WHAT? As I pointed out when >I entered this discussion, the language does need *some* type that can >represent *all* values if it's going to support dynamic typing. C has >such a type, and adequate macros, and that's enough for me to get work >done. C has absolutely nothing akin to dynamic typing. One cannot "implement dynamic typing on top of C", without writing some kind of preprocessor, such has been done with Objective-C. I think that there is some confusion over terminology here: 1) Dynamic binding: Dynamic binding is a feature whereby the compiler chooses the correct function to apply to some object, depending upon the *type* of the object. If I have dynamic binding, I can have code like the following (in C++): int list::insert(linkable& lnk, int pos) { .... lnk.setNextNode(NULL); // Compiler chooses appropriate function to call // for the given object. ... } The C compiler will allow *any type* to be passed to list::insert(), as long as the type is a linkable (or is a descendent of class linkable). Therefore, the programmer may send different types to the function list::insert(), and the compiler determines the appropriate function to call, depending upon the type of lnk for lnk.setNextNode(). However, since C++ is statically typed, the first argument to list::insert() *must* be either a linkable, or a descendent of linkable. If not, the COMPILER WILL GENERATE A COMPILE-TIME ERROR. Bertrand Meyer, of Eiffel fame, has already posted an example of this kind in Eiffel, (which, like C++ has multiple inheritance and dynamic binding). 2) Dynamic typing: With "dynamic typing", one may write (in Objective-C): id collection = [Container new]; [collection add:[Dog new]]; [collection add:[Cat new]]; [collection add:[bottleOWine new]]; Here, one is adding arbitrary elements to a collection. There is *no restriction whatsoever* as to the type of things that can be added to the collection. Note that this differs from the C++ example, where all elements added to the list *must* be linkables (or descendents of class linkable). The "pitfall" of dynamic typing, of course, is that it is possible to try to apply a method to an object, which the object is not prepared to deal with, and the error MAY NOT BE CAUGHT UNTIL RUNTIME. In a statically typed language, such as Eiffel and C++ the compiler will simply not allow that to happen. Lastly, note that neither of the two examples given above may be implemented in C, without the programmer *at one time or another* explicitly identifying the types of all objects being operated upon. (In other words, in Dan's example above, it is the programmer's, not the compiler's, responsiblity to ensure that the correct functions are called for the appropriate types). Here, BTW, are some good references. I would suggest that Dan read some of these before providing any more erroneous information in the tradition of his previous postings: Object Oriented Software Construction, Bertrand Meyer. (excellent, BTW) Object Oriented Programming, Brad Cox. An introduction To OOP and C++, Wiener & Pinson
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (04/04/91)
In article <3776@ssc-bee.ssc-vax.UUCP> dmg@ssc-vax.uucp (David M Geary) writes: >In article <7689:Mar2623:28:5091@kramden.acf.nyu.edu>> (Dan Bernstein) writes: >>>In article <48805@nigel.ee.udel.edu> new@ee.udel.edu (Darren New) writes: >>>Hmm... How about a window with a hetrogeneous collection of buttons, sliders, >>>text displays, etc, all of which respond to "redraw" and "is the mouse >>>over you"? >>struct {any object; void (*redraw)(); int (*ismouseover)();} *whatsinwindow(); [ ... ] >NO. This is *not* an example of dynamic typing implemented on top of C. What a load of... uh, what I mean is that this is a perfect example of the fact that dynamic typing is just a programming technique. (``A state of mind'' is perhaps too fluffy for such a serious discussion as this.) With appropriate macros, I can use the above structure in the same way as someone using a dynamically typed language. In fact, with a reasonable preprocessor like AT&T's C++, I can declare the structure in the same way. I can get all the same type-checking (at run-time, too!). You can shout all you want about it not *really* being dynamic typing. But it obviously is. Why does it so offend you that dynamic typing can be implemented so effectively outside the compiler? > A void* is not a "polymorphic type", and C++ provides much more than > "merely syntactic sugar". Uh-huh, whatever you say, boss. > > On the occasions when I want dynamically typed variables, I > >can use them without trouble in C. > No you cannot; C has no support whatsover for "dynamically typed variables." It has a macro facility that is adequate to let me use a variable, x, that can take on any value I can express in the language, and that forces me to use x as the type it is currently holding. What else do you want out of types, other than the syntax and the checking? > One cannot "implement > dynamic typing on top of C", without writing some kind of preprocessor, In case you haven't noticed, C has a preprocessor. It's not great, but it works. But even if it didn't, I would happily use m4. As I've said before, you cannot change the fundamental characteristics of a language by adding a library---or a preprocessor. > Here, one is adding arbitrary elements to a collection. There is > *no restriction whatsoever* as to the type of things that can be > added to the collection. Note that this differs from the C++ example, > where all elements added to the list *must* be linkables (or > descendents of class linkable). Nobody has come up with any examples of why anyone would want to use such a list---i.e., a list which does not have a definite type, and to which you cannot meaningfully apply any particular operations. Do you have a brilliant example that everyone else has missed? > Lastly, note that neither of the two examples given above may be > implemented in C, without the programmer *at one time or another* > explicitly identifying the types of all objects being operated upon. C++ is a counterexample. > Here, BTW, are some good references. I would suggest that Dan read > some of these before providing any more erroneous information in the > tradition of his previous postings: Why, thank you, ma'am. Here, BTW, is an excellent reference. I strongly suggest that you read it---and work at least 10% of the exercises---before you post anything, again, anywhere, ever. Art of Computer Programming, Donald E. Knuth. 3 volumes. ---Dan
gudeman@cs.arizona.edu (David Gudeman) (04/08/91)
In article <11479:Apr319:53:2191@kramden.acf.nyu.edu> Dan Bernstein writes:
]With appropriate macros, I can use the above structure in the same way
]as someone using a dynamically typed language. In fact, with a
]reasonable preprocessor like AT&T's C++, I can declare the structure in
]the same way. I can get all the same type-checking (at run-time, too!).
Well I can't. I've tried pretty hard to find a way to get extensible
dynamic typing in C++, and I don't believe it can be done. I'm
talking about (1) a single package that I write including a header and
linked module, (2) minimal overhead for new dynamic types, (3) using
dynamically typed values just like statically typed values. If you
can do this I'd like to see it.
--
David Gudeman
gudeman@cs.arizona.edu
noao!arizona!gudeman
dmg@ssc-vax (David M Geary) (04/09/91)
Dan Bernstein claims to be able to implement dynamic typing on top of C: ] Dan Bernstein ]] David Geary ]]] David Gudeman ]struct {any object; void (*redraw)(); int (*ismouseover)();} *whatsinwindow(); ]] NO. This is *not* an example of dynamic typing implemented on top of C. ]With appropriate macros, I can use the above structure in the same way ]as someone using a dynamically typed language. In fact, with a ]reasonable preprocessor like AT&T's C++, I can declare the structure in ]the same way. I can get all the same type-checking (at run-time, too!). ]]] Well I can't. I've tried pretty hard to find a way to get extensible ]]] dynamic typing in C++, and I don't believe it can be done ... ]]] If you can do this I'd like to see it. I'd like to see it also. Either Dan does not understand dynamic typing, or he has found something which the rest of the world needs to know. Let's take the window example since that was the original context of this discussion: Developer A implements buttons, menus, and icons which are displayable in a window. Developer A provides developer B with: 1) Header files defining structures for buttons, menus and icons. (menu.h, button.h and icon.h). 2) Object modules which implement functionality for each. (menu.o, button.o and icon.o). Menus, buttons, and icons all have a pointer to a redraw function in their structure definition; however, structures for buttons, menus and icons are all different, ie: struct button struct menu { { int x,y,w,h; int x,y,w,h; char* text; int numItems; char** itemText; void (*redraw)(); }; void (*redraw)(); }; struct icon { int x,y,w,h; bitmap* picture; void (*redraw)(); }; Developer A provides a function that returns a list of things in a window (things being buttons, menus, and icons). Let's call the function getListOfThingsInWindow(). Now, developer B, given the header files and object modules defined above, processes the list, and displays all items on the list in a fashion similar to: drawWindowThings(window) window_t* window; { list_t* wlist = getListOfThingsInWindow(window); for(each object in wlist) redraw the object } Admittedly, the same effect can be had (in C++) if developer A ensures that buttons, menus, and icons all have a superclass in common, such as windowThing which has a redraw method. However, that is *not* dynamic typing, that is inheritance - two very different things. Dan, since you can implement dynamic typing in C, would you please post the *appropriate macros* so that developer B can get his job done, without *in any way* having to modify (recompile) the object modules that are supplied from developer A.
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (04/12/91)
In article <3810@ssc-bee.ssc-vax.UUCP> dmg@ssc-vax.UUCP (David M Geary) writes: > Dan Bernstein claims to be able to implement dynamic typing on top of C: Although I can implement and have implemented dynamic typing with a suitable preprocessor over C, I did not make that claim in the quoted material. Please read a quote before you paraphrase it. > ] Dan Bernstein > ]] David Geary > ]]] David Gudeman > ]struct {any object; void (*redraw)(); int (*ismouseover)();} *whatsinwindow(); > ]] NO. This is *not* an example of dynamic typing implemented on top of C. The original example in question was *presented* as an example of what people do with heterogeneous (dynamically typed) lists. I responded with the above structure to show how you implement the same thing in C, and here Geary claims that the example was no longer an example of dynamic typing. Sheesh. My response: > ]With appropriate macros, I can use the above structure in the same way > ]as someone using a dynamically typed language. In fact, with a > ]reasonable preprocessor like AT&T's C++, I can declare the structure in > ]the same way. I can get all the same type-checking (at run-time, too!). What can one mean by typing, if not storage format plus type-checking plus syntax? What I said here was that C++ has sufficient typing for this example. Where do you see this claim of dynamic typing in C? I'll answer your (trivial) question anyway, even though it has been adequately answered by Chip and others in comp.lang.misc. [ sample problem ] If you had been keeping up with the discussion in comp.lang.misc, you would understand that giving the same name to variables in different structures does NOT imply any magical connection between those variables. In order to solve your problem as stated, you must make the connection explicit, like so (as per my structure as above): struct redrawable { void *object; void (*redraw)(); } ; ... struct redrawable menu2redraw(struct menu *m) { struct redrawable r; r.object = m; r.redraw = m->redraw; } (OO fans will note that I have just, in effect, defined a subtype.) That makes the connection between menus and the redrawing you want to deal with. Similarly for button and icon. > Developer A provides a function that returns a list of things in a window > (things being buttons, menus, and icons). Let's call the function > getListOfThingsInWindow(). Wrong, wrong, wrong. There is no such thing in C as a list of buttons, menus, and icons. My point in the heterogenous-list discussion was that people only use heterogeneous lists as (a) union types; (b) objects, to which a FIXED set of operations will be applied. What you mean is that A defines a function to return a list of redrawables. > Now, developer B, given the header files and object modules defined above, > processes the list, and displays all items on the list in a fashion similar > to: > drawWindowThings(window) > window_t* window; > { > list_t* wlist = getListOfThingsInWindow(window); > for(each object in wlist) > redraw the object > } foo->redraw(foo->object); Done. > Admittedly, the same effect can be had (in C++) if developer A ensures that > buttons, menus, and icons all have a superclass in common, such as > windowThing which has a redraw method. As almost everyone in the comp.lang.misc discussion realized, you can also define a SUBclass as I just did. As Chip pointed out explicitly, you can avoid tricky inheritance issues by having the subclasses *point* to their parents, but I've written the above solution in C anyway. ---Dan
dmg@ssc-vax.uucp (David M Geary) (04/16/91)
] Dan Bernstein ]] David Geary ]] Dan Bernstein claims to be able to implement dynamic typing on top of C: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ] Although I can implement and have implemented dynamic typing with a ] suitable preprocessor over C, I did not make that claim in the quoted ^^^^^^^^^^^^^^^^^^^^^^^^^^ ] material. Please read a quote before you paraphrase it. ]The original example in question was *presented* as an example of what ]people do with heterogeneous (dynamically typed) lists. I responded with ^^^^^^^^^^^^^^^^ ]the above structure to show how you implement the same thing in C, and ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ]here Geary claims that the example was no longer an example of dynamic ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ]typing. Sheesh. My response: ^^^^^^ Sheesh yourself. Either it *was* an example of dynamic typing or it was *not*. You cannot have it both ways, Dan. I did not claim that your example was *no longer* an example of dynamic typing. I said that your example was *never* an example of dynamic typing. Here, BTW, since you do not want me to paraphrase, is the original article written by Bernstein: ------------------------------------------------------------------------------ % = Darren New %% = Dan Bernstein In article <25655:Mar2803:50:2491@kramden.acf.nyu.edu> (Dan Bernstein) writes: %In article <49087@nigel.ee.udel.edu> new@ee.udel.edu (Darren New) writes: %% Am I crazy, or isn't (void *) impossible to indirect? Don't you have %% to type-cast it first? Isn't this dynamic typing implemented on top of ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ %% C? ^^^ %YES. People are tossing around the term ``dynamic typing'' as if it were %some truly important feature. ``Yeah, Bob, not only does the language %have *loops*, but it has *dynamic typing*!'' ``Wow! *Dynamic typing*? %Really?'' ----------------------------------------------------------------------------- YES is pretty clear to me. Did you really mean NO? If so, then I misunderstood. ]If you had been keeping up with the discussion in comp.lang.misc, you ]would understand that giving the same name to variables in different ]structures does NOT imply any magical connection between those ]variables. In order to solve your problem as stated, you must make the ]connection explicit, like so (as per my structure as above): Exactly what I was trying to say. Dan Bernstein is *not* implementing dynamic typing on top of C. Since it appeared to me that Bernstein was claiming to be implementing dynamic typing on top of C, I posted the following challenge for Dan: ]]Developer A implements buttons, menus, and icons which are displayable in a ]]window. Developer A provides developer B with: ]] 1) Header files defining structures for buttons, menus and icons. ]] (menu.h, button.h and icon.h). ]] 2) Object modules which implement functionality for each. ]] (menu.o, button.o and icon.o). ]] Menus, buttons, and icons all have a pointer to a redraw function in their ]] structure definition; however, structures for buttons, menus and icons are ]] all different, ie: ]] struct button struct menu ]] { { ]] int x,y,w,h; int x,y,w,h; ]] char* text; int numItems; char** itemText; ]] void (*redraw)(); ]] }; void (*redraw)(); }; ]] struct icon ]] { ]] int x,y,w,h; ]] bitmap* picture; ]] void (*redraw)(); ]] }; ]] Developer A provides a function that returns a list of things in a window ]](things being buttons, menus, and icons). Let's call the function ]]getListOfThingsInWindow(). ]] Now, developer B, given the header files and object modules defined above, ]]processes the list, and displays all items on the list in a fashion similar ]]to: ]] drawWindowThings(window) ]] window_t* window; ]] { ]] list_t* wlist = getListOfThingsInWindow(window); ]] for(each object in wlist) ]] redraw the object ]] } ]] Dan, since you can implement dynamic typing in C, would you please post ]]the *appropriate macros* so that developer B can get his job done, without ]]*in any way* having to modify (recompile) the object modules that are supplied ]]from developer A. Dan replies with: foo->redraw(foo->object); Done. No. Wrong. Not done. Dan is using his own structure instead of those I provided in the example. In the example above, each object in wlist must be a void*. You cannot defererence a void pointer. You cannot implement dynamic typing in C without writing an external preprocessor. Period. BTW, this whole series of postings occurred because I thought that Bernstein claimed to have implemented dynamic typing in C without writing any *external* preprocessor. (As did others in this newsgroup). Since this is impossible to do, I posted the above challenge. Now, Dan seems to be claiming that he never stated he could implement dynamic typing on top of C without writing any *external* preprocessor. If Bernstein's claim today is that he *cannot* implement dynamic typing on top of C withoug writing an external preprocessor, then we are in agreement.
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (04/17/91)
In article <3843@ssc-bee.ssc-vax.UUCP> dmg@ssc-vax.uucp (David M Geary) writes: > ]] Dan Bernstein claims to be able to implement dynamic typing on top of C: > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ David, there is a big difference between claiming that a *particular* example of dynamic typing can be implemented (directly) in C, and claiming that *all* examples of dynamic typing can be implemented (directly) in C. As you will realize if you reread your article, I have claimed the former, for several particular examples. I have not claimed the latter, though of course a more powerful preprocessor obviates this argument. In other words, please stop misquoting me; it's getting rather tiresome. > ]If you had been keeping up with the discussion in comp.lang.misc, you > ]would understand that giving the same name to variables in different > ]structures does NOT imply any magical connection between those > ]variables. In order to solve your problem as stated, you must make the > ]connection explicit, like so (as per my structure as above): > Exactly what I was trying to say. Dan Bernstein is *not* implementing > dynamic typing on top of C. Making an explicit connection between button->redraw and mouse->redraw has absolutely nothing to do with dynamic typing. There are statically typed languages where the connection IS explicit: "redraw" is (in effect) a string which is sent as a message to the object, and by declaring two different objects that support "redraw" you automatically make them usable in the same context. > Since it appeared to me that Bernstein was claiming to be implementing > dynamic typing on top of C, For each EXAMPLE of dynamic typing that people put up, I showed how it would typically be implemented (directly) in C. I hope you can see the difference between this and what you're talking about. > No. Wrong. Not done. Dan is using his own structure instead of those > I provided in the example. In the example above, each object in wlist > must be a void*. Ah. So you're saying ``Developer A provides an almost entirely useless function. It lets you count the number of objects in a window, or test whether another object you have happens to be in the window. Gee, Dan, you can't use this function to redraw everything in the window!'' What a shock. Are you trying to solve real programming problems, or whimper about how you can't solve them? I've shown you how they would be solved in C. You're saying ``no, no, you're not allowed to solve them, because your solution uses your structure rather than my structure.'' Who tf cares? It's a solution. You can write a trivial interface to convert between the structures. It works. End of discussion. > You cannot implement > dynamic typing in C without writing an external preprocessor. You can implement all real-world EXAMPLES---or, at least, every example that's come up in this group---of dynamic typing directly in C. That's exactly what I've been doing. People say ``hey, here's a use of dynamic typing,'' and I show them how a C programmer would accomplish the same result. ---Dan
dan@ece.arizona.edu (Dan Filiberti) (04/17/91)
In article <27313@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu writes: >You can implement all real-world EXAMPLES---or, at least, every example >that's come up in this group---of dynamic typing directly in C. That's >exactly what I've been doing. People say ``hey, here's a use of dynamic >typing,'' and I show them how a C programmer would accomplish the same >result. So what? I don't see your point. Sure, you could probably accomplish the same result, but at an unreasonable production cost. And, no matter how much you insist, C DOES NOT SUPPORT DYNAMIC TYPING. Period. The whole point of having dynamic typing is reusability of code. And, if I wanted to reuse the modules you have written, I'd have to use your interface...what makes you think that I would want to do that! Sorry, but your point is dumb. If you're argueing against using C++, I can give you at least two great reasons to use it: 1. Dynamic Typing is easily and readily available, done the same way every time. 2. If you don't want to use dynamic typing, then DON'T. C++ doesn't force you to do anything, just write C if you want. So please, tell me your point, and end this useless thread.... Daniel Filiberti dan@helios.ece.arizona.edu [:)}
amanda@visix.com (Amanda Walker) (04/18/91)
In article <1991Apr16.183750@ece.arizona.edu> dan@ece.arizona.edu (Dan Filiberti) writes: And, no matter how much you insist, C DOES NOT SUPPORT DYNAMIC TYPING. Period. Lisp supports dynamic typing. Lisp can be interpreted by, or translated into, C. Therefore, C supports dynamic typing. QED. Now, you can argue that the C language does not *include* dynamic typing. I don't think anyone here would disagree with you there. However, you can certainly *implement* dynamic typing in C, with as low an overhead as you can get in any other language. The whole point of having dynamic typing is reusability of code. And, if I wanted to reuse the modules you have written, That's portability, not reusability. Dynamic typing can be just as useful when I want to reuse my own code as when you want to reuse it. And if you want to reuse my code, you have to use whatever framework I wrote it in anyway. I'd have to use your interface...what makes you think that I would want to do that! That's a red herring. The interface is always fixed, whether its explicit or implicit in the language used. I will agree that implicit support helps portability. 1. Dynamic Typing is easily and readily available, done the same way every time. OK so far... 2. If you don't want to use dynamic typing, then DON'T. C++ doesn't force you to do anything, just write C if you want. So why bother with C++, then? I don't follow you... Either you're going to use C++ features, in which case using C++ is a good idea, or you're not, in which case it's silly. You can't have it both ways... -- Amanda Walker amanda@visix.com Visix Software Inc. ...!uunet!visix!amanda -- "How can I worry about your miserable violin when I am speaking to my God?" --Beethoven
dmg@ssc-vax.uucp (David M Geary) (04/18/91)
] Dan Bernstein
]] David Geary
]]] Darren New
]] Dan Bernstein claims to be able to implement dynamic typing on top of C:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
] David, there is a big difference between claiming that a *particular*
] example of dynamic typing can be implemented (directly) in C, and
] claiming that *all* examples of dynamic typing can be implemented
] (directly) in C. As you will realize if you reread your article, I have
] claimed the former, for several particular examples. I have not claimed
] the latter ...
] For each EXAMPLE of dynamic typing that people put up, I showed how it
] would typically be implemented (directly) in C. I hope you can see the
] difference between this and what you're talking about.
If C had dynamic typing, we would be able to do this:
void doFooToThingsInList(list)
list_t* list;
{
void* nextThingInList;
while(nextThingInList = list->getNextThing())
nextThingInList->foo(&nextThingInList);
}
However, this is not possible, due to the fact that a void* in C must
have a cast applied to it before it can be dereferenced. Therefore, we
must do something like the following:
((someType*)nextThingInList)->foo(&nextThingInList);
In other words, the *programmer* is responsible for ensuring that the statement
((someType*)nextThingInList)->foo() is valid for the type someType.
With dynamic typing, however, this requirement (that the programmer ensures
that all statements are type-safe) is no longer a requirement at all. The
responsiblity for type-safety is no longer left to the programmer, as there
is no requirement that all statements be type-safe.
]]] Am I crazy, or isn't (void *) impossible to indirect? Don't you have
]]] to type-cast it first? Isn't this dynamic typing implemented on top of
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]]] C?
^^^
]YES. People are tossing around the term ``dynamic typing'' as if it were
^^^
]some truly important feature. ``Yeah, Bob, not only does the language
]have *loops*, but it has *dynamic typing*!'' ``Wow! *Dynamic typing*?
]Really?''
NO. It was *not* dynamic typing implemented on top of C. It was
an example of what a programmer in a statically typed language has to do
in order to accomplish what is (more simply) done with a dynamically typed
language.
Dynamic typing *is* a truly important feature. It allows a greater
degree of code reuse. Dan, if you would take the time to understand the
scenario I proposed where one developer provides another developer with
classes of objects in a window, the benefits of dynamic typing would be
apparent.
]You can implement all real-world EXAMPLES---or, at least, every example
]that's come up in this group---of dynamic typing directly in C. That's
You cannot implement the real-world example that I posted earlier
directly in C. If you wish, I will post a different real-world example
of dynamic typing that cannot be implemented directly in C.
olson@juliet.ll.mit.edu ( Steve Olson) (04/18/91)
In article <1991Apr17.173651.23103@visix.com> amanda@visix.com (Amanda Walker) writes:
Now, you can argue that the C language does not *include* dynamic
typing. I don't think anyone here would disagree with you there.
However, you can certainly *implement* dynamic typing in C, with as
low an overhead as you can get in any other language.
No question that you can implement user-defined dynamic typing (or
object-oriented programming - I see this thread is cross-posted) on
top of a language such a C. But what do you mean by "overhead"? Often
there will low machine overhead - but programmer overhead might be a
different story. Which one is more important will vary drastically
between different applications.
--
Amanda Walker amanda@visix.com
- Steve Olson
MIT Lincoln Laboratory
olson@juliet.ll.mit.edu
cs450a03@uc780.umd.edu (04/18/91)
Dan Bernstein writes: >For each EXAMPLE of dynamic typing that people put up, I showed how >it would typically be implemented (directly) in C. I hope you can see >the difference between this and what you're talking about. heh heh heh... Excellent :-) f(x, y) LIMIT ERROR ------------------------ Let's say I was trying to implement a dynamically typed language in C. (Of course, I wouldn't _really_ be that crazy :-) Let's say I wanted to detect when, for instance, the addition of 2 integers produces an invalid result. Let's say that I can not accept a severe performance hit for this checking (most of the time, it's not going to happen. When it does happen, I'm going to switch to float -- performance must be better than floating point). Now, I know that this sort of information is available if I was working in assembly (I'm not working on a pathologically silly machine). But how would I do it in C? As near as I can tell, C just throws the information away. This is a _very_ simple sort of test. I'd want to detect erroneous results for every primitive expression I built into the language. These tests would be less significant (in terms of time and space) than simple housekeeping (loads and stores, loop management, etc.) if I were working in assembly. How do I do it? Raul Rockwell
diamond@jit345.swstokyo.dec.com (Norman Diamond) (04/18/91)
In article <1991Apr17.173651.23103@visix.com> amanda@visix.com (Amanda Walker) writes: >In article <1991Apr16.183750@ece.arizona.edu> dan@ece.arizona.edu (Dan >Filiberti) writes: > And, no matter how much you insist, C DOES NOT SUPPORT DYNAMIC > TYPING. Period. >Lisp supports dynamic typing. Lisp can be interpreted by, or >translated into, C. Therefore, C supports dynamic typing. QED. >Now, you can argue that the C language does not *include* dynamic >typing. I don't think anyone here would disagree with you there. >However, you can certainly *implement* dynamic typing in C, with as >low an overhead as you can get in any other language. I hope we're not going to repeat the metalinguistic argument over the meaning of the word "support." An electric power cable can be used as a tool by a programmer to write code to support dynamic typing. (I'm using several such cables to write a Usenet article too.) But the programmer is writing the code to do the support. The cable itself does not do the support. A pencil does not support software design the way some CAD products do. -- Norman Diamond diamond@tkov50.enet.dec.com If this were the company's opinion, I wouldn't be allowed to post it.
amanda@visix.com (Amanda Walker) (04/19/91)
diamond@jit345.swstokyo.dec.com (Norman Diamond) writes:
A pencil does not support
software design the way some CAD products do.
And it's a good thing, too :).
A pencil is so far the most effective software design tool I have found...
--
Amanda Walker amanda@visix.com
Visix Software Inc. ...!uunet!visix!amanda
--
"A keyboard... how quaint!" --Star Trek IV: The Voyage Home
cs450a03@uc780.umd.edu (04/19/91)
Joseph Allen > Me >> >>Let's say I was trying to implement a dynamically typed language in C. >>(Of course, I wouldn't _really_ be that crazy :-) Let's say I wanted >>to detect when, for instance, the addition of 2 integers produces an >>invalid result. >#define add(a,b) (a<0 && b<0 && a+b>=0 || a>=0 && b>=0 && a+b<0 ? error():a+b) Ok, that should work, fairly generically I'd hope. Now how do I generalize that to multiplication? >I believe C is not really the problem. What you want is for the >processor to give an integer overflow signal so that the calculation >can be repeated in floating point. Unfortunately most (all?) don't. > >Even in an interpretive language you'd have to: > > add > bov error > sub > bov error > mul > bov error Interpretive?? That looks like _assembly_ Also note the existence of the new HP machines which have add and branch semantics (and presumably multiply and branch). I would hope that that's branch on overflow (though I haven't actually asked -- if not you'd still have to execute two machine instructions per HLL op). Finally, note that a lot of time in assembly is spent in "routine housekeeping" -- things like fetching and storing variable values, as opposed to actually computing the results specified by the HLL. Raul Rockwell
jallen@eeserv1.ic.sunysb.edu (Joseph Allen) (04/19/91)
In article <17APR91.21054415@uc780.umd.edu> cs450a03@uc780.umd.edu writes: >Let's say I was trying to implement a dynamically typed language in C. >(Of course, I wouldn't _really_ be that crazy :-) Let's say I wanted >to detect when, for instance, the addition of 2 integers produces an >invalid result. Let's say that I can not accept a severe performance >hit for this checking (most of the time, it's not going to happen. >When it does happen, I'm going to switch to float -- performance must >be better than floating point). >How do I do it? #define add(a,b) (a<0 && b<0 && a+b>=0 || a>=0 && b>=0 && a+b<0 ? error():a+b) :-) I believe C is not really the problem. What you want is for the processor to give an integer overflow signal so that the calculation can be repeated in floating point. Unfortunately most (all?) don't. Even in an interpretive language you'd have to: add bov error sub bov error mul bov error which is quite gross. -- #define h 23 /* Height */ /* jallen@ic.sunysb.edu (129.49.12.74) */ #define w 79 /* Width */ /* Amazing */ int i,r,b[]={-w,w,1,-1},d,a[w*h];m(p){a[p]=2;while(d=(p>2*w?!a[p-w-w]?1:0:0)|( p<w*(h-2)?!a[p+w+w]?2:0:0)|(p%w!=w-2?!a[p+2]?4:0:0)|(p%w!=1?!a[p-2]?8:0:0)){do i=3&(r=(r*57+1))/d;while(!(d&(1<<i)));a[p+b[i]]=2;m(p+2*b[i]);}}main(){r=time( 0L);m(w+1);for(i=0;i%w?0:printf("\n"),i!=w*h;i++)printf("#\0 "+a[i]);}
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (04/19/91)
In article <17APR91.21054415@uc780.umd.edu> cs450a03@uc780.umd.edu writes: > Let's say I was trying to implement a dynamically typed language in C. > (Of course, I wouldn't _really_ be that crazy :-) Let's say I wanted > to detect when, for instance, the addition of 2 integers produces an > invalid result. Okay, I know what you're about to say, and I agree with you completely. One of the problems with C is that it supports so few arithmetic operations: my favorite example is getting the high word of a multiply, Herman Rubin's favorite example is dividing two floats and getting an integer quotient and float remainder, and your example here is adding two integers and getting an exception of some sort upon overflow. (Note that any good language or library would provide both the unrestricted operation of add-with-undefined-effects-upon-overflow and the restricted operation here.) Now what does this have to do with dynamic typing? Exception handling is not dynamic typing. ---Dan
quale@saavik.cs.wisc.edu (Douglas E. Quale) (04/19/91)
In article <1991Apr17.173651.23103@visix.com> amanda@visix.com (Amanda Walker) writes: > >However, you can certainly *implement* dynamic typing in C, with as >low an overhead as you can get in any other language. > This is not true. A C implementation of dynamic typing will be slower. A compiler for a dynamic language can take advantage of its knowledge of datatype representations to generate faster code. Two simple examples: 1) tag operations for type discrimination A compiler for a dynamically typed language can dedicate a register to hold a bitmask that will speed type tag operations. A C program would either use an immediate value or a global variable, either of which is slower and bulkier on many architectures. 2) generic arithmetic Suppose the dynamic language includes generic arithmetic on integers of arbitrary size. In lisp this would give two types of integer, fixnum and bignum. A lisp compiler can add two fixnums inline and branch on the overflow flag to a bignum routine if the sum of the fixnums is too large. C blithely ignores integer overflow. In addition, some CPU architectures have special instructions to speed tagged arithmetic (notably the Sparc). I would be surprised if C compilers were able to use that instruction for generic arithmetic. ... and there are numerous other type representation hacks that an implementation of a dynamically-typed language system can exploit. -- Doug Quale saavik.cs.wisc.edu
eliot@cs.qmw.ac.uk (Eliot Miranda) (04/29/91)
In article <1991Apr19.132239.9252@daffy.cs.wisc.edu> quale@saavik.cs.wisc.edu (Douglas E. Quale) writes: >In article <1991Apr17.173651.23103@visix.com> amanda@visix.com (Amanda Walker) writes: >> >>However, you can certainly *implement* dynamic typing in C, with as >>low an overhead as you can get in any other language. >> > >This is not true. A C implementation of dynamic typing will be slower. >A compiler for a dynamic language can take advantage of its knowledge of >datatype representations to generate faster code. > >Two simple examples: > > 1) tag operations for type discrimination > > A compiler for a dynamically typed language can dedicate a register to > hold a bitmask that will speed type tag operations. A C program would > either use an immediate value or a global variable, either of which is > slower and bulkier on many architectures. I have tried this in my Smalltalk VM. On both 68020 & SPARC there is no significant difference in performance attributable to dedicating a register to tag detection. Add a register here loose it there. > > 2) generic arithmetic > > Suppose the dynamic language includes generic arithmetic on integers of > arbitrary size. In lisp this would give two types of integer, fixnum > and bignum. A lisp compiler can add two fixnums inline and branch on > the overflow flag to a bignum routine if the sum of the fixnums is too > large. C blithely ignores integer overflow. In addition, some CPU > architectures have special instructions to speed tagged arithmetic > (notably the Sparc). I would be surprised if C compilers were able to > use that instruction for generic arithmetic. > >... and there are numerous other type representation hacks that an >implementation of a dynamically-typed language system can exploit. If you use gcc which has a) global register variables & b) a powerful trap-door to assembler you can certainly produce as efficient a dynamic binder in C as you could in any system. I've written a quick threaded-code Smalltalk VM in C with minimal assembler (the direct threaded code jump). It would be easy to define Smalltalk objects at the C level. I accept that using (or at least specifying a language in terms of) an abstract machine leads to a concise design at one level. This does not imply that such a solution will be implementable more efficiently. With persistence (& perversity) one can get C to compile to very efficient machine code. With good compiler support (gcc) less persistence is required :-). Using C as an assembler is becomming more & more popular because it works not just because its relatively easy to do. -- Eliot Miranda email: eliot@dcs.qmw.ac.uk Dept of Computer Science ARPA: eliot%dcs.qmw.ac.uk@nsf.ac.uk Queen Mary Westfield College UUCP: eliot@qmw-dcs.uucp Mile End Road Fax: 081 980 6533 (+44 81 980 6533) LONDON E1 4NS Tel: 071 975 5229 (+44 71 975 5229)
mathew@mantis.co.uk (mathew) (04/30/91)
eliot@cs.qmw.ac.uk (Eliot Miranda) writes: > In article <1991Apr19.132239.9252@daffy.cs.wisc.edu> quale@saavik.cs.wisc.edu > > A compiler for a dynamically typed language can dedicate a register to > > hold a bitmask that will speed type tag operations. A C program would > > either use an immediate value or a global variable, either of which is > > slower and bulkier on many architectures. > > I have tried this in my Smalltalk VM. On both 68020 & SPARC there is no > significant difference in performance attributable to dedicating a register > to tag detection. Add a register here loose it there. You're saying that you've tried keeping the tags in memory vs. keeping them in a register on a 68020, and you've not noticed any difference? I find this a little hard to believe. Exactly what changes did you make to the code in order to use register-based tags rather than memory-based tags, and what sort of program did you run in order to test the result? mathew -- mathew - mathew@mantis.co.uk or mcsun!ukc!ibmpcug!mantis!mathew
quale@saavik.cs.wisc.edu (Douglas E. Quale) (05/01/91)
eliot@cs.qmw.ac.uk (Eliot Miranda) writes: > In article <1991Apr19.132239.9252@daffy.cs.wisc.edu> quale@saavik.cs.wisc.edu > > A compiler for a dynamically typed language can dedicate a register to > > hold a bitmask that will speed type tag operations. A C program would > > either use an immediate value or a global variable, either of which is > > slower and bulkier on many architectures. > > I have tried this in my Smalltalk VM. On both 68020 & SPARC there is no > significant difference in performance attributable to dedicating a register > to tag detection. Add a register here loose it there. > Experience in lisp implementation shows that it is often a good tradeoff to dedicate one or two registers to tag masks. Another trick is to have a register pointing to a vector in memory that holds commonly used constants and subroutines so that they can be accessed by a short immediate offset register indirect mode. The best papers in tagging issues for lisp are a couple by Hennessy. One of the most interesting results is that even for lisp, the percentage of execution time spent by ALL tag operations -- tag checking, extraction and addition -- is much smaller than I would have thought. I think it is a common perception that static typing is always an order of magnitude faster than dynamic binding, but this is not the case. Analysis of Smalltalk implementation issues might give different results, of course, and I am not familiar with the Smalltalk literature. -- Doug Quale quale@saavik.cs.wisc.edu
eliot@cs.qmw.ac.uk (Eliot Miranda) (05/01/91)
In article <7w4813w164w@mantis.co.uk> mathew@mantis.co.uk (mathew) writes: >eliot@cs.qmw.ac.uk (Eliot Miranda) writes: >> In article <1991Apr19.132239.9252@daffy.cs.wisc.edu> quale@saavik.cs.wisc.edu >> > A compiler for a dynamically typed language can dedicate a register to >> > hold a bitmask that will speed type tag operations. A C program would >> > either use an immediate value or a global variable, either of which is >> > slower and bulkier on many architectures. >> >> I have tried this in my Smalltalk VM. On both 68020 & SPARC there is no >> significant difference in performance attributable to dedicating a register >> to tag detection. Add a register here loose it there. > >You're saying that you've tried keeping the tags in memory vs. keeping them >in a register on a 68020, and you've not noticed any difference? I find this >a little hard to believe. > >Exactly what changes did you make to the code in order to use register-based >tags rather than memory-based tags, and what sort of program did you run in >order to test the result? > The program is a "dynamic translation to direct threaded code" Smalltalk-80 virtual machine written in C, compiled with GCC & edited into threaded code by sed-scripts run on the compiler generated assembler. The system is about 20,000 lines of C. The system is tested by running the standard Smalltalk-80 macro benchmark suite, which produces a performance figure in percents of a Dorado, Xerox's fastest D machine. The format of tagged data is tags in the bottom 2 bits 01 -> 30 bit signed integer 10 -> 16 bit unsigned character 11 -> 30 bit fixed point (16 bit fraction) 00 -> Ordinary Object Pointer Using GCC one can declare global register variables, e.g. register void (**tcip)() asm("a5"); declares the threaded code instruction pointer to be in a5 on 68020s. To test tags using immediate masks I use: #define TagMask 3 #define isTagged(o) ((unsigned long)(o)&TagMask) To test tags using a tag register I use: #define TagMask 3 register unsigned long tagReg asm("d3"); #define isTagged ((unsigned long)(o)&tagReg) ... tagReg = TagMask ... The code generated by the two sequences is either movel a3@,d6 moveq #3,d2 andl d6,d2 jeq LABEL or movel a3@,d6 andl d3,d6 jeq LABEL When I compared the two variants they ran the benchmarks to within 0.5% of each other. This difference is below the noise and hence not significant. I suspect that this is because a) moveq is very quick b) reserving a register for the tag mask slows down other parts of the system, cancelling out. Baically optimizations are tradeoffs between representations, and each implementation of a given piece of functionality will have its performance and its cost. -- Eliot Miranda email: eliot@dcs.qmw.ac.uk Dept of Computer Science ARPA: eliot%dcs.qmw.ac.uk@nsf.ac.uk Queen Mary Westfield College UUCP: eliot@qmw-dcs.uucp Mile End Road Fax: 081 980 6533 (+44 81 980 6533) LONDON E1 4NS Tel: 071 975 5229 (+44 71 975 5229)