Loading AI tools
Из Википедии, свободной энциклопедии
Haxe — высокоуровневый кросс-платформенный язык программирования с открытым исходным кодом, а также компилятор, с помощью которого можно создавать приложения и генерировать исходный код для разных платформ, сохраняя единую кодовую базу[3][4][5][6].
Haxe | |
---|---|
Класс языка | Мультипарадигмальный |
Появился в | 2005 |
Разработчик | Haxe Foundation |
Выпуск | |
Система типов | статическая, динамическая через аннотации |
Испытал влияние | Java, OCaml, ActionScript, MTASC[2], JavaScript и C++ |
Лицензия | GPL v2, библиотека: MIT |
Сайт | haxe.org (англ.) |
Платформа | ARM, IA-32, x64 |
ОС | Android, iOS; Linux, macOS, Windows |
Haxe включает в себя функциональность, поддерживаемую на всех платформах, например: числовые типы данных, строки, массивы, а также поддержку некоторых файловых форматов (xml, zip)[4][7]. Haxe также включает в себя поддержку специфических API для каждой целевой платформы компилятора.
Код, написанный на языке Haxe, может быть скомпилирован в код JavaScript, C++, Java, JVM, PHP, C#, Python, Lua и Node.js[8]. Haxe-код также компилируется в SWF, HashLink и Neko, байт-код, а так же может быть выполнен в режиме интерпретации[8].
Основные пользователи Haxe — это TiVo, Prezi, Nickelodeon, Disney, Mattel, Hasbro, Coca Cola, Toyota и BBC[9][10]. OpenFL и Flambe — популярные фреймворки Haxe для создания мультиплатформенного контента и программ из единой кодовой базы[10]. Кроме этого, в данный момент активно развивается Snõwkit[11]. В связи с всё большим вытеснением технологии Adobe Flash в последние годы в пользу HTML5, Haxe, Unity и другие кросс-платформенные инструменты уделяют последнему всё больше времени, сохраняя обратную поддержку с Adobe Flash Player[10][12].
Самым значимым аспектом разработки архитектуры Haxe было решение о поддержке Adobe Flash, JavaScript и серверных приложений единой кодовой базой[13][14]. В типичных веб-проектах разработчики должны использовать множество разных языков, чтобы построить полноценное веб-приложение[13][14]:
Haxe был создан с идеей объединения всех этих компонентов единой кодовой базой, а также упрощения взаимодействия между компонентами приложения[13][14][15].
В книге, за авторством Николаса Кеннеси (основателя проекта Haxe), указываются первоначальные цели создания Haxe[13]:
Компилятор Haxe разделён на один фронтенд и множество бэкэндов. Фронтенд отвечает за парсинг и проверку типов, применение макросов, общую оптимизацию, различные трансформации кода и создания промежуточного представления кода в виде абстрактного синтаксического дерева (АСД). Каждый из бэкендов отвечает за трансляцию этого АСД в исходный код или байткод целевой платформы.
Компилятор написан на OCaml. Он может быть запущен в режиме сервера для поддержки автодополнения кода в IDE, также в этом режиме поддерживается кэш для уменьшения времени компиляции[16].
Компилятор Haxe — оптимизирующий компилятор, также использующий подстановку функций, свёртку констант, удаление мёртвого кода (DCE) для оптимизации производительности скомпилированных программ.
Производительность программ, написанных на Haxe, зависит от целевой платформы.
Разработка Haxe началась в октябре 2005[21], а первая бета-версия была выпущена в феврале 2006. Haxe 1.0 был выпущен в апреле 2006 и поддерживал трансляцию в Adobe Flash, Javascript и Neko.
Haxe был разработан Николасом Хеннесси (Nicolas Cannasse) и другими авторами, и первоначально был назван haXe, потому что это короткое, простое имя, а также «у него есть X в названии» — атрибут, необходимый для того, чтобы новая технология стала успешной, с юмором отмечал автор языка[22].
Haxe — это преемник ActionScript 2 компилятора MTASC с открытым исходным кодом, также сделанный Николасом Хеннесси[13][23] и выпущенный под лицензией GNU General Public License версии 2 или выше[24].
Haxe имеет много общего с ActionScript 3. Компилятор Haxe разрабатывается на языке OCaml, но для того, чтобы писать на Haxe, знаний OCaml не требуется.
Преимущества использования Haxe включают в себя:
Рекомендуемая IDE для разработки на Haxe — это FlashDevelop[13], которая поддерживает ActionScript 2, 3 и Haxe, как основные языки с подсветкой синтаксиса, автодополнением кода и другими возможностями[13][26]. Эта IDE также поддерживает сворачивание кода, рефакторинг и интерактивную отладку.[27]
Для того, чтобы использовать уже существующий код, сообщество открытого ПО создало конверторы исходного кода для:
Язык Haxe можно транслировать в байткод различных виртуальных машин, таких как Adobe Flash Player и Neko, а также в исходные коды ActionScript 3, JavaScript, включая экспериментально поддерживаемые C++ и C#. Эта стратегия «компиляции» в различные исходные коды была разработана под вдохновение парадигмы «один раз написать, запускать где угодно». Данная стратегия также позволяет выбирать программисту наилучшую платформу для работы программ.
Генератор кода | Результат | Платформа | Использование | Начиная с какой версии Haxe |
---|---|---|---|---|
AVM1[7] | Байткод | Adobe Flash Player 6+ | Desktop, Browser | 2005 (alpha) |
AVM2[7] | Байткод | Adobe Flash Player 9+, Adobe AIR, Tamarin VM | Desktop, Browser, Server | 2005 (alpha) |
ActionScript 3[7] | Исходный код | Adobe Flash Player 9+ | Server, Desktop | 2007 (1.12) |
C++ (hxcpp)[7] | Исходный код | Windows, Linux, Mac OS X | Server, Desktop, CLI | 2009 (2.04) |
C++ | Исходный код | Android[30], Apple iOS[31], Palm webOS[32] | Mobile | 2009 (2.04) |
C#[7] | Исходный код | .NET Framework | Server, Desktop, Mobile | 2012 (2.10) |
Java[7] | Исходный код | Java | Server, Desktop | 2012 (2.10) |
JavaScript[7] | Исходный код | HTML 5, Node.js, PhoneGap | Server, Desktop, Browser, Mobile | 2006 (beta) |
Neko[7] | Байткод | NekoVM | Server, Desktop, CLI | 2005 (alpha) |
PHP[7] | Исходный код | PHP | Server | 2008 (2.0) |
Python[7] | Исходный код | Python | CLI, Web, Desktop | 2014 (3.2) |
Lua[33] | Исходный код | Lua | Web, Desktop, Mobile | 2016 (3.3) |
Haxe — это объектно-ориентированный язык общего назначения, с поддержкой механизма обработки исключений и вывода типов для параметров классов. Также языком и библиотеками поддерживаются обобщённое программирование, рефлексия, итераторы и функциональное программирование[34]. Haxe также, в отличие от многих других языков, одновременно поддерживает и статическую и динамическую типизацию. Компилятор может проверять вывод типов и выдавать ошибки времени компиляции, но также разработчики могут выключить эту проверку, и положиться на динамическую проверку типов целевой платформы.
Язык Haxe похож на ECMAScript, хотя практически любой код на ECMAScript не сможет быть скомпилирован на Haxe без модификации. В отличие от ECMAScript, Haxe — компилируемый язык. Haxe был создан под влиянием ActionScript, Java, и OCaml[14].
Так как Haxe был основан на ActionScript 3, он поддерживает все функции Flash API, хотя и требует лучше оформленный код и более высокие стандарты разработки, нежели компиляторы Adobe.
Эта программа напишет «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();
}
Перечисляемые типы — это ключевая особенность языка. Перечисления могут иметь собственные параметры, а также быть рекурсивными[35]. Они похожи на алгебраические типы данных, как таковые в языках вроде 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>);
}
Документация на сайте указывает[36], что 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:
Другие мультиплатформенные языки:
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.