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