Linguagem de programação V

A Linguagem de Programação V

Este artigo apresenta uma visão geral da linguagem de programação V (VLANG)


Antes de falarmos sobre as características da linguagem, é bom avisar que, até o momento em que estou escrevendo esse artigo (Julho/2020), a linguagem V ainda não  tinha um release oficial e, portanto, ainda não estava preparada para ser usada em ambientes de produção. Além disso sua documentação é escassa e incompleta.

Trata-se de uma linguagem de uso geral, com foco em desenvolvimento de sistemas back end, infraestrutura, bancos de dados, aplicações WEB e gráficas.

Histórico e Características

A linguagem V está sendo desenvolvida por Alexander Medvednikov e uma comunidade de programadores no GITHUB, e pode-se dizer que é uma mistura entre GOLANG e RUST.
Vejamos algumas de suas características:

    • Sintaxe GO like;
    • Estaticamente compilada, mas com inferência de tipos;
    • Variáveis imutáveis por padrão;
    • Generics;
    • Pointers e unsafe blocks;
    • Funções com múltiplos valores de retorno;
    • Limpeza da memória na compilação, sem garbage collection no estilo de Rust;
    • Concorrência no estilo de GO

Vamos explorar alguns aspectos da linguagem…

Instalação

Mais simples, impossível:

    1. Baixar o zip do site oficial e descompactar.
    2. Configurar o PATH para a pasta raiz da instalação
    3. Configurar a IDE  Visual Studio Code com a extensão V.

Alô Mundo

// Primeiro programa V
fn main() {
    println('hello world')
}

Observações:

    1. Assim como em GO, os separadores de comando (ponto e vírgula) não são necessários;
    2. Parecido com RUST, as funções iniciam com a palavra reservada fn;
    3. Do mesmo modo como em GO, a função main é um entry point. No entanto, a declaração do pacote não é obrigatória;
    4. Diferente de GO, a função println é embutida;
    5. A declaração da função main pode ser omitida caso se trate de um programa de um arquivo só, tipo um script. Dessa forma,  o nosso programa “Alô Mundo” se resumiria à uma única linha.

Para compilar e executar o programa alo.v:

<span style="color: #00ff00;"><span style="font-size: 18pt;">v run alo.v</span></span>

Tipos de dados

Os principais tipos de dados primitivos em V são:

    • Valores booleanos true e false: bool;
    • Inteiros com sinal: i8, i16, int e i64;
    • Inteiros sem sinal: byte, u16, u32 e u64
    • Caracteres unicode : rune
    • Ponto flutuantes: f32 e f64

A principal diferença aqui é que o tipo int é sempre de 32 bits, independe do hardware.

Variáveis

Aqui começam algumas diferenças em relação às outras linguagens. Vejamos:

    • Variáveis em V são imutáveis por padrão, a não ser que você use o modificador mut.
    • Variáveis sempre possuem um valor, não existe null, nil, etc.
    • Variáveis são declaradas por inferência, sempre;
    • Não existe escopo global. A declaração tem que ser somente dentro das funções;
    • Não existe shadowing: nomes de variáveis não podem se repetir em blocos internos .

O design de V é baseado em parte na premissa “só existe uma forma de fazer isso”, então a declaração de variáveis só pode ser feita através da inicialização com o operador “:=“.

Veja um exemplo com comentários:

v := 1 // Erro de compilação - não existem variáveis globais
fn main() {
  mut a := 10 // Válido - a variável 'a' será do tipo int
  mut b := 1.5 // Válido - a variável 'b' será do tipo f64 
  c := a + b // Válido - a variável 'c' será do tipo f64
  c = 1.5 // Erro de compilação - a variável 'c' não é mutável
  println($a $b $c) // Válido vai imprimir os valores de 'a','b' e 'c'
  {
    d := 5 // Válido - a variável 'd' será do tipo int
    a := 1 // Erro de compilação - shadowing não permitido
  }
}

Observações:

  • Veja que a variável c da linha 5 é a soma de um float com um int. Aqui foi feito um cast automático, diferente de GO, que daria um erro de compilação. Mas veja que o cast automático não é feito em todas as situações.
  • Um ponto interessante da função println é que ela aceita um único argumento do tipo string. As variáveis podem ser impressas através de placeholders com prefixo $ que lembram um pouco o PHP.

Estruturas de controle

A estrutura condicional IF em V é parecida com a linguagem GO, mas diferentemente de C, os parênteses nas condições não são necessários e as chaves são obrigatórias:

fn main() {
	v := 0
	if v < 0 {
		println("O número $v é negativo")
	} else if v > 0 {
		println("O número $v é positivo")
	} else {
		println("O número $v é neutro")
	}
}
fn main() {
	
	idade := 11
	v := (if idade > 17 {
		'Maior de idade'
	} else {
		'Menor de idade'
	})
  println(v) // Vai imprimir: Menor de idade
}

A estrutura match é semelhante ao switch de GO:

fn main() {
  uf := 'sp'
  match uf {
    'sp' { println('São Paulo') }
    'mg' { println('Minas Gerais') }
    'rg' { println('Rio de Janeiro') }
    'es' { println('Espírito Santo') }
   else { println('Outras regiões') }
  }
}

A estrutura de repetição FOR segue o mesmo padrão de GO, com vários sabores:

for i := 0; i < 10; i++ {
  // Pula o número 3
  if i == 3 {
      continue
  }
  // Para no número 7
  if i > 7 {
    break
  }
  println(i)
}
fn main() {
  mut pares := [0, 2, 4, 6, 8, 10]
  for i, v in pares {
    println('Índice = $i, valor = $v')
  }
}
for i in 0..10 {
    print(i)
}

Estruturas de Dados

As estruturas de dados básicas em V são:

    • Strings: Cadeia imutável de caracteres unicode. Internamente, array de bytes
    • Arrays: Coleção de dados indexados do mesmo tipo de tamanho variável
    • Maps: Coleção de pares key-value
    • Structs: Conjunto de variáveis de tipos diferentes agrupadas logicamente

Vejamos alguns exemplos:

fn main() {
  nome := 'João'
  println('Alô, $nome!')
  println(nome.len) 
  nomecompleto := nome + ' Silva'
  println(nomecompleto[0..3]) 
}
fn main() {
  mut numeros := []int{} // Criação de array vazio
  numeros << 5 // adicionou elemento 5
  println(numeros)  //[5]
  println(numeros[0]) // 5
  numeros[0] = 1 
  println(numeros) //[1]
  println(numeros.len) // 1
  numeros << [2,3,4] // adicionou 2,3,e 4
  println(numeros) // [1,2,3,4]
  numeros.delete(1) // deletou elemento de índice 1
  println(numeros) //[1,3,4]
  println(3 in numeros) // true
}
fn main() {
  mut uf := map[string]string 
  uf['sp'] = 'São Paulo'
  uf['rj'] = 'Rio de Janeiro' 
  println(uf['sp']) // "São Paulo"
  println(uf['mg']) // "0"
  println('sp' in uf) // true
  uf.delete('rj')
  println(uf) // {'sp': 'São Paulo', '': ''}
}

Funções

Vamos ver alguns exemplos de funções:

fn div(n1, n2 f64) (bool, f64) {
  mut err := false
  mut ret := 0.0
  if n2 == 0{
    err = true
  } else {
    ret = n1 / n2
  }
  return err,ret
}

fn main() {
  e,r := div(6,2)
  println("$e $r")
}
fn produto_escalar(n f64, mut vetor [] f64) {
  for i in 0..vetor.len {
    vetor[i] *= 2
  }
}

fn main() {
  mut nums := [1.0, 2.0, 3.0]
  produto_escalar(4, mut nums)
  println(nums) // "[4.0, 8.0, 12.0]"
}

Outras características

    • Para efeitos de modularização, V trabalha com packages de forma parecida com outras linguagens. Ele vem com um gerenciador de pacotes tipo NodeJS que facilita a instalação das aplicações.
    • Para que um membro de um pacote seja exportável, ou seja, visível em outros pacotes, existe o modificador pub, ao contrário de GO que faz isso através de letras capitalizadas. Na minha opinião essa abordagem de V para membros públicos é mais clara que em GO.
    • A V standard library (vlib) já possui um número considerável de pacotes e está em fase de crescimento.
    • V possui uma biblioteca GUI nativa com controles nativos e uma biblioteca gráfica de plataforma cruzada compatível com OpenGL. Veja aqui um port de DOOM em V.

Conclusões

Pelo exposto, percebemos que a linguagem V, pelas suas características de segurança, rapidez, e facilidade de uso é muito promissora.
Neste artigo oferecemos apenas uma pequena visão da linguagem. Para saber mais, consulte as seguintes referências:

Até mais!

 

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *