Initial commit
parent
825419003a
commit
8dd6fb1766
|
@ -0,0 +1,2 @@
|
|||
*.v linguist-language=Go
|
||||
website/* linguist-vendored
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 Alexander Medvednikov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
82
README.md
82
README.md
|
@ -1,3 +1,81 @@
|
|||
# Official V repository
|
||||
# The V Programming Language
|
||||
|
||||
V is going to be open-sourced in mid 2019.
|
||||
V is going to be open-sourced in June 2019. Early access on April 15.
|
||||
|
||||
https://vlang.io
|
||||
|
||||
Documentation: https://vlang.io/docs
|
||||
|
||||
Twitter: https://twitter.com/vlang_io
|
||||
|
||||
|
||||
|
||||
|
||||
## Fast compilation
|
||||
V compiles 1.5 million lines of code per second per CPU core
|
||||
```
|
||||
cd doom3/
|
||||
wc -l doom3.v # 458 713
|
||||
time v doom3.v # 0.5s
|
||||
```
|
||||
[Compilation speed benchmark and comparison with other languages.](https://vlang.io/compilation_speed)
|
||||
|
||||
## Safety
|
||||
- No global state
|
||||
- No null
|
||||
- No undefined values
|
||||
- Option types
|
||||
- Generics
|
||||
- Immutability by default
|
||||
- Partially pure functions
|
||||
|
||||
## C/C++ translation
|
||||
V can translate your entire C/C++ project and offer you the safety, simplicity, and up to 200x compilation speed up.
|
||||
```
|
||||
std::vector<std::string> s;
|
||||
s.push_back("V is ");
|
||||
s.push_back("awesome");
|
||||
std::cout << s.size();
|
||||
```
|
||||
```
|
||||
s := []string
|
||||
s << 'V is '
|
||||
s << 'awesome'
|
||||
println(s.len)
|
||||
```
|
||||
Read about translating Doom & Doom 3, LevelDB, SQLite (coming in March).
|
||||
|
||||
## 400 KB compiler with zero dependencies
|
||||
The entire V language and its standard library is less than 400 KB. You can build V in 0.3 seconds.
|
||||
|
||||
|
||||
## Performance
|
||||
- As fast as C
|
||||
- Minimal amount of allocations
|
||||
- Built-in serialization without reflection
|
||||
|
||||
## Hot code reloading
|
||||
Get your changes instantly without recompiling!
|
||||
|
||||
Since you also don't have to waste time to get to the state you are working on after every compilation, this can save a lot of precious minutes of your development time.
|
||||
|
||||
[Demonstration of hot code reloading.](https://volt-app.com/img/lang.webm)
|
||||
|
||||
## Simple language for building maintainable programs
|
||||
You can learn the entire language by going through the documentation in half an hour.
|
||||
|
||||
Despite being simple, it gives a lot of power to the developer. Anything you can do in other languages, you can do in V.
|
||||
|
||||
## REPL
|
||||
```
|
||||
v
|
||||
>> data := http.get('https://vlang.io/utc_now')?
|
||||
>> data
|
||||
'1551205308'
|
||||
```
|
||||
|
||||
## Native cross platform UI library
|
||||
Build native apps that look native. You no longer need to embed a browser to develop cross platform apps quickly.
|
||||
|
||||
## Run everywhere
|
||||
V can compile to (human readable) C, so you get the great platform support and optimization of gcc and Clang.
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
module base64
|
||||
|
||||
const (
|
||||
INDEX = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
|
||||
47, 48, 49, 50, 51]
|
||||
)
|
||||
|
||||
fn decode(data string) string {
|
||||
p := data.str
|
||||
len := data.len
|
||||
mut pad := 0
|
||||
if len > 0 && (len % 4 != 0 || p[len - 1] == `=`) {
|
||||
pad = 1
|
||||
}
|
||||
L := ((len + 3) / 4 - pad) * 4
|
||||
str_len := L / 4 * 3 + pad
|
||||
mut str := malloc(str_len + 2)
|
||||
mut j := 0
|
||||
for i := 0; i < L; i += 4 {
|
||||
n := (INDEX[p[i]] << 18) | (INDEX[p[i + 1]] << 12) |
|
||||
(INDEX[p[i + 2]] << 6) | (INDEX[p[i + 3]])
|
||||
str[j] = n >> 16
|
||||
j++
|
||||
str[j] = n >> 8 & 0xff
|
||||
j++
|
||||
str[j] = n & 0xff
|
||||
j++
|
||||
}
|
||||
if pad > 0 {
|
||||
mut nn := (INDEX[p[L]] << 18) | (INDEX[p[L + 1]] << 12)
|
||||
str[str_len - 1] = nn >> 16
|
||||
if len > L + 2 && p[L + 2] != `=` {
|
||||
nn = nn | (INDEX[p[L + 2]] << 6)
|
||||
str[str_len] = nn >> 8 & 0xff
|
||||
}
|
||||
}
|
||||
str[str_len + 1] = `\0`
|
||||
return string(str)
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import base64
|
||||
|
||||
fn test_decode() {
|
||||
assert base64.decode('TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=')
|
||||
== 'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.'
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Please share your thoughts, suggestions, questions, etc here:
|
||||
// https://github.com/vlang-io/V/issues/3
|
||||
// I'm very interested in your feedback.
|
||||
import http
|
||||
import json
|
||||
import runtime
|
||||
|
||||
struct Story {
|
||||
title string
|
||||
}
|
||||
|
||||
// Fetches top HN stories in 8 coroutines
|
||||
fn main() {
|
||||
resp := http.get('https://hacker-news.firebaseio.com/v0/topstories.json')?
|
||||
ids := json.decode([]int, resp.body)?
|
||||
mut cursor := 0
|
||||
for _ in 0..8 {
|
||||
go fn() {
|
||||
for {
|
||||
lock { // Without this lock the program will not compile
|
||||
if cursor >= ids.len {
|
||||
break
|
||||
}
|
||||
id := ids[cursor]
|
||||
cursor++
|
||||
}
|
||||
url := 'https://hacker-news.firebaseio.com/v0/item/$id.json'
|
||||
resp := http.get(url)?
|
||||
story := json.decode(Story, resp.body)?
|
||||
println(story.title)
|
||||
}
|
||||
}()
|
||||
}
|
||||
runtime.wait() // Waits for all coroutines to finish
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// Please share your thoughts, suggestions, questions, etc here:
|
||||
// https://github.com/vlang-io/V/issues/3
|
||||
|
||||
// I'm very interested in your feedback.
|
||||
|
||||
module main
|
||||
|
||||
struct User { /* ... */ }
|
||||
struct Post { /* ... */ }
|
||||
struct DB { /* ... */ }
|
||||
|
||||
struct Repo <T> {
|
||||
db DB
|
||||
}
|
||||
|
||||
// Generic code is notoriously verbose. To reduce clutter, V doesn't require you
|
||||
// to add `<T>` every time, since it already knows that Repo is a generic type.
|
||||
fn new_repo<T>(db DB) Repo {
|
||||
return Repo<T>{db: db}
|
||||
}
|
||||
|
||||
// This is a generic function. V will generate it for every type it's used with.
|
||||
fn (r Repo) find_by_id(id int) T? { // `?` means the function returns an optional
|
||||
table_name := T.name // in this example getting the name of the type gives us the table name
|
||||
return r.db.query_one<T>('select * from $table_name where id = ?', id)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
db := new_db()
|
||||
users_repo := new_repo<User>(db)
|
||||
// I'm also considering passing the type as an argument
|
||||
// users_repo := new_repo(User, db)
|
||||
posts_repo := new_repo<Post>(db)
|
||||
user := users_repo.find_by_id(1) or {
|
||||
eprintln('User not found')
|
||||
return
|
||||
}
|
||||
post := posts_repo.find_by_id(1) or {
|
||||
eprintln('Post not found')
|
||||
return
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// Please share your thoughts, suggestions, questions, etc here:
|
||||
// https://github.com/vlang-io/V/issues/3
|
||||
|
||||
// I'm very interested in your feedback.
|
||||
|
||||
module main
|
||||
|
||||
import ui // Native cross platform ui toolkit (uses Cocoa, win32, GTK+)
|
||||
|
||||
// There are no globals, so we have to use a context struct
|
||||
struct Context {
|
||||
input ui.TextBox // this uses native controls (NSTextView on macOS, edit HWND on Windows)
|
||||
names []string // let's log the names to demonstrate how arrays work
|
||||
}
|
||||
|
||||
fn main() {
|
||||
wnd := ui.new_window(ui.WindowCfg{ // V has no default arguments and overloading.
|
||||
width: 600 // All stdlib functions with many args use Cfg wrappers.
|
||||
height: 300
|
||||
title: 'hello world'
|
||||
})
|
||||
ctx := Context{
|
||||
input: ui.new_textbox(wnd)
|
||||
// we don't need to initialize the names array, it's done automatically
|
||||
}
|
||||
ctx.input.set_placeholder('Enter your name')
|
||||
btn := ui.new_button(wnd, 'Click me', ctx.btn_click)
|
||||
for {
|
||||
ui.wait_events()
|
||||
}
|
||||
}
|
||||
|
||||
fn (ctx mut Context) btn_click() {
|
||||
name := ctx.input.text()
|
||||
ctx.input.hide()
|
||||
println('current list of names: $ctx.names') // >> current list of names: [ "Bob", "Alex" ]
|
||||
ui.alert('Hello, $name!')
|
||||
if ctx.names.contains(name) {
|
||||
ui.alert('I already greeted you ;)')
|
||||
}
|
||||
ctx.names << name
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
// Please share your thoughts, suggestions, questions, etc here:
|
||||
// https://github.com/vlang-io/V/issues/3
|
||||
|
||||
// I'm very interested in your feedback.
|
||||
|
||||
module main
|
||||
|
||||
import json // V will automatically insert missing imports (like the goimports tool)
|
||||
import http
|
||||
|
||||
// Right now V requires all consts to be uppercase.
|
||||
// I'm still not certain about this.
|
||||
const API_URL = 'https://vlang.io/users.json'
|
||||
|
||||
// V will generate json.encode and json.decode functions for this type since
|
||||
// `json.decode([]User, ...)` is called later. This results in better
|
||||
// performance, since reflection is not used.
|
||||
struct User {
|
||||
name string // V will automatically format and align your code.
|
||||
age int // No need to use an additional tool.
|
||||
is_registered bool
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// `http.get()` returns an optional string.
|
||||
// V optionals combine the features of Rust's Option<T> and Result<T>.
|
||||
// We must unwrap all optionals with `or`, otherwise V will complain.
|
||||
s := http.get(API_URL) or {
|
||||
// `err` is a reserved variable (not a global) that
|
||||
// contains an error message if there is one
|
||||
eprintln('Failed to fetch "users.json": $err')
|
||||
// `or` blocks must end with `return`, `break`, or `continue`
|
||||
return
|
||||
}
|
||||
// Types can be passed as arguments
|
||||
users := json.decode([]User, s) or {
|
||||
eprintln('Failed to parse users.json')
|
||||
return
|
||||
}
|
||||
// Encoding JSON doesn't require a type, since V knows what type
|
||||
// the variable `users` has
|
||||
println(json.encode(users))
|
||||
// Please note the difference between V and Go:
|
||||
// when there's only one variable, it's a value, not an index.
|
||||
for user in users {
|
||||
println('$user.name: $user.age')
|
||||
}
|
||||
// `for` loop has an alternative form when an index is required:
|
||||
for i, user in users {
|
||||
println('$i) $user')
|
||||
if !user.can_register() {
|
||||
// V allows both ' and " to denote strings.
|
||||
// However, for consistency V will replace " with '
|
||||
// unless the string contains an apostrophe.
|
||||
println("Can't register")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The method declaration is the same as in Go.
|
||||
// There is one big difference. Here `u` can be either passed by value (User)
|
||||
// or by reference (&User). The compiler will make the right decision
|
||||
// depending on the size of the User struct. You no longer have to remember
|
||||
// which one to use. It works here because `u` can't be modified (it's not
|
||||
// marked as `mut`).
|
||||
fn (u User) can_register() bool {
|
||||
return u.age >= 16
|
||||
}
|
||||
|
||||
// Here `u` can be modified and it will always be a reference.
|
||||
fn (u mut User) register() {
|
||||
u.is_registered = true
|
||||
}
|
Loading…
Reference in New Issue