Reflection of exceptions, expressions, and empty
In the previous installment, I introduced the innovative way in which the next generation of Java language was used to eliminate the flashy things and complexities in the Java language. In this installment, I'll show how these languages eliminate some of the flaws in Java: exceptions, statements and expressions, and edges around null.
An expression
A legacy of the Java language inherited from the C language is the distinction between programming languages and programming expressions. Examples of Java statements include lines of code that use if or while, and lines of code that use void to declare methods that do not return any values. An expression, such as 1 + 2, is used to fetch a value.
This distinction has already begun in the earliest programming languages, such as in Fortran, which is based on hardware conditions and a preliminary understanding of programming language design. In many languages, it is kept as an indicator of the action (statement) and the evaluation (expression). But language designers have come to realize that the language can be composed entirely of expressions, ignoring results when not interested in the results. In fact, all functional languages can completely eliminate this distinction, using only expressions.
Groovy's if and?:
In the Java next-generation language, the separation between traditional imperative language (Groovy) and functional languages (Clojure and Scala) shows evolution to expressions. Groovy still contains statements that are based on the Java syntax, but add more expressions. Scala and Clojure use an expression entirely.
The words contained in statements and expressions add grammatical awkwardness to the language. You can consider the IF statement in Groovy, which inherits from Java. It has two versions, which are compared in Listing 1, and these two are the IF statements for executing judgments, and the mysterious ternary operator?::
Listing 1. Groovy's two IF statements
def x = 5
def y = 0
if (x 2 = = 0)
y = x * 2
else
y = x-1
println y //4
y = x% 2 = 0 ? (x *= 2): (x = 1)
println y //4
In Listing 1 of the IF statement, I must set the value of X to a side effect (side effect) because the IF statement does not return any values. To perform a judgment and assign the value at the same time, you must use a ternary assignment, as shown in the second assignment statement in Listing 1.
Scala's expression-based if statement
Scala eliminates the need for ternary operators and allows if expressions to be processed in both cases. You can use it, just as you would use an if statement in Java code (ignoring the return value), or use it in an assignment statement, as shown in Listing 2:
Listing 2. Scala's expression-based if statement
Val x = 5
val y = if (x 2 = 0)
x * 2
else
x-1
println (y)
Scala, like the other two Java next languages, does not require a clear return statement to be included in the method. Therefore, the last line of the method is the return value, emphasizing the expression-based attributes of the methods in these languages.
When you manipulate and set values in Java and Groovy code, you can encapsulate each response as a block of code, as shown in Listing 3, and include any required side effects:
Listing 3. Scala if + side effects
Val z = if (x 2 = 0) {
println (' centerisible by 2 ')
x * 2
} else {
println ("Not centerisible by 2; Odd ")
x-1
}
println (z)
In Listing 3, I also print a status message for each case, in addition to returning the newly computed value. The order of the lines of code in the code block is important: The last line of code blocks represents the return value that meets the criteria. Therefore, you must be very careful when you use an if based on an expression for mixed evaluation and side effects.
expressions and side-effects of Clojure
Clojure is also entirely composed of expressions, but it goes further and distinguishes the side-effects code from the evaluation code. The Clojure version of the first two examples is expressed in a let code block, which in Listing 4 allows for the definition of a local scope variable:
Listing 4. Clojure an If statement based on an expression
(Let [x 5
y (if (= 0 (rem x 2)) (* x 2) (-X 1))]
(println y))
In Listing 4, I assign a value of 5 to X, and then use the if to create an expression to compute the two conditions: (REM x2) calls the remainder function, similar to the Java% operator, and compares the result with 0 values, checking 0 remaining values by 2 o'clock (zero Rema Inder). In the Clojure if expression, the first argument is condition, the second argument is a true branch, and the third argument is an optional else branch. The results of an if expression are assigned to Y and then printed.
Clojure also allows code blocks to be used for each condition (can contain side effects), but requires a wrapper, such as (do ...). )。 The wrapper is evaluated for each expression in the code block by using the last line as the return value of the code block. Listing 5 shows how to evaluate a condition or side effect:
Listing 5. Explicit side-effects in Clojure
(Let [x 5
A (if (= 0 (rem x 2))
(Does
(println "centerisible by 2") (
* x 2))
(Does
(println) not Centerisib Le by 2; Odd ")
(-X 1))]
(println a))
In Listing 5, I assign a to the return value of an if expression. For each condition, a (do ...) is created. ) wrapper and allows any number of statements to be used. The last line of code block is (do ...). The return value of the code block, similar to the Scala example in Listing 3. Make sure the target return value is evaluated at the end. Use in this way (do ...). Code blocks are so common that many of the structures in Clojure (such as let []) already contain implicit (do ...). Code blocks, which eliminates the need for them in many cases.
A comparison of expressions in Java/groovy code and Scala/clojure code indicates the general trend in the programming language to eliminate unnecessary statement/expression differences.