Skip to content

Instantly share code, notes, and snippets.

@SlimerDude
Last active January 9, 2018 10:05
Show Gist options
  • Save SlimerDude/5acaca8584ea08290809834785d79116 to your computer and use it in GitHub Desktop.
Save SlimerDude/5acaca8584ea08290809834785d79116 to your computer and use it in GitHub Desktop.
Fantom Syntax Cheat Sheet
// this is a single line comment
/* multi-line comments
look like this! */
// an entire Fantom libraries can be imported with 'using' statements
using xml
// individual types can be imported as well
using xml::XParser
// types can also be renamed to avoid name clashes
// now we can use 'XmlNode' instead of 'XNode'
using xml::XNode as XmlNode
// note that the 'sys' library is implicitly imported so we don't have to write
// the following for every class:
// using sys
// this is a standard Fantom class that extends Obj
public class FantomIn60Mins01 : Obj { }
// but all classes extend from Obj, so we don't need to specify it
public class FantomIn60Mins02 { }
// Note that classes are public by default, so I can also just write:
class FantomIn60Mins03 { }
// Internal classes are only visible to the library (pod) it is defined in. This
// makes them fantastic for hiding complexity away from public APIs.
internal class FantomIn60Mins04 { }
** This is fandoc comment.
** Fandoc comments are compiled into API documentation.
** Fandoc is very similar to markdown and may contain *italics*, **bold**,
** [Links]`http://fantom-lang.org`, 'code', lists, and images, etc...
**
** See [fandoc]`http://fantom.org/doc/fandoc/index#overview` for details.
class FantomIn60Mins05 { }
class FantomIn60Mins06 {
// ---- Fields ----
// This is a field
** Fields may also have fandoc comments
public Str str01
** fields are also public by default, so I can also just write:
Str str02
** fields may be private to the containing type
private Str str03
** or also internal to the pod
internal Str str04
** fields may have accessors. Use & to reference the *actual* value.
Str str05 {
get { return &str05 }
set { &str05 = it }
}
** which may do strange things as the value is get and set
Str str06 {
get { return "Hello " + &str06 + "!" }
set { &str06 = it * 3 }
}
** fields may be read-only (to everyone but this type)
Str str07 { private set }
** fields may initialised inline
Str str08 := "Hello Mum!"
** even fields with accessors can be initialised inline
Str str09 := "Hello Dad!" {
get { return &str09 }
set { &str09 = it }
}
// ---- Standard Constructor ----
** Standard constructors return 'new' and are usually prefixed with the
** word 'make'
new make() {
// you should set all the un-initialised field values in the ctor
str01 = ""
// how to set lots of variables / fields at once!
str02 = str03 = str04 = str05 = str06 = str07 = str08 = str09 = ""
}
// ---- Methods ----
** Methods are also public by default but, like fields, may also be private,
** or internal.
Void method01() { }
** Methods may be static
static Void method02() { }
** Simple 1-line methods don't need a return statement
Str method03() {
"Hello Mum!"
}
** Method parameters may have default values
Str method04(Str name := "Mum") {
"Hello " + name + "!"
}
Void method05(Str name) {
// echo() is a method inherited from Obj - you will use it a lot!
echo("Hello " + name + "!")
// use ${...} notation for easy string interpolation
echo("Hello ${name}!")
// note for simple expressions, the curly brackets are optional
echo("Hello $name!")
// when calling methods, if it doesn't take any arguments, then brackets
// are optional. So this:
str01 := method03
// is the same as this:
str02 := method03()
// it also applies to default parameters:
str03 := method04("Mum") // --> Hello Mum!
str04 := method04() // --> Hello Mum!
str05 := method04 // --> Hello Mum!
}
// ---- Literals ----
Void method06() {
// the 3 'value types' map directly to Java the primitives long,
// boolean, and double and as such have default values when defined:
Int int01 // --> 0
Bool bool01 // --> false
Float float01 // --> 0f
// all other types must be initialised
Str str01 := ""
// it is common to let Fantom *infer* the type from the value, meaning
// you can just write:
str02 := ""
// all types *must* have a value, unless they are nullable.
// nullable types have a ? suffix:
Str? str03 := null
// all nullable types default to null, so you can just write:
Str? str04
// or, if you want to use type inference, you can write:
str05 := null as Str
// note that nullable value types map to Java objects, not primitives:
Int? int02 // a Java Integer object
Bool? bool02 // a Java Boolean object
Float? float02 // a Java Float object
// literals are shorthand syntax for instantiating common types
// note := is used to define and assign a value
int03 := 66 // sys::Int - 64 bit integer
bool03 := false // sys::Bool
float03 := 66f // sys::Float - 64 bit double
int04 := '\n' // sys::Int - character
int05 := 0xCAFE_BABE // sys::Int - hex notation using _ separators
str06 := "" // sys::Str (Java String)
decimal := 0.66d // sys::Decimal (Java BigDecimal)
duration := 3sec // sys::Duration - may also be ns, ms, sec, min, hr, day
range := (0..10) // sys::Range
uri := `http//fantom-lang.org` // sys::Uri
// just use = to re-assign a value
int03 = 69
// all other types have to be instantiated via a ctor
example01 := FantomIn60Mins04.make()
// Fantom infers which ctor to use from the arguments, so you the ctor
// name is usally optional:
example02 := FantomIn60Mins04()
}
// ---- Lists and Maps ----
Void method07() {
// Lists and Maps have generics
// declare a list of strings
list := ["one", "two"]
// lists are zero based
item := list[1] // --> two
// from the declaration, Fantom infers that the list contains strings
list.typeof // --> sys::Str[]
list[1].upper // --> TWO
// use a single comma to declare an empty list of a given type
emptyList01 := Str[,]
emptyList01.typeof // --> sys::Str[]
// or use shorthand notation for creating lists of Objs
emptyList02 := [,]
emptyList02.typeof // --> sys::Obj[]
// declare a map of strings to ints
map := ["foo":1, "bar":2]
// get and set values
val := map["bar"]
map["beer"] = 3
// from the declaration, Fantom infers the type of the keys and values
map.typeof // --> [sys::Str:sys::Int]
map.keys.first.upper // --> FOO
// use a single colon to declare an empty map of a given type
emptyMap01 := Str:Str[:]
emptyMap01.typeof // --> [sys::Str:sys::Str]
// or use shorthand notation for creating maps of Objs
emptyMap02 := [:]
emptyMap02.typeof // --> [sys::Obj:sys::Obj]
}
}
// Beginner
// --------
// The Basics
// Fields
// Methods
// Literals
// Lists and Maps
// Intermediate
// ------------
// functions
// const classes
// mixins
// Errs
// enums -> show simple / complex with ctor
// Advanced
// --------
// annotations
// it blocks
// shortcuts Operators
// reflection
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment