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