fantom on the jvm devoxx09 bof

Post on 18-Dec-2014

1.808 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Fantom on the JVM Devoxx09 BOF

TRANSCRIPT

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

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.

Thanks for your attention!

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

top related