Conteúdo


A Linguagem de Programação Blue

Simplicidade e minimalismo

Comments

Como engenheiro de software, sempre fui fascinado pelas linguagens de programação. Sejam elas sua típica linguagem imperativa (como C), uma linguagem funcional (como Scheme), ou uma linguagem orientada a objetos (como Ruby), há algo fascinante sobre a gramática, o design e a implementação das linguagens. Como as linguagens naturais, as linguagens de programação são os meios através dos quais nos comunicamos com as máquinas para especificar nossa intenção. Mas nem todas as linguagens são o mesmo, e cada um fornece formas interessantes e distintas de solucionar os problemas.

Uma das linguagens que fornece um aspecto exclusivo na solução de problemas é a Blue. Blue é uma linguagem orientada a objetos de tipo dinâmico que é também multiparadigma — o que significa que ela suporta paradigmas de múltiplos estilos de linguagens (por exemplo, combinando orientação a objetos com aspectos de linguagem funcional). Isto é útil a partir de uma perspectiva de solução de problemas pois ela permite que você combine estilos, solucionando problemas individuais das formas mais efetivas.

Antes de nos aprofundarmos em uma introdução mais técnica sobre a linguagem Blue, é importante observar que esta dica foca na linguagem de programação Blue desenvolvida por Erik Lechak, não na linguagem de programação Blue desenvolvida na Monash University.

Motivação para a linguagem Blue

Blue é uma linguagem de programação dinâmica com recursos exclusivos. Ela foi projetada como uma linguagem multiparadigmas e mulitplataformas com a uma sintaxe simples e consistente. A Blue é interpretada, mas pode ser compilada para bytecode para desempenho superior. Mas o que é mais impressionanto sobre a linguagem Blue é seu foco no minimalismo. Ela apresenta uma linguagem rica e expressiva com recursos mínimos. Por exemplo, em muitas linguagens, há uma série de formas pelas quais a iteração é implementada. Na linguagem Blue, ignorando a recursão ou mapa (agente iterativo funcional), há uma forma de implementar construções em loop.

Recursos da linguagem

Apesar de uma introdução completa à linguagem Blue não ser possível nesta dica, uma olhada em alguns dos recursos mais notáveis ajudará você a entender melhor a linguagem. Esta seção explora os tipos, as condições, iterações, trapping de erros e as classes, seguida de um par de aplicativos em Blue um pouco maiores para unir os elementos.

Tipos

A linguagem Blue inclui uma série de tipos integrados, incluindo números (que cobrem os tipos de número inteiro e de ponto flutuante), cadeias, arrays, funções e outros. Lembre-se de que a linguagem Blue é do tipo dinâmico, o que significa que você simplesmente associa uma variável a um valor (a definição de variável não é necessária). O exemplo na Listagem 1 ilustra a criação de variáveis de uma variedade de tipos (int, float, string, array e function).

Listagem 1. Criação de variáveis de uma variedade de tipos
x = 9;
y = 3.14159;
s = "esta é uma cadeia";
a = [1, 2, 3, 5, 8];
f = func{ arg name; sys.print( "Olá ", name, "\n" ); };

sys.print( f("Marc") );

sys.attribs( &s ).print();

O última linha emite os atributos para um tipo de cadeia especificado. Este atributos são os atributos de tipo nativo (ou membros) desse tipo. Quando a função attribs for executada sobre o tipo de variável — que é recuperado usando o operador typeof (&), o resultado é:

[replace,repeat,num,ltrim,length,import,endsWith,compile,find,eval,load,print,
substr,rtrim,save,startsWith,split,trim]

Estes métodos devem parecer familiares como métodos de objeto de cadeia típicos. Você também pode usar o método use attribs no próprio objeto (em vez do tipo) que fornece os atributos do próprio objeto.

Condições

Na linguagem Blue, uma condição é uma expressão em vez de uma instrução. Isto significa que você pode usar uma condição no lugar de um valor,o que pode resultar em um código mais simples e mais limpo. Na linguagem Blue, uma condição tem a seguinte forma:

condition ? true-expression ;
condition ? true-expression : false-expression ;

Assim, você começa como uma expressão e fornece uma ou duas opções (caminhos true ou false). São fornecidos dois exemplos na Listagem 2. Nestes casos simples, as expressões são fornecidas, mas elas também podem ser blocos de código (usando chaves) para especificar múltiplas instruções.

Listagem 2. Exemplos de condições
foo = 2;

(foo == 2) ? sys.print("foo é 2\n");

(foo == 1) ? sys.print("foo é 1\n") : sys.print("foo não é 1\n");

Iteração

A linguagem Blue fornece um mecanismo único para looping, que está contido dentro de um bloco de código. Um bloco de código é simplesmente um bloco de código que retorna um valor, e se nenhum valor for retornado, então um objeto NULL é retornado. Um bloco de código é definido como mostrado a seguir.

Listagem 3. Como um bloco de códigos é definido
z = {
  x = 1;
  y = x+3;
  return y;
};

sys.print( z );

Uma iteração é construída a partir deste padrão como mostrado na Listagem 4 (acumulando os número de 10 até 1):

Listagem 4. Exemplo de iteração
sum = 0;
value = 10;

ret = loop {
  sum = sum + value;
  value = value - 1;
  (value == 0) ? return sum;
};

sys.print( ret );

Neste exemplo, o bloco de código é iterado até que o loop seja interrompido através da condição. Mas mesmo com a simplicidade desta construção de loop, você pode construir qualquer loop complexo.

Erros de trapping

A linguagem Blue implementa um sistema de exceção que é semelhante ao da linguagem de programação Java em alguns aspectos, mas com algumas simplificações. Na linguagem Blue, você "gera" uma exceção (comparada ao "throwing" de uma exceção do Java). Você pode "capturar" exceções para gerenciar erros na linguagem Blue com o operador de trap de erro (|). Esta seção fornece alguns exemplos para mostrar como isto funciona.

O uso mais comum da manipulação de exceção é interromper uma função para gerar uma exceção para um responsável pela chamada (que pode ser o responsável pela chamada ou um responsável pela chamada acima da pilha). No exemplo fictício mostrado na Listagem 5, eu valido o argumento passado e, se ele for inválido, eu gero uma exceção. Uma diferença da linguagem Blue é que você pode gerar qualquer objeto como uma exceção. No responsável pela chamada, eu uso o operador de trapping de erro para capturar a exceção. Eu emito um mensagem de erro e, em vez disso, substituo o valor de retorno por 0(lembre-se: cada bloco de código sequencial retorna um objeto).

Listagem 5. Exemplo de manipulação de exceções
z = func {
  arg my_arg;

  (my_arg == 0) ? raise -1;

  return 10 / my_arg;
};

x = z( 0 ) | { sys.print("erro\n"); return 0; };

Outro caso de uso interessante e mais simples para este método é o fornecimento de valores-padrão para argumentos. Você pode usar a linha de código mostrada na Listagem 6 para especificar um valor para um argumento que está ausente. Neste caso, se o usuário chamar a função z sem um argumento, 1 é usado como um valor-padrão.

Listagem 6. Especificando um valor-padrão para um argumento ausente
z = func {
  arg my_arg | 1;

  ...

};

Finalmente, você pode implementar o caso de uso tradicional para manipulação de exceção sobre um bloco de códigos como mostrado na Listagem 7. Este é um caso de uso típico que abrange todo o bloco para o gerenciamento de exceções.

Listagem 7. Manipulação de exceções sobre um bloco de códigos
{
  first_func();
  second_func();
  ...
} | {

  # Gerencia os erros para o bloco

}

Classes

A linguagem Blue também usa uma abordagem claramente minimalista para a programação orientada a objetos. Na linguagem Blue, você pode criar novas classes, herdar de classes ou estender classes. Para criar uma nova classe, eu começo com a função sys.class(). Isso retorna uma nova classe vazia à qual eu posso incluir atributos. A Listagem 8 explora a criação de uma classe de caracteres que poderia ser usada em um RPG (Role-Playing Game) simples. Eu agora posso preencher a nova classe vazia com atributos como os tipos string e number (representando os elementos do caractere), assim como funções comuns para esta classe. Observe que eu forneço três funções: um construtor, um destruidor e uma função de status que emita informações sobre o caracter representado pela instância do objeto.

Listagem 8. Classe do caractere
#
# Classe do caractere
#
Character = sys.class();

Character.name = "";
Character.weapon = "";
Character.hp = 0;

# Construtor
Character._ = func {
    arg name | { name = "anônimo"; };
    arg weapon | { weapon = "varinha"; };
    arg hp | { hp = 10; };

    this.name = name;
    this.weapon = weapon;
    this.hp = hp;
};

# Destruidor
Character.__ = func {
    sys.print( this.name, " está eliminado.\n" );
};

# Método da classe
Character.status = func {
    sys.print( this.name, " (HP ", this.hp, ") empunha um(a) ", this.weapon, ".\n" );
};

Com a classe de caractere completa, eu agora posso criar os objetos de caracteres, como mostrado na Listagem 9. No primeiro caso, eu crio um objeto, char1, e fornece todos os argumentos. No segundo caso, eu não forneço argumentos, assim ele usa os padrões. Finalmente, eu chamo as funções de status para cada um dos objetos.

Listagem 9. Objetos de caractere
char1 = Character( "Ralph", "empunha", 5 );
char2 = Character();

char1.status();
char2.status();

Mas a linguagem Blue é altamente dinâmica, assim você pode anexar objetos depois de criá-los. No exemplo mostrado na Listagem 10, eu incluo uma função greet ao objeto char1. Esta função é específica para char1 e não aparece em nenhuma outra instância da classe Caractere.

Listagem 10. Incluindo uma função greet no objeto char1
char1.greet = func {
    sys.print( this.name, " diz olá.\n" );
};

char1.greet();

del char1.greet();

A saída para este aplicativo, incluindo as três listagens anteriores, é mostrada a seguir.

Listagem 11. Saída para o aplicativo que inclui as Listagens de 8 a 10
$ blue char.bl
Ralph (HP 5) empunha um chicote.
anônimo (HP 10) empunha uma varinha.
Ralph diz olá.

Apesar de não exibido neste exemplo, a linguagem Blue não permite herança. A linguagem Blue permite que você estenda classes dinamicamente e as contrate (ou seja, remova atributos de classe de uma classe estendida).

Exemplo de rede

Esta seção fornece um exemplo da linguagem Blue na forma de um aplicativo de rede. Um dos aspectos mais interessantes das linguagens orientadas a objetos é sua habilidade para prototipar aplicativos em rede rápida e facilmente. A linguagem Blue não é exceção. A linguagem Blue implementa módulos para comportamentos úteis como soquetes, encadeamentos, fluxos (de vários tipos) e mesmo em um analisador XML.

Este exemplo final demonstra um servidor da Web dinâmico simples. Dinâmico significa que as páginas são construídas em tempo de execução em vez de ler o conteúdo do sistema de arquivos. O servidor da Web da linguagem Blue simples é mostrada a seguir.

Listagem 12. Servidor da Web dinâmico simples
#
# Classe de Servidor da Web Dinâmico
#
WebServerClass = sys.class();

WebServerClass.name = "";
WebServerClass.port = 0;

# Construtor
WebServerClass._ = func {

  arg name | { name = "SimpleWebServer"; };
  arg port | { port = 80; };

  this.name = name;
  this.port = port;

  global Stream = sys.library("streams.dll");

};


# Servidor
WebServerClass.server = func {

  server = Stream.listen(this.port);

  loop {

    client = server.accept();

    request = client.read().substr("/", " ");

    sys.print("Pedido: ", request, "\n");

    {

      client.write("<html><head><title>");
      client.write( this.name );
      client.write( "</title></head><body>" );

      ( request.find("status") != 0 ) ? {

          client.write("<h1>O servidor está ativo.</h1>" );

      };

    } | {

      # Manipulador de exceções

      client.write("<h1>Página não localizada.</h1>" );

    };

    client.write("</body></html>");

    client = ();

  };

};


myWebServer = WebServerClass( "MyWebServer", 80 );
myWebServer.server();

O exemplo começa através da criação de uma nova classe chamada WebServerClass. Eu incluo um nome de cadeia e uma variável de classe de porta e, em seguia, duas funções: um construtor e o servidor. Eu uso o construtor para inicializar os argumentos e executar qualquer configuração necessária (como carregamento das bibliotecas de fluxos). A função server então implementa o loop do servidor da Web. Esta função cria um soquete de atendimento na porta definida e aguarda que um servidor se conecte através da função accept.

Quando um cliente se conectar, o servidor HTTP lê o pedido HTTP e fornece uma resposta através do soquete do cliente. O pedido indica o arquivo solicitado e se o arquivo foi testado usando a função find. Se o arquivo de status for solicitado, uma simples mensagem é emitida. Caso contrário, ocorre um trap para find e o manipulador de exceções emite o erro file not found padrão. Quando a saída é concluída, o fluxo é descarregado através da gravação de um objeto NULL no fluxo do cliente e entra em loop aguardando pelo próximo cliente. O fim da listagem mostra como criar e iniciar um objeto WebServerClass.

Status da linguagem

A linguagem és em constante desenvolvimento, com seu release mais recente (V1.75) liberado em abril de 2009. Você pode usar a linguagem Blue no Linux® e Microsoft® Windows®, com suporte para OS X em breve. O Web site da linguagem Blue fornece um fórum para a discussão sobre a linguagem, tarballs atuais e anteriores para instalação e tutoriais sobre recursos de linguagem (consulte Recursos).

Seguindo em frente

A linguagem Blue é interessante e possui uma série de conceitos imprescindíveis. Como muitas das linguagens de script orientadas a objetos (Ruby, Python etc.), ela é fácil de aprender e divertida de usar. Esta classe de linguagem é ideal para prototipagem rápida e teste novas ideias. A linguagem Blue está sob desenvolvimento e tem o potencial de mudar, mas vale a pena conferir.


Recursos para download


Temas relacionados


Comentários

Acesse ou registre-se para adicionar e acompanhar os comentários.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre
ArticleID=457497
ArticleTitle=A Linguagem de Programação Blue
publish-date=12172009