Jump to content

V (programming language)

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Hitalinho (talk | contribs) at 12:54, 3 November 2022 (Created page with ''''V''' é uma linguagem de programação de uso geral projetada por Alexander Medvednikov. É inspirada majoritariamente em Golang mas, também, influenciada pelas linguagens: Clang, Rust e Dlang. == Características == A linguagem V apresenta, dentre outras características: ===Safety=== * Verificação de limites * Nenhum valor indefinido (undefined) * Sem sombreamento variável * Variáveis imutáveis por padrão * Estruturas im...'). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)

V é uma linguagem de programação de uso geral projetada por Alexander Medvednikov. É inspirada majoritariamente em Golang mas, também, influenciada pelas linguagens: Clang, Rust e Dlang.

Características

A linguagem V apresenta, dentre outras características:

Safety

  • Verificação de limites
  • Nenhum valor indefinido (undefined)
  • Sem sombreamento variável
  • Variáveis imutáveis por padrão
  • Estruturas imutáveis por padrão
  • Opção/Resultado e verificações de erros obrigatórias
  • Sum types
  • Genéricos
  • Argumentos de função imutáveis por padrão, argumentos mutáveis devem ser marcados na chamada
  • No null (permitido apenas dentro do build-in unsafe)
  • Nenhum comportamento indefinido (wip, algum estouro ainda pode resultar em UB)
  • Nenhuma variável global (pode ser habilitada para aplicativos de baixo nível como kernels por meio de um sinalizador)

Performace

  • Tão rápido quanto C (o backend principal do V compila para C legível por humanos)
  • C interoperabilidade sem custos
  • Quantidade mínima de alocações
  • Serialização integrada sem reflexão de tempo de execução
  • Compila para binários nativos sem dependências: um servidor web simples tem apenas 65 KB

Compilação rápida

V é escrito em V e se compila em menos de um segundo.

Gerenciamento de memória flexível

V evita fazer alocações desnecessárias em primeiro lugar usando tipos de valor, buffers de string, promovendo um estilo de código simples e livre de abstração.

No momento, as alocações são tratadas por um GC mínimo e com bom desempenho até que o motor autofree do V esteja pronto para produção.

Autofree pode ser ativado com -autofree. Ele cuida da maioria dos objetos (~90-100%): o compilador insere chamadas gratuitas necessárias automaticamente durante a compilação. A pequena porcentagem restante de objetos é liberada via GC. O desenvolvedor não precisa alterar nada em seu código. "Simplesmente funciona", como em Python, Go ou Java, exceto que não há GC pesado rastreando tudo ou RC caro para cada objeto.

Para desenvolvedores que desejam ter mais controle de baixo nível, a memória pode ser gerenciada manualmente com a tag -gc none.

A alocação de arena está disponível via v -prealloc.

Tradução para C

V pode traduzir todo o seu projeto C e oferecer a você segurança, simplicidade e agilidade de compilação (via módulos).

Traduzindo DOOM de C para V e construindo-o leva menos de um segundo:

Tradução para Go e para JavaScript já está em desenvolvimento.

Exemplos de Códigos

Olá Mundo

fn main() {
	println('hello world')
}
fn main() {
    areas := ['game', 'web', 'tools', 'science', 'systems', 'embedded', 'drivers', 'GUI', 'mobile']
    for area in areas {
        println('Hello, $area developers!')
    }
}

Structs

struct Point {
	x int
	y int
}

mut p := Point{
	x: 10
	y: 20
}
println(p.x) // Struct fields are accessed using a dot
// Alternative literal syntax for structs with 3 fields or fewer
p = Point{10, 20}
assert p.x == 10

Heap structs

Structs are allocated on the stack. To allocate a struct on the heap and get a reference to it, use the & prefix:

struct Point {
	x int
	y int
}

p := &Point{10, 10}
// References have the same syntax for accessing fields
println(p.x)

Methods

V doesn't have classes, but you can define methods on types. A method is a function with a special receiver argument. The receiver appears in its own argument list between the fn keyword and the method name. Methods must be in the same module as the receiver type.

In this example, the can_register method has a receiver of type User named u. The convention is not to use receiver names like self or this, but a short, preferably one letter long, name.

struct User {
	age int
}

fn (u User) can_register() bool {
	return u.age > 16
}

user := User{
	age: 10
}
println(user.can_register()) // "false"
user2 := User{
	age: 20
}
println(user2.can_register()) // "true"


Error handling

Optional types are for types which may represent none. Result types may represent an error returned from a function.

Option types are declared by prepending ? to the type name: ?Type. Result types use !: !Type.

link

fn do_something(s string) !string {
	if s == 'foo' {
		return 'foo'
	}
	return error('invalid string')
}

a := do_something('foo') or { 'default' } // a will be 'foo'
b := do_something('bar') or { 'default' } // b will be 'default'
c := do_something('bar') or { panic("{err}") } // will return a error with 'invalid string'

println(a)
println(b)

Vweb

link

import vweb

struct App {
    vweb.Context
}

fn main() {
	vweb.run(&App{}, 8080)
}

or

import vweb

struct App {
    vweb.Context
}

fn main() {
	vweb.run_at(new_app(), vweb.RunParams{
	    host: 'localhost'
	    port: 8099
	    family: .ip
	}) or { panic(err) }
}


ORM

V has a built-in ORM (object-relational mapping) which supports SQLite, MySQL and Postgres, but soon it will support MS SQL and Oracle.

V's ORM provides a number of benefits:

  • One syntax for all SQL dialects. (Migrating between databases becomes much easier.)
  • Queries are constructed using V's syntax. (There's no need to learn another syntax.)
  • Safety. (All queries are automatically sanitised to prevent SQL injection.)
  • Compile time checks. (This prevents typos which can only be caught during runtime.)
  • Readability and simplicity. (You don't need to manually parse the results of a query and then manually construct objects from the parsed results.)
import pg

struct Member {
	id         string [default: 'gen_random_uuid()'; primary; sql_type: 'uuid']
	name       string
	created_at string [default: 'CURRENT_TIMESTAMP'; sql_type: 'TIMESTAMP']
}

fn main() {
	db := pg.connect(pg.Config{
		host: 'localhost'
		port: 5432
		user: 'user'
		password: 'password'
		dbname: 'dbname'
	}) or {
		println(err)
		return
	}

	defer {
		db.close()
	}

	sql db {
		create table Member
	}

	new_member := Member{
		name: 'John Doe'
	}

	sql db {
		insert new_member into Member
	}

	selected_member := sql db {
		select from Member where name == 'John Doe' limit 1
	}

	sql db {
		update Member set name = 'Hitalo' where id == selected_member.id
	}
}


Ligações externas