DiffFantom.md
August 31, 2021 · View on GitHub
Fantom Compatibility
Overview
- Generics Type
- Extension Method
- Async/Await Coroutine
- Checked Dynamic Invoke
- Struct Type
- RunTime Immutable
- Readonly/Let keyword
- Data Class
- Initialization Assignment
- Closure Inference
- Local Return
- Static Namespace
- Primitive and Array type
- Named Param
- Virtual Class
- Unicode Identifier
- Float Literals Enhance
- Build Script Enhance
- Portable Library
- .Fanx File
- Little Things
Generics Type
class Foo<T> {
T? t
T get() { return t }
}
foo := Foo<Str>()
foo.t = "abc"
Extension Method
To add methods out side the class
class Whatever {
extension static Void foo(Str str) {
...
}
}
//shortcut of Whatever.foo(str)
str.foo
Async/Await Coroutine
The C#/Javascript like async/await pattern.
async Void foo(Int id) {
user := await getUser(id)
image := await getImage(user.image)
imageView.image = image
}
Checked Dynamic Invoke
Aspect Oriented Programming by ~> invoke
//same as bar.trap("foo", arg)
bar~>foo(arg)
Struct Type
A struct type is a pass by value type
const struct class Point {
const Int x
const Int y
}
p := Point{ x=1; y=2 }
RunTime Immutable
To override the toImmutable methods.
rtconst class Buf {
override Bool isImmutable() { ... }
override This toImmutable() { ... }
}
Readonly/Let keyword
readonly is a shallow const
class Bar {
const Str name
readonly StrBuf buf
}
Data Class
Auto generate toStr, hash, make, equals, compare methods if absent.
data class Point { Float x; Float y }
p := Point(0.1, 2.0)
echo(p)
Initialization Assignment
Str str := "Hi"
Str str = "Hi" //both ok
str := "Hi"
Closure Inference
To omit the function signature if params size less than one, not only it-block.
Void foo(|->| f) { f() }
foo { echo("Hi") }
Local Return
A new keyword 'lret' as same as 'return' but only be used in closures. The return keyword will be deprecated in closures.
list.eachWhile {
if (it == 0) lret null
lret it
}
Static Namespace
fanx allow same name static slots in inheritance.
class Base {
static Void foo() {}
}
class Sub : Base {
static Void foo() {}
static Void main() {
foo //call Sub.foo
Base.foo //call Base.foo
}
}
Primitive and Array type
More primitive type: Int8/Int16/Int32/Int64/Float32/Float64.
Named Param
foo(name:0, name2:1)
Virtual Class
Class default is 'final'
virtual class Base {}
Unicode Identifier
class 一个类 {
static Void main() {
你好 := "你好"
echo(你好)
}
}
Float Literals Enhance
The Default Number is Float
f := 0.1 //Float
f := 0.2f //Float
f := 0.3d //Decimal
Build Script Enhance
The pod.props file:
podName = testlib
summary = test lib
version = 2.0
srcDirs = fan/*
depends = sys 1.0
Run build:
fanb yourPath/pod.props
Portable Library
The sys pod is written in Fantom with little native code.
It's more portable to write a new backend platforms. Future targets might include C, LLVM, WebAssembly.
.Fanx File
The '.fan' file is almost like Fantom. The '.fanx' file have some break changes:
variable declaration
class Person {
var age: Int
let name: Str
const size: Int
new make(n: Str) {
name = n
size = 0
}
fun foo(): Person {
p : Person = Person("pick")
return p
}
}
Collection Literals
not support explicit type collection literals:
//old way new way
Str[] names := Str[,] ---> names: [Str] = []
[Str:Int] map := [Str:Int][:] ---> map: [Str:Int] = [:]
Type Cast
not support C-like paren cast
//old way new way
(Str)a a as Str / a as Str?
Compound Assignment
The compound assignment exper resolved type now is 'Void'.
foo(a += 1) //error
foo(a++) //error
foo(a = 1) //ok
a++ //ok
++a //not support
Final Class
class is final by default.
virtual Bar {
virtual fun foo() {}
}
Switch Fall-through
switch (x) {
case 1: case 2:
...
}
//fanx way
switch (x) {
case 1,2:
...
}
Constructor
- java like constructor chain
- static ctor is not supported
Literals
Unsupport decimal and uri literals.
Little Things
Return From Void
not allow return a value from Void method, except return a Void type.
More Container
LinkedList, Set, Tuple, ConcurrentMap, LRUCache, TreeMap and more.
Tuple<Int, Str> tuple := Tuple(1, "a")
Actor Enhance
class Bar {
Str foo(Str str) { str+"2" }
}
actor := ActorProxy { Bar() }
actor->foo("Hi")
//ActorLocal
static const AcotrLocal<Bar> local := ActorLocal()
New JSON Api
The new api support 'encoding' and 'nonstandard' options and xpath.
val := JVal.readJson("""{name=["abc"]}""")
val.xpath("name[0]")
val->name->getAt(0)
s := val.asStr //safe cast
str := JVal.writeJson(val)
Extension Methods API
Most Convenience methods are changed to extension methods to break the dependency.
Math Methods:
mixin Math {
extensiosn static Float cos(Float self) { ... }
extensiosn static Float sin(Float self) { ... }
}
class Main : Math {
Void main() {
f := 0.1
//Fantom compatible style
r := f.cos * f.sin
//mathematics familiar style
r := cos(f) * sin(f)
}
}
Deprecated Boxing
Some Fantom API return nullable Int, for example: InStrem.read(), Str.index(). To avoid int boxing, prefer -1 instead of null.
DateTime
Added TimePoint class. All time APIs are based on millis ticks. The Time is renamed to TimeOfDay.
Depend
The Depend class only support simple version constraint.
Type Erasure
The List.fits and Func.returns are no longer available.
Map
The Map.caseInsensitive and Map.ordered replaced by Orderedmap and CaseInsensitiveMap.
Static Cotr
The static constructor return nonNullable type.
Charset
It's more Unicode compliant.
More Tools
Lock, Lazy, SoftRef,...
const Lazy<Bar> lazyBar := Lazy<Bar> { Bar() }
bar := lazyBar.get
Closures with Resources
outStream.use { it.print("Hi") }
lock.sync { ... }
Assert
assert(a == b, "error")
More Str Utils
Str.splitBy, Str.splitAny, Str.extract, Str.format
Str.format("%s %d %f", ["Hi", 12, 0.3])