When talking about the type and method of the Java language, the Java Community is divided into two camps. Some people like error checking during compilation, better security, and improved tools-these are all features of static types. Others prefer a more dynamic type of experience. This time, you will see some very different types of policies used by the two highly productive non-Java languages, and some methods to improve the type flexibility of concurrency in Java programming.
In the discussion of any programming language, a controversial issue is the type model. The type determines the types of tools that can be used and affects the application design. Many developers associate the type with productivity or Maintainability (I am one of them ). Typical Java developers are usually very happy to maintain the role of the type model of the Java language, emphasizing that the Java language can adopt better development tools, capture certain types of bugs (such as type incompatibility and spelling errors) during compilation, as well as performance advantages.
If you want to understand a new programming language or even a series of languages, you should generally start with the type strategy. In this article, you will see the type model in some languages other than Java. First, I will briefly introduce some decisions that must be taken into account by any language designer in the type model, focusing on some different decisions of static and dynamic types. I will show some extreme examples-static types in Objective Caml and dynamic types in Ruby. I will also talk about the type restrictions of the Java language and how to break through the restrictions of the Java type for fast programming.
Type Policy
The following types can be viewed from at least three perspectives:
The static or dynamic type depends on when the type model is implemented. Static type language implements the type during compilation. Dynamic Language is usually implemented at runtime based on the characteristics of an object.
Strong or weak type depends on how the type model is implemented. The type is strictly enforced. If any violation of the type rule is found, a runtime or compile-time error is thrown. The weak type leaves more room. In extreme cases, a weak type language (such as a hacker) allows any data type to be assigned to another type (whether or not the value is meaningful ). Static languages can be either strongly typed or weak. Dynamic type systems are usually strongly typed, but not completely.
The explicit or implicit type depends on how the language determines the type of a given object. Explicit language requires that each variable and each function parameter be declared. The implicit type language determines the object type based on the syntax and structure clues in the language. Static language is usually explicit, but not completely; Dynamic Language is almost implicit.
The following two examples illustrate the connotation of these two perspectives. Suppose you compile the following Java code:
Class Test { Public static void test (int I ){ String s = I; } } |
You will receive the following error message:
Test. java: 3: incompatible types Found: int Required: java. lang. String String s = I; ^ 1 error |
Run the following Ruby code:
You will receive the following error message:
TypeError: String cant be coerced into Fixnum From (irb): 3: in + From (irb): 3 |
Both languages tend to be strongly typed, because they throw an error message when you try to use an object of A type structure other than they expected. The Java type policy provides an error message during compilation because it performs a static type check. Ruby provides error messages at runtime, because Ruby supports dynamic types. In other words, Java binds an object to a type during compilation. Ruby binds the object to the type whenever the object is changed during runtime. Because I declare variables in Java code rather than Ruby, we can see that the explicit type of the Java language works differently from the implicit type of Ruby.
From these three perspectives, static and dynamic types have the greatest impact on language features. Therefore, I will focus on the advantages of these two strategies.
Advantages of static types
In a static type language, the programmer (by declaration or by Convention) or the compiler (based on the structure and syntax clue) assigns a type to a variable, and that type will not change. Static types usually require additional costs, because static types (such as Java) are usually explicit. This means that all variables must be declared and the code is compiled. Cost is also accompanied by benefits: Early error detection. Static types provide much more information for compilers at the most basic level. The advantage of more information is that some types of errors can be captured earlier, and dynamic type languages can only detect these errors at runtime. If you wait until the runtime to capture these bugs, some of them will enter the production environment. Perhaps this is one of the most criticized aspects of Dynamic Language.
In another view, modern software development teams typically run automated tests, and supporters of dynamic languages claim that even the simplest automated tests can capture most types of errors. The best argument that dynamic language supporters can provide is that the benefits of early detection are less than the cost, because whether dynamic types are used or not, all tests are required.
An interesting compromise is to use an implicit type in a static type language to reduce the type cost. Open source code language Objective Caml (OCaml) is a derivative of static type Language Lisp, which can provide good performance without sacrificing productivity. OCaml uses the implicit type, so you can write the following code using the static type:
# Let x = 4 + 7
OCaml returns:
Val x: int = 11 |
Based on the syntax clues in the expression, OCaml deduced the x type. 4 is the int type, and 7 is also the int type. Therefore, x must be the int type. Implicit type languages can have all types of Java security, or even more. The difference lies in the amount of information you need to provide and the amount of information available when reading the program. Many people who prefer static types prefer implicit types. They would rather have the compiler do this, rather than repeatedly entering the variable type in the code.
The implicit type system does not need to declare a type for a function parameter because the compiler will deduce the type of the parameter from the input value. Therefore, the same method can be used for multiple purposes.
Errors about refactoring
Some people think that static type features are necessary to obtain a good IDE with refactoring support. This is ridiculous. Most modern ides have absorbed something from earlier Smalltalk ides. In fact, some basic things in Eclipse early on were Visual Age for Java, which was first published on the Smalltalk Virtual Machine! Smalltalk Refactoring Browser is still one of the most comprehensive Refactoring tools available today (see references ). The Java language still has better tools than most popular dynamic languages (except Smalltalk), and static types are the biggest reason.
Not only the compiler can take advantage of the additional information provided by the static type. IDE can provide better support for refactoring through static types. Several years ago, a revolutionary idea changed the way the development environment works. In IDEA and Eclipse, your code looks like a text view, but the development environment is actually editing Abstract Syntax Tree (AST ). Therefore, when you need to rename a method or class, it is easy for the development environment to precisely locate each place where the method or class is referenced in the AST. Today, without the excellent refactoring simplified by static types, it is hard to imagine programming in Java. I miss IDEA more than any other tool or feature when I explore Ruby.
Static types have other advantages. I will not describe them in detail here. Static types provide better security and obviously improve code readability. Static types can also provide more information, making it easier for the compiler to optimize and thus improve performance. But the biggest reason why static types have won developers' favor is that they are easier to detect errors and have more available tools.
Advantages of dynamic types
Ruby expert Dave Thomas called the dynamic type duck typing (see references), which has two meanings. The first layer means that this language does not actually implement the type-it uses duck theory to solve this problem. The second layer means that if something goes up like a duck, it may be a duck. In the context of a programming language, duck typing means that if an object reacts to a certain type of method, it can actually be treated as that type. Such features can lead to some interesting optimizations.
Most developers who prefer dynamic types not only emphasize the unnecessary cost of early error detection, but also mention the good expressiveness and productivity of dynamic types of languages. Very simple. You can usually use fewer keywords to express more ideas. As a new supporter of Ruby, I am confident that dynamic languages can improve productivity, although I cannot come up with more concrete evidence than those of common static languages. However, since I started writing more Ruby code, I feel that my productivity has improved significantly. It is true that I still see the advantages of static types, especially in terms of tool sets, But I gradually realized the disadvantages of static types. When I started writing code in Ruby, the biggest change I had was the ability to generate and use a metaprogramming structure. If you have been focusing on cross-border series from the beginning, you will know that meta-programming, or programming programs for programming, is a major driving force of Ruby on Rails. More generally, it is a major driving force for domain-specific languages. When programming with Ruby, I usually write larger build blocks or build with larger ones. I found that, compared to Java programming, I can extend my program with more types of reusable blocks. Just