Иван Иноземцев — fantom

Post on 15-Jun-2015

1.443 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

Иван Иноземцев рассказывает о языке Fantom для платформ JVM и .NET и IDE для Fantom написанное на нём же на базе Eclispe

TRANSCRIPT

FantomCross-VM language

четверг, 24 июня 2010 г.

Общие сведения

Объектно-ориентированный

Статически типизированный

Opensource (Academic Free license 3.0)

четверг, 24 июня 2010 г.

Почему Fantom?

Мультиплатформенность

Отличный язык

Удобство “из коробки” (built-in tools)

Интеграция с платформой

О@#$%ная IDE от Xored :)

четверг, 24 июня 2010 г.

Мультиплатформенность

.fan

.fcode .js

JVM .NET LLVM Parrot

четверг, 24 июня 2010 г.

Достоинства языка

Повышение производительности программиста (по сравнению с Java)

Страховка от ошибок

Мультипарадигменность

Низкий порог вхождения (по сравнению с Scala, Clojure)

четверг, 24 июня 2010 г.

Производительность

Литералы

First-class функции

Замыкания

Вывод типов

Миксины

Множество удобных мелочей

четверг, 24 июня 2010 г.

ЛитералыСписки [1, 3, 5, 7]

["a", ["b", "cd"]]

Мапы ["str": "Str", 1: 3, "list": [null, 5]]

Типы (reflecion)Str#sys::Str#Str#capitalize

URIs `ftp://user001:pass@ftp.com/mydir/myfile.txt``http://fantom.org``/Users/ivaninozemtsev/work/fantom`

Временные интервалы [1ns, 5ms, 12sec, 3hr, 1day]

Диапазоны [1..5, 2..8, 0..<5]

четверг, 24 июня 2010 г.

Функции и замыкания

Функции как объекты //simple signatures|->| voidSig := |->| {}|->Int| returnsInt := |->Int| { 42 }

Методы содержат функции

|Int a, Int b ->Int| plus := Int#plus.func|->| mainFunc := #main.func

Функции могут связывать аргументы

opFunc := |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|

Замыкания - выражения, возвращающие функции

Str prefix := ""print := |Obj o->Str| { prefix + o.toStr }

четверг, 24 июня 2010 г.

Вывод типов

Вывод локальных переменных

mc := MyClass()s := "this is string"duration := 1day

Вывод параметров типа для коллекций

intList := [1,2,4]strIntMap := ["a":4, "b":5]

четверг, 24 июня 2010 г.

Миксиныmixin 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)" } }

Абстрактные поля и методы

Методы с имплементацией

Перегрузка методов из Obj

четверг, 24 июня 2010 г.

Мелкие удобства

Неявные upcast’ы Derived derived := base

Safe invoke person?.phones?.first //null if p == null

Elvis operator //alias for this == null ? that : thisthis ?: that

Не нужны () для методов без параметров

cap := "a".capitalize

Опциональный return Int negate(Int arg) { arg.negate }

isnot’ keyword alwaysFalse := "a" isnot Str

четверг, 24 июня 2010 г.

Безопасность

Nullable типы

Константные классы и члены

No shared mutable state

четверг, 24 июня 2010 г.

Nullable types

Every type non-nullable by default

Obvious errors are caught by compiler

Automatic coercion between nullable and non-nullable with runtime check

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

четверг, 24 июня 2010 г.

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}

четверг, 24 июня 2010 г.

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

четверг, 24 июня 2010 г.

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

четверг, 24 июня 2010 г.

Мультипарадигменность

четверг, 24 июня 2010 г.

Декларативный стиль

a := AddressBook { Person { first = "Ivan" last = "Inozemtsev" phones = [ Phone { num = "+79139494750"; type = PhoneType.cell}, Phone { num = "+73833631033" type = PhoneType.work } ] }, }

четверг, 24 июня 2010 г.

Динамический стильclass 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 }

четверг, 24 июня 2010 г.

Функциональный стиль

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

четверг, 24 июня 2010 г.

Что включено?

Возможность писать build-скрипты на Фантоме

Компиляция документации API

Встроенные юнит-тесты

Встроенный веб-сервер

Интерактивная консоль (почти REPL)

четверг, 24 июня 2010 г.

Билд-скриптыusing buildclass Build : build::BuildPod{ new make() { podName = "f4builder" summary = "" depends = ["sys 1.0", "compiler 1.0", "compilerJava 1.0", "javaBytecode 1.0", "f4core 1.0"] srcDirs = [`fan/`] outDir = `./` }}

четверг, 24 июня 2010 г.

Билд-скриптыclass Build : BuildPod{ @Target { help = "Build native JavaFx files" } Void javafx() { log.info("javafx [$podName]") log.indent

src := scriptFile.parent + `javafx/` dist := scriptFile.parent + `res/javafx/`

// start with a clean directory Delete.make(this, dist).run CreateDir.make(this, dist).run

// compile and package cmd := ["javafxpackager", "-src", src.osPath, "-appClass", "fan.fwt.Canvas", "-d", dist.osPath] r := Process.make(cmd).run.join...

четверг, 24 июня 2010 г.

документация API

** ** Compare two strings without regard to case and return -1, 0, or 1 ** if this string is less than, equal to, or greater than the specified ** string. Only ASCII character case is taken into account. ** See `localeCompare` for localized case insensitive comparisions. ** ** Examples: ** "a".compareIgnoreCase("b") => -1 ** "hi".compareIgnoreCase("HI") => 0 ** "b".compareIgnoreCase("a") => 1 ** Int compareIgnoreCase(Str s)

четверг, 24 июня 2010 г.

документация APIcompareIgnoreCase

Int compareIgnoreCase(Str s)

Compare two strings without regard to case and return -1, 0, or 1 if this string is less than, equal to, or greater than the specified string. Only ASCII character case is taken into account. See localeCompare for localized case insensitive comparisions.

Examples:

"a".compareIgnoreCase("b") => -1"hi".compareIgnoreCase("HI") => 0"b".compareIgnoreCase("a") => 1

четверг, 24 июня 2010 г.

Тесты

class ParseExprTest : Test{////////////////////////////////////////////////////////////////// Literals//////////////////////////////////////////////////////////////// Void testNullLiteral() { verifyExpr(ExprId.nullLiteral, "null", |Literal l| { verifyEq(l.val, null) verifyEq(l.resolvedType.qname, "sys::Obj") }) }

четверг, 24 июня 2010 г.

Веб-серверclass WebHello : AbstractMain{ @Opt { help = "http port" } Int port := 8080

override Int run() { wisp := WispService { it.port = this.port it.root = RouteMod { routes = [ "hello": HelloMod() ] } } return runServices([wisp]) }}

const class HelloMod : WebMod{ override Void onGet() { res.headers["Content-Type"] = "text/plain; charset=utf-8" res.out.print("hello world #4") }}

четверг, 24 июня 2010 г.

Как поиграться?komaz-mac:margincon ivaninozemtsev$ fanshFantom Shell v1.0.53 ('?' for help)fansh> a := [1,2,3,4,5][1, 2, 3, 4, 5]fansh> a.map { it * 2 }.map { it.toStr }.sortr[8, 6, 4, 2, 10]fansh> [1,2,3,4,5].reduce(0) |Int r, Int i -> Int| { r + i }15fansh> mul := |Int op1, Int op2 -> Int| { op1 * op2 }|sys::Int,sys::Int->sys::Int|fansh> plusSlot := Int#plussys::Int.plusfansh> plus := |Int op1, Int op2 -> Int| { plusSlot.callOn(op1, [op2]) }|sys::Int,sys::Int->sys::Int|fansh> plus(4, 5)9

четверг, 24 июня 2010 г.

Как поиграться?

komaz-mac:margincon ivaninozemtsev$ echo "#! /usr/bin/env fanclass Hello{ Void main() { echo(\"Hello, world\") }} " > hw.fankomaz-mac:margincon ivaninozemtsev$ chmod +x hw.fankomaz-mac:margincon ivaninozemtsev$ ./hw.fan Hello, worldkomaz-mac:margincon ivaninozemtsev$

четверг, 24 июня 2010 г.

Взаимодействие с платформой (на примере Java)

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

четверг, 24 июня 2010 г.

F4 IDEНаписана на Фантоме

Компиляция/запуск/отладка

Ссылки между проектами

Продвинутое автодополнение

Семантическая подсветка

Навигация по коду

Построение иерархий наследования

Показ API-doc’ов

четверг, 24 июня 2010 г.

Демонстрация F4 IDE в действии

четверг, 24 июня 2010 г.

Спасибо!

четверг, 24 июня 2010 г.

top related