nov 2009 10

Logotipo de Linguagem GOAtenção tecnólogos, tem notícia pesada hoje no pedaço. Todas as empresas de tecnologia de grande porte tinham suas linguagens, hoje o Google lança a sua e desde início me parece uma grande promessa.

É uma linguagem de relativo baixo nível, apesar disso terá(ainda não implementado) coletor de lixo, e recursos para parelelismo e concorrência segura de threads. A linguagem traz inovações interessantes como uma espécie de multi-threading “light” onde funções são despachadas para serem executadas paralelamente e canais são criados para “conversar” com essas threads. Tudo pensando em processadores multi-core e computação distribuida. Não há aritmética de ponteiros, o que resolve um dos problemas históricos do C/C++.

E é software livre!

Parabéns ao Google pela iniciativa, é uma notícia e tanto. Confira o site oficial aqui.

Correção 12/11: No post original afirmei que tinha sintaxe baseada em C e Java. Apesar de haverem algumas semelhanças, as diferenças são tantas que achei por bem remover essa afirmação. Acrescentadas algumas informações.

nov 2009 11

Atualmente existem dois compiladores Go:

1) O gccgo, que é um front-end Go para o gcc
2) O gc

gccgo
Durante mais de 3 horas tentei compilar o gccgo sem sucesso. O código não está 100% pois diversas opções de compilação falharam, parece que não foi testado em várias plataformas. A compilação sob Slackware 13 não deu certo e, após dezenas de tentativas, desistí. O gcc não encontrou a opção -ggo para gerar sysinfo.go, os diretórios de include não estavam configurados para puxar os cabeçalhos do kernel, falhando em linux/user.h entre outros. Após hackear diversos arquivos e configurar todos os diretórios a compilação da biblioteca padrão falhou, ou seja, o compilador gccgo funciona mas não conseguí terminar a compilação da biblioteca padrão. Ou seja, de nada servirá.

gc
Partí então para a compilação do gc, que me parece é o compilador recomendado pelo Google.

O único problema na compilação do gc foi durante testes de diversos pacotes, path, net e os (arquivos src/pkg/path/path_test.go src/pkg/os/os_test.go e src/pkg/net/net_test.go). No caso do net, o teste tentou discar através de um modem e falhou, o que era esperado, visto que não tenho modem.

Resolvi o problema na marra, editando
src/pkg/net/net_test.go

func TestDialError(t *testing.T) {
/*
for i, tt := range dialErrorTests {
c, e := Dial(tt.Net, tt.Laddr, tt.Raddr);
if c != nil {
c.Close()
}
if e == nil {
t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern);
continue;
}
s := e.String();
match, _ := regexp.MatchString(tt.Pattern, s);
if !match {
t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
}
}
*/
}

O comentário acima desabilita os testes em net.TestDialError. Será preciso comentar a linha que importa o pacote regex. Como citei, diversos outros testes falharam. Novamente editei os arquivos de testes e comentei o código da função que falhava…. Não é a melhor solução, no entanto o codigo do Go em geral não é para produção, está em fase de testes. Ou seja, desabilitar alguns testes não irá causar um novo desastre em Chernobyl.

Finalmente recebo a mensagem esperada:

--- cd ../test
0 known bugs; 0 unexpected bugs

Os compiladores tem um prefixo diferente para cada plataforma. Para o 386 é 8, para amd64 é 6. No caso, testarei o hello world com o 8g.

root@hendrix:~/go/progs# 8g hello.go
root@hendrix:~/go/progs# ls
hello.8 hello.go
root@hendrix:~/go/progs# 8l hello.8
root@hendrix:~/go/progs# ls
8.out* hello.8 hello.go
root@hendrix:~/go/progs# ./8.out
hello, world
root@hendrix:~/go/progs#

E assim começa a longa jornada para aprender Go e suas bibliotecas.

nov 2009 13

O dia corrido não permitiu um bom estudo da Linguagem Go, no entanto diversas coisas vão ficando mais claras a seu respeito.

Trata-se de uma linguagem muito fácil de usar, não é preciso ter muita preocupação com gerenciamento de memória e o código resultante é bastante legível. Alguns experimentos de iniciante já deram uma boa idéia de como é a rotina de se trabalhar com Go.

Para quem vem do Java ou linguagens da “família” C/C++ a parte mais estranha é acostumar-se com os tipos vindo à direita dos identificadores. Sendo uma linguagem para desenvolvimento em baixo nível, a Go vai contra a tendência atual de linguagens cada vez mais abstratas e mais distantes da máquina. Logo abaixo citaremos o fato curioso da linguagem não possuir classes. Também contrasta com C++ e Java nesse sentido.

Exemplo C:
int a = 19;

Exemplo em Go:
var a int = 19;

Ou a versão simplificada em Go
a:= 19;

Este último utiliza o que chamamos de “duck typing”, invocado através do operador := (comum em Pascal, entre outras). O compilador identifica o 19 como um inteiro e é tratado como tal durante a execução do programa. Contrasta com C e Java onde devemos ser explícitos na declaração de tipos(Java tendo tolerância zero nesse sentido).

O operador := deixa para o compilador a tarefa de descobrir de que tipo é o valor sendo atribuido. Perceba que não foi preciso o uso da palavra-chave var ou especificar o tipo(int).

O que é Duck Typing?
Linguagens que são flexiveis na tipagem normalmente utilizam o que programadores chamam de “duck typing”. A expressão é um tanto inusitada porque vem da cultura popular Inglesa, a frase muito popular que diz “se parece um pato, e anda feito um pato, então deve ser um pato”. Ou seja, se o tipo parece um inteiro, é considerado inteiro até que se use de outra forma. Se parecer texto, é tratado como String, e por aí vai.

Exemplos:
a := 19; // a representará um valor inteiro
b := 19.34; // b representará um float
s := “Caminhando contra o vento”; // String

Outra diferença sutil para Java/C/C++ é o fato de não serem exigidos parenteses na condição dos if. As chaves { e } são obrigatórias em corpos de loops e if’s. Nesse sentido Go se assemelha a Perl, linguagem na qual os parenteses são optativos mas as chaves obrigatórias. Em Go não existem if’s sem chaves.

Exemplo:
if a == b func(); // ilegal

Compilador Pre-Beta
Este é o primeiro software Google aberto ao público em estágio pré-Beta. Ou talvez Alpha… O compilador ainda tem seus errinhos triviais. Não detecta, por exemplo, if’s incondicionais. Ou seja, if’s sem função por ter uma condição constante.

Exemplo:
if true {
// este codigo executa independente da existencia do if()
}

Não é um problema muito sério, mas certamente o compilador deverá identificar esses casos no futuro.

Outro caso em que se revela a imaturidade do compilador é caso de retornos dentro dos dois casos possiveis num if.

Exemplo:
func Teste (i int) {
if (i > 0) {
return true;
} else {
return false;
}
}

Nesse exemplo o compilador não enxerga que a função retorna de uma forma ou de outra, e termina com erro:

teste.go:25: function ends without a return statement

Onde estão os objetos?
Algo interessante mencionado em alguns foruns é que a especificação da linguagem não menciona a palavra “objeto” uma só vez. Isso mesmo: nenhuma menção a objetos! Esse fato não é acidental. A linguagem Go tem como propósito ser bastante simples, “densa” e mantendo o conjunto de regras bem limitado. Contrasta com Java e C++ onde tomos inteiros de regras são precisos para compreender totalmente a linguagem, se é que alguém conhece C++ ou Java por completo.

Descendentes sem herança
Como resultado disso, Go não tem classes e tampouco oferece recurso para hereditariedade de objetos. Em pleno 2009 o fato de uma empresa de ponta como o Google adotar uma linguagem sem objetos e que não implementa palavras da moda como “hereditariedade” é uma ousadia e tanto. Achei excelente essa característica. Há anos que acho a a composição de objetos muito mais adequada que a hereditariedade na maioria dos casos. O mesmo é sugerido no clássico “Design Patterns”[GoF] e outros vários textos sobre Padrões e boas práticas em geral.

private e Public?
Notou o p minúsculo de private? Pois é, mais uma característica da simplicidade de Go: funcs que começam com minúscula são private e podem ser usadas apenas na mesma package. Funções que iniciem com maiuscula são publicas e podem ser chamadas de outros pacotes e programas.

Resolução de dependências – Adeus cabeçalhos
Uma das metas de Go é diminuir o problema de dependências entre cabeçalhos e arquivos-objeto. Em C e C++ existe a eterna rotina de definir estruturas e variáveis em cabeçalhos e implementar suas interfaces em arquivos separados. Usuários dessas bibliotecas, por exemplo, chamam #include “cabecalho.h” e utilizam as funções declaradas em cabecalho.h. Posteriormente o programa é ligado ao arquivo contendo a definição das funções de cabecalho.h. Este modelo tem funcionado há mais de 30 anos, porém sempre foi motivo de problemas.

Go resolve o problema eliminando os cabeçalhos, como já é de praxe em linguagens de alto nivel como Python, Perl, Ruby e Java. É, no entanto, uma novidade para linguagens de relativo baixo nível. Para utilizar funções da biblioteca fmt por exemplo, basta

import "fmt"

Navegando um pouco descobrimos que o código-objeto de fmt está debaixo de $GOROOT/pkg/$GOOS_$GOARCH/ na forma de arquivos .a – típicos de bibliotecas em sistemas UNIX.

Exemplo
import "fmt"
Puxará código-objeto de /root/go/hg/pkg/linux_386/fmt.a

No entanto, não se deixe enganar, a extensão .a não é o que parece. O utilitário ar não reconhece o formato dessas bibliotecas:


O file identifica como archive ar
$file /root/go/hg/pkg/linux_386/rpc.a
/root/go/hg/pkg/linux_386/rpc.a: current ar archive random library

Mas o ar não....
$ ar p /root/go/hg/pkg/linux_386/rpc.a
ar: /root/go/hg/pkg/linux_386/rpc.a: File format not recognized

O interessante aqui é observar que apenas através da variável de ambiente $GOROOT e as variaveis $GOOS e $GOARCH o loader de Go sabe onde achar suas dependências.
No exemplo acima vemos que $GOROOT é = ‘/root/go/hg’, $GOOS = linux e $GOARCH = 386.

Go! ou Go?
Um fato pra lá de controverso tomou conta dos foruns de programadores ontem. O nome Go! já foi utilizado para batizar uma linguagem anterior. A única diferença para a nova linguagem do Google é a exclamação. Diversas hipóteses foram cogitadas. O problema foi levantado no ticket número 9 no sistema de rastreio de problemas do Google, por isso muitos sugeriram batizar a linguagem de “Issue9″, pois ela tem suas raízes no sistema operacional Plan 9…. A solução não foi divulgada, no entanto tudo indica que o autor da linguagem Go! será sumariamente ignorado pelo Google.

Procuram-se programadores “experientes” em Go
A curiosidade do dia ficou por conta da rápida propagação da onda de programação em Go (nada a ver com a outra Wave). No StackOverflow já havia alguém buscando contratar um programador “com longa experiência em programação Go para a Web”. .

[GoF]

jul 2010 06

A seção sobre a linguagem Go ficou congelada um bom tempo. O motivo foi a falta de tempo e, confesso, um certo “desencanto” com a linguagem. Trata-se de um projeto experimental do Google, e ainda precisa amadurecer bastante.

No ritmo de trabalho típico de um desenvolvedor, torna-se impossível acompanhar novas linguagens experimentais e, ao mesmo tempo, produzir no ritmo exigido pelos projetos em andamento.

Espero poder voltar a estudar Go em breve, e que esta interessante linguagem encontre um nicho onde seja aproveitada. Por enquanto, esta seção do blog ficará congelada.