Иван Иноземцев — Fantom
Post on 15-Jun-2015
1434 Views
Preview:
DESCRIPTION
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