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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,c406e0c4a6eb74ed X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news1.google.com!news.glorb.com!border1.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!feed2.news.rcn.net!rcn!feed3.news.rcn.net!not-for-mail Sender: jsa@rigel.goldenthreadtech.com Newsgroups: comp.lang.ada Subject: Re: ADA Popularity Discussion Request References: <49dc98cf.0408110556.18ae7df@posting.google.com> <6F2Yc.848$8d1.621@newsread2.news.pas.earthlink.net> <413e2fbd$0$30586$626a14ce@news.free.fr> <9snhizowcwg9.16smaxkxhyu67$.dlg@40tude.net> <413f770d$0$30111$626a14ce@news.free.fr> From: jayessay Organization: Tangible Date: 09 Sep 2004 20:47:54 -0400 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: DXC=ll1ED_KeZ]EXH7>k6?ZMSO0R]m=BkYWIG:6bU3OT9S9J=M6JT0^P`=F^aM2i8keRmM]mkK60 Lionel Draghi writes: > jayessay wrote: > ... > > First, types are indeed part of program design in dynamic languages. > > In some respects they are even more important than in static languages > > as they exist at _all_ times: compile load (link) and run. They are > > _always_ checked _all_ the time. If you want to say "Ooo! this has a > > performance hit", fine, but with current systems any such checks are > > basically in the noise. OTOH, you can annotate a dynamic program with > > static type information and/or use type inference to remove this issue > > from most cases. > > Jon, > > I am trying my best to understand you without knowing Lisp, but I > don't. This is the second time you explain this, but you are to > abstract for me. I'm not sure which part you are having trouble with. Let's try this (admittedly somewhat handwavy, but intended to help get the ideas): To a reasonable first approximation: What is typed? Static: Variables and expressions (including literals and variables) Dynamic: Values (the things you think of as "in a variable" or as the result of the evaluation of an expression) Where/when is the "type"? Static: In the compiler's symbol table and semantic analyzer; exists during compilation. Types do not exist at runtime. To some extent they are still around at link time in C++ in order for template instantiation to work. Important: Types are _not_ first class objects. Dynamic: In values; exists whenever a value exists - compiletime, load/link time, and runtime. Important: Types _are_ first class objects, i.e., there are _values_ which are _types_. The types of these value types are meta types. You can walk as far up the "logic ladder" as you want with this. "Ontologically" there is no difference (they have the same fundamental status) between these kinds of values and any other, e.g., integers, class instances, etc. You can bind them, query them, create them, if (as in Common Lisp) you have a meta object protocol (MOP) you can even _change_ them and _alter_ the behavior of the type system. There is a lot more here. What is checked? Static: Variables (containers) conform to expressions Dynamic: Values conform to operations (functions operators, etc.) When are things checked? Static: Mostly at compile time (though there are important exceptions) Examples: (Ada) x := a; The type of variable A is checked to conform with the type of variable X, so that X is assured that whatever the _value_ in A during runtime, it should be a member of the type of X (conform to it). x := a + b; the types of A & B are used to select a set of + operator candidates whose result types are then checked against the type of X to determine the unique operation (if it exists) to use. Generally, there is a good deal of copying of values going on at runtime. Variables exist only at compile time (though in C++ there is some level of existence through link), they are transformed to simply locations with enough space to hold values of the variables type (as determined at compile time)[2]. Dynamic: Mostly at runtime (though there are some useful exceptions). Examples: (Common Lisp) (let ((x a)) ...) the value _bound_ by (named by) A is _bound_ to X, so that X is also a _name_ for it within the scope of the let. Unless specifically requested, there are no type checks being made in these cases since there is no need for it - since a variable is just a binding (name) for a value it can be used to name any value. No copying is ever done. You can change or add a name to a value without opening a new scope by means of setf, e.g., (setf x a) (let ((x (+ a b))) ...) the standard + operation is generic (this is more analogous to an Ada function of a class wide type, than to generics). The dispatch mechanism checks the types of A and B and either raises an exception if there is no possible match or performs the operation[2]. If the operation is performed, the resulting value is _bound_ to X within the scope of the let. Values are never copied. Variables typically do not exist at runtime, with the important exception of dynamic variables (full symbols). Variables are basically transformed into locations that reference values. Is type consistency enforeced (is it type safe)? Static: Mostly. Casts, certain unchecked conversions, overlays can all subvert this. Dynamic: Yes, values cannot be interpreted as any type other than what they are. > My point is that with static typing, most type related problems are > caught at compil time, before any execution. > Know, you say here that it is possible to write annotation to reach > the same confort level in Lisp. > Could you explain me how is this supposed to save time and money? It is the extreme flexibility and interactive nature of the development with continual checking that is the big time saver and bug eliminator (both type and logic). The type annotation you can do does not save you any development time (it actually costs time - just like with static typing), it can save you runtime cycles by allowing the compiler to perform more optimizations. The really key thing here is that you develop by testing _everything_ in a very well scoped and limited unit at each incremental stage. I realize this is hard to get a grip on unless you've done it - especially coming from a global static type kind of mind set. > Correct me if I am wrong, but you stated that > "Actually this sort of development will save you much more > time and money than you could ever hope for from typical static typing." > > And this is misinformation: I don't think it is misinformation, but upon reading it again it could well be inaccurate. Misinformation is when you state a falsehood as fact about something you know nothing about. For example, "dynamic typing means no typing", "dynamic typing is unsafe", "lisp is interpreted". The above is inaccurate in that for all I know for some instantiation of "you", that instance will _not_ save anything using this sort of development. I know it has been true for me and many others I know. > *BUT*, static typing is still unbeatable, with or without test-fist > practice, as I illustrate in another message. In general I'm long past believing this. Even the Haskellers, MLers, etc. don't have good enough arguments or data to support the claims. I do believe that in certain niches this can indeed be true. /Jon Notes 1. As noted in the preface this is only a first order approximation. For example, in Ada, there may well be some extra stuff (e.g., dope vectors) beyond simply a location for things like unconstrained arrays. 2. This is _not_ like a "polymorphic" dispatch, that is the domain of methods, and generic functions nor an overloading. Generic functions are a proper superset of standard class based "object oriented" polymorphism. -- 'j' - a n t h o n y at romeo/charley/november com