View
1.805
Download
0
Category
Preview:
DESCRIPTION
Fantom on the JVM Devoxx09 BOF
Citation preview
Fantom on the JVMFantom on the JVM
By Fred Simon, JFrogBy Fred Simon, JFrogDror Bereznitsky, AlphaCSPDror Bereznitsky, AlphaCSPStephen Colebourne, JodaStephen Colebourne, Joda
A BOF about the Fantom language
Agenda
Introduction to FantomWhy Fantom ?The future of Fantom
Speaker’s Qualifications
Fred Simon is a Founder and Chief Architect at JFrog Ltd.Dror Bereznitsky is the Director of
Technologies at AlphaCSP Ltd.Stephen Colebourne is the Joda project lead
Why Fantom ?
A practical programming languageHybrid OO and functional languageStatic typing with dynamic abilitiesElegant APIsModularity baked into the languageModern approach to concurrencyRESTFul designJSON style serialization
Hello World
class HelloWorld { static Void main() {
echo(“Hello world !") }
}
Pods
Pods are used to organize typesLike Java packages or C# namespacesQualified type names - <pod>::<type>
sys::DateTimeweb::Weblet
Pod Declaration – pod.fan@podDepends = [Depend("sys 1.0"),
Depend("someOtherPod 1.0")] @podSrcDirs = [`fan/`, `test/`] pod myPod {
// symbols Str mySymbol := "value"
}
Pods
Unit of deployment and versioningSimilar to a Java JAR file or a .NET assemblyPod names must be globally unique
Standard ZIP fileBundles Fantom code, meta-data, and file
resources
Type System
Two kind of typesClassesMixins
Everything is an objectValue types – Bool, Int, Float
Classes
Single class inheritanceMay inherit multiple MixinsThe root of all classes is the sys::Obj
class Foo : Bar { }
Mixins
Similar Scala traitsJava/C# interfaces + method implementationNo statemixin Foo {
Int bar() { return 42 } }
Enums
Enums are normal classesEnums have a fixed range of instances
enum Color { red, blue, green }
Null Safety
Types may be nullable or non-nullableBy default types are non-nullableUse ? to specify a nullable type
Int? x := null
Int x := null // Error
Generics
No user defined genericsLimited to List, Map, and Func
Str[] // list of Str [Str:User] // map of Users keyed by Str |Int a->Str| // takes Int, returns Str
Why Fantom?
Built in modularity Everything is an Object
Value-types for performance
Statically typed mixinsNull safetyNo user defined generics
SlotsFields and Methods on TypesUniquely named
No overloadingProtection Scope
public (default)privateprotectedinternal - only accessible inside pod
Slots - Methods
Not virtual by defaultMust explicitly specify virtual and override
class Animal { virtual Void talk()
{ echo("generic") } }
class Cat : Animal {
override Void talk() { echo("meow") } }
Slots – Methods Continued
Default parameters
Void foo(Int a, Int b := 5)
Once methodsComputed first time, then cached
once Str fullName() {
return "$firstName $lastName" }
Slots - Fields
Use the := operator to provide an initial valueStr message := "hello world"
Implicitly use a getter/setterUse * to access field storage directly
*message := "hello world"
Slots – Field Accessors
AccessorsInt x := 10 {
get { return *x } set { *x = val }
}
Can narrow field setter scopeInt x { private set } readonly Int x // the same
Slots – Field Immutability
const - indicate that the field is immutableCannot be assigned outside of the
construction processValue of all const fields must be immutable
Any object instance of a const classThe result of Obj.toImmutable (1.0.47)
Constructors
Multiple constructors allowedUse the new keywordConvention is makeXXX()Implicit make() constructor if not defined
new make(Str name := "anonymous"){this.name = name
} new makeFoo(Int x) { this.x = x }
Calling Constructors
Called just like static factory methods
foo := Foo.make foo := Foo.make("bar") foo := Foo.makeFoo(5)
Construction Calls
Special construction syntax: Type(args)Bind to Type.fromStr if exists and takes a
single Str argumentOtherwise bind to Type.make
foo := Foo.make // non-preferred foo := Foo() // preferred
Why Fantom ?
No overloadingSimple reflectionMethod resolution with default parameters
Implicit getter and settersImmutabilityHuman readable serialization
Literals
Int 45 -89_039 0xCAFE_BABE
Float 3.0f 3f 0.2e+6f
Decimal 4d 4.0 0.2e+6D
Str “foo” “x is $x, in hex $x.toHex”
Duration 4ns 100ms -0.5hr
Uri `index.html` `http://fandev.org`
Types, Slots Str# sys::Str# Int#plus #echo
Literals Continued
Range 0..5 x...y
List [1, 2, 3] Int[10, 20, 30] Int[,]
Map [1:”one”, 2:”two”] Int:Str[1:”one”] Int:Str[:]
Str Literals
Multilinex := "line 1
line 2 line3"
Triple quotesecho("""Do you know "What lies beneath the shadow of the statue"?""")
Interpolation"x is $x, in hex $x.toHex, and x+8 is ${x+8}"
Functions
First class objects - sys::FuncMethodsClosuresBind
Signature – |A a, B b ... H h -> R|
|Int a||Str a, Str b -> Int|
Functions
Calling
func.callList([7, 8])func.call(7, 8)func(7, 8)
Methods
Wrapper around a FuncMethod.func
func := Str#replace.func func("hi!", "hi", "hello") "hi!".replace("hi", "hello")
Func.bind
Binds one or more fixed arguments to create a new functionf := |Int a, Int b-> Str| {
return "$a $b"
}
g := f.bind([0])
f(0, 1) // 0 1
g(1) // 0 1
Closures
Functions that can reference enclosing scopecounter := 0
// counter = 1f := |->Int| { return ++counter } f()f() // counter = 2
Closures
Last arg to a method, can be defined “outside”
// not preferred
foo(5, |->Int| { x }) // preferred foo(5) |->Int| { x }
Closures
Used extensively in the API
[1, 2, 3].each |Int i| {echo(i)}[3, 8, 4].sort |Int a, Int b->Int| { a <=> b }
It Blocks
Syntax sugar to bind this to another variable named it
foo := Foo() { age = 15 } foo := Foo(); foo.age = 15
Can set const fields
Dynamic Invoke
Dynamic invoke operator: ->No compile time type checkingActually invokes Obj.trap()
By default trap() uses reflection to lookup and call methoda->x a.trap(“x”, [,])a->x = b a.trap(“x”, [b])a->x(b, c) a.trap(“x”, [b, c])
Why Fantom ?
Functions are 1st class citizensStatically typed, duck typing possibleDeclarative style with blocksBuilt-in immutable calls
Facets
Annotate types/slots with meta-dataSimilar to Java annotations or C# attributes@symbolName=value
@serializable @icon=`/icons/account.png`
@version=Version("1.2")
Facets
Access at runtime using Pod.facetType.facetSlot.facet
obj.type.facet(@simple) == true
Symbolspod fanDemo{ Str defaultName := "anonymous“}
class Person { const Str firstName const Str lastName new make(Str firstName := @defaultName, Str lastName := "") {
...}
}
DSL
Embed other languages into your Fantom sourceBuilt in DSLs Str <|no \ or $ escapes need, and multi-line works too|> Regex <|foo|foo/(\d*)|>
DSL Plugins
Concurrency
No mutable shared stateThreads may never share mutable state under
any circumstances
ImmutabilityMessage passingREST
UriSpaces - a whiteboard mechanism for multiple threads to share state
Immutability
Immutable object = once constructed it never changes state
Any object instance of a const classThe result of Obj.toImmutable()
Immutability - Const Classes
Use const keywordconst class Foo {}
Can only contain const fields or fields with no storage
Use const keyword - const Int id := 5Can only be set in the constructor
Must inherit from a const class or sys::Obj
Message Passing - Actors
pool := ActorPool() a := Actor(pool) |Obj msg| {
echo("$Time.now: $msg") } a.send("start")a.sendLater(1sec, "1sec")
Serialization
Syntax is a subset of the Fantom grammar
myPod::Person { name = "Homer Simpson" age = 39 children =
["Bart", "Lisa", "Maggie"] }
Serialization
Tree basedNo attempt to keep track of object referencesTree nodesLiteralSimple - serialized via string representationComplex - aggregate of literal, simple, and/or complex
Serialization - Simple
Types that are serializable to/from a stringtoStr() must return suitable string
representationMust have static fromStr() method
Serialization - Simple@simple
class Point {
static Point fromStr(Str s) {
t := s.split(",");
return make(t[0].toInt, t[1].toInt)
}
override Str toStr() { return "$x,$y" }
Int x := 0
Int y := 0
}
Serialization - Complex
@serializable facetBy default will serialize all non-static fieldsUse @transient to skip fields@serializable
class Rectangle { Int x; Int y Int w; Int h @transient Int area}
Serialization - @collections
Nicer syntax for nesting children
Person { name = "Homer Simpson" Person { name = "Bart" } Person { name = "Lisa" } Person { name = "Maggie" }
}
Java FFIusing [java] java.util::Date as JavaDate
class Test { Void main() {
date := JavaDate() // constructorsyear := date.getYear + 1900 // methods // dynamic invokes millis := date->getTime echo(
"$date, $year, $millis") }
}
UriSpaces
Standard ‘RESTful’ URI naming systemResources are represented as Fantom objectsResources are identified with UrisResources are managed using a small set of
"verbs"Resources are transferred between threads
safely
UriSpacesUriSpace.root.create(`/hello`, "hi")UriSpace.root[`/hello`] // "hi“UriSpace.root.put(`/hello`, "hola")UriSpace.root[`/hello`] // "hola“UriSpace.root.delete(`/hello`)UriSpace.root[`/hello`] // raises UnresolvedErrUriSpace.root.get(`/hello`, false) // null
Type Database
Maintains database of all installed pods and typesProvide a mechanism to index facet name/value pairs to typesAutomatically rebuilt as needed
Type Database – Facet Indexing@podIndexFacets = [@parserForExt]
pod acme {
Str[] parserForExt := Str[,]
}
@parserForExt=["xml"]
class XmlParser {}
parsers := Type.findByFacet(@parserForExt, "xml")
Buildusing build class Build : BuildPod {
override Void setup() { podName = “myPodName" version = Version("1.0")
} }
Build – Custom Codeusing build class Build : BuildScript {
@target="Compile everything" Void compile() { log.info("Compile away!") }
@target="Clean it all up" Void clean() { log.info("Clean away!") }
}
Fandoc
Plaint-text documentation languageInline code: 'FandocParser'Emphasis: *foo bar*Hyperlink: [Fantom Home Page]`http://fandev.org/`
Based on Markdown
Deployment
Fantom shipped as fcode in podsAt runtime, fcode is emitted to Java bytecode
or MSILSys API is implemented natively in Java/C#
Why Fantom ?
Concurrency – state isolationType database
No more scanning for annotations
Easy integration with JavaOut of the box build systemProvided test framework
No more modifiers trick with dynamic calls
DEMODEMO
What’sthis demo aboutWhat’sthis demo about
Thanks for your attention!
http://www.fantom.orghttp://wiki.jfrog.org/confluence/display/FANP/Home
Recommended