Haxe - Haxe

Haxe
Haxe logo.svg
Paradigma Multiparadigma
Desenvolvedor Fundação Haxe
Apareceu pela primeira vez 2005 ; 16 anos atrás ( 2005 )
Versão estável
4.2.3  Edite isso no Wikidata / 1 de julho de 2021 ; 3 meses atrás ( 1 de julho de 2021 )
Disciplina de digitação Estático , dinâmico por meio de anotações, nominal
Linguagem de implementação OCaml
Plataforma ARM ; IA-32 , x86-64
SO Android , iOS ; Linux , macOS , Windows
Licença GPL 2.0, biblioteca: MIT
Extensões de nome de arquivo .hx, .hxml
Local na rede Internet haxe .org
Influenciado por
EcmaScript , OCaml , Java , JavaScript , C ++ , PHP , C # , Python , Lua , ActionScript , NekoVM

Haxe é uma linguagem de programação de plataforma cruzada de alto nível de código aberto e compilador que pode produzir aplicativos e código-fonte, para muitas plataformas de computação diferentes a partir de um código-base. É um software gratuito e de código aberto , lançado sob a licença MIT . O compilador, escrito em OCaml , é lançado sob a GNU General Public License (GPL) versão 2.

Haxe inclui um conjunto de recursos e uma biblioteca padrão com suporte em todas as plataformas , como tipos de dados numéricos , strings , matrizes , mapas , binário , reflexão , matemática, HTTP , sistema de arquivos e formatos de arquivo comuns . O Haxe também inclui APIs específicas da plataforma para cada destino do compilador. Kha , OpenFL e Heaps.io são estruturas Haxe populares que permitem a criação de conteúdo multiplataforma a partir de uma base de código.

Haxe originou-se com a ideia de apoiar do lado do cliente e do lado do servidor de programação em um idioma, e simplificando a lógica comunicação entre eles. O código escrito na linguagem Haxe podem ser compilados em JavaScript , C ++ , Java , JVM , PHP , C # , Python , Lua e Node.js . O Haxe também pode compilar diretamente o bytecode SWF , HashLink e Neko e também é executado no modo interpretado.

O Haxe oferece suporte a arquivos externos (arquivos de definição) que podem conter informações de tipo de bibliotecas existentes para descrever a interação específica do destino de maneira segura, como arquivos de cabeçalho C ++ que podem descrever a estrutura de arquivos de objetos existentes . Isso permite usar os valores definidos nos arquivos como se fossem entidades Haxe estaticamente tipadas. Além dos externos, existem outras soluções para acessar os recursos nativos de cada plataforma.

Muitos IDEs populares e editores de código-fonte têm suporte disponível para o desenvolvimento Haxe . Nenhum ambiente de desenvolvimento específico ou conjunto de ferramentas é oficialmente recomendado pela Fundação Haxe, embora o VS Code , IntelliJ IDEA e HaxeDevelop tenham mais suporte para o desenvolvimento Haxe. As principais funcionalidades de destaque de sintaxe , conclusão de código , refatoração , depuração , etc. estão disponíveis em vários níveis.

História

O desenvolvimento do Haxe começou em outubro de 2005. A primeira versão beta foi lançada em fevereiro de 2006. O Haxe 1.0 foi lançado em abril de 2006, com suporte para programas Adobe Flash , JavaScript e Neko . Suporte para PHP foi adicionado em 2008 e C ++ foi adicionado em 2009. Mais plataformas como C # e Java foram adicionadas com uma revisão do compilador em 2012.

Haxe foi desenvolvido por Nicolas Cannasse e outros colaboradores, e foi originalmente chamado de haXe porque era curto, simples e "tem um X dentro", que o autor afirma com humor ser necessário para tornar qualquer nova tecnologia um sucesso.

Haxe é o sucessor do compilador de código aberto ActionScript 2 MTASC , também desenvolvido por Nicolas Cannasse e lançado sob a GNU General Public License versão 2 ou posterior.

Compilador

A linguagem Haxe pode ser compilada em bytecode que pode ser executado diretamente pelas máquinas virtuais a que se destina. Ele pode compilar o código-fonte em C ++ , JavaScript , PHP , C # , Java , Python e Lua . Haxe também tem um intérprete chamado eval . Esse mesmo interpretador também é usado em tempo de compilação para executar macros, que permitem a modificação do AST .

Essa estratégia de compilar em várias linguagens de código-fonte é inspirada no paradigma escrever uma vez, executar em qualquer lugar . Também permite que o programador escolha a melhor plataforma para o trabalho. Os programas Haxe típicos são executados de forma idêntica em todas as plataformas, mas os desenvolvedores podem especificar o código específico da plataforma e usar a compilação condicional para evitar que seja compilado em outras plataformas.

O compilador Haxe é um compilador otimizador e usa inlining de campo e função , eliminação de recursão de cauda , dobramento constante , desenrolamento de loop e eliminação de código morto (DCE) para otimizar o desempenho em tempo de execução de programas compilados. O compilador Haxe oferece segurança nula opcional , ele verifica o tempo de compilação para valores anuláveis.

Alvos

No Haxe, as plataformas suportadas são conhecidas como "destinos", que consistem nos seguintes módulos:

  • Os back-ends do compilador responsáveis ​​por gerar o respectivo código.
  • As APIs específicas de tempo de execução que vão além do suporte ao idioma principal (destinos de plataforma).

A tabela a seguir documenta a plataforma e o suporte ao idioma no Haxe. A linguagem Haxe permite que os desenvolvedores obtenham acesso a muitos recursos da plataforma, mas o Haxe não é um mecanismo completo, eles podem precisar de estruturas que permitem a criação de conteúdo para determinadas plataformas.

Alvo do compilador Saída Plataforma Usar Desde a versão Haxe
JavaScript fonte HTML5 , NodeJS , PhoneGap Servidor, desktop, navegador, celular 2006
C ++ fonte Windows , Linux , MacOS , Android , iOS , Palm , WebOS Servidor, desktop, celular, CLI, consoles de jogos 2009 (2.04)
PHP fonte PHP Servidor 2008 (2,0)
C # fonte .NET Framework Servidor, desktop, celular 2012 (2,10)
Java fonte Java Servidor, desktop 2012 (2,10)
JVM bytecode Máquina Virtual JAVA Servidor, desktop 2019 (4,0)
Pitão fonte Pitão CLI, web, desktop 2014 (3,2)
Lua fonte Lua CLI, web, desktop, mobile 2016 (3,3)
Neko código de byte NekoVM Servidor, desktop, CLI 2005
Flash / SWF código de byte Adobe Flash Player 9+, Adobe AIR , Tamarin Desktop, navegador, servidor 2005
HashLink código de byte HashLink VM ou HL / C (compilar para arquivo C) Servidor, desktop, celular, consoles de jogos (exportação C) 2016 (3,4)

Desde Haxe versão 1.12 (2007) havia um destino de origem ActionScript 3 (para Adobe FlashPlayer), este foi removido do Haxe na versão 4.0.

Vantagens para Haxe

  • Capacidade de direcionar várias plataformas e dispositivos usando o mesmo idioma
  • Capacidade de usar código estritamente digitado
  • Capacidade de usar macros (transformação de sintaxe), o que pode ser feito com a linguagem Haxe
  • Adicionados recursos de linguagem, como métodos de extensão e programação funcional
  • O desempenho de tempo de execução dos programas Haxe é comparável à velocidade de fontes escritas à mão.

Língua

Haxe é uma linguagem de propósito geral que suporta programação orientada a objetos , programação genérica e várias construções de programação funcional . Recursos como iterações , exceções e reflexão de código também são funções integradas da linguagem e das bibliotecas. Incomum entre as linguagens de programação, Haxe contém um sistema de tipos forte e dinâmico . O compilador verificará os tipos implicitamente usando inferência de tipo e fornecerá erros de tempo de compilação, mas também permite que o programador contorne a verificação de tipo e conte com o tratamento de tipo dinâmico da plataforma de destino. Todas as APIs de destino nativas podem ser usadas.

Sistema de tipo

Haxe possui um sistema de tipologia sofisticado e flexível. Os tipos de tipo que ele oferece são classes, interfaces, tipos de método de função, tipos anônimos, tipos de dados algébricos (ADTs, chamados de enum em Haxe) e tipos abstratos. O polimorfismo paramétrico é possível com classes, ADTs e tipos de função, dando suporte à linguagem para programação genérica baseada na eliminação de tipo. Isso inclui suporte para variação em funções polimórficas , embora não em construtores de tipo .

O sistema de tipos é estático, a menos que anotações para tipagem dinâmica estejam presentes, para uso com destinos que as suportam. A verificação de tipo segue a digitação nominal, com exceção dos tipos anônimos, onde a tipagem estrutural é usada. Finalmente, a inferência de tipo é suportada, permitindo declarações de variáveis ​​sem anotações de tipo .

Módulos e namespaces

Todo o código Haxe é organizado em módulos, que são endereçados por caminhos. Em essência, cada arquivo .hx representa um módulo que pode conter vários tipos. Por exemplo, para criar o tipo Ano pacote my.pack conforme mostrado, a estrutura da pasta deve ser my \ pack e o arquivo pode ser A.hx no pacote de pastas .

 // file my/pack/A.hx
package my.pack;

class A {}

Em outros módulos, outros tipos podem ser importados colocando importinstruções abaixo da definição do pacote, por exemplo, import my.pack.A; um módulo pode conter vários tipos, como o seguinte. É possível importar um tipo de cada vez desse módulo, usando import my.pack2.A;. Um tipo pode ser e private, nesse caso, apenas o módulo que o contém pode acessá-lo.

package my.pack2;

typedef A = {a:String}
private typedef B = {b:String}

Aulas

As classes (palavra-chave class) em Haxe são semelhantes às de Java ou TypeScript. Seus campos podem ser métodos, variáveis ​​ou propriedades, cada um estático ou por instância, respectivamente. Haxe suporta os acessadores publice privatemétodos mais avançados para controle de acesso que são indicados por meio de anotações. Métodos e variáveis ​​constantes estáticas podem ser embutidos usando a palavra-chave inline. Os campos podem ser marcados finalpara declarar uma constante que deve ser inicializada imediatamente ou no construtor e não pode ser gravada, caso a função seja marcada finalcomo não substituível nas subclasses.

As interfaces em Haxe são muito semelhantes àquelas em, por exemplo, 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();
}

Genéricos

Haxe suporta programação genérica . A seguir está um exemplo da função de identidade .

function identity<T>(arg:T):T {
	return arg;
}

Tipos enumerados

Os tipos enumerados são uma característica importante da linguagem; eles podem ter parâmetros de tipo e ser recursivos. Eles fornecem suporte básico para tipos de dados algébricos , permitindo a inclusão de tipos de produtos , de forma semelhante a Haskell e ML . Uma switchexpressão pode aplicar correspondência de padrão a um valor enum, permitindo soluções elegantes para problemas de programação complexos:

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

Exemplos de tipos de enum paramétricos são os tipos de biblioteca padrão Haxe Option e Either:

enum Option<T> {
    Some(v:T);
    None;
}

enum Either<L, R> {
    Left(v:L);
    Right(v:R);
}

Haxe também suporta tipos de dados algébricos generalizados (GADTs).

Tipos anônimos

Os tipos anônimos são definidos denotando sua estrutura explicitamente, usando uma sintaxe que segue a representação matemática baseada em registros de um tipo. Eles podem ser usados ​​para implementar tipagem estrutural para argumentos de função (veja abaixo) e podem receber um alias com a palavra typedef- chave :

typedef AliasForAnon = { a:Int, b:String, c:Float->Void };

Tipos de função

Funções são valores de primeira classe em Haxe. Seu tipo é denotado pelo uso de setas entre os tipos de argumento e entre o (s) tipo (s) de argumento e o tipo de retorno, como é comum em muitas linguagens funcionais. No entanto, ao contrário de exemplos proeminentes como Haskell ou a família de linguagem ML , nem todas as funções são funções unárias (funções com apenas um argumento) e, em Haxe, as funções não podem ser parcialmente aplicadas por padrão. Assim, as seguintes assinaturas de tipo têm semântica diferente do que nas línguas mencionadas. O tipo F1é uma função que recebe a Stringcomo argumentos e retorna um valor do tipo Float.

Tipos F1e F2 denotam o mesmo tipo, exceto que F2usa o parâmetro rotulado, que é útil para finalidades de preenchimento e documentação.

Digita F4e F5denotam o mesmo tipo. Ambas são funções binárias que retornam uma função binária do tipo F3. Para que F5a sintaxe declare um tipo de função dentro de um tipo de função, é usado.

typedef F1 = String -> Float;
typedef F2 = (text:String) -> Float;

typedef F3 = (score:Int, text:String) -> Float;
typedef F4 = (score:Int, text:String) -> F3;
typedef F5 = (score:Int, text:String) -> ((score:Int, text:String) -> Float);

Tipos abstratos

A última adição ao sistema de tipos Haxe é um conceito denominado tipos abstratos . Conforme usado em Haxe, refere-se a algo diferente de um tipo abstrato convencional . Eles são usados ​​para fazer conversões entre tipos implícitos, permitindo a reutilização de tipos existentes para fins específicos, como implementar tipos para unidades de medida. Isso reduz muito o risco de misturar valores do mesmo tipo subjacente, mas com significados diferentes (por exemplo, milhas x km).

O exemplo a seguir assume que o sistema métrico é o padrão, enquanto uma conversão para milhas é necessária para dados legados. O Haxe pode converter automaticamente milhas em quilômetros, mas não o contrário.

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

Como mostra o exemplo, nenhuma conversão explícita é necessária para a atribuição "km = one100Miles;" para fazer a coisa certa.

Tipagem estrutural

Em muitas linguagens de programação funcional, a tipagem estrutural desempenha um papel importante. Haxe o emprega na presença de tipos anônimos, usando a tipagem nominativa da programação orientada a objetos , quando apenas tipos nomeados estão envolvidos. Os tipos anônimos em Haxe são análogos às interfaces implícitas da linguagem para a digitação. Em contraste com as interfaces Go, é possível construir um valor usando um tipo anônimo.

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

Arquitetura interna

Compilador

O compilador Haxe é dividido em um front-end e vários back-ends. O frontend cria uma árvore de sintaxe abstrata (AST) a partir do código-fonte e executa a verificação de tipo, expansão de macro e otimização no AST . Os vários back-ends traduzem o AST processado em código-fonte ou geram bytecode , dependendo de seu destino.

O compilador é escrito em OCaml . Ele pode ser executado no modo de servidor para fornecer autocompletar código para ambientes de desenvolvimento integrado (IDEs) e manter um cache, para acelerar ainda mais a compilação.

Veja também

Referências

links externos