Showing posts with label Xtend. Show all posts
Showing posts with label Xtend. Show all posts

Sunday, December 7, 2014

Arrays and Indexers in Xtend



Today's post is about Arrays and Indexers in Xtend. Here below you will find a very easy to follow program, that demonstrate arrays and indexer, by implementing some simple tasks that will make you grasp the idea of those 2 features real quick. The main goal of this post, is not really teaching arrays because, come on, you probably already know "all" about them, in fact, it is more to show you how you do that in Xtend, in this case, compared to all other 22 languages on future posts, which essentially, is the real aim behind this blog.

By the way, if you missed my (not so) recent post (anymore), "New Series - Arrays and Indexers", check it out. It has more details about the following program, and a bunch of definitions for the concepts used on this, and the following, posts. Or you can check my previous posts about arrays in Java just to compare.

I encourage you to copy the code below and try it yourself, normally, all programs you find in this blog are source code complete, just paste it on your IDE and run it.

There is room for improvement of the code, using generics is one example, but Generics, Collections, lambdas, etc. will have their own "series" of posts.


"Xtend does not support Multidimensional Arrays out-of-the box. You can add support by declaring a Java class like this : " by Sven Efftinge - Google Groups: Xtend Programming Language
// ArrayLiterals2.java
package xtendarrays;

import org.eclipse.xtext.xbase.lib.Inline;

public class ArrayLiterals2 {
 @Inline("new int[$1][$2]")
 public static int[][] new2DIntArrayOfSize(int outerSize, int innerSize) {
  throw new UnsupportedOperationException();
 }
}

"@Inline tells the compiler to replace any calls to the annotated method with the to-be-inlined Java expression (the 'value' template). Note that the @Inlined is not stable API (flagged as @Beta) and will likely be removed once Xtend has support for more powerful method-macros." by Sven Efftinge - Google Groups: Xtend Programming Language
// XtendArrays.xtend
package xtendarrays

import java.util.Random
import java.lang.StringBuffer
import static extension xtendarrays.ArrayLiterals2.*

class XtendArrays {
 def static void main(String[] args) {
  // Single-dimensional Array(s)  
        printTitle("Reverse Array Elements")
        
        // Declare and Initialize Array of Chars  
        val char[] letters = newCharArrayOfSize(5)
        letters.set(0, 'A')
        letters.set(1, 'E')
        letters.set(2, 'I')
        letters.set(3, 'O')
        letters.set(4, 'U')
        
        printArrayChar(letters)  
        val char[] inverse_letters = reverseChar(letters)  
        printArrayChar(inverse_letters)
        
        printTitle("Sort Integer Array Elements")  

        // Declare and Initialize Array of Integers   
        val int[] numbers = #[10, 8, 3, 1, 5]
        printArrayInt(numbers)
        val int[] ordered_numbers = bubbleSortInt(numbers)
        printArrayInt(ordered_numbers)

        printTitle("Sort String Array Elements")  

        // Declare and Initialize and Array of Strings  
        val String[] names = #[                       
                "Damian",   
                "Rogelio",  
                "Carlos",   
                "Luis",                       
                "Daniel"  
            ]
        printArrayString(names)
        val String[] ordered_names = bubbleSortString(names)
        printArrayString(ordered_names)

        // Multi-dimensional Array (Matrix row,column)  

        printTitle("Transpose Matrix")

        /* Matrix row=2,col=3 
         * A =  [6  4 24] 
         *      [1 -9  8] 
        */  
        val int[][] matrix = #[#[6, 4, 24],   
                               #[1, -9, 8]]  
        printMatrix(matrix)
        val int[][] transposed_matrix = transposeMatrix(matrix)  
        printMatrix(transposed_matrix)

        // Jagged Array (Array-of-Arrays)  

        printTitle("Upper Case Random Array & Graph Number of Elements")
        
        /*              
         * Creating an array of string arrays using the String.Split method 
         * instead of initializing it manually as follows: 
         *  
         * val text = #[  
         *      #[ "word1", "word2", "wordN" ],  
         *      #[ "word1", "word2", "wordM" ],  
         *      ... 
         *      ] 
         *  
         * Text extract from: "El ingenioso hidalgo don Quijote de la Mancha" 
         *  
         */  
        val String[][] text = #[   
        "Hoy es el día más hermoso de nuestra vida, querido Sancho;".split(' '),  
        "los obstáculos más grandes, nuestras propias indecisiones;".split(' '),  
        "nuestro enemigo más fuerte, miedo al poderoso y nosotros mismos;".split(' '),  
        "la cosa más fácil, equivocarnos;".split(' '),  
        "la más destructiva, la mentira y el egoísmo;".split(' '),  
        "la peor derrota, el desaliento;".split(' '),  
        "los defectos más peligrosos, la soberbia y el rencor;".split(' '),  
        "las sensaciones más gratas, la buena conciencia...".split(' ')   
        ]       
        printJaggedArray(text)
        upperCaseRandomArray(text)  
        printJaggedArray(text)
        graphJaggedArray(text)  

        // Array Exceptions  

        printTitle("Common Array Exceptions")  
        
        printCommonArrayExceptions(null)  
        printCommonArrayExceptions(text)  

        // Accessing Class Array Elements through Indexer  

        printTitle("Alphabets")
        
        val vowels = new Alphabet(5)
        vowels.set(0, 'a')  
        vowels.set(1, 'e')  
        vowels.set(2, 'i')  
        vowels.set(3, 'o')  
        vowels.set(4, 'u')
        
        println(String.format("\nVowels = {%s}",  #[vowels.get(0), 
         vowels.get(1), vowels.get(2), vowels.get(3), vowels.get(4)].join(',')))
         
        var en = new Alphabet("abcdefghijklmnopqrstuvwxyz")
        println('''English Alphabet = «en.toString»''') 
        
        println('''Alphabet Extract en[9..19] = «new Alphabet(en.slice(9, 10))»''')   
     
      var word1 = #[en.get(6), en.get(14), en.get(14), en.get(3)].join('')
      var word2 = #[en.get(1), en.get(24), en.get(4)].join('')
      var word3 = #[en.get(4), en.get(21), en.get(4), en.get(17), 
           en.get(24), en.get(14), en.get(13), en.get(4)].join('')
  
      println
      println('''«word1» «word2», «word3»!''')                      
 }
 
 def static char[] reverseChar(char[] arr) {  
        val char[] reversed = newCharArrayOfSize(arr.length)  
        for (var i = 0, var j = arr.length - 1; j >= 0; i++, j--) {
            reversed.set(i, arr.get(j))  
        }
        return reversed
    }  
    
    def static int[] bubbleSortInt(int[] arr) {  
        var int swap = 0  
        for (var i = arr.length - 1; i > 0; i--) {  
            for (var j = 0; j < i; j++) {  
                if (arr.get(j) > arr.get(j + 1)) {  
                    swap = arr.get(j)  
                    arr.set(j, arr.get(j + 1))
                    arr.set(j + 1, swap)
                }  
            }  
        }  
  return arr;  
    }  
    
    def static String[] bubbleSortString(String[] arr) {  
        var String swap = ""
        for (var i = arr.length - 1; i > 0; i--) {  
            for (var j = 0; j < i; j++) {                  
                if (arr.get(j).charAt(0) > arr.get(j + 1).charAt(0)) {  
                    swap = arr.get(j)  
                    arr.set(j, arr.get(j + 1))  
                    arr.set(j + 1, swap)
                }  
            }  
        }  
        return arr;  
    }
    
    def static int[][] transposeMatrix(int[][] m) {  
        /* Transposing a Matrix 2,3  
         *  
         * A =  [6  4 24]T [ 6  1]  
         *      [1 -9  8]  [ 4 -9] 
         *                 [24  8] 
        */  
        val int[][] transposed = new2DIntArrayOfSize(m.get(0).length, m.length)   
        for (var i = 0; i < m.length; i++) {  
            for (var j = 0; j < m.get(0).length; j++) {  
                transposed.get(j).set(i, m.get(i).get(j))  
            }  
        }  
        return transposed
    }    
    
    def static void upperCaseRandomArray(String[][] arr) {  
        val r = new Random
        var int i = r.nextInt(arr.length)
        for (var j = 0; j < arr.get(i).length; j++) {
            arr.get(i).set(j, arr.get(i).get(j).toUpperCase)
        }
    }
 
 def static printArrayChar(char[] arr) {
  println
  println('''Print Array Content «arr.class.name» «arr.class.name.class.name»[«arr.length»]''')
  
     for(var i = 0; i < arr.length; i++) {
      println(String::format(" array [%2d] = %2s", i, arr.get(i)))
     }
 }
 
 def static printArrayInt(int[] arr) {
  println
  println('''Print Array Content «arr.class.name» «arr.class.name.class.name»[«arr.length»]''')
  
     for(var i = 0; i < arr.length; i++) {
      println(String::format(" array [%2d] = %2s", i, arr.get(i)))
     }
 }
 
 def static printArrayString(String[] arr) {
  println
  println('''Print Array Content «arr.class.name» «arr.class.name.class.name»[«arr.length»]''')
  
     for(var i = 0; i < arr.length; i++) {
      println(String::format(" array [%2d] = %2s", i, arr.get(i)))
     }
 }
 
 def static void printMatrix(int[][] m) {  
        println(String.format("\nPrint Matrix Content %s[%d,%d]\n",  
            m.class.name.class.name,
            m.length,  
            m.get(0).length))

        for (var i = 0; i < m.length; i++) { 
            for (var j = 0; j < m.get(0).length; j++) {
                println(String.format(" array [%2d,%2d] = %2d", i, j, m.get(i).get(j)))
            }
        }    
 }
 
 def static void graphJaggedArray(String[][] arr) {  
        /* When using Arrays, we can use foreach instead of for:  
         *  
         * for (var i = 0; i < arr.length; i++) 
         *   for (var j = 0; j < arr.length; j++)                 
         *  
        */  
        println("\nPrint Text Content " + arr.class.name.class.name)
        var lineCount = 1
        for(s : arr) {  
            print(String.format("Line%2s|", lineCount))
            for(w : s) {  
                print(String.format("%3s", '*'))
            }  
            print(String.format(" (%d)\n", s.length))  
            lineCount++
        }  
    }  
    
    def static void printJaggedArray(String[][] arr) {  
        var StringBuffer line
        println("\nPrint Jagged Array Content " + arr.class.name + 
         " " + arr.class.name.class.name + "[]") 
        for (var i = 0; i < arr.length; i++)  {  
            line = new StringBuffer 
            for (var j = 0; j < arr.get(i).length; j++) {  
                line.append(" ").append(arr.get(i).get(j)) 
            }
            if (line.toString.equals(line.toString.toUpperCase)) {
                line.append(" <-- [UPPERCASED]")
            }
            println(line)
        }  
    }  
    
    def static void printCommonArrayExceptions(String[][] arr) {  
        try {  
            arr.get(100).set(100, "hola") 
        }  
        catch (NullPointerException ex) { 
         println(String.format("\nException: \n%s\n%s\n", 
                    ex.class.name, ex.message))
        }
        catch (ArrayIndexOutOfBoundsException ex) {  
            println(String.format("\nException: \n%s\n%s\n", 
                    ex.class.name, ex.message))  
        }  
    }  
 
    def static printTitle(String message) {
        println
        println("======================================================")
        println(message)
        println("======================================================")
    }
}


class Alphabet {
 // Array Field
    var char[] letters
    
    // Indexer Getter/Setter 
    def char get(int index) {
     return letters.get(index)
    }
    def void set(int index, char value) {
     this.letters.set(index, value.toString.toUpperCase.charAt(0))
    }
    
    // Getter
    def int length() {  
        return this.letters.length  
    }  
    
    // Constructors  
    new(int size) {  
        this.letters = newCharArrayOfSize(size)  
    }  

    new(String list) {  
        this.letters = list.toUpperCase.toCharArray
    }  

    new(char[] list) {  
        this.letters = list  
    }  
    
    // Overridden Method  
    override String toString() {  
        return this.letters.join(",")
    } 
    
    // Method  
    def char[] slice(int start, int length) {  
        val char[] result = newCharArrayOfSize(length)  
        for (var i = 0, var j = start; i < length; i++, j++) {  
            result.set(i, this.letters.get(j))  
        }  
        return result
    }  
}


The output:








Voilà, that's it. Next post in the following days.

Sunday, July 8, 2012

Factorial and Fibonacci in Xtend



Here below a little program in Xtend that implements 2 classes (in fact, they are 3 + an extra utility Stopwatch class from my previous post http://carlosqt.blogspot.com/2011/05/stopwatch-class-for-java.html). There is the main class, called Fiborial (Fibo(nnacci)+(Facto)rial) that implements the Fibonacci and the Factorial algorithms in two ways, one Recursive (using recursion) and the other Imperative (using loops and states). The second class is just an instance class that does the same thing, but its there just to show the difference between static and instance classes, and finally the third one (which will not appear in other languages) is the Program class which has the static execution method "main".

You can also find 3 more little examples at the bottom. One prints out the Factorial's Series and Fibonacci's Series, the second one just shows a class that mixes both: static and instance members, and finally the third one that uses different return types (including java.math.BigInteger) for the Factorial method to compare the timing and result.

As with the previous posts, you can copy and paste the code below in your Eclipse IDE and start playing and learning with it. This little "working" program will teach you some more basics of the Programming Language.

There are some "comments" on the code added just to tell you what are or how are some features called. In case you want to review the theory, you can read my previous post, where I give a definition of each of the concepts mentioned on the code. You can find it here: http://carlosqt.blogspot.com/2011/01/new-series-factorial-and-fibonacci.html 


The Fiborial Program

// Factorial and Fibonacci in Xtend  
package com.series
import com.series.Stopwatch
import java.math.BigInteger
import java.util.List

// Instance Class
// static is not a class modifier in Xtend
class StaticFiborial {
    // Static Field
    private static String className = "'Static' Constructor"
    // Static Constructor/Initializer  
    // no available static constructor support  
    // Static Initializer Method instead, but need to be explicitly invoked  
    def static constructor() {  
        className = "'Static' Constructor"  
        println(className)  
    }  
    // Static Method - Factorial Recursive  
    def static BigInteger factorialR(int n) {
        if (n == 1)  
              return 1BI
        else
            return BigInteger::valueOf(n) * factorialR(n - 1)       
    }
    // Static Method - Factorial Imperative  
    def static BigInteger factorialI(int n) {
        var res = 1BI
        var m = n // method parameters are final
        while (m > 1) {
            res = res * BigInteger::valueOf(m)
            m = m - 1    
        }   
        return res     
    }
    // Static Method - Fibonacci Recursive   
    def static long fibonacciR(int n) {
        if (n < 2)
            return 1L
        else
            return fibonacciR(n - 1) + fibonacciR(n - 2)
    } 
    // Static Method - Fibonacci Imperative
    def static long fibonacciI(int n) {
        var pre = 1L
        var cur = 1L
        var tmp = 0L
        for (int i : 2..n) {
            tmp = cur + pre
            pre = cur
            cur = tmp
        }             
        return cur
    }    
    // Static Method - Benchmarking Algorithms  
      def static void benchmarkAlgorithm(int algorithm, List<Integer> values) {  
        val timer = new Stopwatch  
        var testValue = 0
        var facTimeResult = 0BI  
        var fibTimeResult = 0L 
        var i = 0 
        // "Switch" Flow Control Statement
        switch algorithm {
            case 1: {
                println("\nFactorial Imperative:")  
                // "For" Loop Statement  
                for (int j : 0..values.size - 1) {  
                    testValue = values.get(j).intValue
                    // Taking Time
                    timer.start
                    facTimeResult = factorialI(testValue)  
                    timer.stop 
                    // Getting Time  
                    println(''' («testValue») = «timer.getElapsed»''')
                    }
                }
            case 2: {
                println("\nFactorial Recursive:")    
                // "While" Loop Statement                
                while (i < values.size) {                            
                    testValue = values.get(i).intValue    
                    // Taking Time    
                    timer.start    
                    facTimeResult = factorialR(testValue)    
                    timer.stop    
                    // Getting Time    
                    println(''' («testValue») = «timer.getElapsed»''')
                    i = i + 1    
                }
            }
            case 3: {
                println("\nFibonacci Imperative:")   
                // "Do-While" Loop Statement
                do {    
                    testValue = values.get(i).intValue    
                    // Taking Time    
                    timer.start    
                    fibTimeResult = fibonacciI(testValue)    
                    timer.stop
                    // Getting Time    
                    println(''' («testValue») = «timer.getElapsed»''')
                    i = i + 1        
                } while (i < values.size)    
            }
            case 4: {
                println("\nFibonacci Recursive:")    
                // "For Each" Loop Statement    
                for (int item : values) {    
                    testValue = item;    
                    // Taking Time    
                    timer.start    
                    fibTimeResult = fibonacciR(testValue)    
                    timer.stop    
                    // Getting Time    
                    println(''' («testValue») = «timer.getElapsed»''')
                }    
            }
            default : println("DONG!")
        }
    }
}

package com.series
import com.series.StaticFiborial
import java.math.BigInteger

// Instance Class    
class InstanceFiborial {
    // Instance Field    
    private String className    
    // Instance Constructor    
    new() {    
        this.className = "Instance Constructor"
        println(this.className)
    }    
    // Instance Method - Factorial Recursive    
    def BigInteger factorialR(int n) {    
        // Calling Static Method    
        return StaticFiborial::factorialR(n)    
    }    
    // Instance Method - Factorial Imperative    
    def BigInteger factorialI(int n) {    
        // Calling Static Method
        return StaticFiborial::factorialI(n)
    }    
    // Instance Method - Fibonacci Recursive
    def long fibonacciR(int n) {    
        // Calling Static Method    
        return StaticFiborial::fibonacciR(n)    
    }    
    // Instance Method - Factorial Imperative    
    def long fibonacciI(int n) {    
        // Calling Static Method    
        return StaticFiborial::fibonacciI(n);    
    }    
}

package com.series
import com.series.StaticFiborial
import com.series.InstanceFiborial 
import java.util.List
import java.util.ArrayList
import java.util.Scanner

class FiborialProgram {
    def static main(String[] args) {
        println("\n'Static' Class")    
        // Calling Static Class and Methods    
        // No instantiation needed. Calling method directly from the class
        StaticFiborial::constructor        
        println('''FacImp(5) = «StaticFiborial::factorialI(5)»''')    
        println('''FacRec(5) = «StaticFiborial::factorialR(5)»''')    
        println('''FibImp(11)= «StaticFiborial::fibonacciI(11)»''')    
        println('''FibRec(11)= «StaticFiborial::fibonacciR(11)»''')    

        println("\nInstance Class");    
        // Calling Instance Class and Methods     
        // Need to instantiate before using. Calling method from instantiated object    
        val ff = new InstanceFiborial
        println('''FacImp(5) = «ff.factorialI(5)»''')
        println('''FacRec(5) = «ff.factorialR(5)»''')  
        println('''FibImp(11)= «ff.fibonacciI(11)»''')   
        println('''FibRec(11)= «ff.fibonacciR(11)»''')  
  
        // Create a (generic) list of integer values to test    
        // From 5 to 50 by 5    
        val List<Integer> values = new ArrayList<Integer>
        var i = 5
        while (i < 55) {  
            values.add(i)  
            i = i + 5  
        }
  
        // Benchmarking Fibonacci                         
        // 1 = Factorial Imperative                
        StaticFiborial::benchmarkAlgorithm(1, values)    
        // 2 = Factorial Recursive    
        StaticFiborial::benchmarkAlgorithm(2, values)     
  
        // Benchmarking Factorial                
        // 3 = Fibonacci Imperative    
        StaticFiborial::benchmarkAlgorithm(3, values)    
        // 4 = Fibonacci Recursive    
        StaticFiborial::benchmarkAlgorithm(4, values)     
  
        // Stop and exit    
        println("Press any key to exit...")          
        val in = new Scanner(System::in)    
        val line = in.nextLine    
        in.close         
    }
}

And the Output is:





Printing the Factorial and Fibonacci Series
package com.series
import java.math.BigInteger
import java.lang.StringBuffer

class Fiborial {
    // Using a StringBuffer as a list of string elements  
    def static String getFactorialSeries(int n) {  
        // Create the String that will hold the list  
        val series = new StringBuffer  
        // We begin by concatenating the number you want to calculate  
        // in the following format: "!# ="  
        series.append("!")  
        series.append(n) 
        series.append(" = ")  
        // We iterate backwards through the elements of the series  
        var i = n  
        while (i > 0) {  
            // and append it to the list  
            series.append(i)  
            if (i > 1)  
                series.append(" * ")  
            else  
                series.append(" = ")  
            i = i - 1  
        }  
        // Get the result from the Factorial Method  
        // and append it to the end of the list  
        series.append(factorial(n))  
        // return the list as a string  
        return series.toString
    }  
  
    // Using a StringBuffer as a list of string elements  
    def static String getFibonnaciSeries(int n)  
    {  
        // Create the String that will hold the list  
        val series = new StringBuffer  
        // We begin by concatenating the first 3 values which  
        // are always constant  
        series.append("0, 1, 1")
        // Then we calculate the Fibonacci of each element  
        // and add append it to the list  
        for (int i : 2..n) {  
            if (i < n)  
                series.append(", ")  
            else  
                series.append(" = ")  
            series.append(fibonacci(i))  
        }  
        // return the list as a string  
        return series.toString
    }  
  
    def static BigInteger factorial(int n) {
        if (n == 1)  
              return 1BI
        else
            return BigInteger::valueOf(n) * factorial(n - 1)       
    }       
  
    def static long fibonacci(int n) {
        if (n < 2)
            return 1L
        else
            return fibonacci(n - 1) + fibonacci(n - 2)
    }    
}

package com.series
import com.series.Fiborial

class FiborialProgram {
    def static void main(String[] args) {
        // Printing Factorial Series  
        println 
        println(Fiborial::getFactorialSeries(5))
        println(Fiborial::getFactorialSeries(7))  
        println(Fiborial::getFactorialSeries(9))  
        println(Fiborial::getFactorialSeries(11))  
        println(Fiborial::getFactorialSeries(40))  
        // Printing Fibonacci Series  
        println 
        println(Fiborial::getFibonnaciSeries(5))  
        println(Fiborial::getFibonnaciSeries(7))  
        println(Fiborial::getFibonnaciSeries(9))  
        println(Fiborial::getFibonnaciSeries(11))  
        println(Fiborial::getFibonnaciSeries(40))  
    }
}

And the Output is:

















Mixing Instance and Static Members in the same Class

Instance classes can contain both, instance and static members such as: fields, getters/setters, constructors/initializers, methods, etc.

package com.series

class Fiborial {
    // Instance Field    
    var int instanceCount
    // Static Field    
    static var int staticCount
    // Instance Read-Only Getter    
    // Within instance members, you can always use      
    // the "this" reference pointer to access your (instance) members.    
    def int getInstanceCount() {    
        return this.instanceCount     
    }    
    // Static Read-Only Getter        
    // As with Static Methods, you cannot reference your class members    
    // with the "this" reference pointer since static members are not    
    // instantiated.            
    def static int getStaticCount() {    
        return staticCount
    }    
    // Instance Constructor    
    public new() {    
        this.instanceCount = 0
        println    
        println('''Instance Constructor «this.instanceCount»''')   
    }    
    // Static Constructor 
    // not supported in Xtend. Constructor cannot be static.
    // using an explicit initializer method instead    
    def static constructor() { 
        staticCount = 0
        println 
        println('''Static Constructor «staticCount»''') 
    }    
    // Instance Method    
    def void factorial(int n) {    
        this.instanceCount =  this.instanceCount + 1
        println    
        println('''Factorial(«n»)''')    
    }    
  
    // Static Method    
    def static void fibonacci(int n) {    
        staticCount = staticCount + 1
        println    
        println('''Fibonacci(«n»)''');    
    }                    
}

package com.series
import com.series.Fiborial

class FiborialProgram {
    def static void main(String[] args) {
        // Calling Static Initializer and Methods  
        // No need to instantiate  
        Fiborial::constructor  
        Fiborial::fibonacci(5)  
      
        // Calling Instance Constructor and Methods  
        // Instance required  
        val fib = new Fiborial  
        fib.factorial(5)  
      
        Fiborial::fibonacci(15)  
        fib.factorial(5)  
      
        // Calling Instance Constructor and Methods  
        // for a second object  
        val fib2 = new Fiborial  
        fib2.factorial(5)  
      
        println
        // Calling Static Property  
        println('''Static Count = «Fiborial::getStaticCount»''')  
        // Calling Instance Property of object 1 and 2  
        println('''Instance 1 Count = «fib.getInstanceCount»''')  
        println('''Instance 2 Count = «fib2.getInstanceCount»''')          
    } 
}

And the Output is:























Factorial using java.lang.Long, java.lang.Double, java.math.BigInteger


package com.series
import com.series.Stopwatch
import java.math.BigInteger

class Fiborial {
    def static void main(String[] args) {
        val timer = new Stopwatch  
        var facIntResult = 0L
        var facDblResult  = 0d  
        var facBigResult = 0BI 
        var i = 5
        
        println("\nFactorial using Int64")  
        // Benchmark Factorial using Int64  
        while (i < 55) {  
            timer.start
            facIntResult = factorialInt64(i)  
            timer.stop  
              println(''' («i») = «timer.getElapsed» : «facIntResult»''')  
              i = i + 5  
        }  
        println("\nFactorial using Double")  
        // Benchmark Factorial using Double  
        i = 5  
        while (i < 55) {  
            timer.start  
            facDblResult = factorialDouble(i)  
            timer.stop
            println(''' («i») = «timer.getElapsed» : «facDblResult»''')  
            i = i + 5  
        }  
        println("\nFactorial using BigInteger")  
        // Benchmark Factorial using BigInteger  
        i = 5  
        while (i < 55) {  
            timer.start  
            facBigResult = factorialBigInteger(i)  
            timer.stop  
              println(''' («i») = «timer.getElapsed» : «facBigResult»''')  
            i = i + 5    
        }  
    }
    
    // Long Factorial    
    def static long factorialInt64(int n) {    
        if (n == 1)    
            return 1L  
        else    
            return n * factorialInt64(n - 1)  
    }  
      
    // Double Factorial
    def static double factorialDouble(int n) {    
        if (n == 1)    
            return 1d
        else    
            return n * factorialDouble(n - 1)  
    }  
      
    // BigInteger Factorial   
    def static BigInteger factorialBigInteger(int n) {    
        if (n == 1)    
            return 1BI  
        else    
            return BigInteger::valueOf(n) * factorialBigInteger(n - 1)  
    }  
}



And the Output is:

Sunday, May 6, 2012

Xtend - Basics by Example



Extending my Basics by Example series to a new language. today's version of the post written in Xtend.

You can copy and paste the code below in your favorite IDE/Editor and start playing and learning with it. This little "working" program will teach you the basics of the Programming Language.

There are some "comments" on the code added just to tell you what are or how are some features called. In case you want to review the theory, you can read my previous post, where I give a definition of each of the concepts mentioned on the code. You can find it here: http://carlosqt.blogspot.com/2010/08/new-series-languages-basics-by-example.html 


Greetings Program - Verbose
// Xtend Basics
package com.series
import java.util.Calendar
import java.util.GregorianCalendar

public class Greet {
    // Fields or Attributes
    private String message  
    private String name
    private int loopMessage 
    // Getters and Setters. 
    // M7 will introduce annotation @Property to auto generate them (if not present)
    def public String getMessage() {  
        return this.message
    }  
    def public void setMessage(String value) {  
        this.message = this.capitalize(value)  
    }  
    def public String getName() {  
        return this.name
    }  
    def public void setName(String value) {  
        this.name = this.capitalize(value)  
    }  
    def public int getLoopMessage() {  
        return this.loopMessage  
    }  
    def public void setLoopMessage(int value) {  
        this.loopMessage = value  
    }  
    // Constructor  
    public new() {
        this.message = ""  
        this.name = ""
        this.loopMessage = 0           
    }
    // Overloaded Constructor  
    public new(String message, String name, int loopMessage) {  
        this.message = this.capitalize(message)  
        this.name = this.capitalize(name)  
        this.loopMessage = loopMessage  
    }    
    // Method 1  
    def private String capitalize(String value) {  
        // "if-then-else" statement  
        if (value.length() >= 1) {  
            return value.toFirstUpper()  
        }  
        else  {  
            return ""  
        }  
    }  
    // Method 2  
    def public void Salute() {  
        // "for (each)" statement
        for (int i : 0..this.loopMessage) {  
            println(this.message + " " + this.name + "!")  
        }  
    }  
    // Overloaded Method 2.1  
    def public void Salute(String message, String name, int loopMessage) {  
        // "while" statement  
        var int i = 0  
        while(i < loopMessage) {  
            println(this.capitalize(message) + " " + this.capitalize(name) + "!")
            i = i + 1
        }  
    }      
    // Overloaded Method 2.2  
    def public void Salute(String name) {  
        // "switch/case" statement  
        // doesn't work with iterables (i.e: case 6..11: ...)
        // doesn't allow multiple expressions in one case (i.e: case i>=6 && i<=11: ...)
        // doesn't allow fall through (i.e: case 6: case 7: case N: ...)
        // so better to use if-else-if expression instead
        var GregorianCalendar dtNow = new GregorianCalendar()        
        val int hh = dtNow.get(Calendar::HOUR_OF_DAY) 
        if (hh >= 6 && hh <= 11) this.message = "good morning,"        
        else if (hh >= 12 && hh <= 17) this.message = "good afternoon,"
        else if (hh >= 18 && hh <= 22) this.message = "good evening,"            
        else if (hh == 23 || (hh >= 0 && hh <= 5)) this.message = "good night,"
        else this.message = "huh?"        
        println(this.capitalize(this.message) + " " + this.capitalize(name) + "!")  
    }  
}
package com.series
import java.util.Scanner  
import java.lang.System 
// Greet Program
public class Program { 
    def public static void main(String[] args) {
        // Define variable object of type Greet and Instantiate. Call Constructor  
        val Greet g = new Greet()           
        // Call Setters  
        g.setMessage("hello")  
        g.setName("world")  
        g.setLoopMessage(5)  
        // Call Method 2  
        g.Salute()
        // Overloaded Method 2.1 and Getters  
        g.Salute(g.getMessage(), "xtend", g.getLoopMessage())  
        // Overloaded Method 2.2  
        g.Salute("carlos")
        
        // Stop and exit  
        println("Press any key to exit...")        
        val Scanner in = new Scanner(System::in)  
        val String line = in.nextLine()  
        in.close()                 
    }    
}

Greetings Program - Minimal
// Xtend Basics
import java.util.Calendar
import java.util.GregorianCalendar

class Greet {
    // Fields or Attributes
    private String message  
    private String name
    private int loopMessage    
    // Getters and Setters. 
    // M7 will introduce annotation @Property to auto generate them (if not present)    
    def getMessage() {  
        message
    }  
    def setMessage(String value) {  
        message = capitalize(value)  
    }  
    def getName() {  
        name
    }  
    def setName(String value) {  
        name = capitalize(value)  
    }  
    def getLoopMessage() {  
        loopMessage  
    }  
    def setLoopMessage(int value) {  
        loopMessage = value  
    }  
    // Constructor  
    new() {
        message = ""  
        name = ""
        loopMessage = 0           
    }
    // Overloaded Constructor  
    new(String message, String name, int loopMessage) {  
        this.message = capitalize(message)  
        this.name = capitalize(name)  
        this.loopMessage = loopMessage  
    }    
    // Method 1  
    def private String capitalize(String value) {  
        // "if-then-else" statement  
        if (value.length >= 1)  
            value.toFirstUpper  
        else    
            ""  
    }  
    // Method 2  
    def Salute() {  
        // "for (each)" statement
        for (i : 0..loopMessage) {  
            println(message + " " + name + "!")  
        }  
    }  
    // Overloaded Method 2.1  
    def Salute(String message, String name, int loopMessage) {  
        // "while" statement  
        var i = 0  
        while(i < loopMessage) {  
            println(capitalize(message) + " " + capitalize(name) + "!")
            i = i + 1
        }  
    }      
    // Overloaded Method 2.2  
    def Salute(String name) {  
        // "switch/case" statement  
        // doesn't work with iterables (i.e: case 6..11: ...)
        // doesn't allow multiple expressions in one case (i.e: case i>=6 && i<=11: ...)
        // doesn't allow fall through (i.e: case 6: case 7: case N: ...)
        // so better to use if-else-if expression instead
        var dtNow = new GregorianCalendar        
        val hh = dtNow.get(Calendar::HOUR_OF_DAY) 
        if (hh >= 6 && hh <= 11) message = "good morning,"        
        else if (hh >= 12 && hh <= 17) message = "good afternoon,"
        else if (hh >= 18 && hh <= 22) message = "good evening,"            
        else if (hh == 23 || (hh >= 0 && hh <= 5)) message = "good night,"
        else message = "huh?"        
        println(capitalize(message) + " " + capitalize(name) + "!")  
    }  
}
import java.util.Scanner  
// Greet Program
class Program { 
    def static main(String[] args) {
        // Define variable object of type Greet and Instantiate. Call Constructor  
        val g = new Greet           
        // Call Setters  
        g.setMessage("hello")  
        g.setName("world")  
        g.setLoopMessage(5)  
        // Call Method 2  
        g.Salute
        // Overloaded Method 2.1 and Getters  
        g.Salute(g.getMessage, "xtend", g.getLoopMessage)  
        // Overloaded Method 2.2  
        g.Salute("carlos")
        
        // Stop and exit  
        println("Press any key to exit...")        
        val in = new Scanner(System::in)  
        val line = in.nextLine  
        in.close
    }    
}


And the Output is:




Auto-Implemented Properties in Xtend

Auto-implemented properties enable you to quickly specify a property of a class without having to write code to Get and Set the field. In Xtend you will use the @Property annotation which will generate a Java-Bean-style getter and setter (if the field is not final) for an annotated field and only generated when not explicitly defined.


// Xtend Basics  
class AutoImplementedProperties {  
    // Fields + Auto-Implemented Properties  
    @Property String message  
    @Property String name  
    @Property int loopMessage  
    // Methods  
    def salute() {    
        println('''«message.toFirstUpper» «name.toFirstUpper» «loopMessage»!''')
    }  
}
class Program { 
    def static void main(String[] args) {
        var g = new AutoImplementedProperties => [ 
            // Call Set Property  
            message = "hello"         
            name = "world"
            loopMessage = 5        
        ]
        // print them out  
        g.salute
        // and print them again using Get Properties  
        println('''«g.message» «g.name» «g.loopMessage»!''')
    }    
}

And the output is:


Sunday, April 22, 2012

OO Hello World - Xtend



The OO Hello World in Xtend, the "the CoffeScript for the JVM", is here!

Xtend is a statically-typed programming language which is tightly integrated with and
runs on the Java Virtual Machine.


You can see the OO Hello World series post here: http://carlosqt.blogspot.com/2010/06/oo-hello-world.html where I give some details on why these "oo hello world series" samples.

Version 1 (Minimal):
The minimum you need to type to get your program compiled and running.
class Greet {
 String name
 new(String name) {
  this.name = name.toFirstUpper
 }
 def salute() {
  println("Hello " + name + "!")
 }
}
// Greet Program
class Program {
 def static void main(String[] args) {
  val g = new Greet("world")  
  g.salute
 } 
}

Version 2 (Verbose):
Explicitly adding instructions and keywords that are optional to the compiler.
package com.series

public class Greet {
 private String name
 public new(String name) {
  this.name = name.toFirstUpper()
 }
 def public void salute() {
  println("Hello " + this.name + "!")
 }
}
package com.series

// Greet Program
public class Program { 
 def public static void main(String[] args) {
  val g = new Greet("world")  
  g.salute()
 } 
}

The Program Output:








Xtend Info:

"Xtend is a statically-typed programming language developed at Eclipse.org. It
has a strong focus on leveraging all the good parts of Java, including seamless
integration with the huge amount of Java frameworks and libraries out there.” Taken from: ( Pragmatic Magazine - Issue 30, December 2011 )

Appeared:
2011
Current Version:
Developed by:
Eclipse
Creator:
Sven Efftinge, Sebastian Zarnekow
Influenced by:
Java (James Gosling)
Predecessor Language
N/A
Predecessor Appeared
N/A
Predecessor Creator
N/A
Runtime Target:
JVM
Latest Framework Target:
JDK 6,7
Mono Target:
No
Allows Unmanaged Code:
No
Source Code Extension:
“.xtend”
Keywords:
41
Case Sensitive:
Yes
Free Version Available:
Yes
Open Source:
Yes
Standard:
N/A
Latest IDE Support:
Eclipse
Language Reference:
Extra Info: