BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias The Ioke JVM Language: The power of Lisp and Ruby with an intuitive syntax

The Ioke JVM Language: The power of Lisp and Ruby with an intuitive syntax

Ola Bini, membro do time de desenvolvimento do JRuby e autor do livro Practical JRuby on Rails Projects, está desenvolvendo uma nova linguagem para a JVM chamada Ioke. Fortemente tipada e extremamente dinâmica, esta linguagem de orientação a objetos baseada em prototipação busca dar aos desenvolvedores o mesmo tipo de poder que eles tem com Lisp e Ruby, combinados com uma sintaxe agradável, pequena e regular.

Ola explica a natureza básica do Ioke:

Ioke é fortemente tipada e extremamente dinâmica, uma linguagem de orientação a objetos baseada em prototipação. É homo icônico (mesma representação de código e dados) e possui um suporte built-in para diversos tipos de macros. A linguagem que mais influenciou Ioke é Io, Smalltalk, Self, Ruby e Lisp (especificamente Common Lisp).

A linguagem é construída sobre a JVM, mas estou considerando compilar-la para JavaScript e rodá-la sobre no V8.

Eu tenho muitos objetivos com esta linguagem, mas o objetivo mais específico é criar uma linguagem que combine as coisas que eu mais gosto de Ruby e Lisp. Acontece que Io já possui muitas das funcionalidades que eu estou procurando, mas em alguns casos não vão tão longe. Eu também quero ter uma linguagem que seja boa para expressar DSLs internas. Eu quero uma linguagem que não fique no meu caminho, mas ao mesmo tempo me ofereça força suficiente para fazer o que eu quero. Para isso eu desenhei um sistema de macros que muita gente provavelmente vai achar insano.

InfoQ fez um pequeno bate-bola com Ola Bini sobre o design de Ioke:

InfoQ: Parece que uma das funcionalidades chave de Ioke é o fato de que ela usa herança baseada em prototype. Você acha que os benefícios muito maiores quando comparados com uma orientação baseada em classe dominante?

OK, sim, esta é uma das funcionalidades, mas não estou certo se é uma funcionalidade chave ou não. Isso muda o design de algumas coisas substancialmente, sim. Eu me sinto mais confortável assim do que com um sistema baseado em classes, e desde que Ioke é uma linguagem apenas para minha satisfação pessoal, meu conforto tende a ser importante.

Em Ruby, você pode usar classes singleton para conseguir algo que se parece um pouco com o estilo prototype de OO e eu descobri que você pode modelar algoritmos mais claros dessa forma. E não há problemas óbvios de poder, porque você pode sempre seguir o estilo de classes em OO por convenção, se você quiser.

Um dos princípios chave de Ioke é que eu não quero tomar nenhuma decisão apenas para agradar. Devo usar OO baseada em classes só porque é o paradigma dominante? Não necessariamente. Há muitas boas razões para muitas coisas, mas há também muita bagagem histórica que não faz muito sentido para a maioria das aplicações. Portanto estou tentando revisitar tanto quanto eu posso durante o desenvolvimento da Ioke.

InfoQ: Sendo JavaScript a única linguagem famosa que usa OO baseado em herança por prototype, você acha que este paradigma tem potencial para ser abertamente compreendido e utilizado?

Eu acho que OO baseada em Prototype é mais natural e fácil de entender do que OO baseada em classe. Eu acho que OO baseada em classe tem sido mais difundida e que a maioria das pessoas vai achar prototype mais intuitivo uma vez que eles desaprenderem o mantra de OO baseada em classe. Claro, JavaScript pode não ser a melhora comparação, até porque a natureza prototype da linguagem facilmente é escondida pelos diversos usos do modelo da linguagem, que significa que a maioria dos desenvolvedores não sabem como usar esta parte da linguage, de forma elegante.

InfoQ: Parece que Ioke tem sido desenhada desde o início para ser uma linguagem da JVM. Você acha que isso será a plataforma das próximas linguagens que estão por vir?

Meu pensamento atual é que não faz muito sentido criar sua máquina virtual do zero. A maioria das novas linguagens possui garbage collector, por exemplo, e eu não entendo porque as pessoas que criam linguagens querem escrever seu próprio garbage collector. Isso apenas consumirá meses de suas vidas e eles geralmente só terão feito um trabalho parcial. Veja quantos problemas Ruby tem com GC. Esse pensamento obviamente é relevante para várias outras coisas também -- especialmente bibliotecas. Então sim, Ioke é uma linguagem para a JVM (mas a maior parte da linguagem não é dependente disso. Você poderia reimplementá-la sobre outra plataforma facilmente. O core é bem pequeno). Sim, eu acredito que linguagens para a JVM, o CLR, Parrott e em certo grau LLVM devem ser a norma. Há poucos casos onde faz sentido escrever sua própria VM do zero.

InfoQ: O sistema condicional que você está implementando para Ioke para similar à manipulação de exceções em Java, só que mais flexível. Você pode nos dar alguns exemplos que demonstrem melhor o valor desse sistema?

Bem, você pode dizer que exceptions oferecem um subset das funcionalidades de um sistema de condicional. Há duas diferenças - a primeira é relacionada protocolo e abstração. Todas as situações onde as exceptions são usadas devem ser exceção ou erro. Ou veja warnings por exemplo. Na maioria das linguagens dinâmicas há sistemas de warnings baseados em logging ad-hoc. Mas o que acontece se você quiser fazer algo a mais? Em Ruby você poderia modificar o método warn para disparar uma exception, mas isso ainda significa que há uma divisão em como os warnings e as exception são tratadas. Ou veja interrupções de sistema ou de threads. Todos esses são superficialmente funcionalidades diferentes, mas podem ser vistos como a mesma coisa.

Condições permitem a você unificá-los. Eles oferecem um protocolo uniforme para tratar esse tipo de eventos.

A funcionalidade que as condições oferecem é dupla. A primeira é restarts, que é atualmente quase separada.

Um restart é algo que você pode registrar em um bloco. São basicamente peças de código que executam quando um restart é invocado. Há alguns métodos para invocar um restart nomeado, encontrar todos os restarts e assim por diante. Um restart pode ser visto quase como um mecanismo de exception. Isso é dinâmico em relação ao escopo.

Conditions permitem a você manipuladores para algo que possa acontecer. Quando esta condição acontece, um manipulador pode escolher manipular isso ou deixar passar para a próxima manipulação. Mas isso não sobrecarrega o stack (pelo menos, não ainda). Se um manipulador quer fazer algo a respeito de uma condição (e um manipulador é também um pedaço de código), aquele bloco de código será executado no contexto léxico do manipulador, mas no escopo dinâmico do local onde a condição oi primeiro sinalizada. Isso significa que um manipulador que está a muitas chamadas de métodos longe do ponto de sinalização da condição pode realizar algo naquele contexto.

Isso não é tão estranho assim, você poderia fazer isso em Ruby puro por exemplo. Mas perde um pouco de força se isso não estiver disponível na biblioteca padrão.

Em Common Lisp isso é muito poderoso. Quando você usa Common Lisp interativamente, a manipulação padrão de uma condição é colocar você no debugger. Este debugger executa no contexto do local onde o erro aconteceu e ele pode fazer a mesma coisa que um manipulador pode - incluindo fornecer novos valores para variáveis e assim por diante. O debugger não precisa fazer nada especial, ele é somente um caso de uso específico para o sistema de condições.

Eu não consigo enfatizar o suficiente o quanto isso é poderoso.

InfoQ: Como você acha que Ioke se encaixa em termos de manutenção e refactoring, sendo dinâmico mas também fortemente tipada?

Difícil de dizer nesse momento. Porque Ioke é concisa e oferece muitas funcionalidades poderosas para escrever código sucinto, deveria ser de fácil manutenção. Refactoring automatizado provavelmente não é tão interessante nesse momento, pela mesma razão.

Assim como Lisp, Ioke oferece abstrações sintáticas. Elas tem duas formas, a primeira são as macros, que são basicamente como chamadas de métodos com argumentos tardios que podem ser interpretados de maneiras especiais. A outra forma é syntax, que funciona muito parecida com a defmacro de Commom Lisp. Juntos essas formas oferecem a possibilidade de criar novas estruturas de controle e definir novas abstrações. A linguagem é poderosa o suficiente para permitir a criação de seus próprios tipo de métodos, por exemplo. Se você não gosta da palavra chave arguments, você pode criar definir um novo tipo de método que não a usa. O DefaultMethod atualmente em Ioke pode ser implementado puramente em Ioke, usando Macros.

InfoQ: Para a sintaxe da Ioke você escolheu seguir os exemplos de Lisp e Smalltalk, ex: uso do espaço. Alguém pode sugerir que isso vai alienar a maioria dos desenvolvedores que estão acostumados a ler e escrever código C-like. Você acha que esse é o caso?

Eu tenho desenvolvido em C, C++ e Java há muito tempo e nunca me senti confortável com isso. A sintaxe é pesada e muitas pessoas antes de mim notaram que isso é um grande obstáculo para abstrações poderosas. As macros sintáticas são muito convenientes quando você tem um AST(Abstract Syntax Tree) que se parece com estas linguagens. A sintaxe é uma grande parte disso, já que é extremamente uniforme.

Então, sim, as pessoas podem achar não natural no começo, mas eu gosto da legibilidade e acho que as pessoas vão gostar deste aspecto. Eu acho que o fato de Ioke ser altamente legível de uma forma que Java não é, por exemplo, não há muitos caracteres de pontuação no seu caminho. Compare Java, Ruby e Ioke:

Arrays.asList("foo", "bar", "quux")
	.map(new Function<String, Pair<String, Int>>(){
		public Pair<String, Int> call(String str){
			return new Pair<String, Int>(str, str.length());
	}}).select ..... // isso vai longe, ok?
	
["foo", "bar", "quux"].map {|str| [str, str.length]}.select {|n|  n[1] > 3}
	
["foo", "bar", "quux"] map(str, [str, str length]) select(second > 3)

A diferença com Ruby não é tão grande assim nesse caso, mas pode chegar a ser muito diferente também. Eu acho que é muito mais fácil ler aplicação de métodos separadas com espaço. Usar pontos para terminar uma expressão também é uma grande diferença.

Bom, como uma pessoa que veio do Lisp, me parece um pouco herege dizer isso, mas a sintaxe é muito importante. Meu objetivo com Ioke é conseguir o mesmo tipo de poder que eu possuo em Lisp e Ruby, mas combinar isso com uma sintaxe agradável, pequena e regular.

Se você está interessado em acompanhar o desenvolvimento de Ioke, você pode fazer isso pelo repositório git do Ola’s, ou visitar a página do projeto.

Você também pode encontrar mais informações sobre Linguagens de Programação, a JVM e Ruby aqui mesmo na InfoQ.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT