Haxe
Haxe — высокоуровневый кросс-платформенный язык программирования с открытым исходным кодом, а также компилятор, с помощью которого можно создавать приложения и генерировать исходный код для разных платформ, сохраняя единую кодовую базу[2][3][4][5].
Haxe | |
---|---|
Класс языка | Мультипарадигмальный |
Появился в | 2005 |
Разработчик | Haxe Foundation |
Выпуск | 4.2.5 (6 марта 2022 года) |
Система типов | статическая, динамическая через аннотации |
Испытал влияние | Java, OCaml, ActionScript, MTASC[1], JavaScript и C++ |
Лицензия | GPL v2, библиотека: MIT |
Сайт | haxe.org |
Платформа | ARM, IA-32, x64 |
ОС | Android, iOS; Linux, macOS, Windows |
Haxe включает в себя функциональность, поддерживаемую на всех платформах, например: числовые типы данных, строки, массивы, а также поддержку некоторых файловых форматов (xml, zip)[3][6]. Haxe также включает в себя поддержку специфических API для каждой целевой платформы компилятора.
Код, написанный на языке Haxe, может быть скомпилирован в код JavaScript, C++, Java, JVM, PHP, C#, Python, Lua и Node.js[7]. Haxe-код также компилируется в SWF, HashLink и Neko, байт-код, а так же может быть выполнен в режиме интерпретации[7].
Основные пользователи Haxe — это TiVo, Prezi, Nickelodeon, Disney, Mattel, Hasbro, Coca Cola, Toyota и BBC[8][9]. OpenFL и Flambe — популярные фреймворки Haxe для создания мультиплатформенного контента и программ из единой кодовой базы[9]. Кроме этого, в данный момент активно развивается Snõwkit[10]. В связи с всё большим вытеснением технологии Adobe Flash в последние годы в пользу HTML5, Haxe, Unity и другие кросс-платформенные инструменты уделяют последнему всё больше времени, сохраняя обратную поддержку с Adobe Flash Player[9][11].
АрхитектураПравить
Единый языкПравить
Самым значимым аспектом разработки архитектуры Haxe было решение о поддержке Adobe Flash, JavaScript и серверных приложений единой кодовой базой[12][13]. В типичных веб-проектах разработчики должны использовать множество разных языков, чтобы построить полноценное веб-приложение[12][13]:
- PHP или другой серверный язык для генерации HTML;
- JavaScript для манипуляций над HTML на стороне клиента;
- ActionScript для графической части, при использовании Flash;
- XML или похожий протокол для коммуникации между компонентами.
Haxe был создан с идеей объединения всех этих компонентов единой кодовой базой, а также упрощения взаимодействия между компонентами приложения[12][13][14].
В книге, за авторством Николаса Кеннеси (основателя проекта Haxe), указываются первоначальные цели создания Haxe[12]:
- создать язык более мощный, чем ActionScript 2 или ActionScript 3;
- сделать так, чтобы было легко портировать приложения с ActionScript на Haxe;
- сделать язык, поддерживающий разработку для Flash 6, 7, 8 и 9;
- сделать язык, поддерживающий разработку для JavaScript/AJAX;
- сделать язык, поддерживающий разработку серверно-ориентированных программ, вместо PHP или Java.
КомпиляторПравить
Компилятор Haxe разделён на один фронтенд и множество бэкэндов. Фронтенд отвечает за парсинг и проверку типов, применение макросов, общую оптимизацию, различные трансформации кода и создания промежуточного представления кода в виде абстрактного синтаксического дерева (АСД). Каждый из бэкендов отвечает за трансляцию этого АСД в исходный код или байткод целевой платформы.
Компилятор написан на OCaml. Он может быть запущен в режиме сервера для поддержки автодополнения кода в IDE, также в этом режиме поддерживается кэш для уменьшения времени компиляции[15].
ПроизводительностьПравить
Компилятор Haxe — оптимизирующий компилятор, также использующий подстановку функций, свёртку констант, удаление мёртвого кода (DCE) для оптимизации производительности скомпилированных программ.
Производительность программ, написанных на Haxe, зависит от целевой платформы.
- ActionScript 3: программы, скомпилированные на Haxe, обычно быстрее, чем программы, скомпилированные с помощью Flex SDK ActionScript Compiler.[16] Однако, используя ActionScript Compiler 2 (ASC2) и грамотно составленный код[17], можно добиться сравнимой производительности.
- JavaScript: программы, скомпилированные на Haxe, сравнимы по скорости с программами, написанными просто на JavaScript[18]. OpenFl — самый распространённый фреймворк, который можно запустить на HTML5/JavaScript, но приложения, построенные с помощью этого фреймворка, на текущий момент страдают от потерь производительности на мобильных устройствах[18].
- C++: программы, скомпилированные на Haxe, работают почти также быстро, как и написанные просто на C++, но приложения, построенные с помощью OpenFL, могут страдать от потерь производительности[19].
РазработкаПравить
Разработка Haxe началась в октябре 2005[20], а первая бета-версия была выпущена в феврале 2006. Haxe 1.0 был выпущен в апреле 2006 и поддерживал трансляцию в Adobe Flash, Javascript и Neko.
Haxe был разработан Николасом Хеннесси (Nicolas Cannasse) и другими авторами, и первоначально был назван haXe, потому что это короткое, простое имя, а также «у него есть X в названии» — атрибут, необходимый для того, чтобы новая технология стала успешной, с юмором отмечал автор языка[21].
Haxe — это преемник ActionScript 2 компилятора MTASC с открытым исходным кодом, также сделанный Николасом Хеннесси[12][22] и выпущенный под лицензией GNU General Public License версии 2 или выше[23].
Haxe имеет много общего с ActionScript 3. Компилятор Haxe разрабатывается на языке OCaml, но для того, чтобы писать на Haxe, знаний OCaml не требуется.
Преимущества использования Haxe включают в себя:
- платформо-независимая разработка;
- разработка на высокоуровневом языке программирования;
- возможность использовать, как целевую платформу, передовые C#.NET и Adobe AIR;
- возможность разработки для устройств, поддерживающих только C++[24].
Исходный кодПравить
Рекомендуемая IDE для разработки на Haxe — это FlashDevelop[12], которая поддерживает ActionScript 2, 3 и Haxe, как основные языки с подсветкой синтаксиса, автодополнением кода и другими возможностями[12][25]. Эта IDE также поддерживает сворачивание кода, рефакторинг и интерактивную отладку.[26]
Для того, чтобы использовать уже существующий код, сообщество открытого ПО создало конверторы исходного кода для:
Поддержка платформПравить
Язык Haxe можно транслировать в байткод различных виртуальных машин, таких как Adobe Flash Player и Neko, а также в исходные коды ActionScript 3, JavaScript, включая экспериментально поддерживаемые C++ и C#. Эта стратегия «компиляции» в различные исходные коды была разработана под вдохновение парадигмы «один раз написать, запускать где угодно». Данная стратегия также позволяет выбирать программисту наилучшую платформу для работы программ.
Генератор кода | Результат | Платформа | Использование | Начиная с какой версии Haxe |
---|---|---|---|---|
AVM1[6] | Байткод | Adobe Flash Player 6+ | Desktop, Browser | 2005 (alpha) |
AVM2[6] | Байткод | Adobe Flash Player 9+, Adobe AIR, Tamarin VM | Desktop, Browser, Server | 2005 (alpha) |
ActionScript 3[6] | Исходный код | Adobe Flash Player 9+ | Server, Desktop | 2007 (1.12) |
C++ (hxcpp)[6] | Исходный код | Windows, Linux, Mac OS X | Server, Desktop, CLI | 2009 (2.04) |
C++ | Исходный код | Android[29], Apple iOS[30], Palm webOS[31] | Mobile | 2009 (2.04) |
C#[6] | Исходный код | .NET Framework | Server, Desktop, Mobile | 2012 (2.10) |
Java[6] | Исходный код | Java | Server, Desktop | 2012 (2.10) |
JavaScript[6] | Исходный код | HTML 5, Node.js, PhoneGap | Server, Desktop, Browser, Mobile | 2006 (beta) |
Neko[6] | Байткод | NekoVM | Server, Desktop, CLI | 2005 (alpha) |
PHP[6] | Исходный код | PHP | Server | 2008 (2.0) |
Python[6] | Исходный код | Python | CLI, Web, Desktop | 2014 (3.2) |
Lua[32] | Исходный код | Lua | Web, Desktop, Mobile | 2016 (3.3) |
ЯзыкПравить
Haxe — это объектно-ориентированный язык общего назначения, с поддержкой механизма обработки исключений и вывода типов для параметров классов. Также языком и библиотеками поддерживаются обобщённое программирование, рефлексия, итераторы и функциональное программирование[33]. Haxe также, в отличие от многих других языков, одновременно поддерживает и статическую и динамическую типизацию. Компилятор может проверять вывод типов и выдавать ошибки времени компиляции, но также разработчики могут выключить эту проверку, и положиться на динамическую проверку типов целевой платформы.
Язык Haxe похож на ECMAScript, хотя практически любой код на ECMAScript не сможет быть скомпилирован на Haxe без модификации. В отличие от ECMAScript, Haxe — компилируемый язык. Haxe был создан под влиянием ActionScript, Java, и OCaml[13].
Так как Haxe был основан на ActionScript 3, он поддерживает все функции Flash API, хотя и требует лучше оформленный код и более высокие стандарты разработки, нежели компиляторы Adobe.
Hello worldПравить
Эта программа напишет «Hello World» после компиляции и запуска:
class Main {
static function main() {
trace("Hello World");
}
}
Проверить этот код можно, сохранив его в файл с именем Main.hx
и запустив компилятор Haxe со следующими параметрами: haxe -main Main --interp
. Эта команда запустит Haxe Compiler в режиме интерпретации кода и выведет на экран терминала Main.hx:3: Hello world
.
Система типовПравить
Haxe — статически типизированный язык. Он имеет богатую систему типов, включая классы, интерфейсы, функциональные типы, анонимные типы, алгебраические типы данных (ADT, называемые «перечислениями» в Haxe), а также абстрактные типы данных. Классы, алгебраические типы данных и функциональные типы поддерживают параметрический полиморфизм, основанный на стирании типов, в других объективно-ориентированных языках часто называемый «Дженериками».
Haxe включает с себя поддержку ограниченного полиморфизма и полиморфизма подтипов.
К тому же, Haxe поддерживает структурную типизацию и номинальную типизацию. Для облегчения работы программистов и без ущерба безопасности типов, Haxe поддерживает вывод типов, который во многих случаях позволяет не писать типы вручную.
КлассыПравить
Классы (ключевое слово «class») в Haxe похожи на таковые в Java или AS3. Их полями могут быть методы, статические переменные класса или свойства экземпляра класса. Haxe поддерживает атрибуты доступа «public» и «private», а также более продвинутые методы контроля доступа (ACL, ссылки), которые описываются аннотациями. Методы и статические переменные с постоянным значением могут быть встроены с помощью ключевого слова «inline».
Интерфейсы в Haxe похожи на интерфейсы Java.
interface ICreature {
public var birth:Date;
public var name:String;
public function age():Int;
}
class Fly implements ICreature {
public var birth:Date;
public var name:String;
public function age():Int return Date.now().getFullYear() - birth.getFullYear();
}
ПеречисленияПравить
Перечисляемые типы — это ключевая особенность языка. Перечисления могут иметь собственные параметры, а также быть рекурсивными[34]. Они похожи на алгебраические типы данных, как таковые в языках вроде ML или Haskell. Строго говоря, это правильные типы-суммы, при условии, что типы‑произведения, включенные в них, обязаны быть определены внутри этих типов-сумм. Это значит, что перечисления не просто именованные «магические числа», как в большинстве языков, ими можно элегантно решать сложные архитектурные проблемы:
enum Color {
red;
green;
blue;
rgb( r : Int, g : Int, b : Int );
}
class Colors {
static function toInt ( c : Color ) : Int {
return switch ( c ) {
case red: 0xFF0000;
case green: 0x00FF00;
case blue: 0x0000FF;
case rgb(r, g, b): (r << 16) | (g << 8) | b;
}
}
static function validCalls() {
var redint = toInt(Color.red);
var rgbint = toInt(Color.rgb(100, 100, 100));
}
}
Haxe также поддерживает параметрические перечисляемые типы. Примером могут послужить реализация типов Option, Either и ConsList, причем ConsList ещё и рекурсивный:
enum Option<T> {
Some(v:T);
None;
}
enum Either<T,U> {
Left(v:T);
Right(v:U);
}
enum ConsList<T> {
Nil;
Cons(head:T,tail:ConsList<T>);
}
Документация на сайте указывает[35], что Haxe также поддерживает обобщённые алгебраические типы (GADT), но не приводит пример создания такового.
Анонимные типыПравить
Анонимные типы определяются с помощью явного описания их структуры, им также можно назначить псевдоним, используя определение типа (ключевое слово «typedef»):
typedef Anon = { a:Int, b:String, c:Float->Void };
Функциональные типыПравить
Функциональные типы являются объектами первого класса в Haxe. Они описываются, используя стрелки между типами аргументов, и между типами и возвращаемым значением, как и в многих других функциональных языках. Однако, в отличие от Haskell или семейства ML, не все функции в Haxe унарные (функции с одним аргументом), по умолчанию они не могут быть частично применены. Таким образом сигнатуры типов в следующих примерах имеют отличное от вышеупомянутых языков значение.
Тип F — это функция, которая принимает Int и String как аргументы и возвращает Float как результат.
В языках, где существуют только унарные функции, этот тип означал бы функцию, которая принимает Int как аргумент и возвращает функцию типа String->Float.
Типы F2 и F3 описывают один и тот же тип. Они оба описывают бинарные функции, которые возвращают бинарную функцию типа F. Для F2 описывается случай использования функционального типа внутри другого определения.
typedef F = Int->String->Float;
typedef F2 = Int->String->F;
typedef F3 = Int->String->(Int->String->Float);
Абстрактные типыПравить
Концепция, названная абстрактные типы, — это последнее дополнение в систему типов Haxe. Они позволяют повторно использовать существующие типы для специфических целей, например, реализации типов для единиц измерения, при этом сильно уменьшая возможность смешивания разных систем (например мили и километры). Термин «абстрактный тип» в контексте языка Haxe имеет другое значение, в отличие от обычных абстрактных типов.
Следующий пример предполагает, что метрическая система используется по умолчанию, а конвертация в мили необходима, чтобы поддерживать устаревшие данные. Haxe способен автоматически преобразовывать мили в километры, но не в обратную сторону.
abstract Kilometer(Float) {
public function new(v:Float) this = v;
}
abstract Mile(Float) {
public function new(v:Float) this = v;
@:to public inline function toKilometer():Kilometer return (new Kilometer(this / 0.62137));
}
class Test {
static var km:Kilometer;
static function main(){
var one100Miles = new Mile(100);
km = one100Miles;
trace(km); // 160.935
}
}
Пример показывает, что не обязательно делать явное преобразование km = one100Miles;
для использования корректных единиц.
Структурная типизацияПравить
Структурная типизация играет важную роль во многих функциональных языках программирования и, в то же время, довольно малую в распространенных ООП языках. В отличие от номинальной системы типов, равенство двух типов определяется не равенством каких-либо имён типа, а скорее устройством типа. Структурные типы можно рассматривать как неявные интерфейсы:
class FooBar {
public var foo:Int;
public var bar:String;
public function new(){ foo=1; bar="2";}
function anyFooBar(v:{foo:Int,bar:String}) trace(v.foo);
static function test(){
var fb = new FooBar();
fb.anyFooBar(fb);
fb.anyFooBar({foo:123,bar:"456"});
}
}
См. такжеПравить
Также, на платформе Haxe:
Другие языки, компилирующиеся в JavaScript:
Другие мультиплатформенные языки:
ПримечанияПравить
- ↑ https://haxe.org/manual/introduction-haxe-history.html
- ↑ Nicolas' announcement of spelling change on Haxe official mail list (неопр.).
- ↑ 1 2 Ponticelli, Franco. Professional haXe and Neko (неопр.). — Wiley, 2008. — ISBN 0470122137. Архивная копия от 28 ноября 2015 на Wayback Machine
- ↑ Ivanov, Michael. Away3D 3.6 Cookbook (неопр.). — Packt Publishing Ltd (англ.) (рус., 2011. — ISBN 1849512817. Архивная копия от 2 ноября 2015 на Wayback Machine
- ↑ Doucet, Lars Haxe/OpenFL for home game consoles (неопр.). Gamasutra (3 июня 2015). Дата обращения: 9 октября 2015. Архивировано 8 сентября 2015 года.
- ↑ 1 2 3 4 5 6 7 8 9 10 11 Introduction to the Haxe Standard Library Архивная копия от 14 августа 2015 на Wayback Machine, Haxe Docs
- ↑ 1 2 Compiler Targets (неопр.). Haxe - The Cross-platform Toolkit. Дата обращения: 23 февраля 2021. Архивировано 2 марта 2021 года.
- ↑ Companies using Haxe Архивная копия от 7 сентября 2015 на Wayback Machine, Haxe Docs
- ↑ 1 2 3 Doucet, Lars Dear Adobe: Support Haxe, save your Tools (неопр.). Gamasutra (24 июня 2014). Дата обращения: 9 октября 2015. Архивировано 24 сентября 2015 года.
- ↑ about snõwkit (неопр.). snõwkit (20 сентября 2014). Дата обращения: 9 августа 2016. Архивировано 9 августа 2016 года.
- ↑ Doucet, Lars Flash is dead, long live OpenFL! (неопр.) Gamasutra (18 марта 2014). Дата обращения: 9 октября 2015. Архивировано 30 августа 2015 года.
- ↑ 1 2 3 4 5 6 7 Grden, John; Mineault, Patrick; Balkan, Aral; Hughes, Marc; Arnold, Wade. The Essential Guide to Open Source Flash Development (англ.). — Apress, 2008. — P. Chapter 9 (Using Haxe). — ISBN 1430209941. Архивная копия от 8 февраля 2016 на Wayback Machine
- ↑ 1 2 3 4 Haxe Interview (неопр.). — Io Programmo, 2009. — 1 April. — С. 1—6. Архивировано 8 декабря 2015 года.
- ↑ Fisher, Matt. HTML5 for Flash Developers (неопр.). — Packt Publishing Ltd (англ.) (рус., 2013. — ISBN 1849693331. Архивная копия от 24 ноября 2015 на Wayback Machine
- ↑ Server mode command-line :
haxe --wait [host:]port
- ↑ AS3 vs haXe performance Архивная копия от 5 января 2013 на Wayback Machine, SplashDust website
- ↑ AS3 Performance Optimization Архивная копия от 6 октября 2015 на Wayback Machine, Starling Wiki
- ↑ 1 2 Vadim Dyachenko. On “You can’t make good HTML5 games in Haxe” (неопр.). Yellow After Life (5 декабря 2013). Дата обращения: 9 октября 2015. Архивировано из оригинала 30 сентября 2015 года.
- ↑ Kaya, Talha OpenFL & Haxe, A Bumpy Start (неопр.). Gamasutra (4 июля 2014). Дата обращения: 9 октября 2015. Архивировано 24 сентября 2015 года.
- ↑ Haxe 3.2 Release (неопр.). Github. Дата обращения: 9 октября 2015. Архивировано 21 февраля 2016 года.
- ↑ Haxe mailing list post on naming (неопр.). Архивировано 28 марта 2007 года.
- ↑ MTASC Compiler Архивная копия от 20 октября 2020 на Wayback Machine, MTASC website
- ↑ Haxe license page (неопр.). Архивировано 12 мая 2012 года.
- ↑ Haxe introduction page (неопр.). Архивировано 4 мая 2012 года.
- ↑ Main Page, FlashDevelop Wiki Архивная копия от 10 октября 2015 на Wayback Machine, «first class support for Flash ActionScript (AS2 and AS3) and Haxe development»
- ↑ Haxe Support Архивная копия от 6 июля 2015 на Wayback Machine, FlashDevelop Wiki
- ↑ as3hx Архивная копия от 14 мая 2015 на Wayback Machine, AS3 to Haxe converter, Haxe source code repository
- ↑ CS2HX — C# to haXe converter Архивная копия от 4 марта 2010 на Wayback Machine, CodePlex project hosting
- ↑ Blog post mentioning Android port progress (неопр.). Дата обращения: 9 октября 2015. Архивировано 28 декабря 2015 года.
- ↑ Haxe, iPhone & C++ At Last Архивная копия от 15 апреля 2012 на Wayback Machine, GameHaxe website
- ↑ How to get started with Haxe 2.06 and the webOS PDK [archived on WayBackMachine] (неопр.). Архивировано 22 октября 2014 года.
- ↑ Hello Lua! - Haxe - The Cross-platform Toolkit (неопр.). Дата обращения: 9 августа 2016. Архивировано 6 августа 2016 года.
- ↑ Haxe language reference (неопр.). Архивировано 2 мая 2012 года.
- ↑ Haxe reference detailing the use of enum (неопр.). Архивировано 11 мая 2012 года.
- ↑ Language Features (неопр.). Haxe - The Cross-platform Toolkit. Haxe Foundation. Дата обращения: 30 апреля 2015. Архивировано 16 мая 2015 года.
- ↑ A Scala to JavaScript compiler (неопр.). Дата обращения: 9 октября 2015. Архивировано 10 августа 2015 года.