Showing posts with label Fantom. Show all posts
Showing posts with label Fantom. Show all posts

Friday, December 5, 2014

Arrays and Indexers in Fantom



Today's post is about Arrays and Indexers in Fantom. 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 Fantom, 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.


using [java] fanx.interop::CharArray
using [java] fanx.interop::IntArray 

class FantomArrays
{
  static Void main()
  {
    // For char and int I'm using primitive arrays (CharArray and IntArray)
    // and for String arrays and Multi-dimensional arrays I'm using List (Type[])
    // reference: http://fantom.org/doc/docLang/JavaFFI
    // section Interop Summary and Arrays
    
    // Single-dimensional Array(s)
    printTitle("Reverse Array Elements")
    
    // Declare and Initialize Array of Chars
    letters := CharArray.make(5)
    letters[0] = 'A'
    letters[1] = 'E'
    letters[2] = 'I'
    letters[3] = 'O'
    letters[4] = 'U'

    printArrayChar(letters)
    CharArray inverse_letters := reverseChar(letters)
    printArrayChar(inverse_letters)
    
    printTitle("Sort Integer Array Elements")
    
    // Declare and Initialize Array of Integers
    numbers := IntArray(5)
    numbers[0] = 10
    numbers[1] = 8
    numbers[2] = 3
    numbers[3] = 1
    numbers[4] = 5
    
    printArrayInt(numbers)
    IntArray ordered_numbers := bubbleSortInt(numbers)
    printArrayInt(ordered_numbers)
    
    printTitle("Sort String Array Elements") 

    // Declare and Initialize and Array of Strings  
    Str[] names := Str[                      
            "Damian",   
            "Rogelio",  
            "Carlos",   
            "Luis",                       
            "Daniel"  
          ] 
    printArrayString(names)
    Str[] 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] 
    */  
    Int[][] matrix := [[6, 4, 24],   
                       [1, -9, 8]]  
    printMatrix(matrix)
    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: 
     *  
     * Str[][] text := [  
     *      [ "word1", "word2", "wordN" ],  
     *      [ "word1", "word2", "wordM" ],  
     *      ... 
     *      ]
     *  
     * Text extract from: "El ingenioso hidalgo don Quijote de la Mancha" 
     *  
     */  
    Str[][] text := [   
    "Hoy es el dia mas hermoso de nuestra vida, querido Sancho;".split,  
    "los obstaculos mas grandes, nuestras propias indecisiones;".split,  
    "nuestro enemigo mas fuerte, miedo al poderoso y nosotros mismos;".split,  
    "la cosa mas facil, equivocarnos;".split,  
    "la mas destructiva, la mentira y el egoismo;".split,  
    "la peor derrota, el desaliento;".split,  
    "los defectos mas peligrosos, la soberbia y el rencor;".split,  
    "las sensaciones mas 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")

    vowels := Alphabet(5)  
    vowels.set(0, 'a')  
    vowels.set(1, 'e')  
    vowels.set(2, 'i')  
    vowels.set(3, 'o')  
    vowels.set(4, 'u') 
    
    l := [vowels.get(0).toChar, vowels.get(1).toChar, vowels.get(2).toChar, vowels.get(3).toChar, vowels.get(4).toChar].join(",")
    echo("\nVowels = {$l}")
    
    //en := Alphabet.make(...) <-- this should work...
    en := Alphabet.makeFromStr("abcdefghijklmnopqrstuvwxyz")
    echo("English Alphabet = {${en.toStr}}") 
    
    //extract := Alphabet.make(...) <-- this should work...
    extract := Alphabet.makeFromList(en.slice(9, 10))
    echo("Alphabet Extract en[9..19] = {$extract}")
    
    word1 := [en.get(6).toChar, en.get(14).toChar, en.get(14).toChar, en.get(3).toChar].join
    word2 := [en.get(1).toChar, en.get(24).toChar, en.get(4).toChar].join
    word3 := [en.get(4).toChar, en.get(21).toChar, en.get(4).toChar, en.get(17).toChar, en.get(24).toChar, en.get(14).toChar, en.get(13).toChar, en.get(4).toChar].join
    
    echo("\n$word1 $word2, $word3!")
  }
  
  static CharArray reverseChar(CharArray arr) 
  {
    // for List Int[] you use arr.reverse() 
    reversed := CharArray.make(arr.size)
    Int j := arr.size - 1
    for (i := 0; i < arr.size; ++i) {
        reversed[i] = arr[j]
        j--
    }
    return reversed
  }
  
  static IntArray bubbleSortInt(IntArray arr) 
  {  
    Int swap := 0
    for (Int i := arr.size - 1; i > 0; i--) 
    {  
      for (Int j := 0; j < i; j++) 
      {  
        if (arr[j] > arr[j + 1]) 
        {  
          swap = arr[j]  
          arr[j] = arr[j + 1]  
          arr[j + 1] = swap 
        }  
      }  
    }  
    return arr
  } 
  
  static Str[] bubbleSortString(Str[] arr) 
  {  
    Str swap := ""  
    for (Int i := arr.size - 1; i > 0; i--) {  
      for (Int j := 0; j < i; j++) {                  
        if (arr[j][0] > arr[j + 1][0]) {  
          swap = arr[j];  
          arr[j] = arr[j + 1];  
          arr[j + 1] = swap;  
        }  
      }  
    }  
    return arr  
  }  
  
  static Int[][] transposeMatrix(Int[][] m) 
  {  
    /* Transposing a Matrix 2,3  
     *  
     * A =  [6  4 24]T [ 6  1]  
     *      [1 -9  8]  [ 4 -9] 
     *                 [24  8] 
    */
    Int[][] transposed := [,]    

    for (Int i := 0; i < m[0].size; i++) 
    { 
      Int[] row := [,]
      for (Int j := 0; j < m.size; j++) 
      {        
        row.add(m[j][i])        
      }  
      transposed.add(row)
    }
    return transposed
  }  
  
  static Void upperCaseRandomArray(Str[][] arr) 
  {   
    Int i := Int.random(0..<arr.size)
    for (Int j := 0; j < arr[i].size; j++) 
    {
      arr[i][j] = arr[i][j].upper
    }
  }
  
  static Void printArrayChar(CharArray arr) 
  {
    echo("\nPrint Array Content ${arr.typeof.name} [${arr.size}]")
  
    for (i := 0; i < arr.size; i++)  
    {
      echo(" array [${i.toStr.padl(2)}] = ${arr[i].toChar.padl(2)}")
    }
  }
  
  static Void printArrayInt(IntArray arr) 
  {
    echo("\nPrint Array Content ${arr.typeof.name} [${arr.size}]")
  
    for (i := 0; i < arr.size; i++)  
    {
      echo(" array [${i.toStr.padl(2)}] = ${arr[i].toStr.padl(2)}")
    }
  }
  
  static Void printArrayString(Str[] arr) 
  {
    echo("\nPrint Array Content ${arr.typeof.name} ${arr[0].typeof.name}[${arr.size}]")
  
    for (i := 0; i < arr.size; i++)  
    {
      echo(" array [${i.toStr.padl(2)}] = ${arr[i].padl(2)}")
    }
  }
  
  static Void printMatrix(Int[][] m) 
  {  
    echo("\nPrint Matrix Content ${m.typeof.name} ${m[0][0].typeof.name}[${m.size},${m[0].size}]")
  
    for (Int i := 0; i < m.size; i++) 
    { 
      for (Int j := 0; j < m[0].size; j++) 
      {
        echo(" array [${i.toStr.padl(2, ' ')},${j.toStr.padl(2, ' ')}] = ${m[i][j].toStr.padl(2, ' ')}")
      }
    }
  }  
  
  static Void graphJaggedArray(Str[][] arr) 
  { 
    echo("\nPrint Text Content ${arr.typeof.name} ${arr[0][0].typeof.name}[${arr.size}]")
    Int lineCount := 1  
    arr.each |Str[] s| 
    {  
      Env.cur.out.print("Line${lineCount.toStr.padl(2)}|")  
      s.each |Str w| 
      {  
        Env.cur.out.print(" * ")  
      }  
      echo(" (${s.size})")
      lineCount++  
    }      
  }
  
  static Void printJaggedArray(Str[][] arr) 
  {  
    echo("\nPrint Jagged Array Content ${arr.typeof.name} ${arr[0][0].typeof.name}[${arr.size}]")
    for (Int i := 0; i < arr.size; i++)  
    {  
      line := StrBuf()
      for (Int j := 0; j < arr[i].size; j++) 
      {  
          line.add(" ").add(arr[i][j])  
      }
      if (line.toStr == line.toStr.upper) 
      {
        line.add(" <-- [UPPERCASED]")
      }
      echo(line)  
    }  
  }  
  
  static Void printCommonArrayExceptions(Str?[]?[]? arr) 
  {  
    try 
    {  
        arr[100][100] = "hola"        
    }  
    catch (NullErr ex) 
    {  
      echo("\nException: \n${ex.typeof.name}\n$ex") 
    } 
    catch (IndexErr ex) 
    {  
      echo("\nException: \n${ex.typeof.name}\n$ex") 
    } 
    catch (Err ex)
    {  
      echo("\nException: \n${ex.typeof.name}\n$ex") 
    } 
  }  
  
  static Void printTitle(Str message) 
  {
    echo()
    echo("".padr(54, '='))
    echo(message)
    echo("".padr(54, '='))
  }
}

class Alphabet
{
  // Array Field
  Int[] letters := [,]
  
  // Indexer Getter/Setter 
  Int get(Int index) 
  {
    return letters[index]
  }
  
  Void set(Int index, Int value) 
  {
    letters[index] = value.upper
  }
  
  // Constructors
  new make(Int size) 
  {  
    letters.fill(0, size)
  }  

  new makeFromStr(Str list) 
  {  
    letters = list.upper.chars
  }  

  new makeFromList(Int[] list) 
  {  
    letters = list
  }  
  
  // Overriden Method
  override Str toStr()
  {
    Str[] characters := [,]
    this.letters.each |Int c| { characters.add(c.toChar) }
    return characters.join(",")
  }
  
  // Method
  Int[] slice(Int start, Int length)
  {
    return letters.getRange(start..<start+length)
  }
  
}


The output:








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

Wednesday, February 8, 2012

Factorial and Fibonacci in Fantom



Here below a little program in Fantom 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 favorite IDE/Editor 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 Fantom

using [java] com.carlosqt.util::Stopwatch
using [java] java.math::BigInteger

// static is not a valid class modifier
// Instanced Class
class StaticFiborial 
{
  // (Constant) Static Field  - Static fields must be const - this ensures thread safety  
  private const static Str className
  // Class/Static Constructor/Initializer
  // It is permissible to have multiple static initializers; they run in order of declaration
  static 
  {      
    className = "Static Constructor"  
    echo(className)  
  }
  // Static Method - Factorial Recursive
  static BigInteger factorialR(Int n)      
  {      
    if (n == 1)      
      return BigInteger.ONE  
    else      
      return BigInteger.valueOf(n).multiply(factorialR(n - 1))  
  }
  // Static Method - Factorial Imperative      
  static BigInteger factorialI(Int n)      
  {      
    BigInteger res := BigInteger.ONE  
    for (i := n; i >= 1; i--)      
    {                      
      res = res.multiply(BigInteger.valueOf(i))  
    }      
    return res  
  }
  // Static Method - Fibonacci Recursive      
  static Int fibonacciR(Int n)      
  {      
    if (n < 2)      
      return 1  
    else      
      return fibonacciR(n - 1) + fibonacciR(n - 2)  
  }      
  // Static Method - Fibonacci Imperative      
  static Int fibonacciI(Int n)      
  {                  
    Int pre := 1  
    Int cur := 1  
    Int tmp := 0   
    for (i := 2; i <= n; i++)  
    {      
      tmp = cur + pre  
      pre = cur  
      cur = tmp  
    }      
    return cur    
  }          
  // Class/Static Method - Benchmarking Algorithms      
  static Void benchmarkAlgorithm(Int algorithm, List values)      
  {                  
    Stopwatch timer := Stopwatch()  
    Int testValue := 0 
    BigInteger facTimeResult := BigInteger.ZERO  
    Int fibTimeResult := 0
    // "Switch" Flow Control Statement
    switch (algorithm)    
    {    
      case 1:    
        echo("\nFactorial Imperative:")    
        // "For" Loop Statement    
        for (i := 0; i < values.size; i++)    
        {                            
          testValue = values.get(i)    
          // Taking Time    
          timer.start()    
          facTimeResult = factorialI(testValue)    
          timer.stop()
          // Getting Time    
          echo(" ($testValue) = ${timer.getElapsed()}")    
        }
      case 2:    
        echo("\nFactorial Recursive:")    
        // "While" Loop Statement
        Int i := 0
        while (i < values.size)    
        {                            
          testValue = values.get(i)   
          // Taking Time    
          timer.start()    
          facTimeResult = factorialR(testValue)
          timer.stop()
          // Getting Time    
          echo(" ($testValue) = ${timer.getElapsed()}")    
          i++
        }    
      case 3:    
        echo("\nFibonacci Imperative:")    
        // "While" Loop Statement
        Int i := 0
        while (i < values.size)    
        {
          testValue = values.get(i)    
          // Taking Time    
          timer.start()    
          fibTimeResult = fibonacciI(testValue)    
          timer.stop()    
          // Getting Time    
          echo(" ($testValue) = ${timer.getElapsed()}")    
          i++    
        }    
      case 4:    
        echo("\nFibonacci Recursive:")      
        // "For" Loop Statement    
        for (i := 0; i < values.size; i++)    
        {    
          testValue = values.get(i)
          // Taking Time    
          timer.start()    
          fibTimeResult = fibonacciR(testValue)   
          timer.stop()   
          // Getting Time    
          echo(" ($testValue) = ${timer.getElapsed()}")    
        }    
        default:    
          echo("DONG!")    
    }                    
  }
}


// Instance Class      
class InstanceFiborial      
{      
  // Instance Field      
  private Str className  
  // Instance Constructor      
  new make()      
  {      
      this.className = "Instance Constructor"  
      echo(this.className)  
  }      
  // Instance Method - Factorial Recursive      
  BigInteger factorialR(Int n)      
  {      
      // Calling Static Method      
      return StaticFiborial.factorialR(n)  
  }      
  // Instance Method - Factorial Imperative      
  BigInteger factorialI(Int n)
  {      
      // Calling Static Method      
      return StaticFiborial.factorialI(n)      
  }      
  // Instance Method - Fibonacci Recursive  
  Int fibonacciR(Int n)  
  {      
      // Calling Static Method      
      return StaticFiborial.fibonacciR(n)  
  }      
  // Instance Method - Factorial Imperative      
  Int fibonacciI(Int n)  
  {      
      // Calling Static Method      
      return StaticFiborial.fibonacciI(n)  
  }      
}    

// Console Program  
public class FiborialApp    
{    
  public static Void main()    
  {
    echo("\nStatic Class")      
    // Calling Static Class and Methods  
    // No instantiation needed. Calling method directly from the class      
    echo("FacImp(5) = ${StaticFiborial.factorialI(5)}")  
    echo("FacRec(5) = ${StaticFiborial.factorialR(5)}")     
    echo("FibImp(11)= ${StaticFiborial.fibonacciI(11)}")      
    echo("FibRec(11)= ${StaticFiborial.fibonacciR(11)}")  
      
    echo("\nInstance Class")      
    // Calling Instance Class and Methods       
    // Need to instantiate before using. Calling method from instantiated object      
    InstanceFiborial ff := InstanceFiborial.make()  
    echo("FacImp(5) = ${ff.factorialI(5)}")  
    echo("FacRec(5) = ${ff.factorialR(5)}")  
    echo("FibImp(11)= ${ff.fibonacciI(11)}")  
    echo("FibRec(11)= ${ff.fibonacciR(11)}")  
      
    // Create a list of integer values to test  
    // From 5 to 50 by 5      
    Int[] values := Int[,]  
    for(i := 5; i <= 50; i += 5)
        values.add(i)
            
    // 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      
    echo("Press any key to exit...")  
    console := Env.cur  
    userInput := console.in.readLine  
  }
}

And the Output is:




















































Printing the Factorial and Fibonacci Series
using [java] java.math::BigInteger    
using [java] java.lang::StringBuffer  
    
class Fiborial
{    
  // Using a StringBuffer as a list of string elements
  // because of the following compile error: 
  // Ambiguous call append(sys::Str) FiborialSeries.fan ... Fantom Problem
  // I had to use StringBuffer.apend(s, 0, s.length) instead of just StringBuffer.apend(CharSequence s) 
  static Str getFactorialSeries(Int n)    
  {    
    // Create the String that will hold the list    
    StringBuffer series := StringBuffer()  
    // We begin by concatenating the number you want to calculate    
    // in the following format: "!# ="    
    series.append("!", 0, "!".size)  
    series.append(n.toStr, 0, n.toStr.size)  
    series.append(" = ", 0, 3)
    // We iterate backwards through the elements of the series    
    for (i := n; i <= n && i > 0; i--)   
    {
      // and append it to the list    
      series.append(i.toStr, 0, i.toStr.size)
      if (i > 1)  
        series.append(" * ", 0, 3)  
      else     
        series.append(" = ", 0, 3)
    }  
    // Get the result from the Factorial Method    
    // and append it to the end of the list
    Str fac := factorial(n).toStr
    series.append(fac, 0, fac.size)    
    // return the list as a string    
    return series.toStr  
  }    
  
  // Using a StringBuffer as a list of string elements    
  static Str getFibonnaciSeries(Int n)    
  {    
    // Create the String that will hold the list    
    StringBuffer series := StringBuffer()    
    // We begin by concatenating the first 3 values which    
    // are always constant    
    series.append("0, 1, 1", 0, 7)  
    // Then we calculate the Fibonacci of each element    
    // and add append it to the list
    Str fib := ""
    for (i := 2; i <= n; i++)
    {    
      if (i < n)    
        series.append(", ", 0, 2)
      else    
        series.append(" = ", 0, 3)
      
      fib = fibonacci(i).toStr
      series.append(fib, 0, fib.size)  
    }    
    // return the list as a string    
    return series.toStr
  }    
  
  static BigInteger factorial(Int n)    
  {    
    if (n == 1)      
      return BigInteger.ONE
    else      
      return BigInteger.valueOf(n).multiply(factorial(n - 1))  
  }            
  
  static Int fibonacci(Int n)    
  {    
    if (n < 2)
      return 1  
    else      
      return fibonacci(n - 1) + fibonacci(n - 2)  
  }       
}    
  
// Console Program  
public class FiborialSeriesApp    
{    
  public static Void main()    
  {  
    // Printing Factorial Series    
    echo("")  
    echo(Fiborial.getFactorialSeries(5))   
    echo(Fiborial.getFactorialSeries(7)) 
    echo(Fiborial.getFactorialSeries(9)) 
    echo(Fiborial.getFactorialSeries(11)) 
    echo(Fiborial.getFactorialSeries(40))  
    // Printing Fibonacci Series    
    echo("")  
    echo(Fiborial.getFibonnaciSeries(5)) 
    echo(Fiborial.getFibonnaciSeries(7)) 
    echo(Fiborial.getFibonnaciSeries(9)) 
    echo(Fiborial.getFibonnaciSeries(11))  
    echo(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, constructors/initializers, methods, etc.

// Instance Class  
class Fiborial
{  
  // Instance Field  
  private Int instanceCount  
  // Static Field
  // Static field 'staticCount' must be const
  private const static Int staticCount
  // Instance Read-Only Property   
  Int InstanceCount
  {
    get { return &instanceCount }  
  }  
  // Static Fields need to be const. A static const cannot have getter
  // using Static Read-Only Getter instead  
  // As with Static Methods, you cannot reference your class members  
  // with the "this" reference pointer since static members are not  
  // instantiated.  
  /*static Int StaticCount
  {    
    get { return &staticCount }    
  }*/
  static Int getStaticCount() 
  {
    return staticCount
  }
  // Instance Constructor  
  new make() 
  {  
    this.instanceCount = 0  
    echo("\nInstance Constructor ${this.instanceCount}")  
  }  
  // Static Constructor
  // Static constructors are methods executed to initialize the class itself. 
  // They are typically used to initialize static fields.
  static  
  {    
    staticCount = 0    
    echo("\nStatic Constructor $staticCount")
  }      
  // Instance Method  
  Void factorial(Int n) 
  {  
    this.instanceCount += 1  
    echo("\nFactorial($n)")  
  }  
  // Static Method  
  static Void fibonacci(Int n) 
  {  
    // Error: 
    // Cannot set const static field 'staticCount' outside of static initializer 
    // (static constructor) so we cannot increment staticCount
    // staticCount += 1  
    echo("\nFibonacci($n)")  
  }  
}

public class FiborialExtrasApp    
{    
  public static Void main()    
  {  
    // Calling Static Constructor and Methods  
    // No need to instantiate  
    Fiborial.fibonacci(5)  
      
    // Calling Instance Constructor and Methods  
    // Instance required  
    Fiborial fib := Fiborial()  
    fib.factorial(5)  
      
    Fiborial.fibonacci(15)  
    fib.factorial(5)  
      
    // Calling Instance Constructor and Methods  
    // for a second object  
    Fiborial fib2 := Fiborial()
    fib2.factorial(5)
      
    echo("")  
    // Calling Static Property  
    echo("Static Count = ${Fiborial.getStaticCount}")  
    // Calling Instance Property of object 1 and 2  
    echo("Instance 1 Count = ${fib.InstanceCount}")  
    echo("Instance 2 Count = ${fib2.InstanceCount}")   
  }
}

And the Output is:

























Factorial using java.lang.Long/sys::Int, java.lang.Double/sys::Float, java.math.BigInteger


using [java] com.carlosqt.util::Stopwatch
using [java] java.math::BigInteger

public class FiborialTypesApp    
{    
  public static Void main()    
  {     
    Stopwatch timer := Stopwatch()    
    Int facIntResult := 0
    Float facDblResult := 0f    
    BigInteger facBigResult := BigInteger.ZERO 
    
    echo("\nFactorial using Int64")  
    // Benchmark Factorial using Int64    
    for (i := 5; i <= 50; i += 5)    
    {    
      timer.start
      facIntResult = factorialInt64(i)    
      timer.stop    
      echo(" ($i) = ${timer.getElapsed} : $facIntResult")  
    }    
    echo("\nFactorial using Float/Double")
    // Benchmark Factorial using Double    
    for (i := 5; i <= 50; i += 5)    
    {    
      timer.start    
      facDblResult = factorialDouble(i)    
      timer.stop                
      echo(" ($i) = ${timer.getElapsed} : $facDblResult")  
    }    
    echo("\nFactorial using BigInteger")    
    // Benchmark Factorial using BigInteger    
    for (i := 5; i <= 50; i += 5)    
    {    
      timer.start();    
      facBigResult = factorialBigInteger(i);    
      timer.stop();    
      echo(" ($i) = ${timer.getElapsed} : $facBigResult")
    }            
  }  
      
  // Int64 Factorial    
  static Int factorialInt64(Int n)    
  {    
    if (n == 1)    
      return 1
    else    
      return n * factorialInt64(n - 1)  
  }  
    
  // Float Factorial  
  static Float factorialDouble(Int n)    
  {    
    if (n == 1)    
      return 1f
    else    
      return n * factorialDouble(n - 1)  
  }  
    
  // BigInteger Factorial   
  static BigInteger factorialBigInteger(Int n)    
  {    
    if (n == 1)    
      return BigInteger.ONE  
    else    
      return BigInteger.valueOf(n).multiply(factorialBigInteger(n - 1))
  }
}

And the Output is:



Saturday, October 30, 2010

Fantom - Basics by Example



Continue with the Basics by Example; today's version of the post written in Fantom Enjoy!

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
// Fantom Basics
internal class Greet  
{
    // Fields or Attributes
    private Str? message  
    private Str? name 
    private Int? loopMessage 
    // Properties, Getters and Setters
    public Str Message
    { 
      get { return this.&message }
      set { this.&message = this.capitalize(it) }
    }
    public Str Name
    { 
      get { return this.&name }
      set { this.&name = this.capitalize(it) }
    }
    public Int LoopMessage
    { 
      get { return this.&loopMessage }
      set { this.&loopMessage = it }
    }
    // Constructor
    public new make()
    {   
        this.message = ""
        this.name = ""
        this.loopMessage = 0
    }  
    // Overloaded Constructor
    // No Overloaded Constructor support as designed
    // Method 1
    private Str capitalize(Str val)
    {
        // "if-then-else" statement  
        if (val.size() >= 1) {  
            return val.capitalize()
        }  
        else  {  
            return ""
        }  
    }
    // Method 2
    public Void salute() 
    {  
        // "for" statement
        for (i:=1; i<=this.loopMessage; i++) 
        {  
            echo("$this.message $this.name!")  
        }  
    }  
    // Overloaded Method
    // No Overloaded Methods Support in Fantom. News methods instead.
    // Method 2.1  
    public Void salute21(Str message, Str name, Int loopMessage) 
    {  
        // "while" statement  
        Int i := 0
        while(i < loopMessage) 
        {  
            echo("${this.capitalize(message)} ${this.capitalize(name)}!")            
            i++
        }  
    }  
    // Method 2.2
    public Void salute22(Str name) 
    {
        // "switch/case" statement  
        DateTime dtNow := DateTime.now();
        switch(dtNow.hour)
        {
            case 6: case 7: case 8: case 9: case 10: case 11:  
                this.message = "good morning," 
            case 12: case 13: case 14: case 15: case 16: case 17:  
                this.message = "good afternoon,"
            case 18: case 19: case 20: case 21: case 22:  
                this.message = "good evening," 
            case 23: case 0: case 1: case 2: case 3: case 4: case 5:  
                this.message = "good night,"
            default:
                this.message = "huh?" 
        }
        echo("${this.capitalize(this.message)} ${this.capitalize(name)}!")            
    }
}  

// Console Program
public class FanGreetProgram  
{  
    public static Void main()  
    {  
        // Define variable object of type Greet and Instantiate. Call Constructor
        Greet g := Greet.make()
        // Call Setters
        g.Message = "hello"
        g.Name = "world"
        g.LoopMessage = 5
        // Call Method 2    
        g.salute()  
        // Overloaded Method 2.1 and Getters    
        g.salute21(g.Message, "fantom", g.LoopMessage)   
        // Overloaded Method 2.2    
        g.salute22("carlos")  

        // Stop and exit    
        echo("Press any key to exit...")
        console := Env.cur
        userInput := console.in.readLine
    }  
}

Greetings Program - Minimal
// Fantom Basics
class Greet  
{
    // Fields or Attributes
    private Str? message  
    private Str? name 
    private Int? loopMessage 
    // Properties, Getters and Setters
    Str Message
    { 
      get { return &message }
      set { &message = capitalize(it) }
    }
    Str Name
    { 
      get { return &name }
      set { &name = capitalize(it) }
    }
    Int LoopMessage
    { 
      get { return &loopMessage }
      set { &loopMessage = it }
    }
    // Constructor
    new make()
    {   
        message = ""
        name = ""
        loopMessage = 0
    }  
    // Overloaded Constructor
    // No Overloaded Constructor support as designed
    // Method 1
    private Str capitalize(Str val)
    {
        // "if-then-else" statement  
        if (val.size >= 1) {  
            return val.capitalize
        }  
        else  {  
            return ""
        }  
    }
    // Method 2
    Void salute() 
    {  
        // "for" statement
        for (i:=1; i<=loopMessage; i++) 
        {  
            echo("$message $name!")  
        }  
    }  
    // Overloaded Method
    // No Overloaded Methods Support in Fantom. News methods instead.
    // Method 2.1  
    Void salute21(Str message, Str name, Int loopMessage) 
    {  
        // "while" statement  
        Int i := 0
        while(i < loopMessage) 
        {              
            echo("${capitalize(message)} ${capitalize(name)}!")
            i++  
        }  
    }  
    // Method 2.2
    Void salute22(Str name) 
    {
        // "switch/case" statement  
        DateTime dtNow := DateTime.now;
        switch(dtNow.hour)
        {
            case 6: case 7: case 8: case 9: case 10: case 11:  
                message = "good morning," 
            case 12: case 13: case 14: case 15: case 16: case 17:  
                message = "good afternoon,"
            case 18: case 19: case 20: case 21: case 22:  
                message = "good evening," 
            case 23: case 0: case 1: case 2: case 3: case 4: case 5:  
                message = "good night,"
            default:
                message = "huh?" 
        }
        echo("${capitalize(message)} ${capitalize(name)}!")
    }
}  

// Console Program
class FanGreetProgram  
{  
    static Void main()  
    {  
        // Define variable object of type Greet and Instantiate. Call Constructor
        Greet g := Greet()
        // Call Setters
        g.Message = "hello"
        g.Name = "world"
        g.LoopMessage = 5
        // Call Method 2    
        g.salute
        // Overloaded Method 2.1 and Getters    
        g.salute21(g.Message, "fantom", g.LoopMessage)   
        // Overloaded Method 2.2    
        g.salute22("carlos")  

        // Stop and exit    
        echo("Press any key to exit...")
        console := Env.cur
        userInput := console.in.readLine
    }  
}


And the Output is:


















Emulating Overloaded Constructor in Fantom
Fantom does not support Overloading Constructors by design, but you can some how "emulate" it by calling the constructor with an initializers list as shown here below.
class Greet  
{
    // defining public fields
    Str? message  
    Str? name 
    Int? loopMessage
    // Constructor
    new make()    
    {   
        echo("greet.make")
        message = "empty_message"
        name = "empty_name"
        loopMessage = 0
    }          
    // Method 2  
    Void Salute()  
    {  
        echo("$this.loopMessage $this.message $this.name!")
    }  
}  

class Program  
{  
    static Void main()  
    {  
        // calling constructor (printing greet.make)
        Greet g := Greet()        
        g.Salute()
        // calling constructor (printing greet.make) and explicitly assigning values to each field
        // this can be done if the fields are defined as public 
        // or you will get a Private field xxx not accessible
        Greet g2 := Greet{ message="hello"; name="world"; loopMessage=5 }
        g2.Salute()
    }  
}

And the Output is:

Saturday, July 3, 2010

OO Hello World - Fantom



The Fantom version is here. Fantom is one of the newest languages out there targeting the Java JVM and the .NET CLR runtimes! It is also a C#/Java – Like language with lots of interesting features.


By the way, you can see my previous 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
{
 Str? name
 new make(Str name) 
 { 
  this.name = name.capitalize()
 }
 Void salute()
 {
  echo("Hello $name!")
 }
}

// Greet the world!
class GreetProgram
{
 static Void main()
 {
  Greet g := Greet("world")
  g.salute()  
 }
}

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

internal class Greet
{ 
 private Str? name
 new make(Str name) 
 { 
  this.name = name.capitalize()
 }
 Void salute()
 {
  echo("Hello $name!")
 }
}

// Greet the world!
public class GreetProgram
{
 public static Void main()
 {
  Greet g := Greet.make("world")
  g.salute()  
 }
}

The Program Output:












Fantom Info:
“Fantom is a general purpose object-oriented programming language that runs on the JRE, .NET CLR, and Javascript. The language supports functional programming through closures and concurrency through the Actor model. Fantom takes a "middle of the road" approach to its type system, blending together aspects of both static and dynamic typing. Like C# and Java, Fantom uses a curly brace syntax.” Taken from: (http://en.wikipedia.org/wiki/Fantom_(programming_language))

Appeared:
2008
Current Version:
Developed by:
Brian Frank, Andy Frank
Creator:
Brian Frank, Andy Frank
Influenced by:
Java (James Gosling) and C# (Anders Hejlsberg)
Predecessor Language

Predecessor Appeared

Predecessor Creator

Runtime Target:
JVM/CLR
Latest Framework Target:
JDK 6/NET 2.0
Mono Target:
No
Allows Unmanaged Code:
?
Source Code Extension:
“.fan”
Keywords:
46
Case Sensitive:
Yes
Free Version Available:
Yes
Open Source:
Yes
Standard:
No
Latest IDE Support:
NetBeans 6.9
Eclipse
IntelliJ IDEA
Language Reference:
Extra Info: