
Before you begin, you need to install the following software on your computer. The installation instruction of these software is described as Exercise 0 below.



















1. Open Lang_ClassAndObject
NetBeans project.



| // Class definitions share many
similarities with the Java // programming language, but some differences are notable. // State, for example, is information stored in vars, // not fields. Behavior is exposed through functions, not // methods. The following is an example class definition. class X { var a: Integer; var b: Integer; function add(a: Integer, b: Integer): Integer { return a + b; } } // Literal object instance var x_object_instance = X { a: 20 b: 30 } println("----var x_object_instance.a = {x_object_instance.a}"); println("----var x_object_instance.b = {x_object_instance.b}"); println("----x_object_instance.add(x_object_instance.a, x_object_instance.b) = {x_object_instance.add(x_object_instance.a, x_object_instance.b)}"); // You can also create object instance using new keyword // like in Java programming language. var x_object_instance2 = new X(); println("----x_object_instance2.add(5, 6) = {x_object_instance2.add(5, 6)}"); |


| ----var x_object_instance.a = 20 ----var x_object_instance.b = 30 ----x_object_instance.add(x_object_instance.a, x_object_instance.b) = 50 ----x_object_instance2.add(5, 6) = 11 |
| // Define Address class. class Address { var street: String; var city: String; var state: String; var zip: String; } // Create the first Address object instance. def addressOne = Address { street: "1 Main Street"; city: "Santa Clara"; state: "CA"; zip: "95050"; } // Create the second Address object instance. def addressTwo = Address { street: "200 Pine Street"; city: "San Francisco"; state: "CA"; zip: "94101"; } println("----addressOne.street = {addressOne.street}"); println("----addressTwo.street = {addressTwo.street}"); |
| ----addressOne.street = 1 Main
Street ----addressTwo.street = 200 Pine Street |
| // Define class X class X { var a: Integer; var b: Integer; function add(a: Integer, b: Integer): Integer { return a + b; } } // Define class Y extending class X adding multiply // method. class Y extends X { function multiply(a: Integer, b: Integer): Integer { return a * b; } } // Create literal object instance of Y. var y_object_instance = Y { a: 21 b: 31 } println("----addition = {y_object_instance.add(y_object_instance.a, y_object_instance.b)}"); println("----multiplication = {y_object_instance.multiply(y_object_instance.a, y_object_instance.b)}"); |
| ----addition = 52 ----multiplication = 651 |
| // It is possible to declare
default values for vars (which // can later be overridden by values provided in object literals.) The // initializers are evaluated in the order the vars are specified // in the class declaration in the context of the newly created object: class X { var a: Number = 10; var b: Number = -1; } var x = X { }; println("----x.a = {x.a}"); // prints 10.0 println("----x.b = {x.b}"); // prints -1.0 x.a = 11; x.b = -2; println("----x.a = {x.a}"); // prints 11.0 println("----x.b = {x.b}"); // prints -2.0 // In the absence of explicit initialization, each var is // assigned a reasonable default: class DefaultValuesDemo { var a: Number; var b: Integer; var c: Boolean; var d: String; } var demo = DefaultValuesDemo {}; println("----Default Value: {demo.a}, Type: {demo.a.getClass()}"); // 0.0 println("----Default Value: {demo.b}, Type: {demo.b.getClass()}"); // 0 println("----Default Value: {demo.c}, Type: {demo.c.getClass()}"); // false println("----Default Value: {demo.d}, Type: {demo.d.getClass()}"); // |
| ----x.a = 10.0 ----x.b = -1.0 ----x.a = 11.0 ----x.b = -2.0 ----Default Value: 0.0, Type: class java.lang.Double ----Default Value: 0, Type: class java.lang.Integer ----Default Value: false, Type: class java.lang.Boolean ----Default Value: , Type: class java.lang.String |
| def
a = 6; //a = 7; // Expect compile error class X { def a: Number = 10; var b: Number = -1; } var x = X { }; println("----x.a = {x.a}"); println("----x.b = {x.b}"); //x.a = 11; // Expect compile error x.b = -2; println("----x.a = {x.a}"); println("----x.b = {x.b}"); def x2 = X {b: -5}; //x2 = X {b: -9}; // Expect compile error println("----x2.a = {x2.a}"); println("----x2.b = {x2.b}"); |
| ----x.a = 10.0 ----x.b = -1.0 ----x.a = 10.0 ----x.b = -2.0 ----x2.a = 10.0 ----x2.b = -5.0 |
| // For character strings, you
can specify a string literal using either single or double quotes: def s1 = 'Hello'; def s2 = "Hello"; println("----s1 = {s1}"); println("----s2 = {s2}"); // The difference is that with the latter, you can embed expressions within curly braces ({}): var name = 'Joe'; var s = "Hello {name}"; // s = 'Hello Joe' println("----s = {s}"); // The embedded expression can itself contain quoted strings, which, in turn, can contain further embedded expressions: var answer = true; var s3 = "The answer is {if (answer) "Yes" else "No"}"; // s = 'The answer is Yes' println("----s3 = {s3}"); println("----s3.getClass() = {s3.getClass()}"); // String concatenation var s4 = "Hello {name}" " how are you?"; // s4 = 'Hello Joe how are you?'; println("----s4 = {s4}"); s4 += " I'm fine."; println("----s4 = {s4}");// s4 = 'Hello Joe how are you?I'm fine.'; //var s5 = "Hello" + " how are you?"; // expect compiler error |
| ----s1 = Hello ----s2 = Hello ----s = Hello Joe ----s3 = The answer is Yes ----s3.getClass() = class java.lang.String ----s4 = Hello Joe how are you? ----s4 = Hello Joe how are you? I'm fine. |
| // A class that defines a
duration of time. Duration instances // are defined in milliseconds, but can be easily created using // time literals; for example, a two-and-a-half minute Duration // instance can be defined in several ways: var t1 = 2m + 30s; var t2 = 2.5m; var t3 = 150s; var t4 = 150000ms; println("----t1 = {t1}"); // 150000ms println("----t2 = {t2}"); // 150000ms println("----t3 = {t3}"); // 150000ms println("----t4 = {t4}"); // 150000ms // Time can be computed var t5 = 2.5m + t3; println("----t5 = {t5}"); // 300000ms var t6 = 100s * 6; println("----t6 = {t6}"); // 600000ms |
| ----t1 = 150000ms ----t2 = 150000ms ----t3 = 150000ms ----t4 = 150000ms ----t5 = 300000ms ----t6 = 600000ms |
| //
Range expressions var one2five = [1..5]; // [1, 2, 3, 4, 5] displayNumbers("one2five", one2five); var one2four = [1..<5]; // [1, 2, 3, 4] displayNumbers("one2four", one2four); var odds = [1..10 step 2]; // [1, 3, 5, 7, 9] displayNumbers("odds", odds); var decrease = [3..0 step -1]; // [3, 2, 1, 0] displayNumbers("decrease", decrease); var my_array = [1, 2, 3]; displayNumbers("my_array", my_array); // Utility function function displayNumbers(description, my_num_sequence: Integer[]){ println("----{description}"); for (n in my_num_sequence) { print("{n} ") } println(""); } |
| ----one2five 1 2 3 4 5 ----one2four 1 2 3 4 ----odds 1 3 5 7 9 ----decrease 3 2 1 0 ----my_array 1 2 3 |
| // Reversing var nums = [1..5]; nums = reverse nums; // result is [5,4,3,2,1]; displayNumbers("nums after reversing", nums); nums = reverse nums; // Inserting var x = 6; insert x into nums; // result is [1,2,3,4,5,6] displayNumbers("nums after inserting x to the last", nums); x++; insert x before nums[0]; // result is [7,1,2,3,4,5,6] displayNumbers("nums after inserting x before nums[0]", nums); x++; insert x after nums[3]; // result is [7,1,2,3,8,4,5,6] displayNumbers("nums after inserting x after nums[3]", nums); // Deleting nums = [1..5]; delete 2 from nums; // result is [1,3,4,5] displayNumbers("nums after deleting 2", nums); delete nums[0];// result is [3,4,5] displayNumbers("nums after deleting nums[0]", nums); nums = [1..10]; // result is [1,2,3,4,5,6,7,8,9,10] delete nums[3..7]; // result is [1,2,3,9,10] displayNumbers("nums after deleting numbers greater than 3 but less than 7", nums); delete nums; // result is [] displayNumbers("nums after deleting all", nums); nums = [1..10]; delete nums[5..]; // result is [1,2,3,4,5] displayNumbers("nums after deleting numbers after 5", nums); function displayNumbers(description, my_num_sequence: Integer[]){ println("---- {description}"); for (n in my_num_sequence) { print("{n} ") } println(""); } |
| ---- nums after reversing 5 4 3 2 1 ---- nums after inserting x to the last 5 4 3 2 1 6 ---- nums after inserting x before nums[0] 7 5 4 3 2 1 6 ---- nums after inserting x after nums[3] 7 5 4 3 8 2 1 6 ---- nums after deleting 2 1 3 4 5 ---- nums after deleting nums[0] 3 4 5 ---- nums after deleting numbers greater than 3 but less than 7 1 2 3 9 10 ---- nums after deleting all ---- nums after deleting numbers after 5 1 2 3 4 5 |
| // Slicing via predicate var nums1 = [1..6]; // Select all items from the nums1 sequence where the
value of an item is greater than 2// and assign those items to a new sequence called nums1GreaterThanTwo. var nums1GreaterThanTwo = nums1[n|n > 2]; displayNumbers("nums1", nums1); displayNumbers("nums1GreaterThanTwo", nums1GreaterThanTwo); function displayNumbers(description, my_num_sequence: Integer[]){ println("---- {description}"); for (n in my_num_sequence) { print("{n} ") } println(""); } |
| ---- nums1 1 2 3 4 5 6 ---- nums1GreaterThanTwo 3 4 5 6 |
| // A sequence holds an ordered
list of objects. This is roughly // analogous to Java programming language arrays. Both hold // multiple values and are accessed by index starting at 0. def week = ["Monday","Tuesday","Wednesday","Thursday", "Friday","Saturday","Sunday"]; def mon = week[0]; def wed = week[2]; def fri = week[4]; // Sequence slices are also supported var weekdays = week[0..4]; // first slice println("----Weekday dates: {weekdays}"); var weekend = week[5..6]; // second slice println("----Weedend dates: {weekend}"); var the_first_3_dates = week[0..<3]; println("----The first 3 dates: {the_first_3_dates}"); // Sequence slice via predicate var days = [1..31]; var oddDays = days[n|n mod 2 == 1]; println("----Odd dates: {oddDays}"); |
| ----Weekday dates:
MondayTuesdayWednesdayThursdayFriday ----Weedend dates: SaturdaySunday ----The first 3 dates: MondayTuesdayWednesday ----Odd dates: 135791113151719212325272931 |
| // Define Album class. Note that
the tracks // variable is a Sequence type of String. class Album { var title: String; var artist: String; var tracks: String[]; } // An example of nested sequence. var albums = [Album { title: "A Hard Day's Night" artist: "The Beatles" tracks: ["A Hard Day's Night", "I Should Have Known Better", "If I Fell", "I'm Happy Just To Dance With You", "And I Love Her", "Tell Me Why", "Can't Buy Me Love", "Any Time At All", "I'll Cry Instead", "Things We Said Today", "When I Get Home", "You Can't Do That"] }, Album { title: "Circle Of Love" artist: "Steve Miller Band" tracks: ["Heart Like A Wheel", "Get On Home", "Baby Wanna Dance", "Circle Of Love", "Macho City"] }]; for (album in albums, track in album.tracks) { if (album.title == track) println("----TITLE TRACK = {track}") else println("----Track = {track}") } |
| ----TITLE TRACK = A Hard Day's
Night ----Track = I Should Have Known Better ----Track = If I Fell ----Track = I'm Happy Just To Dance With You ----Track = And I Love Her ----Track = Tell Me Why ----Track = Can't Buy Me Love ----Track = Any Time At All ----Track = I'll Cry Instead ----Track = Things We Said Today ----Track = When I Get Home ----Track = You Can't Do That ----Track = Heart Like A Wheel ----Track = Get On Home ----Track = Baby Wanna Dance ----TITLE TRACK = Circle Of Love ----Track = Macho City |
| // This example is created by
Weiqi Gao var rs = ["A", "B"]; // rows var cs = ["1", "2"]; // columns var xs = for (r in rs, c in cs) { "{r}{c} " }; println("----result = {xs}"); // [ A1, A2, B1, B2 ] |
| ----result = A1 A2 B1 B2 |
| // This example is created by
Weiqi Gao class Point { var x: Integer; var y: Integer; override function toString() { "P({x},{y}) " } } var xs = [0..2]; var ys = [0..2]; var ps = for (x in xs, y in ys where x*x+y*y <= 4) { // where clause Point { x: x, y: y} }; println("----result = {ps}"); // => [ P(0,0), P(0,1), P(0,2), P(1,0), P(1,1), P(2,0) ] |
| ----result = P(0,0) P(0,1)
P(0,2) P(1,0) P(1,1) P(2,0) |
| def numOne = 100; def numTwo = 2; var result; // Define functions that add, subtract, // multiply, and divide the two numbers. // Please note these are function definitions // not function objects. function add() { result = numOne + numTwo; println("----{numOne} + {numTwo} = {result}"); } function subtract() { result = numOne - numTwo; println("----{numOne} - {numTwo} = {result}"); } function multiply() { result = numOne * numTwo; println("----{numOne} * {numTwo} = {result}"); } function divide() { result = numOne / numTwo; println("----{numOne} / {numTwo} = {result}"); } // Invoke functions add(); subtract(); multiply(); divide(); |
| ----100 + 2 = 102 ----100 - 2 = 98 ----100 * 2 = 200 ----100 / 2 = 50 |
| var result; function run(args : String[]) { // Convert Strings to Integers def numOne = java.lang.Integer.parseInt(args[0]); def numTwo = java.lang.Integer.parseInt(args[1]); // Invoke Functions add(numOne,numTwo); subtract(numOne,numTwo); multiply(numOne,numTwo); divide(numOne,numTwo); } function add(argOne: Integer, argTwo: Integer) { result = argOne + argTwo; println("----{argOne} + {argTwo} = {result}"); } function subtract(argOne: Integer, argTwo: Integer) { result = argOne - argTwo; println("----{argOne} - {argTwo} = {result}"); } function multiply(argOne: Integer, argTwo: Integer) { result = argOne * argTwo; println("----{argOne} * {argTwo} = {result}"); } function divide(argOne: Integer, argTwo: Integer) { result = argOne / argTwo; println("----{argOne} / {argTwo} = {result}"); } |
| ----5 + 9 = 14 ----5 - 9 = -4 ----5 * 9 = 45 ----5 / 9 = 0 |



| ----4 + 19 = 23 ----4 - 19 = -15 ----4 * 19 = 76 ----4 / 19 = 0 |
| // Define Compute class with
functions class Compute { var someNumber1: Integer; var someNumber2: Integer; function add(numOne:Integer, numTwo:Integer) { var result = numOne + numTwo + someNumber1; } function subtract(numOne:Integer, numTwo:Integer) { var result = numOne - numTwo - someNumber2; } } // Create the first Compute object instance. def ComputeOne = Compute { someNumber1: 2; someNumber2: 4; } // Invoke functions println("----ComputeOne.add(13, 5) = {ComputeOne.add(13, 5)}"); println("----ComputeOne.subtract(13, 5) = {ComputeOne.subtract(13, 5)}"); |
| ----ComputeOne.add(13, 5) = 20 ----ComputeOne.subtract(13, 5) = 4 |
| def numOne = 100; def numTwo = 2; var result; // Note that the return value of a function is the // result of the evaluation of the last statement. function add_return_random_number() { 33 + 5; } function add_return_result() { result = numOne + numTwo; } function add_return_result_implicitly() { result = numOne + numTwo; result + 10; } function add_return_result_explicitly() { result = numOne + numTwo; return result * 2; } // Display return values of functions. println(add_return_random_number()); println(add_return_result()); println(add_return_result_implicitly()); println(add_return_result_explicitly()); |
| 38 102 112 204 |
| def numOne = 100; def numTwo = 2; function return_IntegerType1(): Integer { numOne + numTwo; } function return_IntegerType2(): Integer { var result: Integer; result = numOne + numTwo; } function return_StringType(): String { "Life is good!"; } function return_Boolean(): Boolean { true; } function return_Duration(): Duration { 1ms; } function return_Sequence(): Integer[] { [1..5]; } function return_VoidType(): Void { } class X { var a: Integer; var b: Integer; function add(a: Integer, b: Integer): Integer { return a + b; } } function return_ClassXType(): X { // Literal object instance var x_object_instance = X { a: 20 b: 30 } } // Invoke functions which are declared with explicit types println("----return_IntegerType1() => {return_IntegerType1()}"); println("----return_IntegerType2() => {return_IntegerType2()}"); println("----return_StringType() => {return_StringType()}"); println("----return_Boolean() => {return_Boolean()}"); println("----return_Duration() => {return_Duration()}"); println("----return_Sequence() => {return_Sequence()}"); return_VoidType(); // You cannot println on this println("----return_ClassXType().a => {return_ClassXType().a}"); |
| ----return_IntegerType1() =>
102 ----return_IntegerType2() => 102 ----return_StringType() => Life is good! ----return_Boolean() => true ----return_Duration() => 1ms ----return_Sequence() => 12345 ----return_ClassXType().a => 20 |
| // Function
function_which_returns_Integer_type() returns Integer // as a return value type. function function_which_returns_Integer_type(p: Integer): Integer { p + 10; } println("-------- return type is Integer type --------------------------"); println("---- function_which_returns_Integer_type(5) => {function_which_returns_Integer_type(5)}"); println("---- function_which_returns_Integer_type(6) => {function_which_returns_Integer_type(6)}"); // Function function_which_returns_function_type() returns function // as a return value type function function_which_returns_function_type(p: Integer): function(): Integer { return function(): Integer { p + 10; } } // Display the returned function objects - you will add address pointers println("-------- return type is function type with no argument --------"); println("---- function_which_returns_function_type(5) => {function_which_returns_function_type(5)}"); println("---- function_which_returns_function_type(6) => {function_which_returns_function_type(6)}"); // Display the result of calling returned function objects println("---- function_which_returns_function_type(5)() ) => {function_which_returns_function_type(5)()}"); // 15 = 5 + 10 println("---- function_which_returns_function_type(6)() ) => {function_which_returns_function_type(6)()}"); // 16 = 6 + 10 // Function function_which_returns_function_type() returns function // as a return value type function function_which_returns_function_type2(p: Integer): function(x: String): Integer { return function(y: String): Integer { p + 10 + java.lang.Integer.parseInt(y); } } // Display the returned function objects - you will add address pointers println("-------- return type is function type with an argument --------"); println("---- function_which_returns_function_type2(5) => {function_which_returns_function_type2(5)}"); println("---- function_which_returns_function_type2(6) => {function_which_returns_function_type2(6)}"); // Display the result of calling returned functions println("---- function_which_returns_function_type2(5)(\"1\") => {function_which_returns_function_type2(5)("1")}"); // 16 = 5 + 10 + 1 println("---- function_which_returns_function_type2(6)(\"2\") => {function_which_returns_function_type2(6)("3")}"); // 19 = 6 + 10 + 3 |
| -------- return type is Integer
type -------------------------- ---- function_which_returns_Integer_type(5) => 15 ---- function_which_returns_Integer_type(6) => 16 -------- return type is function type with no argument -------- ---- function_which_returns_function_type(5) => Main$1@11a698a ---- function_which_returns_function_type(6) => Main$1@107077e ---- function_which_returns_function_type(5)() ) => 15 ---- function_which_returns_function_type(6)() ) => 16 -------- return type is function type with an argument -------- ---- function_which_returns_function_type2(5) => Main$2@1ac04e8 ---- function_which_returns_function_type2(6) => Main$2@765291 ---- function_which_returns_function_type2(5)("1") => 16 ---- function_which_returns_function_type2(6)("2") => 19 |
| var x: Integer = 30; println("-------- Integer object is assigned to variable x (this is what we've seen so far) ----------------------"); println("---- x => {x}"); // Function function_which_returns_function_type return function // as a return value type function function_which_returns_function_type(p: Integer): function(): Integer { return function(): Integer { p + 10; } } // Variables y and z contain (actually refers to) function objects which takes no arguments var y = function_which_returns_function_type(5); var z = function_which_returns_function_type(6); // Display the returned function objects println("-------- Variables y and z contain (actually refers to) function objects which takes no arguments -------"); println("---- y => {y}"); println("---- z => {z}"); println("---- y() => {y()}"); // 15 println("---- z() => {z()}"); // 16 // Function function_which_returns_function_type return function // as a return value type function function_which_returns_function_type2(p: Integer): function(x: String): Integer { return function(y: String): Integer { p + 10 + java.lang.Integer.parseInt(y); } } // Variables s and r contain (actually refers to) function objects which takes an argument var s = function_which_returns_function_type2(5); var r = function_which_returns_function_type2(6); println("-------- Variables s and r contain (actually refers to) function objects which takes an argument --------"); println("---- s => {s}"); println("---- r => {r}"); println("---- s(\"1\") => {s("1")}"); // 16 println("---- r(\"3\") => {r("3")}"); // 19 |
| -------- Integer object is
assigned to variable x (this is what we've seen so far)
---------------------- ---- x => 30 -------- Variables y and z contain (actually refers to) function objects which takes no arguments ------- ---- y => Main$1@bd0108 ---- z => Main$1@8ed465 ---- y() => 15 ---- z() => 16 -------- Variables s and r contain (actually refers to) function objects which takes an argument -------- ---- s => Main$2@107077e ---- r => Main$2@7ced01 ---- s("1") => 16 ---- r("3") => 19 |
| // Function
function_which_returns_function_type return function // as a return value type function function_which_returns_function_type(p: Integer): function(): Integer { return function(): Integer { p + 10; } } // Variables y and z contain (actually refers to) function objects which takes no arguments var y = function_which_returns_function_type(5); var z = function_which_returns_function_type(6); // Target function definition function function_which_receives_function_objects_as_arguments( a: Integer, // Integer as the first argument b: function():Integer // Function as the second argument ): Integer{ // Return type of the target function return a + b(); // y() represents calling passed function } // Display the returned function objects println("-------- Function which takes no argument is passed as an arugment to target function -------"); println("---- function_which_receives_function_objects_as_arguments (100, y) => {function_which_receives_function_objects_as_arguments (100, y)}"); println("---- function_which_receives_function_objects_as_arguments (100, z) => {function_which_receives_function_objects_as_arguments (100, z)}"); |
| -------- Function which takes no
argument is passed as an arugment to target function ------- ---- function_which_receives_function_objects_as_arguments (100, y) => 115 ---- function_which_receives_function_objects_as_arguments (100, z) => 116 |
| // Function
function_which_returns_function_type return function // as a return value type function function_which_returns_function_type(p: Integer): function(): Integer { var localvar_outer = p; return function(): Integer { ++localvar_outer + 10; } } // After the following statement, the localvar_outer is set to 5 var g = function_which_returns_function_type(5); // Note that the value of the localvar_outer is maintained even after // each call. This is the behavior of closure. println("----g() => {g()}"); // 16, localvar_outer is now set to 6 println("----g() => {g()}"); // 17, localvar_outer is now set to 7 println("----g() => {g()}"); // 18, localvar_outer is now set to 8 |
| ----g() => 16 ----g() => 17 ----g() => 18 |