Fantom Cheat Sheet

See also Fan Getting started and fantomIDE


Fantom(Fan) is an exciting new language that targets the Java VM and the CLR.
It borrows it's Syntax from Java but also adds many features and syntactic sugar created or borrowed from .NET, Groovy, Python, Erlang etc...

It's immediately familiar to a Java / .Net programmer but is much less painful to use (no boilerplate).

Fantom has very good documentation on the Wiki, but I created this page here as a "Cheat sheet", with all the basics in one page (for quick find / reference), still it's back linked to the full documentation when more infos are needed.

Source file structure

A Fantom source file is an UTF8 file with the extension .fan.

Comments are supported as // comment and /* comments */
FanDocs (like javadoc) are as follow ** blah (each line starts with **)

A .fan source contains (besides comments / doc):
  • Zero or more using statements (pod import) a.k.a packages.
using inet                  // example: import all of in inet pod
using xml::XNode            // example: import XNode from xml pod
using sys::Time as T        // import Time of sys pod, as "T"  

class Hello
  static Void main()
     echo("Time is $") 


More infos:

fantom is statically typed and purely OO (everything is an object, no primitives), but:
  • You can do a dynamic invocation: obj->dothing instead of obj.dothing
  • The compiler can do lots of implicit casting for you.
  • Type inference is supported for local variables, lists, and maps, so you can write i=3 rather than Int i=3.

fantom does not support generics per say(which I find ugly anyway), however List, Map and Functions do support it:
  • List Examples: Int[] Int?[] Str[][]
  • Map Examples: Str:User [Uri:File]? [Str:File][]
  • Function Examples: |Int a, Int b->Str| |->Bool|

Nullabale types support: Str s(s can NOT be null) Str? s(s can be null)


More infos:

Example: abstract class MyNewClass { }
Class Modifiers:
  • public, Public is the default. The class can be use from anywhere.
  • internal The class can only be used within the same pod (~ java 'protected')
  • abstract Required if the class contains abstract methods.
  • final Can not be sub-classed.
  • const Mark a class as immutable (checked by compiler).

A class can inherit from 1(max) parent class: class Rectangle : Shape {}

A class can also inherit (implement) 0 or more mixins. class Rectangle : Shape, Drawable, Serializable {}
Class inheritance has to be first, then mixins.


More infos:

A Mixin is like a Java interface but can declare method implementations (Cool)
Modifiers: A mixin is automatically abstract.
It can only have the following modifiers: public internal const
Mixin Example
mixin class Audio
  abstract Int volume
  Void incrementVolume() { volume += 1 }
  Void decrementVolume() { volume -= 1 }

class Television : Audio
  // volume is abstract so has to be implemented
  override Int volume := 0


More infos:

Just like a Java enumeration (range of values)
Example enum Color { red, blue, green }

Enum can also have a private constructor:
enum class Suits

  private new make(Str color) { this.color = color; }
  const Str color;

Enum modifiers: can only be public or internal


Slots are the items within a Type(class, mixin, enum) such as fields, methods, constructors.


More Infos:

Field type is not required if it can be inferred.

Fields have automatic getter and setter - nice

Example: class User{name := "toto"} you can now do (uses the implicit getter)
Example 2: Str? name := "toto" same but address is nullable (default is not)
  • Direct access
In case you want to bypass the getter or setter you can do this *name. ('*' means direct access)
  • Custom getter and setter
You can specify a setter and getter (in the rare case you need it)
Custom getter/setter
Int id := 0  
  get { echo("get id"); return *id }; 
  set { echo("set id"); *id = val } 

  • Field modifiers

const Means the field is immutable, though it can be set in the constructor.
static Static field.
public(default) protected internal private
readonly Makes the automatic setter private. nice !
virtual Makes the setter and getter overloadable.
abstract Getter/Setter have to be overridden by subclass
native Mark the field as native(.NET, Java).

Mixins can only have const or abstract fields.


More infos:
A method is a slot which defines a function within a class or mixin:

Defining methods:
Method examples
class MyObject
// Static method(doesn't need an instance) that return the sum of arguments a and b
	static Int add(Int a, Int b) { return a + b }
// Instance method that increments the field called count
	Void sayHello() { echo("Hello world") }
// Instance method that sets this instance 'name' field to the value 'name'
	Int setName(Str name) { }

If the method returns something but has only 1 expression you can drop return
For example: static Int add(Int a, Int b) { a + b }

Calling methods:
We can call a method using the . (static call), or -> (dynamic call)
A static . call is statically compiled and checked by the compiler.
A dynamic -> call is not checked by the compiler but evaluated at runtime

If there are no parameters to the method, the convention is to drop the parenthesis
Method calls
// static method call (we don't need an instance of MyObject)
// creating a MyObject instance to make methods call on
  myObj := MyObject()
// call setName method
// call sayHello - we drop parenthesis as there are no params
// Same but with a dynamic (runtime) call

The special this keyword can be used in a method, it means "this instance"

Default parameters:
Parameters in a method can have default values, this is quite handy.
Instead of writing as you would do in Java:
in Java
	void parseString(String text, boolean removeLinebreaks) {/*code*/}
// then a shortcut method:
	void parseString(String text) {parseString(text, false)}

You would just have:
fantom with default params
	Void parseString(Str text, bool removeLinebreaks := false) {/*code*/}

Method modifiers:
public(default) protected internal private
static Static method (not running on an instance)
Abstract A method that is unimplemented(no body) and must be implemeted(override)in a subclass.
Virtual A method that is designed to be "override"(reimplemented) in the subclass, but has a default implementation.
override Indicates that the method re-implements a method defined in the parent or implemented mixins
Once A once method uses lazy-caching: it cahes it's results, so if called again it does not have to recompute the result.
native A method marked as implemented natively (FFI)

Only classes can have constructors, not mixin.
A constructor is a special method which returns an instance of the class it's declared in

Defining a constructor:
By convention the default constructor is called make(), other constructors makeSomeUniqueName()
The constructor return type is always new, meaning it returns a new instance of the class.

You can call another constructor or a parent constructor using the constructor chaining syntax, see the example bellow
In the constructor chain you can use this to call another constructor in the instance, or super to call a constructor in the instance parent object.
Constructors example
class MissingPerson
  Str name
  Bool wantedByFBI := false
//Default constructor, create MissingPerson withe given name
  new make(Str name) { = name }
//Other constructor with chaining, calls the default constructor first then sets wantedByFBI
  new makeWanted(Str name) : this.make(name) { wantedByFBI = true }

Static constructor:
A so called static constructor or "init block" is a static block that will be called when the class is initialized(once).
static block
class MyClass
	static{echo "MyClass initialization"}

Calling a constructor:
It's just like calling a method, except the parenthesis are NOT optional.
MissingPerson person := MissingPerson.make("John Doe")
// shorthand
person := MissingPerson("John Doe")


Detailed infos:


bool1:=true;    bool2:=false; // Bool


int1:=45;    int2:=-89_039;    int3:=0xcafebabe;    int4:=0xCAFE_BABE
int5:='?';   int6:='\n';       int7:='\u03ab';      int8:='\u00F2'

f1:=3.0f;    f2:=3f;    f3:=3.0F;    f4:=123_456.0f;
f5:=3e6f;    f6:=0.2e+6f;            f7:=1_2.3_7e-5_6f;

d1:=4d;    d2:=4.0;    d3:=4.00;    d4:=123_456d;
d5:=3e6;   d6:=0.2e+6D;             d7:=1_2.3_7e-5_6

// duration suffixes: ns, ms, sec, min, hr, day
d:=4ns;  d:=100ms;  d:=-0.5hr;


Str s:="hello"

// Multiline string supported (line feed becomes "\n";)
Str s:="It is 73\u00B0 
Fahrenheit outside!"  

String interpolation
Str s:="The price is $price or $ {price}"

String: triple quoted
echo("""Do you know "What lies beneath the shadow of the statue"?""")

String: DSL
echo(Str <|no \ or $ escapes need, and multi-line works too|>)

List & Maps

list1:=Int[10, 20, 30]     // list of the three Ints 10, 20, and 30
list2:=[10, 20, 30]        // same as above using type inference
list3:=Str[,]              // empty list of Strings
list4:=[[10,20], [30]]     // evaluates to Int[][]      
list5:=Int?[1,2,3]         // can store null Int?[]      

map1:=[Int:Str][1:"one", 2:"two"]  // map of Strs keyed by Int
map2:=Int:Str[1:"one", 2:"two"]    // same as above with shorthand type syntax
map3:=[1:"one", 2:"two"]           // same as above using type inference
map4:=Int:Str[:]                   // empty Int:Str map
map5:=[0:["one"]]                  // evaluates to Int:Str[]
Int:Str?[1:"one", 2:"two"]         // can store null String values


u3:=`/dir/$file` ; $file is interpolated variable.
u1.toStr; u2.encode;   // encode url


// can be use in loops etc....
0..5    // 0 to 5 (end is inclusive)
0..<5   // 0 to 4 (end is exclusive)
x..<y   // x to y-1 (end is exclusive)

Type check

Type check
Str#  // String type


More infos:

A statement can be terminated by ; but it's optional, a NewLine will do, or a closing }.
Most common is to end a statement with a line break(NwLine), though a few special cases might require a ;


Same as most languages return var. 'return' optional if only 1 statement in method var

Local Variables

var := 35. := means variable initialization.

If / Else

If example
if(cond) dothis else if(cond2) dothat else donothing
if(cond) {dothis; dothat}    // multiple statement in block -> needs bracket


break and continue can be used in loops just as in Java.

While loops
while (p != null)
  p =

For loops
for (i:=0; i<10; ++i)  // can't use , as in Java/c++


Like Java EXCEPT:
  • no break, if the case has at least one statement, there will be no fall through.
  • not limited to int, you can switch on String and other objects (use equals() method).
Switch example
switch (method.upper)
  case "GET":  serviceGet
  case "POST": servicePost
  default:     methodNotSupported

Exception Handling

More infos:

Try catch example
try {something}              // Curly's are optional if only one statement in block
catch (CastErr e) {e.trace}  // trace to stdout
catch (Err e) {e.trace(log)} // trace to log
catch {/*catch all else*/}
finally {cleanup}

Closures & ItBlocks

Detailed infos:

With arguments
f := |Int a, Int b->Int| { return a + b }
nine := f(4, 5)

No arguments
f := |,| { echo("hi there") }

Binded variable
f := |->Str| { return first + " " + this.last } // binded var

With suffix
evens := list.findAll() |Int v->Bool| { return v%2==0 }


List / maps iteration
list := ["one", "two", "three"]
list.each |Str val, Int index| { echo("$index = $val") }
list.each |Str val| { echo(val) }

Type inference
list.each |v| { echo(v) }
odds = [1, 2, 3, 4, 5].findAll |v| { v.isOdd }


It blocks: .each
["a", "b", "c"].each |Str s| { echo(s.upper) }  // long hand
["a", "b", "c"].each { echo(it.upper) }         // short hand
["a", "b", "c"].each { echo(upper) }     // implicit it call

It blocks: .with
// Apply an IT block to an expression
list := Str[,].with { fill("x", 3) }   // explicit call to with
list := Str[,] { fill("x", 3) }        // implicit call to with


More Infos:
Note that operators are just mapped to methods, a + b is just a shortcut for etc...
Which by the way mean you can overload them, see: Expressions shortcuts

Common operators

Basically the same as Java.
Common operators: + - * / % << >> & | ^ ! ++ -- ~ == != <= >= || &&
Ternary: condition ? value1 : value2

Indexing Operator

Shortcut to get and set methods.
obj[0]                     //same as obj.get(0)
obj[-1]                    //same as obj.get(obj.size-1)
obj[0] = 3                 //same as obj.set(0,3)
obj[-1] = 3                //set last item in obj with value 3
obj[0..2]                  //slice of obj (0,1,2)
obj[0..<2]                 //slice of obj (0,1)

Null check operators (Cool)

Elvis: name ?: defaultName is shortcut for: name != null ? name : defaultName
Safe invoke: email := user?.email same as if(user!=null)
Dynamic safe invoke: Same for dynamic calls. email := user?->email

Other operators

Variable Initialization: := (Define & assign variable initial value)
Range: .. or ..< (exclusive end)
Object equality (Same object): ===(equals), !==(!equals)
Type checking: is isnot. Example bool := email is Int (check email is an Integer)
Casting: as. Example: val := number as Float, same as val := (Float) number
Simples (Serialization): Version("3.2") is same as Version.fromStr("3.2")
Compare: <=> Compare and return an Int(-1,0,1) (compare method).
It Blocks

It Blocks
address := Address{street = "123 Happy Lane"; city   = "Houston";}

// old fashion
address := Address(); address.street="123 Happy Lane";"Houston";

Collections (Sp. itBlock)

,(trailing comma). Calls it.add(suffixedItem).
Example: a,b,d is same as it.add(a).add(b).add(d), especially nice for Swing/Fwt.
Collection operator use
// Notice the trailing comma after MenuItem definition, it does menu.add(menuItem);
menu := Menu{  text = "File";  MenuItem { text = "Open";}, }

//old fashion:
menuItem := MenuItem(); menuItem.text="Open";
menu := Menu(); menu.text = "File"; 


More Infos:

Int#plus                      // Refer to Method plus of class Int
Pod.find("acmeFoo")           // lookup a pod (package)
someObj.typeof                // lookup an object type
Slot.find("")   // lookup a slot(ex: method) by its name[arg0, arg1])     // invoke method using reflection

FFI : Java / C#

More Infos:

using [java] java.lang::Math

See an example here: Fan Java FFI example- Implement Java_interface from fan


Symbols go in


More Infos: See
Facets are the equivalent of Annotations in java:
Facets example
class Account

Advanced Topics

Compile to javascript, deployment, repos, serialization, concurrency, actors, naming, urispace, typedb, logging, localization, DSL


fan, fansh, fand, fanp etc...




Add a new Comment