Reprinted from Http://www.tuicool.com/articles/jYzuAv and http://www.importnew.com/1537.html
In a keynote speech that I collaborated with Martin Fowler, he made an insightful point:
The legacy of Java will be the platform, not the programming language.
The original engineers of Java technology made a wise decision to separate the programming language from the runtime environment, which ultimately enabled more than 200 languages to run on the Java platform. This architecture is critical to the long-term viability of the platform, as computer programming languages are generally short-lived. Starting in 2008, Oracle's annual JVM Language Summit provided an opportunity for other languages on the JVM to collaborate openly with Java platform engineers.
Welcome to the Java.next column series, in this series of articles, I'll cover three modern JVM languages--groovy,scala and clojure--it provides a paradigm, a fun mix of design choices and comfort factors. I'm not going to take the time to go into each language in depth, and this kind of in-depth presentation on their respective sites. But the sites of these language communities-whose primary purpose is to spread these languages-lack objective information or are examples of the language's non-applicability. In this series of articles I will compare independently to fill the above blanks. These articles will outline the Java.next programming languages and the benefits of learning them.
Beyond Java
The extent to which the Java programming language achieves excellence is that, according to Bruce Tate in his beyond Java book, the Perfect Storm: The Rise of Web applications, the emergence of web technologies that cannot adapt to demand for various reasons, and the rise of enterprise-class multi-tier application development, These factors together create the excellence of Java. Tate also pointed out that the storm was a unique series of events that had not been used in other languages to achieve the same excellence program.
The Java language has proved its powerful flexibility in terms of functionality, but its syntax and intrinsic paradigms have long-known limitations. Although some promised changes are about to be introduced into the language, Java syntax cannot easily support some important future grammatical features, such as some of the features in functional programming. But if you're trying to find a language to replace Java, then you're looking at the wrong one.
Multi-language programming
Multi-lingual programming-in a 2006 blog I made the term rejuvenated and popular-based on the recognition that no programming language solves every problem. Some languages have some built-in features that enable them to better adapt to specific problems. For example, because swing is so complex, developers find it difficult to write the swing UI in Java because it requires declaring types beforehand, defining annoying anonymous inner classes for UI actions, and other problems. Building a swing app can be a lot more fun using a language that's better suited to building the UI, such as the Swingbuilder tool in groovy.
The large number of programming languages running on the JVM has greatly stimulated the idea of multilingual programming, because you can mix numbering languages and use best-fit languages, while maintaining the same underlying bytecode and class libraries. For example, Swingbuilder is not an alternative to swing; it is built on the existing swing API. Of course, for a long time, developers will still be mixing programming languages outside the JVM-for example, using SQL and javascript--for specific purposes but in the JVM world, mixed programming will become more prevalent. Many of the projects in ThoughtWorks are shared with a variety of programming languages, and all tools developed by ThoughtWorks Studios use mixed languages.
Even though Java is still your main development language, learning how other languages work will allow you to incorporate them into your future strategy. Java will remain an important part of the JVM ecosystem, but ultimately it is more of an assembly language for the platform-either for purely performance reasons or for special needs.
The evolution of programming languages
When I was in college in the 80 's, we used a development environment called Pecan Pascal. Its unique feature is that the same Pascal code can run on both Apple II and IBM PCs. Pecan's engineers used a mysterious thing called "bytecode" to achieve this goal. The developers compiled their Pascal code into "bytecode", which runs on the native "virtual machines" written for each platform. It was a horrible experience! The final program is surprisingly slow, even if it's just a simple class assignment. The hardware at the time was unable to meet this challenge.
Ten years after Pecan Pascal, Sun released Java, which uses the same architecture, and was constrained by the hardware environment of the 90 's. Java also added other developer-friendly features, such as automatic garbage collection. Now that I've used a language like C + +, I don't want to use a language that doesn't have garbage collection anymore. I'd rather take the time to think about complex business issues at a higher level of abstraction than complex plumbing problems like memory management.
One of the reasons why computer language is usually not long-lived is the speed of innovation in language and platform design. As our platforms become more powerful, they can handle more of the extra work. For example, Groovy's memory (Memoization) attribute (joined in 2010) caches the result of a function call. There is no need to write the cache code manually, which introduces a potential flaw, you just need to call the Memoize method, as shown in Listing 1:
Listing 1. In groovy, the memory function
def static sum = {Number
Factorsof (number). Inject (0, {i, J-i + J})
}
def static sumoffactors = Sum.memoize ()
In Listing 1, the results returned by the Sumoffactors method are automatically cached. You can also use methods Memoizeatleast () and Memoizeatmost () to customize the caching behavior. Clojure also contains memory features, which are also slightly implemented in Scala. Advanced features such as memory that exist in next-generation programming languages (and some Java frameworks) will also gradually enter into the Java language. In the next version of Java, higher-order functions (Higher-order function) are added, which makes memory easier to implement. By studying the next generation of Java languages, you can first see the future features of Java fast.
Groovy,scala and Clojure
Groovy is the 21st century Java syntax-Espresso replaces traditional coffee. Groovy's design goal is to update and eliminate barriers in Java syntax, while supporting the main programming paradigm in the Java language. As a result, groovy wants to "know" such as JavaBean, which simplifies access to properties. Groovy will incorporate new features at a very rapid pace, including important features in functional programming, which I will highlight in subsequent chapters of this series. Groovy is still primarily an object-oriented, imperative language. Groovy differs from the two basic differences in Java: It is dynamic rather than static; it is a much better meta-programming capability.
Scala is designed to use the JVM in its bones, but its syntax is completely redesigned. Scala is a strongly-static type language-its type requirements are stricter than Java's, but it does little trouble-it supports object-oriented and functional paradigms, but prefers the latter. For example, Scala prefers the Val declaration, which generates immutable variables (similar to declaring variables as final in Java) to Var, and Var creates mutable variables that are more familiar to us. With deep support for both paradigms, Scala is a bridge between what you might want (object-oriented imperative programming) and what you should want (functional programming).
Clojure is the most radical, and its grammar is separated from other languages and is considered to be the dialect of Lisp. Clojure is a strongly dynamic type language (like groovy), which reflects a design decision that is not in the way. While Clojure allows you to have full and deep interaction with legacy Java programs, it does not attempt to build a bridge to connect to the object-oriented paradigm. For example, Clojure is a hardcore for functional programming, and it also supports object-oriented to allow interoperability with that paradigm. Although it supports all the features that the object programmer is accustomed to, such as polymorphism, it is implemented in a functional style rather than an object-oriented style. The design of Clojure follows a set of core engineering principles, such as software transaction memory (software transactional memories), which breaks the old programming paradigm to cater for new functionality.
Programming paradigm
In addition to the syntax, the most interesting differences between these languages are the types and their intrinsic programming paradigms: functional or imperative.
Static type vs. dynamic type
A static type in a programming language requires an explicit type declaration, such as an int x in Java, and a declaration statement. Dynamic type languages do not require type information to be provided at the time of declaration. The language considered here is a strongly typed language, meaning that the program can reflect the type after it is assigned.
The widespread criticism of Java's type system is that its static type has too much inconvenience and does not provide sufficient benefits. For example, before the current finite type deduction occurs, Java requires the developer to declare the type repeatedly on both sides of the assignment statement. Scala's type is more static than Java, but it is much less inconvenient in everyday use because it uses a lot of type deduction.
At first glance, groovy, it seems that there is a behavior that connects the gap between static and dynamic. Consider the Simple object collection factory as shown in Listing 2:
Listing 2. Groovy Collection Factory
Class Collectionfactory {
def List GetCollection (description) {
if (Description = = "Array-like")
New ArrayList ()
else if (description = = "Stack-like")
New Stack ()
}
}
The class in Listing 2 behaves as a factory class that returns one of two implementations of the list interface,--arraylist or stack--, based on the passed-in description parameter. For Java developers, the above code ensures that the return value conforms to the Convention. Then, the two unit tests in Listing 3 reveal a complication:
Listing 3. Collection type testing in Groovy
@Test
void Test_search () {
List L = f.getcollection ("Stack-like")
Asserttrue l instanceof Java.util.Stack
L.push ("foo")
Assertthat l.size (), is (1)
def r = L.search ("foo")
}
@Test (Expected=groovy.lang.missingmethodexception.class)
void Verify_that_typing_does_not_help () {
List L = f.getcollection ("Array-like")
Asserttrue l instanceof Java.util.ArrayList
L.add ("foo")
Assertthat l.size (), is (1)
def r = L.search ("foo")
}
In the first unit test in Listing 3, use the aforementioned factory class to get a stack object and verify that it is indeed a stack object before performing a stack operation, such as push (), size (), and search (). However, in the second unit test, I had to declare an expected exception missingmethodexception to make sure that the test would pass. When I get a collection of array-like and assign it to a variable of the list type, I can verify that the returned type is actually a list object. However, when I try to invoke the search () method, the exception is triggered because ArrayList does not contain the search () method. Therefore, this declaration cannot ensure that the method's invocation is correct at compile time.
While this may seem like a flaw, this behavior is appropriate. The type in groovy just ensures the validity of the assignment statement. For example, in Listing 3, if the returned instance does not implement the list interface, a run-time exception groovycastexception will be triggered. In this regard, it is certain that groovy can be a strong dynamic type language family with Clojure.
However, some of the latest changes in groovy have allowed the gap between its static and dynamic to be swept clean. Groovy 2.0 joins the annotation @typechecked, which allows you to specifically type-check the class or method decisions. Listing 4 illustrates the use of this annotation:
Listing 4. Type checking with annotations
@TypeChecked
@Test void Type_checking () {
def f = new Collectionfactory ()
List L = f.getcollection ("Stack-like")
L.add ("foo")
def r = L.pop ()
Assertequals R, "foo"
}
In Listing 4, I added the annotation @typechecked, which validates both the assignment and the subsequent method invocation. For example, the code in Listing 5 will not compile:
Listing 5. Type checking to prevent invalid method calls
@TypeChecked
@Test void Invalid_type () {
def f = new Collectionfactory ()
Stack s = (stack) f.getcollection ("Stack-like")
S.add ("foo")
def result = S.search ("foo")
}
In Listing 5, I had to force type conversions on the objects returned by the collection factory to allow me to invoke the search () method in the Stack class. But this approach has some limitations: when you make a type static, many of groovy's dynamic features will not work. However, the help shown above proves that groovy will continue to improve to bridge the gap between static and dynamic nature.
All of these languages have very powerful meta-programming capabilities, so more rigorous typing can be added afterwards. For example, multiple branch projects have introduced a selective type (selective type) into Clojure. However, it is generally assumed that the selectivity type is optional and is not part of the type system; it is just a type validation system.
Imperative vs. function-type
Another major comparison dimension is imperative and functional. Imperative programming focuses on a single-step structure, and in many cases it mimics the beneficial structure of the early underlying hardware. Functional programming focuses on using functions as first-order structures to minimize state passing and variability.
Groovy is largely inspired by Java, which is still essentially an imperative language. But from the very beginning, groovy added many features of functional commands, and added more such features later.
Scala has bridged both of these programming paradigms, while supporting both paradigms. While more biased (and more encouraging) functional programming, Scala still supports object-oriented and imperative programming. Therefore, in order to properly use Scala, it requires the team to be well trained to ensure that you do not mix and choose the programming paradigm arbitrarily, which is always a danger in multi-paradigm programming languages.
Clojure is a functional programming language for irons. It also supports object-oriented features that make it easy to interact with other JVM languages, and it does not attempt to bridge the gap between the two paradigms. On the contrary, the Clojure decision makes the statements considered by its designers a good engineering practice. These decisions have far-reaching implications, enabling Clojure to solve some lingering problems in the Java world, such as concurrency, in a groundbreaking way.
Many of the mental transformations required to learn these new languages derive from the great difference between imperative and functional, which is one of the most valuable areas to explore in this series of articles.
Recently two large-scale JVM programming languages were voted (Poll 1, poll 2). These polls produce some very interesting data. Because voters come from different camps, the results of the two polls are slightly different.
Clojure has progressed very well in my voting (leading Scala and groovy), because many of the voters are from hackernews groups who love Lisp. Another dzone poll attracted a long line of voters (mainly the Dzone Java Developer Community), and the most popular was groovy, followed by Scala,coljure followed. Two votes the same point is that the JVM language "Big Three" (Scala, Clojure, and groovy) is far ahead of all other languages. This otherworldly combination represents the most developer-supported, non-Orthodox JVM development language.
To get a clearer picture of the popularity of the two voting languages, I integrated the poll results data and drew a picture. The "Big Three" and the JRuby (Encouragement Award) are included in the figure. You can see that the number of votes in Scala, Clojure, and groovy in the consolidated data is very close:
The popularity of developers does not necessarily mean the heat of business applications. Indeed.com collects data from a huge recruiting site as an ideal source of data to reflect business applications. Query the three big languages from the position trend system it offers, and the results are very interesting:
Both groovy and Scala's data show strong business application heat, and clojure are lagging far behind and rising slowly. This is consistent with the Dzone poll results and validates my theory that the majority of Clojure's support comes from amateurs and Lisp hackers rather than business organizations.
Groovy is ranked first in the picture. The big three includes two dynamic-type languages (Groovy, Clojure) and a static-type language (Scala).
The most exciting achievement in recent years has been the thriving ecosystem that has evolved around the emerging JVM programming language, and 10 years ago, at this time, the CLR (. NET-provided common language runtime, translator note) is being declared as a runtime that supports multiple programming languages. Thanks to the active efforts of the broad community, the JVM is becoming a priority for emerging languages, innovations and research.
[reproduced] Details of three modern JVM languages--groovy,scala and Clojure