Java sucks
public static void javaSucks1() { Map<String, List<String>> wtf = new HashMap<String, List<String>>(); }
Java sucks
public static void javaSucks2() { new Thread(new Runnable() { @Override public void run() { System.out.println("WTF?"); } }).run(); }
Java sucks
private int value; public int getCount() { return value; } public void setCount(int value) { this.value = value; } public void javaSucks3() { setCount(getCount() + 1); }
Java sucks
public void javaSucks4() { try {
out.write(new byte[] { 1,2,3}); } catch (IOException e) { System.out.println("Oops!"); } finally { try { out.close(); } catch (IOException e) { } }}
JVM Rocks
• Most popular and powerful VM in the world
• > 15 years on VM market
• True cross-platform
JVM Rocks
• Plenty of frameworks
• Application servers
• Tooling support
• Debugging
• Profiling
• Code coverage
Fantom
• Object-oriented
• Statically typed
• Open source
• Was born in late 2005
• Authors – Brian Frank and Andy Frank
• Created for start-up SkyFoundry.com
Fantom
• Significant developer productivity (comparing to Java)
• Safer code
• Multi-paradigm support
• Interaction with platform
Type inference
Infer local variablesmc := MyClass()s := "this is a string"duration := 1day
Infer generic parameters
intList := [1,2,4]strToIntMap := ["a":4, "b":5]
LiteralsLists [1, 3, 5, 7]
["a", ["b", "cd"]]
Maps ["str": "Str", 1: 3, "list": [null, 5]]
Types(reflection)Str#sys::Str#Str#capitalize
URIs`ftp://user001:[email protected]/mydir/myfile.txt``http://fantom.org``/Users/ivaninozemtsev/work/fantom`
Duration [1ns, 5ms, 12sec, 3hr, 1day]
Ranges [1..5, 2..8, 0..<5]
Functions and closures
Functions are first class objects//simple signatures|->| voidSig := |->| {}|->Int| returnsInt := |->Int| { 42 }
Methods are just function wrappers
|Int a, Int b ->Int| plus := Int#plus.func|->| mainFunc := #main.func
Functions can bind argumentsop := |Method m, Int a, Int b| { m.callOn(a, [b]) }mul := opFunc.bind([Int#mult]) //|Int, Int->Int|plus2 := opFunc.bind([Int#plus, 2]) //|Int -> Int|
Closures are exprs returning funcs
Str prefix := ""print := |Obj o->Str| { prefix + o.toStr }
Mixinsmixin FirstLast{ abstract Str firstName() abstract Str lastName()}
mixin Age{ abstract Int age }
mixin WithImpl : FirstLast{ Str fullName() { "$firstName $lastName" }}
mixin MultiInh : WithImpl, Age{ override Str toStr() { "$fullName ($age years old)" } }
• Replacement of interfaces
• Abstract fields and methods
• Methods can have implementation
Small convenience tricks
Implicit upcasts Derived derived := base
Safe invoke person?.phones?.first //null if p == null
Elvis operator //alias for this == null ? that : thisthis ?: that
No () for methods w/o args cap := "a".capitalize
No ‘return’ for single expr Int negate(Int arg) { arg.negate }
‘isnot’ keyword alwaysFalse := "a" isnot Str
Nullable types
• Every type isn’t nullable by default
• Obvious errors are caught by compiler
• Automatic coercion
class Nullable{ Void main() { Int? nullable := null Int nonNullable := 0 nonNullable = nullable //runtime err nonNullable = null //compile err do3(null) //compile err do3(nullable) //runtime err } Int do1(Int? arg) { null } //compile err Int do2(Int? arg) { arg } //runtime err Int? do3(Int arg) { arg } }
Const types
• Const classes contain only const fields
• Const fields must be set in constructor
• Const fields can have only const type or [List, Map, Func].toImmutable
• Static fields must be const
• List and Maps can be const or mutable
class NonConst{ const Int constField Int nonConstField Void mutate() { constField = 4 //compile err nonConstField = 4 //ok }}
class Const{ new make(Int i, Str[] list) { //implicit call of list.toImmutable this.list = list } const Str[] list}
Actor framework
• Actors are the only way for multithreading
• Actor are const classes extending Actor class
• Actors interchange with const or serializable messages
• Actors can have private mutable data
Actor frameworkusing concurrent
const class Logger : Actor{ new make(ActorPool pool := ActorPool()) : super(pool) {} override Obj? receive(Obj? msg) { echo(msg); return null }}class Actors{ Void main() { logger := Logger() logger.send("Hello") future := logger.sendLater(1sec, "Later") logger.send("Now") future2 := logger.sendWhenDone(future, "After later"); future3 := logger.sendWhenDone(future2, "After after") future3.cancel Actor.sleep(2sec) }}
Declarative style
Window { title = "FWT Demo" size = Size(800, 600)
Label { text = "Hello, codefest!" }, }.open
Declarative style
a := AddressBook { Person { first = "Ivan" last = "Inozemtsev" phones = [ Phone { num = "+79139494750"; type = PhoneType.cell}, Phone { num = "+73833631033" type = PhoneType.work } ] }, }
Dynamic styleclass Dict{ Str:Obj? map new make(Str:Obj? map) { this.map = map } override Obj? trap(Str name, Obj?[]? args) { if(args.isEmpty) return map[name]//getter return (map[name] = args.first) //setter }}
Void main() { dict := Dict(["foo":5, "bar":"str"]) Str a := dict->foo->toStr //"5" Str b := dict->bar //"str" Obj o := dict->o //null dict->o = 42 }
Functional style
persons.findAll |Person p->Bool| { p.first == "Ivan" }.map |Person p -> Phone[]| { p.phones }.flatten .exclude |Phone ph->Bool| { ph.type == PhoneType.work }.map |Phone ph->Str| { ph.num }.each { echo(it) }
Interaction with platform
using [java]org.eclipse.dltk.internal.ui.textusing [java]org.eclipse.core.runtimeusing [java]org.eclipse.dltk.coreusing [java]org.eclipse.ui.progress
class ReconcileListener : IScriptReconcilingListener { private AstView view public new make(AstView view) { this.view = view } override Void aboutToBeReconciled() {} override Void reconciled(ISourceModule? module, Bool forced, IProgressMonitor? progressMonitor) { if (module != null) UpdateJob(view, module).schedule }}
OK, what else?
• Build scripts on Fantom
• API Doc generation
• Built-in unit-testing framework
• Built-in web server
• Interactive shell (REPL)
X5
• Collects, analyzes and groups error reports
• Highly concurrent application
• Pure Fantom solution
• Uses CouchDB
F4• World-class IDE for
Fantom written on Fantom
• Completion
• Navigation
• Highlighting
• Search
• Debugging
Terminals
• Full-featured xterm compatible terminal
• Intense integration with Java
• Embedded into Eclipse
FPF - Fantom presentation framework
• Scene graph-based UI Framework
• Same look&feel on Desktop and browsers
• HTML5 Canvas on Web
• OpenGL Canvas on Desktop
Kloudo.com
• Pure Fantom on server side
• Runs on built-in Fantom web server
• Developed in 4 man-months
Ready to be involved?
• http://fantom.org
• http://xored.com/f4
• mailto:[email protected]
Meet @ chill-out