coderholic

A brief look at the Fantom programming language

As part of my 12 programming languages in 12 months challenge I took a look into the Fantom programming language. Fantom appears to have a lot going for it: It's object-oriented, has familiar C-style syntax, it's functional with built-in closures, and supports both static and dynamic typing (which is something I really liked in Objective-C). What intrigued me most about Fantom though is that the code is portable to the Java JVM, .NET CLR, and most impressive of all can even be converted to JavaScript to run in a browser!

The language documentation is fairly minimal. It does contain a complete class reference, and some basic examples, which was enough for me to cobble together the following simple port scanner:

using inet

**
** Simple fantom port scanner - Ben Dowling
**
class Scan
{
    static Void main(Str[] args)
    {
        if (args.size != 1)
        {
            echo("usage: Scan ")
            Env.cur.exit(-1)
        }
        host := IpAddr.make(args[0])
        for (port:=1; port < 1024; port++) {
            try {
                socket := TcpSocket.make()
                socket.connect(host, port, Duration.fromStr("500ms"))
                echo("${args[0]}:$port [OPEN]")
            }
            catch(IOErr e) {
                echo("${args[0]}:$port [CLOSED]")
            }
        }
    }
}

Running it on the command line with the fan command confirmed it was working as expected:

$ ./fan scan.fan google.com | grep OPEN
google.com:80 [OPEN]
google.com:443 [OPEN]

What I was really interested in was getting something to run in a browser. I had no idea how (or if) Fantom would get the networking code to work in the browser, but there was nothing to say it wouldn't, and I was keen to try. Documentation on the JavaScript side of Fantom is almost completely non-existent. I was hoping to be able run something like ./fan --to-js scan.fan, but it turned out to be much more complicated. After several discussions in the very helpful #fantom IRC channel, digging through some examples, and several failed attempts I came up with the following Fantom script, which takes my original script and outputs JavaScript:

using inet
using util
using compiler
using compilerJs

**
** Covert a .fan file to JavaScript - Ben Dowling
**
class JsCompiler
{
    static Void main(Str[] args)
    {
        c := JsCompiler(File.os("scan.fan"))
        c.compile()
    }

  new make(File f) { file = f }

  Void compile()
  {
    input := CompilerInput.make
    input.podName   = file.basename
    input.summary   = ""
    input.version   = Version("0")
    input.log.level = LogLevel.err
    input.isScript  = true
    input.srcStr    = file.readAllStr
    input.srcStrLoc = Loc.makeFile(file)
    input.mode      = CompilerInputMode.str
    input.output    = CompilerOutputMode.js

    this.compiler = Compiler(input)
    this.js = compiler.compile.js
    echo(this.js)
  }

  File file
  Compiler? compiler
  Str? js
}

After combining the output of that script with some static Fantom JavaScript library files, making some minor manual edits, and putting it all together in a HTML file I loaded it up in the browser. Immediately I get the error fan.inet is undefined, which I confirmed on IRC is due to the networking features of Fantom not being available in the browser, which is what I suspected.

My Verdict

Having only written a single simple script with Fantom I'm not in much of a position to comment on the language itself. I'd like to dig a bit deeper when I get the chance, and explore some of the functional aspects of the language and the class libraries some more.

What I have seen looks very well designed. I really like the fact that Socket.connect method takes a Duration object instead of an integer primitive which you can never remember if it represents ns, ms, or seconds. The utilty method Duration.fromStr is a nice touch too, as it makes for really readable code. I came across quite a few other similar utility methods in the class library.

What let Fantom down was the lack of good documentation. The essentials are there, but more good examples would be really helpful. The JavaScript features are almost completely undocumented, and having to write a script to generate JavaScript output seems like a step too far - I'd assumed the build tools would be able to do this themselves. Everyone on the official Fantom IRC channel was extremely helpful though, and I'm sure the documentation will improve with time. I'll definitely be keeping an eye on Fantom!

Posted on 31 Dec 2010
If you enjoyed reading this post you might want to follow @coderholic on twitter or browse though the full blog archive.