Fantom on the JVM Devoxx09 BOF

65
Fantom on the JVM Fantom on the JVM By Fred Simon, JFrog By Fred Simon, JFrog Dror Bereznitsky, AlphaCSP Dror Bereznitsky, AlphaCSP Stephen Colebourne, Joda Stephen Colebourne, Joda

description

Fantom on the JVM Devoxx09 BOF

Transcript of Fantom on the JVM Devoxx09 BOF

Page 1: Fantom on the JVM Devoxx09 BOF

Fantom on the JVMFantom on the JVM

By Fred Simon, JFrogBy Fred Simon, JFrogDror Bereznitsky, AlphaCSPDror Bereznitsky, AlphaCSPStephen Colebourne, JodaStephen Colebourne, Joda

Page 2: Fantom on the JVM Devoxx09 BOF

A BOF about the Fantom language

Page 3: Fantom on the JVM Devoxx09 BOF

Agenda

Introduction to FantomWhy Fantom ?The future of Fantom

Page 4: Fantom on the JVM Devoxx09 BOF

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

Page 5: Fantom on the JVM Devoxx09 BOF

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

Page 6: Fantom on the JVM Devoxx09 BOF

Hello World

class HelloWorld { static Void main() {

echo(“Hello world !") }

}

Page 7: Fantom on the JVM Devoxx09 BOF

Pods

Pods are used to organize typesLike Java packages or C# namespacesQualified type names - <pod>::<type>

sys::DateTimeweb::Weblet

Page 8: Fantom on the JVM Devoxx09 BOF

Pod Declaration – pod.fan@podDepends = [Depend("sys 1.0"),

Depend("someOtherPod 1.0")] @podSrcDirs = [`fan/`, `test/`] pod myPod {

// symbols Str mySymbol := "value"

}

Page 9: Fantom on the JVM Devoxx09 BOF

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

Page 10: Fantom on the JVM Devoxx09 BOF

Type System

Two kind of typesClassesMixins

Everything is an objectValue types – Bool, Int, Float

Page 11: Fantom on the JVM Devoxx09 BOF

Classes

Single class inheritanceMay inherit multiple MixinsThe root of all classes is the sys::Obj

class Foo : Bar { }

Page 12: Fantom on the JVM Devoxx09 BOF

Mixins

Similar Scala traitsJava/C# interfaces + method implementationNo statemixin Foo {

Int bar() { return 42 } }

Page 13: Fantom on the JVM Devoxx09 BOF

Enums

Enums are normal classesEnums have a fixed range of instances

enum Color { red, blue, green }

Page 14: Fantom on the JVM Devoxx09 BOF

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

Page 15: Fantom on the JVM Devoxx09 BOF

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

Page 16: Fantom on the JVM Devoxx09 BOF

Why Fantom?

Built in modularity Everything is an Object

Value-types for performance

Statically typed mixinsNull safetyNo user defined generics

Page 17: Fantom on the JVM Devoxx09 BOF

SlotsFields and Methods on TypesUniquely named

No overloadingProtection Scope

public (default)privateprotectedinternal - only accessible inside pod

Page 18: Fantom on the JVM Devoxx09 BOF

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") } }

Page 19: Fantom on the JVM Devoxx09 BOF

Slots – Methods Continued

Default parameters

Void foo(Int a, Int b := 5)

Once methodsComputed first time, then cached

once Str fullName() {

return "$firstName $lastName" }

Page 20: Fantom on the JVM Devoxx09 BOF

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"

Page 21: Fantom on the JVM Devoxx09 BOF

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

Page 22: Fantom on the JVM Devoxx09 BOF

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)

Page 23: Fantom on the JVM Devoxx09 BOF

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 }

Page 24: Fantom on the JVM Devoxx09 BOF

Calling Constructors

Called just like static factory methods

foo := Foo.make foo := Foo.make("bar") foo := Foo.makeFoo(5)

Page 25: Fantom on the JVM Devoxx09 BOF

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

Page 26: Fantom on the JVM Devoxx09 BOF

Why Fantom ?

No overloadingSimple reflectionMethod resolution with default parameters

Implicit getter and settersImmutabilityHuman readable serialization

Page 27: Fantom on the JVM Devoxx09 BOF

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

Page 28: Fantom on the JVM Devoxx09 BOF

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[:]

Page 29: Fantom on the JVM Devoxx09 BOF

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}"

Page 30: Fantom on the JVM Devoxx09 BOF

Functions

First class objects - sys::FuncMethodsClosuresBind

Signature – |A a, B b ... H h -> R|

|Int a||Str a, Str b -> Int|

Page 31: Fantom on the JVM Devoxx09 BOF

Functions

Calling

func.callList([7, 8])func.call(7, 8)func(7, 8)

Page 32: Fantom on the JVM Devoxx09 BOF

Methods

Wrapper around a FuncMethod.func

func := Str#replace.func func("hi!", "hi", "hello") "hi!".replace("hi", "hello")

Page 33: Fantom on the JVM Devoxx09 BOF

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

Page 34: Fantom on the JVM Devoxx09 BOF

Closures

Functions that can reference enclosing scopecounter := 0

// counter = 1f := |->Int| { return ++counter } f()f() // counter = 2

Page 35: Fantom on the JVM Devoxx09 BOF

Closures

Last arg to a method, can be defined “outside”

// not preferred

foo(5, |->Int| { x }) // preferred foo(5) |->Int| { x }

Page 36: Fantom on the JVM Devoxx09 BOF

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 }

Page 37: Fantom on the JVM Devoxx09 BOF

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

Page 38: Fantom on the JVM Devoxx09 BOF

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])

Page 39: Fantom on the JVM Devoxx09 BOF

Why Fantom ?

Functions are 1st class citizensStatically typed, duck typing possibleDeclarative style with blocksBuilt-in immutable calls

Page 40: Fantom on the JVM Devoxx09 BOF

Facets

Annotate types/slots with meta-dataSimilar to Java annotations or C# attributes@symbolName=value

@serializable @icon=`/icons/account.png`

@version=Version("1.2")

Page 41: Fantom on the JVM Devoxx09 BOF

Facets

Access at runtime using Pod.facetType.facetSlot.facet

obj.type.facet(@simple) == true

Page 42: Fantom on the JVM Devoxx09 BOF

Symbolspod fanDemo{ Str defaultName := "anonymous“}

class Person { const Str firstName const Str lastName new make(Str firstName := @defaultName, Str lastName := "") {

...}

}

Page 43: Fantom on the JVM Devoxx09 BOF

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

Page 44: Fantom on the JVM Devoxx09 BOF

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

Page 45: Fantom on the JVM Devoxx09 BOF

Immutability

Immutable object = once constructed it never changes state

Any object instance of a const classThe result of Obj.toImmutable()

Page 46: Fantom on the JVM Devoxx09 BOF

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

Page 47: Fantom on the JVM Devoxx09 BOF

Message Passing - Actors

pool := ActorPool() a := Actor(pool) |Obj msg| {

echo("$Time.now: $msg") } a.send("start")a.sendLater(1sec, "1sec")

Page 48: Fantom on the JVM Devoxx09 BOF

Serialization

Syntax is a subset of the Fantom grammar

myPod::Person { name = "Homer Simpson" age = 39 children =

["Bart", "Lisa", "Maggie"] }

Page 49: Fantom on the JVM Devoxx09 BOF

Serialization

Tree basedNo attempt to keep track of object referencesTree nodesLiteralSimple - serialized via string representationComplex - aggregate of literal, simple, and/or complex

Page 50: Fantom on the JVM Devoxx09 BOF

Serialization - Simple

Types that are serializable to/from a stringtoStr() must return suitable string

representationMust have static fromStr() method

Page 51: Fantom on the JVM Devoxx09 BOF

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

}

Page 52: Fantom on the JVM Devoxx09 BOF

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}

Page 53: Fantom on the JVM Devoxx09 BOF

Serialization - @collections

Nicer syntax for nesting children

Person { name = "Homer Simpson" Person { name = "Bart" } Person { name = "Lisa" } Person { name = "Maggie" }

}

Page 54: Fantom on the JVM Devoxx09 BOF

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") }

}

Page 55: Fantom on the JVM Devoxx09 BOF

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

Page 56: Fantom on the JVM Devoxx09 BOF

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

Page 57: Fantom on the JVM Devoxx09 BOF

Type Database

Maintains database of all installed pods and typesProvide a mechanism to index facet name/value pairs to typesAutomatically rebuilt as needed

Page 58: Fantom on the JVM Devoxx09 BOF

Type Database – Facet Indexing@podIndexFacets = [@parserForExt]

pod acme {

Str[] parserForExt := Str[,]

}

@parserForExt=["xml"]

class XmlParser {}

parsers := Type.findByFacet(@parserForExt, "xml")

Page 59: Fantom on the JVM Devoxx09 BOF

Buildusing build class Build : BuildPod {

override Void setup() { podName = “myPodName" version = Version("1.0")

} }

Page 60: Fantom on the JVM Devoxx09 BOF

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!") }

}

Page 61: Fantom on the JVM Devoxx09 BOF

Fandoc

Plaint-text documentation languageInline code: 'FandocParser'Emphasis: *foo bar*Hyperlink: [Fantom Home Page]`http://fandev.org/`

Based on Markdown

Page 62: Fantom on the JVM Devoxx09 BOF

Deployment

Fantom shipped as fcode in podsAt runtime, fcode is emitted to Java bytecode

or MSILSys API is implemented natively in Java/C#

Page 63: Fantom on the JVM Devoxx09 BOF

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

Page 64: Fantom on the JVM Devoxx09 BOF

DEMODEMO

What’sthis demo aboutWhat’sthis demo about

Valerie Hillewaere
DELETE THIS ITEM: The Demo slide should be used before each demo, so we've a good indication during post-processing. If possible try to group all of your demos in one block.
Page 65: Fantom on the JVM Devoxx09 BOF

Thanks for your attention!

http://www.fantom.orghttp://wiki.jfrog.org/confluence/display/FANP/Home