Wednesday, February 29, 2012

Hello World Frege!

Ever since I started learning Scala, the whole functional programming thing is absolutely fascinating to me. As "Scala is a gateway drug to Haskell",  then I was attracted by Haskell's gravity. Haskell changed the way I think about programs and made me enjoy programming more than ever. While learning Haskell, as a Java programmer, I used to think how good would it be to code Haskell in the ubiquitous JVM and then I found this language, Frege more interesting for JVM and Haskell-like.

As I am practicing Frege along with Haskell and Frege is still relatively new, I thought it would be a good idea to share my experience with Frege.


Getting started:

FregIDE Eclipse plugin is still at basic level but is really usable and a good way to start with Frege. The plugin installation details can be found here: http://fregepl.blogspot.com/p/fregide-tutorial.html. Frege requires JRE 7 so even after following the instructions on the page, if you still do not see Frege Builder/Preferences enabled in Eclipse, try starting your Eclipse with "-vm" argument pointing to your JRE 7. Now, the "Hello World"
module Main where
main _ = println "Hello World"

Yes, I know that is not much interesting. How about implementing a function from Haskell?
In Haskell, there is a function "getLine" which reads a line from standard input. Now lets implement that function in Frege using Java's IO classes.

Haskell's 'getLine' using Java's methods:
import frege.IO

--Reads a line from standard input device
getLine :: IO String
getLine = do
  isin  <- stdin
  isrin <- IO.InputStreamReader.new isin
  brin  <- IO.BufferedReader.fromISR isrin
  line <- brin.readLine
  return $ fromExceptionMaybe line

fromExceptionMaybe :: Exception (Maybe a) -> a
fromExceptionMaybe (Right (Just r)) = r
fromExceptionMaybe (Right _) = error "get on Nothing"
fromExceptionMaybe (Left l) = error l.getMessage

--Native reference to Java's parseInt
pure native parseInt java.lang.Integer.parseInt :: String -> Int

main _ = do
  line <- getLine
  println $ parseInt line

Here as you can see, we have defined 'getLine' using Java's Classes, InputStreamReader, BufferedReader, Exception along with Haskell goodies Maybe and Either (through Exception). The parseInt function is declared with native reference to Java's 'parseInt' method from 'Integer' class and since it is a pure method, the types are straight-forward otherwise we would be using ST monad for those native declarations.

Happy Haskelling on JVM!