Expressions are pieces of code that evaluate to a result value,
and that can be combined to produce "bigger" expressions. The JavaFX
Script programming language is an expression language, which means that
everything, including loops, conditionals, and even blocks, are
expressions. In some cases (such as while expressions) the expressions have Void type, which means they don't return a result value.
For a lower-level discussion of expressions, see
Chapter 6. Expressions in the
JavaFX Script Programming Language
Reference.
|
Contents
A block expression consists of a list of declarations or
expressions surrounded by curly braces and separated by semicolons. The
value of a block expression is the value of the last expression. If the
block expression contains no expressions, the block expression has Void type. Note that var and def are expressions.
The following block expression adds a few numbers and stores the result in a variable named total:
var nums = [5, 7, 3, 9];
var total = {
var sum = 0;
for (a in nums) { sum += a };
sum;
}
println("Total is {total}.");
|
Running this script produces the following output:
The first line (var nums = [5, 7, 3, 9];) declares a sequence of integers.
The next line declares a variable named total that will hold the sum of these integers.
The block expression that follows consists of everything between the curly braces:
{
var sum = 0;
for (a in nums) { sum += a };
sum;
}
|
Within this block, the first line of code declares a variable named sum, to hold the sum of the numbers in this sequence. The second line (a for expression) loops through the sequence and adds each number to sum. The last line sets the return value of the block expression (24, in this case).
The if expression makes it possible to direct the flow of a program by executing certain blocks of code only if a particular condition is true.
For example, the following script sets a ticket price based on age.
Ages 12 to 65 pay regular the price of $10. Seniors and children pay
$5; except for children under 5 who are admitted for free.
def age = 8;
var ticketPrice;
if (age < 5 ) {
ticketPrice = 0;
} else if (age < 12 or age > 65) {
ticketPrice = 5;
} else {
ticketPrice = 10;
}
println("Age: {age} Ticket Price: {ticketPrice} dollars.");
|
With age set to 8, the script produces the following output:
Age: 8 Ticket Price: 5 dollars.
|
The program flows through this example as follows:
if (age < 5 ) {
ticketPrice = 0;
} else if (age < 12 or age > 65) {
ticketPrice = 5;
} else {
ticketPrice = 10;
}
|
If age is less than 5, the ticket price is set to 0.
The program then jumps past the remaining conditional tests and prints out the result.
If age is not less than 5, the programs proceeds to the next conditional test (indicated by the else keyword followed by another if expression):
if (age < 5 ) {
ticketPrice = 0;
} else if (age < 12 or age > 65) {
ticketPrice = 5;
} else {
ticketPrice = 10;
}
|
This sets the ticket price to $5 if the person's age is between 5 and 12 or
over 65.
If the age is between 12 and 65, the program flows to the final block of code,
marked with the else keyword:
if (age < 5 ) {
ticketPrice = 0;
} else if (age < 12 or age > 65) {
ticketPrice = 5;
} else {
ticketPrice = 10;
}
|
This block executes only if none of the previous conditions are
satisfied. It sets the ticket price to $10 for ages between 12 and 65.
Note: The previous code can be collapsed to a very concise conditional expression:
ticketPrice = if (age < 5) 0 else if (age < 12 or age > 65) 5 else 10;
|
This is a useful technique to master and you will see it used again later in the tutorial.
The Sequences lesson taught you a shorthand notation for declaring a sequence of numbers that form an arithmetic series:
Technically speaking, [0..5] is a range expression. By default the interval between the values is 1, but you can use the step keyword to specify a different interval. For example, to define a sequence consisting of the odd numbers between 1 and 10:
var nums = [1..10 step 2];
println(nums);
|
The output of this script is:
To create a descending range, make sure the second value is less than the first, and specify a negative step value:
var nums = [10..1 step -1];
println(nums);
|
The output is:
[ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
|
If you do not provide a negative step value while creating a descending range, you will end up with an empty sequence.
The following code:
var nums = [10..1 step 1];
println(nums);
|
results in the following compile-time warning:
range.fx:1: warning: empty sequence range literal, probably not what you meant.
var nums = [10..1 step 1];
^
1 warning
|
You would also end up with an empty sequence if you omit the step value altogether.
Another sequence-related expression is the for expression. The for expression provides a convenient mechanism for looping through the items of a sequence.
The following code provides an example:
var days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
for (day in days) {
println(day);
}
|
The output of this script is:
Mon
Tue
Wed
Thu
Fri
Sat
Sun
|
Let's break this example down into its individual parts. The "for" keyword begins the for expression:
for (day in days) {
println(day);
}
|
The days variable is the name of the input sequence to be processed by the for expression:
for (day in days) {
println(day);
}
|
The day variable holds the current item as the for expression loops through the sequence:
for (day in days) {
println(day);
}
|
Note that the day variable does not need to be declared elsewhere in the script before using it in the for expression. Furthermore, day
cannot be accessed after the loop has run its course. Programmers will
often give temporary variables such as this very short (or one-letter)
names.
In the previous example, for was not shown returning a value; however for
is also an expression that returns a sequence. The following code shows
two examples of creating a sequence from another sequence, using the for expression:
// Resulting sequence squares the values from the original sequence.
var squares = for (i in [1..10]) i*i;
// Resulting sequence is ["MON", "TUE", "WED", and so on...]
var capitalDays = for (day in days) day.toUpperCase();
|
Note that the toUpperCase function is provided by the String object. You can see a full list of available functions by consulting the API documentation.
Another looping construct is the while expression. Unlike the for expression, which operates on the items of a sequence, the while expression loops until a given condition is false. While while is syntactically an expression, it has type Void, and doesn't return a value.
The following provides an example:
var count = 0;
while (count < 10) {
println("count == {count}");
count++;
}
|
The output of this script is:
count == 0
count == 1
count == 2
count == 3
count == 4
count == 5
count == 6
count == 7
count == 8
count == 9
|
The first line declares a variable named count and initializes it to 0:
var count = 0;
while (count < 10) {
println("count == {count}");
count += 1;
}
|
The next line begins the while expression. This expression creates a loop (between the opening and closing braces) that lasts until count < 10 evaluates to false:
var count = 0;
while (count < 10) {
println("count == {count}");
count += 1;
}
|
The body of the while expression prints out the current value of count, then increments its value of count by one:
var count = 0;
while (count < 10) {
println("count == {count}");
count += 1;
}
|
When count becomes equal to 10, the loop will exit. To create an infinite loop, place the true keyword between the parenthesis, as in: while(true){}
Related to the looping expressions are the break and continue expressions. These two expressions affect loop iteration: break abandons the loop entirely, whereas continue abandons only the current iteration.
While break and continue are syntactically expressions, they have type Void and don't return a value.
Example:
for (i in [0..10]) {
if (i > 5) {
break;
}
if (i mod 2 == 0) {
continue;
}
println(i);
}
|
Output:
Without the if expressions, the program would simply output the numbers 0 through 10.
With only the first if expression, the program would break out of the loop when the value of i becomes greater than 5:
The program would therefore print only the numbers 1 through 5.
By adding the second if expression, the program abandons the loop's current iteration only to continue with the next iteration:
if (i mod 2 == 0) {
continue;
}
|
In this case continue only executes when i is even (that is, when 2 divides evenly into i, leaving no remainder.) When this happens, the println() invocation is never reached, and the number is not included in the output.
In real-world applications, there will be times when some event will
disrupt the normal flow of a script's execution. For example, if a
script reads input from a file, and that file cannot be found, the
script will not be able to proceed. We call this condition an
"exception."
Note: Exceptions are objects. Their types generally are named after the conditions they represent (for example, FileNotFoundException
represents the condition of a file that cannot be found.) However,
defining a set of exceptions specific to the upcoming examples is
beyond the scope of this section. We will therefore use a
general-purpose Exception object (borrowed from the Java programming language) to demonstrate the throw, try, catch, and finally expressions.
The following script defines (and invokes) a function that throws an exception:
import java.lang.Exception;
foo();
println("The script is now executing as expected... ");
function foo() {
var somethingWeird = false;
if(somethingWeird){
throw new Exception("Something weird just happened!");
} else {
println("We made it through the function.");
}
}
|
Running this script as-is (with somethingWeird set to false) prints out the following message:
We made it through the function.
The script is now executing as expected...
|
But change that variable to true, and an exception will be thrown. At runtime, the script will crash with the following message:
Exception in thread "main" java.lang.Exception: Something weird just happened!
at exceptions.foo(exceptions.fx:10)
at exceptions.javafx$run$(exceptions.fx:3)
|
To prevent this crash, we would need to wrap the foo() invocation with try/catch expressions. As their names imply, these expressions try to execute some code, but catch an exception if there is a problem:
try {
foo();
} catch (e: Exception) {
println("{e.getMessage()} (but we caught it)");
}
|
Now, instead of crashing, the program simply prints:
Something weird just happened! (but we caught it)
The script is now executing as expected...
|
There is also a finally block (it's not technically an
expression), which always executes at some point after the try
expressions exits, regardless of whether an exception was thrown or
not. The finally block is used to perform cleanup that needs to occur regardless of whether the try-body succeeds or throws an exception.
try {
foo();
} catch (e: Exception) {
println("{e.getMessage()} (but we caught it)");
} finally {
println("We are now in the finally expression...");
}
|
The program output is now:
Something weird just happened! (but we caught it)
We are now in the finally expression...
The script is now executing as expected...
|
Do you have comments about this article? We welcome your participation in our community. Please keep your comments civil and on point. You may optionally provide your email address to be notified of replies - your information is not used for any other purpose. By submitting a comment, you agree to these Terms of Use.
|