Парадигма | Мультипарадигма |
---|---|
Разработчик | Фонд Хакса |
Впервые появился | 14 ноября 2005 |
Стабильный выпуск | 4.2.5 [1] / 6 марта 2022 |
Дисциплина набора текста | Статический , динамический через аннотации, номинальный |
Язык реализации | OCaml |
Платформа | IA-32 , x86-64 , AArch64 , armel , armhf , mips , mips64el , mipsel , ppc64el , s390x |
Операционные системы | Андроид , iOS ; Линукс , макОС , Виндовс |
Лицензия | GPL 2.0, библиотека: MIT |
Расширения файлов | .ХХ, .ХХМЛ |
Веб-сайт | haxe |
Под влиянием | |
EcmaScript , OCaml , Java , JavaScript , C++ , PHP , C# , Python , Lua , ActionScript , NekoVM |
Haxe — это высокоуровневый кроссплатформенный язык программирования с открытым исходным кодом и компилятор , который может создавать приложения и исходный код для множества различных вычислительных платформ из одной кодовой базы. Это бесплатное программное обеспечение с открытым исходным кодом , выпущенное под лицензией MIT . Компилятор, написанный на OCaml , выпущен под GNU General Public License (GPL) версии 2.
Haxe включает в себя набор функций и стандартную библиотеку [3] , поддерживаемую на всех платформах , например числовые типы данных , строки , массивы , карты , двоичные файлы , отражение , математику, HTTP , файловую систему и распространенные форматы файлов . Haxe также включает специфичные для платформы API для каждой цели компилятора. [4] Kha , OpenFL и Heaps.io — популярные фреймворки Haxe, которые позволяют создавать мультиплатформенный контент из одной кодовой базы. [5]
Haxe возник [6] с идеей поддержки клиентского и серверного программирования на одном языке и упрощения логики связи между ними. Код, написанный на языке Haxe, может быть скомпилирован в JavaScript , C++ , Java , JVM , PHP , C# , Python , Lua [7 ] и Node.js. [8] Haxe также может напрямую компилировать байт -код SWF , HashLink и NekoVM , а также работать в интерпретируемом режиме.[9]
Haxe поддерживает externs (файлы определений), которые могут содержать информацию о типах существующих библиотек для описания целевого взаимодействия безопасным для типов способом, подобно тому, как заголовочные файлы C++ могут описывать структуру существующих объектных файлов . Это позволяет использовать значения, определенные в файлах, как если бы они были статически типизированными сущностями Haxe. Помимо внешних, существуют и другие решения для доступа к собственным возможностям каждой платформы.
Многие популярные IDE и редакторы исходного кода поддерживают разработку на Haxe . [10] Никакая конкретная среда разработки или набор инструментов официально не рекомендуются Haxe Foundation, хотя VS Code , IntelliJ IDEA и HaxeDevelop имеют наибольшую поддержку для разработки Haxe. Основные функции подсветки синтаксиса , завершения кода , рефакторинга , отладки и т. д . доступны в разной степени.
Разработка Haxe началась в октябре 2005 года. Первая альфа-версия была выпущена 14 ноября 2005 года. [11] [12] Haxe 1.0 был выпущен в апреле 2006 года с поддержкой программ Adobe Flash , JavaScript и NekoVM . Поддержка PHP была добавлена в 2008 году, а C++ — в 2009 году. Дополнительные платформы, такие как C# и Java, были добавлены после капитального ремонта компилятора в 2012 году.
Haxe был разработан Николасом Каннассом и другими участниками и первоначально назывался haXe [13] , потому что он был коротким, простым и «имеет X внутри», что, как с юмором утверждает автор, необходимо для успеха любой новой технологии. [14]
Haxe является преемником компилятора ActionScript 2 с открытым исходным кодом MTASC [15] , также созданного Николасом Каннассом и выпущенного под лицензией GNU General Public License версии 2 или более поздней.
Язык Haxe может компилироваться в байт -код , который может выполняться непосредственно виртуальными машинами , на которые он нацелен. Он может компилироваться в исходный код на C++ , JavaScript , PHP , C# , Java , Python и Lua . В Haxe также есть интерпретатор под названием eval . [16] Этот же интерпретатор также используется во время компиляции для запуска макросов, позволяющих модифицировать AST .
Эта стратегия компиляции на несколько языков исходного кода вдохновлена парадигмой « напиши один раз, запускай где угодно» . Это также позволяет программисту выбрать лучшую платформу для работы. Типичные программы Haxe работают одинаково на всех платформах, но разработчики могут указать код для конкретной платформы и использовать условную компиляцию , чтобы предотвратить его компиляцию на других платформах.
Компилятор Haxe является оптимизирующим компилятором и использует встраивание полей и функций , устранение хвостовой рекурсии , свертывание констант , развертывание циклов и устранение мертвого кода (DCE) для оптимизации производительности скомпилированных программ во время выполнения. [17] Компилятор Haxe предлагает опцию null-safety , которая проверяет время компиляции на наличие значений, допускающих значение NULL.
В Haxe поддерживаемые платформы называются «целями» и состоят из следующих модулей:
В следующей таблице документирована платформа и языковая поддержка в Haxe. Язык Haxe позволяет разработчикам получить доступ ко многим функциям платформы, но Haxe не является полнофункциональным движком, им могут понадобиться фреймворки, позволяющие создавать контент для определенных платформ.
Имя | Уровень | Выход | Платформа | Использовать | Начиная с версии Haxe |
---|---|---|---|---|---|
Неко | 3 | байт-код | НекоВМ | Сервер, рабочий стол, интерфейс командной строки | 2005 (альфа) |
Flash/SWF | 3 | байт-код | Flash : AVM2 , Flash Player 9+, AIR | Рабочий стол, браузер, сервер | 2005 (альфа) |
JavaScript | 1 | источник | JavaScript : HTML5 , NodeJS , PhoneGap | Сервер, рабочий стол, браузер, мобильный | 2006 г. (бета) |
ActionScript | — | источник | ActionScript 3 : AIR , Flex , Royale | Сервер, рабочий стол, браузер, мобильный | 2007 г. (1.12), удалено с 2019 г. (4.0) |
PHP | 1 | источник | PHP : Зенд-движок | Сервер | 2008 (2.0) PHP 5 ; PHP 7 с 2019 г. (4.0) |
С++ | 2 | источник | C++ : Windows , Linux , macOS , Android , iOS , Palm , WebOS | Сервер, настольный компьютер, мобильный телефон, интерфейс командной строки, игровые приставки | 2009 г. (2,04); cppia добавлено в 2014 (3.2) |
С# | 3 | источник | С# : .NET Framework , .NET Core , моно | Сервер, рабочий стол, мобильный | 2012 (2.10) |
Ява | 3 | источник | Java : Java OpenJDK | Сервер, рабочий стол | 2012 (2.10) |
Питон | 3 | источник | Питон | CLI, веб, рабочий стол | 2014 (3,2) |
Луа | 2 | источник | Луа | CLI, веб, рабочий стол, мобильный | 2016 (3,3) |
ХэшСсылка | 1 | байт-код | HashLink VM или HL/C (компилировать в файл C) | Серверные, десктопные, мобильные, игровые приставки (экспорт C) | 2016 (3,4) |
JVM | 1 | байт-код | JVM : HotSpot , OpenJ9 | Сервер, рабочий стол | 2019 (4,0) |
Оценка | 1 | устный переводчик | Интерпретатор Haxe | Прототипирование, скриптинг | 2019 (4,0) |
Haxe — это язык общего назначения, поддерживающий объектно-ориентированное программирование , универсальное программирование и различные конструкции функционального программирования . Такие функции, как итерации , исключения и отражение кода , также являются встроенными функциями языка и библиотек. Необычный среди языков программирования, Haxe содержит систему типов, одновременно сильную и динамичную . Компилятор будет проверять типы неявно, используя вывод типов .и выдавать ошибки времени компиляции, но также позволяет программисту обходить проверку типов и полагаться на динамическую обработку типов целевой платформы. Можно использовать все собственные целевые API.
Haxe имеет сложную и гибкую систему типов. Типы, которые он предлагает, - это классы, интерфейсы, типы функций-методов, анонимные типы, алгебраические типы данных (называемые enum в Haxe) и абстрактные типы. Параметрический полиморфизм возможен с классами, алгебраическими типами и типами функций, предоставляя языку поддержку универсального программирования , основанного на стирании типов. Это включает поддержку вариативности в полиморфных функциях , но не в конструкторах типов .
Система типов является статической , если не присутствуют аннотации для динамической типизации для использования с целевыми объектами, которые их поддерживают. Проверка типов следует за номинальной типизацией , за исключением анонимных типов, где вместо этого используется структурная типизация . Наконец, поддерживается вывод типов , позволяющий объявлять переменные без аннотаций типов .
Весь код Haxe организован в модули, к которым обращаются с помощью путей. По сути, каждый файл .hx представляет собой модуль, который может содержать несколько типов. Например, чтобы создать тип A
в пакете my.pack , как показано, структура папок должна быть my\pack, а файл может быть A.hx в папке pack .
// файл my/pack/A.hx package my . пакет ;класс А {}
В других модулях можно импортировать другие типы, помещая import
операторы после определения пакета, напримерimport my.pack.A;
Модуль может содержать несколько типов, например следующие. Из этого модуля можно импортировать один тип за раз, используя файлы import my.pack2.A;
. Тип может быть private
, и в этом случае только его содержащий модуль может получить к нему доступ.
упакуйте мой . пакет2 ;typedef A = { a : String } частный typedef B = { b : String }
Классы (ключевое слово class
) в Haxe аналогичны классам в Java или TypeScript. Их поля могут быть либо методами, переменными, либо свойствами, каждый статический или для каждого экземпляра соответственно. Haxe поддерживает средства доступа public
и private
, а также более продвинутые методы управления доступом, которые обозначаются с помощью аннотаций. Методы и статические постоянные переменные могут быть встроены с помощью ключевого слова inline
. Поля могут быть помечены как final
объявляющие константы, которые должны быть инициализированы немедленно или в конструкторе и не могут быть записаны, в случае, если функция final
будет помечена как непереопределяемая в подклассах.
Интерфейсы в Haxe очень похожи на интерфейсы, например, в Java.
интерфейс ICreature { общедоступная переменная рождения : дата ; общедоступное имя переменной : строка ; возраст публичной функции (): Int ; }класс Fly реализует ICreature { public varbirth : Date ; _ общедоступное имя переменной : строка ; публичная функция age (): Int return Date . сейчас (). getFullYear () — рождение . получитьПолныйГод (); }
Haxe поддерживает универсальное программирование . Ниже приведен пример функции тождества .
идентификатор функции < T > ( аргумент : T ): T { return arg ; }
Перечислимые типы — важная особенность языка; они могут иметь параметры типа и быть рекурсивными. [20] Они обеспечивают базовую поддержку алгебраических типов данных , позволяя включать типы продуктов подобно Haskell и ML . switch
Выражение может применять сопоставление с образцом к значению перечисления, что позволяет находить элегантные решения сложных задач программирования:
перечисление Цвет { красный ; зеленый ; синий ; rgb ( r : Int , g : Int , b : Int ); }class Colors { статическая функция toInt ( c : Color ): Int { return switch c { case red : 0xFF0000 ; зеленый регистр : 0x00FF00 ; синий регистр : 0x0000FF ; case rgb ( r , g , b ): ( r << 16 ) | ( г << 8 ) | б ; } }статическая функция validCalls () { var redint = toInt ( Color .red ) ; var rgbint = toInt ( Color .rgb ( 100 , 100 , 100 ) ); } }
Примерами параметрических перечислимых типов являются стандартные библиотечные типы Haxe Option [21] и Choose: [22] .
enum Option < T > { Some ( v : T ); Нет ; }enum Либо < L , R > { Left ( v : L ); Вправо ( v : R ); }
Haxe также поддерживает обобщенные алгебраические типы данных (GADT). [23] [24]
Анонимные типы определяются путем явного указания их структуры с использованием синтаксиса, который соответствует математическому представлению типа на основе записей. Их можно использовать для реализации структурной типизации аргументов функций (см. ниже), и им можно присвоить псевдоним с помощью ключевого слова typedef
:
typedef AliasForAnon = { a : Int , b : String , c : Float -> Void };
Функции — это первоклассные значения в Haxe. Их тип обозначается стрелками между типами аргументов, а также между типом(ами) аргумента и типом возвращаемого значения, как это принято во многих функциональных языках. Однако, в отличие от известных примеров, таких как Haskell или семейство языков ML , не все функции являются унарными функциями (функциями только с одним аргументом), а в Haxe функции не могут быть частично применены по умолчанию. Таким образом, следующие сигнатуры типов имеют другую семантику, чем в вышеупомянутых языках. Тип F1
— это функция, которая принимает в String
качестве аргументов и возвращает значение типа Float
.
Типы F1
и F2
обозначают один и тот же тип, за исключением того, что F2
используется параметр с меткой, который полезен для завершения и документирования.
Типы F4
и F5
обозначают один и тот же тип. Обе являются бинарными функциями, которые возвращают бинарную функцию типа F3
. Используется синтаксис для F5
объявления типа функции внутри типа функции.
typedef F1 = String -> Float ; typedef F2 = ( текст : строка ) -> Float ;typedef F3 = ( счет : Int, текст: строка ) -> Float ; typedef F4 = ( оценка : Int, текст: строка ) -> F3 ; typedef F5 = ( оценка : Int, текст: строка ) -> (( оценка : Int, текст: строка ) -> Float );
Последним дополнением к системе типов Haxe является концепция, называемая абстрактными типами . Как используется в Haxe, это относится к чему-то отличному от обычного абстрактного типа . Они используются для неявных преобразований между типами, что позволяет повторно использовать существующие типы для определенных целей, например реализовать типы для единиц измерения. Это значительно снижает риск смешивания значений одного и того же базового типа, но с разными значениями (например, миль и км).
В следующем примере предполагается, что по умолчанию используется метрическая система, а для устаревших данных требуется преобразование в мили. Haxe может автоматически конвертировать мили в километры, но не наоборот.
абстрактный километр ( с плавающей запятой ) { общественная функция new ( v : с плавающей запятой ) this = v ; } абстрактный Mile ( Float ) { общественная функция new ( v : Float ) this = v ; @: общедоступная встроенная функция toKilometer (): возврат километра ( новый километр ( this / 0.62137 )); } class Test { static var km : Kilometer ; статическая функция main (){ var one100Miles = новая миля ( 100 ); км = одна 100 миль ; трасса ( км ); // 160.935 } }
Как показывает пример, явное преобразование для присваивания «km = one100Miles;» не требуется. делать правильные вещи.
Во многих функциональных языках программирования важную роль играет структурная типизация . Haxe применяет его при наличии анонимных типов, используя номинативную типизацию объектно - ориентированного программирования , когда задействованы только именованные типы. Анонимные типы в Haxe аналогичны неявным интерфейсам языка Go в отношении типизации. В отличие от интерфейсов Go, можно создать значение, используя анонимный тип.
класс FooBar { public var foo : Int ; общедоступная переменная bar : String ;общественная функция new () { foo = 1 ; бар = "2" ; }function anyFooBar ( v : { foo : Int , bar : String }) trace ( v.foo ) ;статическая проверка функции () { var fb = новый FooBar (); фб . любойFooBar ( fb ); фб . anyFooBar ({ foo : 123 , bar : "456" }); } }
Компилятор Haxe разделен на один интерфейс и несколько серверных частей. Внешний интерфейс создает абстрактное синтаксическое дерево (AST) из исходного кода и выполняет проверку типов, раскрытие макросов и оптимизацию AST . Различные серверные части переводят обработанный AST в исходный код или генерируют байт -код в зависимости от своей цели.
Компилятор написан на OCaml . Его можно запускать в режиме сервера, чтобы обеспечить завершение кода для интегрированных сред разработки (IDE) и поддерживать кэш для дальнейшего ускорения компиляции. [25]
{{cite journal}}
: Журнал цитирования требует |journal=
( помощь )haxe --wait [host:]port