I haven't listened to this episode yet, but... thank you for a most
informative post! I was ignorantly classing languages in only 2 of
those dimensions up until now. :)

On Nov 5, 9:19 am, Reinier Zwitserloot <[email protected]> wrote:
> I wish I was there, because the vast majority of points raised have
> absolutely zip squat to do with dynamic vs. static.
>
> 1. Growing existing types - can be done globally (so called dynamic
> scoped), which is awful, because once your project grows beyond the
> small, everyone overriding everything just makes it impossible to
> figure out what is what, and you get conflicts. This is what rails
> does - it redefines half the ruby core. An alternative is lexically
> scoped extensions, which is really much nicer; an import statement
> adds methods to, say, all strings, but *ONLY* inside the file that
> contains the import statement. Both C# and Scala (both very much
> statically typed languages!) can do this. Clearly, no relation
> whatsoever to dynamic v. static typing.
>
> 2. Growing interfaces - nobody can do that without stuff breaking. If
> you need to support pre-extension stuff while still extending, with
> default behaviour, then you can do that. Scala can do this (traits),
> and scala is statically typed. Clearly has not one iota to do with
> dynamic v. static. For those who don't know scala: Imagine you could
> give interface methods a method body, which will be used for all
> classes that implement your interface but do not specify an
> implementation. This method body can't use any of the fields of the
> class, of course, so it's not as unique as being a superclass. Voila:
> Extensible interfaces, in a fully static language.
>
> 3. duck typing the way it was explained in the roundup - in other
> words, ad hoc interfaces, in other words: Give me any object that has
> a 'doFoo();' method. Again, has nothing to do with typing systems. In
> scala, you can make structural types which do exactly this: You can
> create a type that says: Anything that has a doFoo() method. If you
> then accept this type as, say, a method parameter, you can call doFoo
> () on this parameter, and any object of a type that includes a doFoo()
> method can be passed in.
>
> 4. Static typing is verbose. No, it isn't. This has nothing to do with
> static typing.
>
> Time for a rehash of the 4 dimensions of type systems.
>
> Weak vs. Strong: This refers to whether or not the *OBJECT* knows its
> own type. C and C++ are *WEAK* even though they are also static. You
> can cast, say, a String to an Integer object, then get core dumps as
> the methods that work on Integers work on String's data structure
> which is nothing like Integers. Python, Ruby, Javascript, Java, C#,
> and Scala are all Strong. Basically, if objects have a .getClass()
> kind of method, you're looking at strong typing. Strong typing also
> implies you get cast errors of a sort. So, in python, when you call a
> non-existent method on an object, you don't get a core dump, or
> unspecified behaviour. you get clear behaviour: A method missing
> error.
>
> Static vs. Dynamic: Whether *REFERENCES* have a type. So, in: "Object
> x = "foo";", x is a reference, and its type is "Object". x, being a
> reference, points at something. It points, in fact, at a string, which
> has a String type. The fact that "foo" knows its a String means java
> is strongly typed. The fact that 'x' also has a type, means java is
> statically typed. In e.g. javascript, which is dynamically typed, you
> just write "var x = 'foo';" and as a result 'x' itself has no type,
> but the thing x is pointing at, does. *THIS*, and only this, is static
> vs. dynamic typing. You can of course mix the two, which is just what
> groovy and C# do, even though most people refer to these as 'static'
> languages. They are actually hybrids. Java is very much static.
> Sometimes, latent typing (where the compiler INFERS the type of a
> reference, instead of just not caring about what it is) is confused
> for dynamic typing. Don't do that.
>
> Nominal vs. Structural: A type is simply an assertion about an
> object's nature. Thus, this: [Anything with a getFoo() method],
> qualifies as a type, technically. There are two ways to think about
> types: You can think about what a type says about structure, or you
> can think of types by themselves, generally identified by an
> identifier (e.g. a name). This is nominal vs. structural typing. Java
> is 99% nominally typed; if I have: class Foo { void shoot(); }, as
> well as interfaces Gun and Camera, also both with shoot() methods,
> then a Gun isn't a Camera, and a Foo is neither a Gun nor a Camera.
> They ALL have the exact same structure (namely: I have a shoot()
> method), and yet they aren't the same type, because they don't have
> the same name: Thus, nominal typing. Java is structural in how it
> handles main methods - a runnable class is one that has a static void
> main(String[] args) method, regardless of its nominal types (the
> interfaces and superclass). Scala is a hybrid; you can pick and mix.
> Most dynamic languages are structural. Just interact with structure
> (call methods, read or write fields), and if the object has that
> structure, it works, and if not, it doesn't. An obvious downside to
> structural typing is that you can shoot yourself in the foot due to
> lack of namespacing - namespacing every method is rather tedious, so
> you don't do it, and then you get to call shoot() on a Gun, thinking
> it was a Camera.
>
> You can mix structural and static if you want: In such a language, you
> would be able to cast a Camera to a Gun without any issues, because
> they have the same structure. If you want to create a method that
> takes 'any object with a foo()' method, you just create an interface
> with a foo() method, make it private if you want, even, use that as
> method parameter type, and it'll work. This isn't how java works, of
> course, because java is nominally typed. BGGA's (the closure proposal)
> biggest downside is that it turns java into a structural/nominal
> hybrid, as it introduces stuff like {String, String => Integer} as a
> type, which is obviously structural.
>
> Latent vs. Manifest: When you write: List<String> x = Arrays.of("a",
> "b"); - you don't actually specify that Arrays.of() is going to build
> a list of strings. It's not inferred from the left, it's inferred from
> its arguments (which are both strings). Yet, it is very much static
> typing: That is functionally equivalent to Arrays.<String>of("a",
> "b");, but it's just that the compiler inferred the <String> part of
> that. Contrast this to dynamic languages, where "String" (or List)
> isn't needed. Java infers very little, but scala infers more, and
> haskell infers a lot more. Inferring types means you have a latent
> language, and if the language mostly forces you to be explicit, you
> have a manifest language. Virtually all languages are hybrids, and
> this term doesn't really apply to non-static languages. Boo is almost
> exactly like python, but statically typed. It's very latent, so almost
> all python code just runs as boo, and yet one is static, and the other
> is dynamic. A lot of the 'it's all so verbose' complaints actually are
> complaining about java's manifest tendencies. Has nothing to do with
> static v. dynamic.
>
> Example:
>
> You could easily add the following rule to java, so that the following
> is legal, and figures out that you must have meant that the method is
> to return Numbers:
>
> def foo() {
>    if (something) return 1;
>    else return 2.0;
>
> }
>
> because the most specific commonality between 1 and 2.0 is
> java.lang.Number. This isn't legal java, but it could be. That would
> be an example of latent typing - no need to specify types, the
> compiler infers them.
>
> Only after you understand all these distinctions, you can make
> reasonable arguments about pros and cons, without the discussion being
> all over the place, drawing all sorts of faulty conclusions, like the
> roundup. For example, you can weigh the benefits of shorter code
> (which isn't so much about not typing much, but more about reading
> less, which can help), against the obvious conclusion that with a lot
> of latent typing, the compiler has to do a lot of inference, and if
> the compiler gets it wrong, the resulting error messages tend to be
> cryptic. This is why haskell's cryptic errors if you make syntax
> mistakes is something many people think is a fundamental, unfixable
> aspect of that language. Most latent languages allow you to specify if
> you want to, though.
>
> The central argument between static v. dynamic usually boils down to:
> Is it worth it. Types itself are easy, and between using latent typing
> and the simple fact that you can't unit test comments, so moving
> anything you'd stuff into a doc-comment in python into an explicit
> typing system is always a good thing - seems to indicate Static is in
> all ways superior to dynamic. However, to do it right, you need
> generics, which have co- and contravariance, and this is where things
> get rather complicated. Is it worth it to avoid cast bugs? Heck no, it
> isn't. Cast bugs are rare, and the complexity introduced when you want
> to do serious generics-fu is massive. That's the standard argument of
> dynamic typing fans, and it shows that they don't understand what
> static typing is for, because:
>
> Static typing is all about documentation (which fortunately WAS raised
> in the roundup!) - you're going to have to document the structure of
> what your method returns anyway, might as well do so in a way that the
> compiler can help you out, and in a way you can test. Static typing
> make auto-complete work.
>
> So the real question is: Is the considerable complexity of e.g. co/
> contravariance a fair cost compared to the value of having tool-
> readable documentation about how your program chunks behave, which
> those tools can use to do e.g. much smarter refactoring? It's question
> for the ages - and I'm happy the discussion did eventually get around
> to this.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to