I was just wondering if anyone other than me thought that it would be incredibly usefull to have a language that was both dynamic AND statically typed.

Using Java as a example, it could do the following:

1) Define a special dot operator that auto type casted something of type Object to its lowest possible level. So maybe instead of ((Integer)getRandomTypeObject()).intValue(), you could do getRandomObject()->intValue. There -> is the special operator. A function could take an Object as its input and and just constantly use the -> operator, which would make it dynamic.

2) Allow said operator to also "create" instance variables dynamically. So object->notCurrentlyExistantVariable = 2 would make a new variable called notCurrentlyExistantVariable and set it to 2, or else, if it does exist, just set its value.

3) Make everything an object so that the (1) suggestion would work for everything.
4) Make interfaces dynamic as well. So the compiler would just check if the object implements the functions of the interface, and would not care about its actually having the interface.

Is there a reason why this wouldn't be usefull. Methods where you KNOW what it's going to return you can use static types for clarity and for the IDE, but elsewhere you can use the Object type with the -> operator.

incredibly usefull to have a language that was both dynamic AND statically typed

Such languages are called optionally typed languages.

I'm not a big fan of such languages since it seems like a half assed attempt though I'm sure many swear by it. The advantages being:

  • Writing dynamic code when you don't care about the types
  • Start type annotating your code when you feel you need them

But the thing is, modern languages are immensely powerful and include a lot of features which cut down on the boilerplate code and make your life easier. That too to an extent that it makes them look like dynamic languages (since you can omit types due to type inference). As an example, consider the following snippet in Scala:

val names = List("sanjay", "vikas", "nick", "david", "alan")

// shortNames: List(nick, alan)
val shortNames = names filter (_.length <= 4)

// lengths: List((sanjay,6), (vikas,5), (nick,4), (david,5), (alan,4))
val lengths = names map (x => (x, x.length))

In the above snippet, the compiler knows that names represents a list of Strings even when you don't specify string anywhere. Similarly, map and filter operations know they are operating on list of strings. I would say that's pretty damn close to a code written in a dynamic language with all the benefits of a type system.