ci: separate workflow for docs line len check (#6653)

pull/6659/head
Lukas Neubert 2020-10-20 20:14:56 +02:00 committed by GitHub
parent 5c93f942be
commit d881185d79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 194 additions and 103 deletions

View File

@ -1,7 +1,16 @@
name: CI name: CI
on: [push, pull_request]
jobs:
on:
push:
paths-ignore:
- "doc/**"
- "CHANGELOG.md"
pull_request:
paths-ignore:
- "doc/**"
- "CHANGELOG.md"
jobs:
code-formatting: code-formatting:
runs-on: ubuntu-18.04 runs-on: ubuntu-18.04
env: env:
@ -461,15 +470,6 @@ jobs:
# - name: v2 self compilation # - name: v2 self compilation
# run: .\v.exe -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v # run: .\v.exe -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v
docs-line-len-check:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Build
run: make
- name: Check docs line length
run: ./v run cmd/tools/check-md.v doc/docs.md CHANGELOG.md
compilable-v-c-and-v-win-c: compilable-v-c-and-v-win-c:
runs-on: ubuntu-latest runs-on: ubuntu-latest

23
.github/workflows/docs_ci.yml vendored 100644
View File

@ -0,0 +1,23 @@
name: Docs CI
on:
push:
paths:
- "cmd/tools/check-md.v"
- "doc/**"
- "CHANGELOG.md"
pull_request:
paths:
- "cmd/tools/check-md.v"
- "doc/**"
- "CHANGELOG.md"
jobs:
docs-line-len-check:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Build V
run: make
- name: Check docs line length
run: ./v run cmd/tools/check-md.v doc/docs.md doc/upcoming.md CHANGELOG.md

View File

@ -1,7 +1,8 @@
## V 0.1.27 ## V 0.1.27
*5 May 2020* *5 May 2020*
- vfmt has been re-written from scratch using the new AST parser. It's much faster, cleaner, and can format - vfmt has been re-written from scratch using the new AST parser.
It's much faster, cleaner, and can format
files with compilation errors. files with compilation errors.
- `strconv`, `sprintf`, and `printf` in native V, without any libc calls. - `strconv`, `sprintf`, and `printf` in native V, without any libc calls.
- Interfaces are now a lot more stable and have all expected features. - Interfaces are now a lot more stable and have all expected features.
@ -10,13 +11,13 @@ files with compilation errors.
- New `[]int{cap:cap, len:len}` syntax for initializing array length and capacity. - New `[]int{cap:cap, len:len}` syntax for initializing array length and capacity.
- New `is` keyword for checking the type of sum types and interfaces. - New `is` keyword for checking the type of sum types and interfaces.
- `as` can now be used to cast interfaces and sum types. - `as` can now be used to cast interfaces and sum types.
- Profiling with `-profile`. Prints a nice table with detailed information about every single function call: - Profiling with `-profile`. Prints a nice table with details about every single function call:
number of calls, average time per call, total time per function. number of calls, average time per call, total time per function
- `import(xxx)` syntax has been removed in favor of `import xxx` for simplicity and greppability. - `import(xxx)` syntax has been removed in favor of `import xxx` for simplicity and greppability.
- Lots of fixes and improvements in the type checker. - Lots of fixes and improvements in the type checker.
- `time.StopWatch` - `time.StopWatch`
- `dl` module for dynamic loading. - `dl` module for dynamic loading.
- Automatic `str()` method generation for every single type, including all arrays and fixed size arrays. - Automatic `str()` method generation for every single type, including all arrays.
- Short struct initialization syntax for imitating named function args: `foo(bar:0, baz:1)`. - Short struct initialization syntax for imitating named function args: `foo(bar:0, baz:1)`.
- New operator `!in`. - New operator `!in`.
- Performance improvements in critical parts of the builtin data structures (array, map). - Performance improvements in critical parts of the builtin data structures (array, map).
@ -37,13 +38,15 @@ number of calls, average time per call, total time per function.
## V 0.1.25 ## V 0.1.25
*1 Apr 2020* *1 Apr 2020*
- The entire compiler has been re-written with an AST parser. The code is now a lot cleaner and more maintainable. ~15k lines of old compiler code were removed. - The entire compiler has been re-written with an AST parser.
The code is now a lot cleaner and more maintainable.
~15k lines of old compiler code were removed.
## V 0.1.24 ## V 0.1.24
*31 Dec 2019* *31 Dec 2019*
- A new parser/generator built on top of an AST that simplifies code greatly and allows to implement new - A new parser/generator built on top of an AST that simplifies code greatly
backends much faster. and allows to implement new backends much faster.
- Sum types (`type Expr = IfExpr | MatchExpr | IntegerLiteral`). - Sum types (`type Expr = IfExpr | MatchExpr | IntegerLiteral`).
- B-tree map (sped up the V compiler by ~10%). - B-tree map (sped up the V compiler by ~10%).
- `v fmt -w`. - `v fmt -w`.
@ -54,7 +57,7 @@ number of calls, average time per call, total time per function.
- os: `is_link()`, `is_dir()`, `exists()`. - os: `is_link()`, `is_dir()`, `exists()`.
- Ranging through fixed size arrays. - Ranging through fixed size arrays.
- Lots of fixes in ORM and vweb. - Lots of fixes in ORM and vweb.
- The first tutorial: [building a simple web application with vweb](https://github.com/vlang/v/blob/master/tutorials/building-a-simple-web-blog-with-vweb.md). - The first tutorial: [building a simple web application with vweb](https://github.com/vlang/v/blob/master/tutorials/building-a-simple-web-blog-with-vweb.md)
- Match expressions now must be exhaustive. - Match expressions now must be exhaustive.
- freestanding: `malloc()`/`free()`. - freestanding: `malloc()`/`free()`.
- `++` is now required instead of `+= 1` for consistency. - `++` is now required instead of `+= 1` for consistency.
@ -76,13 +79,14 @@ number of calls, average time per call, total time per function.
## V 0.1.23 ## V 0.1.23
*30 Nov 2019* *30 Nov 2019*
- [Direct x64 machine code generation](https://github.com/vlang/v/issues/2849). Hello world being built in 3 milliseconds. - [Direct x64 machine code generation](https://github.com/vlang/v/issues/2849).
- Bare metal support via the `-freestanding` flag, allowing to build programs without linking to libc. Hello world being built in 3 milliseconds.
- Bare metal support via the `-freestanding` flag, to build programs without linking to libc.
- Prebuilt V packages for Linux, macOS, and Windows. - Prebuilt V packages for Linux, macOS, and Windows.
- `string.index()` now returns `?int` instead of `int/-1`. - `string.index()` now returns `?int` instead of `int/-1`.
- Lots of fixes in Generics. - Lots of fixes in Generics.
- vweb framework for developing web applications is back. - vweb framework for developing web applications is back.
- Vorum, the forum/blogging software written in V/vweb, can now be compiled and has been added to CI. - Vorum, the forum/blogging software written in vweb, can now be compiled and has been added to CI.
- REPL, `v up` have been split up into separate applications to keep the core V compiler small. - REPL, `v up` have been split up into separate applications to keep the core V compiler small.
- V now enforces short enum syntax (`.green` instead of `Color.green`) when it's enough. - V now enforces short enum syntax (`.green` instead of `Color.green`) when it's enough.
- V UI for macOS. - V UI for macOS.
@ -90,7 +94,8 @@ number of calls, average time per call, total time per function.
- `os.cp()` for copying files and directores. - `os.cp()` for copying files and directores.
- Additional compile-time flags: `$if clang, msvc, mingw, x32, x64, big_endian, little_endian {`. - Additional compile-time flags: `$if clang, msvc, mingw, x32, x64, big_endian, little_endian {`.
- All C functions now have to be declared, all missing C functions have been defined. - All C functions now have to be declared, all missing C functions have been defined.
- Global variables (only with the `--enable-globals` flag) for low level applications like kernels and drivers. - Global variables (only with the `--enable-globals` flag)
for low level applications like kernels and drivers.
- Nothing can be cast to bool (previously code like `if bool(1) {` worked). - Nothing can be cast to bool (previously code like `if bool(1) {` worked).
- `<<` and `>>` now work with all integer types. - `<<` and `>>` now work with all integer types.
- V detects Cygwin and shows an error (V supports Windows natively). - V detects Cygwin and shows an error (V supports Windows natively).
@ -116,7 +121,7 @@ number of calls, average time per call, total time per function.
- `malloc/free` on bare metal. - `malloc/free` on bare metal.
- `utf8` helper functions (`to_lower()`, `to_upper()`, etc). - `utf8` helper functions (`to_lower()`, `to_upper()`, etc).
- Optimization of `for c in str {`. - Optimization of `for c in str {`.
- `string/array.left/right/slice/substr` were removed (`[a..b]` slicing syntax should be used instead). - `string/array.left/right/slice/substr` were removed (use `[a..b]` slicing syntax instead).
@ -128,8 +133,7 @@ number of calls, average time per call, total time per function.
- Optimized `array.filter()` and `array.map()`. - Optimized `array.filter()` and `array.map()`.
- `sqlite` module. - `sqlite` module.
- Cached modules for faster compilation. - Cached modules for faster compilation.
- Dramatic compilation optimizations: [V now compiles itself in - Dramatic compilation optimizations: [V now compiles itself in 0.10 - 0.30 seconds](https://github.com/vlang/v/wiki/The-V-language-now-compiles-itself-in-0.09-seconds)
0.10 - 0.30 seconds](https://github.com/vlang/v/wiki/The-V-language-now-compiles-itself-in-0.09-seconds).
- V scripts (simpler and cross-platform alternative to Bash). - V scripts (simpler and cross-platform alternative to Bash).
- Infinite multi-dimensional arrays (`[][][]int`). - Infinite multi-dimensional arrays (`[][][]int`).
- `unsafe`. - `unsafe`.
@ -296,7 +300,7 @@ this backend.
## V 0.1.15 ## V 0.1.15
*15 Jul 2019* *15 Jul 2019*
- FreeBSD, OpenBSD, NetBSD, DragonFly support. - FreeBSD, OpenBSD, NetBSD, DragonFly support.
- Hot code reloading now works with graphical applications: [bounce.v](https://github.com/vlang/v/blob/master/examples/hot_code_reloading/bounce.v). - Hot reloading now works with graphical applications: [bounce.v](examples/hot_reload/bounce.v)
- VROOT was removed, the installation process is now much simpler. - VROOT was removed, the installation process is now much simpler.
- `defer` statement. - `defer` statement.
- map.v was re-written. It's now much faster. - map.v was re-written. It's now much faster.
@ -310,7 +314,7 @@ this backend.
## V 0.1.14 ## V 0.1.14
*12 Jul 2019* *12 Jul 2019*
- `gg` module Windows support, V Tetris runs on Windows. - `gg` module Windows support, V Tetris runs on Windows.
- `glad` and `cJSON` are now compiled only once, this makes compilation of programs using `gg` and `json` a bit faster. - Compile `glad` and `cJSON` only once. Programs using `gg` or `json` compile a bit faster.
- `v.c` has been cleaned up and minimized (~16k => ~10k lines of code). - `v.c` has been cleaned up and minimized (~16k => ~10k lines of code).
- `type` aliases can now have methods. - `type` aliases can now have methods.
- Const overflow check during compilation (`byte(1000)` will no longer compile). - Const overflow check during compilation (`byte(1000)` will no longer compile).
@ -332,8 +336,10 @@ this backend.
## V 0.1.12 ## V 0.1.12
*4 Jul 2019* *4 Jul 2019*
- V can finally compile itself on Windows (https://github.com/vlang/v#mingw-w64). - V can finally compile itself on Windows (https://github.com/vlang/v#mingw-w64).
- `os` module now uses optionals in all functions that return `File`. Lots of bugs with optionals fixed. - `os` module now uses optionals in all functions that return `File`.
- `println` was optimized. It no longer results in allocations. Now it also works correctly with all integer types. - Lots of bugs with optionals were fixed.
- `println` was optimized. It no longer results in allocations.
Now it also works correctly with all integer types.
- Lots of `vfmt` fixes, it will be enabled tomorrow. - Lots of `vfmt` fixes, it will be enabled tomorrow.
- New `strings` module. - New `strings` module.
- Lots of other fixes and improvements, thanks to all the contributors. - Lots of other fixes and improvements, thanks to all the contributors.

View File

@ -8,23 +8,36 @@ const (
fn main() { fn main() {
files_paths := os.args[1..] files_paths := os.args[1..]
mut warnings := 0
mut errors := 0 mut errors := 0
for file_path in files_paths { for file_path in files_paths {
real_path := os.real_path(file_path) real_path := os.real_path(file_path)
lines := os.read_lines(real_path) or { lines := os.read_lines(real_path) or {
println('"$file_path" does not exist')
warnings++
continue continue
} }
for i, line in lines { for i, line in lines {
if line.len > too_long_line_length { if line.len > too_long_line_length {
eprintln('$real_path:${i+1}:${line.len+1}: line too long') linetrace_msg := '$file_path:${i + 1}:${line.len + 1}: '
errors++ if line.starts_with('|') {
println(linetrace_msg + 'long table (warn)')
warnings++
} else if line.contains('https') {
println(linetrace_msg + 'long link (warn)')
warnings++
} else {
eprintln(linetrace_msg + 'line too long')
errors++
}
} }
} }
} }
// TODO: uncomment this AFTER doc/docs.md line lengths are fixed if warnings > 0 || errors > 0 {
/* println('\nWarnings | Errors')
println('$warnings\t | $errors')
}
if errors > 0 { if errors > 0 {
exit(1) exit(1)
} }
*/
} }

View File

@ -255,7 +255,8 @@ println(age)
``` ```
To change the value of the variable use `=`. In V, variables are To change the value of the variable use `=`. In V, variables are
immutable by default. To be able to change the value of the variable, you have to declare it with `mut`. immutable by default.
To be able to change the value of the variable, you have to declare it with `mut`.
Try compiling the program above after removing `mut` from the first line. Try compiling the program above after removing `mut` from the first line.
@ -281,8 +282,10 @@ fn main() {
### Declaration errors ### Declaration errors
In development mode the compiler will warn you that you haven't used the variable (you'll get an "unused variable" warning). In development mode the compiler will warn you that you haven't used the variable
In production mode (enabled by passing the `-prod` flag to v `v -prod foo.v`) it will not compile at all (like in Go). (you'll get an "unused variable" warning).
In production mode (enabled by passing the `-prod` flag to v `v -prod foo.v`)
it will not compile at all (like in Go).
```v ```v
fn main() { fn main() {
@ -294,7 +297,8 @@ fn main() {
} }
``` ```
Unlike most languages, variable shadowing is not allowed. Declaring a variable with a name that is already used in a parent scope will cause a compilation error. Unlike most languages, variable shadowing is not allowed. Declaring a variable with a name
that is already used in a parent scope will cause a compilation error.
## Types ## Types
@ -393,8 +397,9 @@ println('Hello, $name!') // Hello, Bob!
It also works with fields: `'age = $user.age'`. It also works with fields: `'age = $user.age'`.
If you need more complex expressions, use `${}`: `'can register = ${user.age > 13}'`. If you need more complex expressions, use `${}`: `'can register = ${user.age > 13}'`.
Format specifiers similar to those in C's `printf()` are also supported. `f`, `g`, `x`, etc. are optional Format specifiers similar to those in C's `printf()` are also supported.
and specify the output format. The compiler takes care of the storage size, so there is no `hd` or `llu`. `f`, `g`, `x`, etc. are optional and specify the output format.
The compiler takes care of the storage size, so there is no `hd` or `llu`.
```v ```v
x := 123.4567 x := 123.4567
@ -503,8 +508,10 @@ The type of an array is determined by the first element:
* `[1, 2, 3]` is an array of ints (`[]int`). * `[1, 2, 3]` is an array of ints (`[]int`).
* `['a', 'b']` is an array of strings (`[]string`). * `['a', 'b']` is an array of strings (`[]string`).
If V is unable to infer the type of an array, the user can explicitly specify it for the first element: `[byte(16), 32, 64, 128]`. If V is unable to infer the type of an array,
V arrays are homogeneous (all elements must have the same type). This means that code like `[1, 'a']` will not compile. the user can explicitly specify it for the first element: `[byte(16), 32, 64, 128]`.
V arrays are homogeneous (all elements must have the same type).
This means that code like `[1, 'a']` will not compile.
The `.len` field returns the length of the array. Note that it's a read-only field, The `.len` field returns the length of the array. Note that it's a read-only field,
and it can't be modified by the user. Exported fields are read-only by default in V. and it can't be modified by the user. Exported fields are read-only by default in V.
@ -543,7 +550,8 @@ and the default element (`init`):
arr := []int{ len: 5, init: -1 } // `[-1, -1, -1, -1, -1]` arr := []int{ len: 5, init: -1 } // `[-1, -1, -1, -1, -1]`
``` ```
Setting the capacity improves performance of insertions, as it reduces the number of reallocations needed: Setting the capacity improves performance of insertions,
as it reduces the number of reallocations needed:
```v ```v
mut numbers := []int{ cap: 1000 } mut numbers := []int{ cap: 1000 }
@ -731,7 +739,8 @@ if a < b {
``` ```
`if` statements are pretty straightforward and similar to most other languages. `if` statements are pretty straightforward and similar to most other languages.
Unlike other C-like languages, there are no parentheses surrounding the condition, and the braces are always required. Unlike other C-like languages,
there are no parentheses surrounding the condition and the braces are always required.
`if` can be used as an expression: `if` can be used as an expression:
@ -767,7 +776,8 @@ if x is Abc {
If you have a struct field which should be checked, there is also a way to name a alias. If you have a struct field which should be checked, there is also a way to name a alias.
```v ```v
if x.bar is MyStruct as bar { if x.bar is MyStruct as bar {
// x.bar cannot be cast automatically, you must explicitly state "as bar" to create a variable with the MyStruct type // x.bar cannot be cast automatically
// you must explicitly state "as bar" to create a variable with the MyStruct type
println(bar) println(bar)
} }
``` ```
@ -797,7 +807,8 @@ if parser.token in [.plus, .minus, .div, .mult] {
} }
``` ```
V optimizes such expressions, so both `if` statements above produce the same machine code and no arrays are created. V optimizes such expressions,
so both `if` statements above produce the same machine code and no arrays are created.
### For loop ### For loop
@ -819,7 +830,8 @@ for i, name in names {
The `for value in arr` form is used for going through elements of an array. The `for value in arr` form is used for going through elements of an array.
If an index is required, an alternative form `for index, value in arr` can be used. If an index is required, an alternative form `for index, value in arr` can be used.
Note, that the value is read-only. If you need to modify the array while looping, you have to use indexing: Note, that the value is read-only.
If you need to modify the array while looping, you have to use indexing:
```v ```v
mut numbers := [0, 1, 2] mut numbers := [0, 1, 2]
@ -982,7 +994,8 @@ Note: `match` as an expression is not usable in `for` loop and `if` statements.
### Defer ### Defer
A defer statement defers the execution of a block of statements until the surrounding function returns. A defer statement defers the execution of a block of statements
until the surrounding function returns.
```v ```v
fn read_log() { fn read_log() {
@ -1061,7 +1074,8 @@ struct Foo {
} }
``` ```
All struct fields are zeroed by default during the creation of the struct. Array and map fields are allocated. All struct fields are zeroed by default during the creation of the struct.
Array and map fields are allocated.
It's also possible to define custom default values. It's also possible to define custom default values.
@ -1158,7 +1172,8 @@ fn main() {
} }
``` ```
This means that defining public readonly fields is very easy in V, no need in getters/setters or properties. This means that defining public readonly fields is very easy in V,
no need in getters/setters or properties.
### Methods ### Methods
@ -1190,11 +1205,11 @@ but a short, preferably one letter long, name.
### Pure functions by default ### Pure functions by default
V functions are pure by default, meaning that their return values are a function of their arguments only, V functions are pure by default, meaning that their return values are a function of their
and their evaluation has no side effects (besides I/O). arguments only, and their evaluation has no side effects (besides I/O).
This is achieved by a lack of global variables and all function arguments being immutable by default, This is achieved by a lack of global variables and all function arguments being
even when [references](#references) are passed. immutable by default, even when [references](#references) are passed.
V is not a purely functional language however. V is not a purely functional language however.
@ -1243,7 +1258,8 @@ It is preferable to return values instead of modifying arguments.
Modifying arguments should only be done in performance-critical parts of your application Modifying arguments should only be done in performance-critical parts of your application
to reduce allocations and copying. to reduce allocations and copying.
For this reason V doesn't allow the modification of arguments with primitive types such as integers. Only more complex types such as arrays and maps may be modified. For this reason V doesn't allow the modification of arguments with primitive types (e.g. integers).
Only more complex types such as arrays and maps may be modified.
Use `user.register()` or `user = register(user)` Use `user.register()` or `user = register(user)`
instead of `register(mut user)`. instead of `register(mut user)`.
@ -1542,7 +1558,8 @@ match color {
``` ```
Enum match must be exhaustive or have an `else` branch. This ensures that if a new enum field is added, it's handled everywhere in the code. Enum match must be exhaustive or have an `else` branch.
This ensures that if a new enum field is added, it's handled everywhere in the code.
### Sum types ### Sum types
@ -1673,7 +1690,8 @@ V combines `Option` and `Result` into one type, so you don't need to decide whic
The amount of work required to "upgrade" a function to an optional function is minimal; The amount of work required to "upgrade" a function to an optional function is minimal;
you have to add a `?` to the return type and return an error when something goes wrong. you have to add a `?` to the return type and return an error when something goes wrong.
If you don't need to return an error message, you can simply `return none` (this is a more efficient equivalent of `return error("")`). If you don't need to return an error message, you can simply `return none`
(this is a more efficient equivalent of `return error("")`).
This is the primary mechanism for error handling in V. They are still values, like in Go, This is the primary mechanism for error handling in V. They are still values, like in Go,
but the advantage is that errors can't be unhandled, and handling them is a lot less verbose. but the advantage is that errors can't be unhandled, and handling them is a lot less verbose.
@ -1728,16 +1746,18 @@ user := repo.find_user_by_id(7) or {
} }
``` ```
Here, you can either call `panic()` or `exit()`, which will stop the execution of the entire program, Here, you can either call `panic()` or `exit()`, which will stop the execution of the
or use a control flow statement (`return`, `break`, `continue`, etc) to break from the current block. entire program, or use a control flow statement (`return`, `break`, `continue`, etc)
to break from the current block.
Note that `break` and `continue` can only be used inside a `for` loop. Note that `break` and `continue` can only be used inside a `for` loop.
V does not have a way to forcibly "unwrap" an optional (as other languages do, for instance Rust's `unwrap()` V does not have a way to forcibly "unwrap" an optional (as other languages do,
or Swift's `!`). To do this, use `or { panic(err) }` instead. for instance Rust's `unwrap()` or Swift's `!`). To do this, use `or { panic(err) }` instead.
--- ---
The third method is to provide a default value at the end of the `or` block. In case of an error, The third method is to provide a default value at the end of the `or` block.
that value would be assigned instead, so it must have the same type as the content of the `Option` being handled. In case of an error, that value would be assigned instead,
so it must have the same type as the content of the `Option` being handled.
```v ```v
fn do_something(s string) ?string { fn do_something(s string) ?string {
@ -1911,8 +1931,9 @@ y := <-ch2 ?
#### Channel Select #### Channel Select
The `select` command allows monitoring several channels at the same time without noticeable CPU load. It consists The `select` command allows monitoring several channels at the same time
of a list of possible transfers and associated branches of statements - similar to the [match](#match) command: without noticeable CPU load. It consists of a list of possible transfers and associated branches
of statements - similar to the [match](#match) command:
```v ```v
select { select {
a := <-ch { a := <-ch {
@ -1934,7 +1955,8 @@ The timeout branch is optional. If it is absent `select` waits for an unlimited
It is also possible to proceed immediately if no channel is ready in the moment `select` is called It is also possible to proceed immediately if no channel is ready in the moment `select` is called
by adding an `else { ... }` branch. `else` and `> timeout` are mutually exclusive. by adding an `else { ... }` branch. `else` and `> timeout` are mutually exclusive.
The `select` command can be used as an *expression* of type `bool` that becomes `false` if all channels are closed: The `select` command can be used as an *expression* of type `bool`
that becomes `false` if all channels are closed:
```v ```v
if select { if select {
ch <- a { ch <- a {
@ -1956,14 +1978,15 @@ res2 := ch2.try_pop(mut b) // try to perform `b = <-ch2
l := ch.len // number of elements in queue l := ch.len // number of elements in queue
c := ch.cap // maximum queue length c := ch.cap // maximum queue length
``` ```
The `try_push/pop()` methods will return immediately with one of the results `.success`, `.not_ready` The `try_push/pop()` methods will return immediately with one of the results
or `.closed` - dependent on whether the object has been transferred or the reason why not. Usage `.success`, `.not_ready` or `.closed` - dependent on whether the object has been transferred or
of these methods and properties in production is not recommended - algorithms based on them are often subject the reason why not.
to race conditions. Use `select` instead. Usage of these methods and properties in production is not recommended -
algorithms based on them are often subject to race conditions. Use `select` instead.
Data can be exchanged between a coroutine Data can be exchanged between a coroutine and the calling thread via a shared variable.
and the calling thread via a shared variable. This variable should be created as reference and passed to This variable should be created as reference and passed to the coroutine as `mut`.
the coroutine as `mut`. The underlying `struct` should also contain a `mutex` to lock concurrent access: The underlying `struct` should also contain a `mutex` to lock concurrent access:
```v ```v
import sync import sync
@ -2035,10 +2058,12 @@ println(foos[1].x)
Because of the ubiquitous nature of JSON, support for it is built directly into V. Because of the ubiquitous nature of JSON, support for it is built directly into V.
The `json.decode` function takes two arguments: the first argument of the `json.decode` function is the type into which the JSON value should be decoded and the second is a string containing the JSON data. The `json.decode` function takes two arguments:
the first is the type into which the JSON value should be decoded and
the second is a string containing the JSON data.
V generates code for JSON encoding and decoding. No runtime reflection is used. This results in much better V generates code for JSON encoding and decoding.
performance. No runtime reflection is used. This results in much better performance.
## Testing ## Testing
@ -2153,7 +2178,8 @@ fn test() []int {
(This is still in an alpha state) (This is still in an alpha state)
V has a built-in ORM (object-relational mapping) which supports SQLite, and will soon support MySQL, Postgres, MS SQL, and Oracle. V has a built-in ORM (object-relational mapping) which supports SQLite,
and will soon support MySQL, Postgres, MS SQL, and Oracle.
V's ORM provides a number of benefits: V's ORM provides a number of benefits:
@ -2161,7 +2187,8 @@ V's ORM provides a number of benefits:
- Queries are constructed using V's syntax. (There's no need to learn another syntax.) - 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.) - Safety. (All queries are automatically sanitised to prevent SQL injection.)
- Compile time checks. (This prevents typos which can only be caught during runtime.) - 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.) - Readability and simplicity. (You don't need to manually parse the results of a query and
then manually construct objects from the parsed results.)
```v ```v
struct Customer { // struct name has to be the same as the table name (for now) struct Customer { // struct name has to be the same as the table name (for now)
@ -2199,7 +2226,8 @@ For more examples, see <a href='https://github.com/vlang/v/blob/master/vlib/orm/
## Writing Documentation ## Writing Documentation
The way it works is very similar to Go. It's very simple: there's no need to The way it works is very similar to Go. It's very simple: there's no need to
write documentation separately for your code, vdoc will generate it from docstrings in the source code. write documentation separately for your code,
vdoc will generate it from docstrings in the source code.
Documentation for each function/type/const must be placed right before the declaration: Documentation for each function/type/const must be placed right before the declaration:
@ -2335,8 +2363,10 @@ fn my_callback(arg voidptr, howmany int, cvalues &charptr, cnames &charptr) int
fn main() { fn main() {
db := &C.sqlite3(0) // this means `sqlite3* db = 0` db := &C.sqlite3(0) // this means `sqlite3* db = 0`
C.sqlite3_open('users.db', &db) // passing a string literal to a C function call results in a C string, not a V string // passing a string literal to a C function call results in a C string, not a V string
// C.sqlite3_open(db_path.str, &db) // you can also use `.str byteptr` field to convert a V string to a C char pointer C.sqlite3_open('users.db', &db)
// C.sqlite3_open(db_path.str, &db)
// you can also use `.str byteptr` field to convert a V string to a C char pointer
query := 'select count(*) from users' query := 'select count(*) from users'
stmt := &C.sqlite3_stmt(0) stmt := &C.sqlite3_stmt(0)
C.sqlite3_prepare_v2(db, query.str, - 1, &stmt, 0) C.sqlite3_prepare_v2(db, query.str, - 1, &stmt, 0)
@ -2365,7 +2395,8 @@ Add `#flag` directives to the top of your V files to provide C compilation flags
- `-L` for adding C library files search paths - `-L` for adding C library files search paths
- `-D` for setting compile time variables - `-D` for setting compile time variables
You can use different flags for different targets. Currently the `linux`, `darwin` , `freebsd`, and `windows` flags are supported. You can use different flags for different targets.
Currently the `linux`, `darwin` , `freebsd`, and `windows` flags are supported.
NB: Each flag must go on its own line (for now) NB: Each flag must go on its own line (for now)
@ -2379,7 +2410,9 @@ NB: Each flag must go on its own line (for now)
### Including C code ### Including C code
You can also include C code directly in your V module. For example, let's say that your C code is located in a folder named 'c' inside your module folder. Then: You can also include C code directly in your V module.
For example, let's say that your C code is located in a folder named 'c' inside your module folder.
Then:
* Put a v.mod file inside the toplevel folder of your module (if you * Put a v.mod file inside the toplevel folder of your module (if you
created your module with `v new` you already have v.mod file). For created your module with `v new` you already have v.mod file). For
@ -2401,11 +2434,13 @@ Module {
#include "header.h" #include "header.h"
``` ```
NB: @VROOT will be replaced by V with the *nearest parent folder, where there is a v.mod file*. NB: @VROOT will be replaced by V with the *nearest parent folder, where there is a v.mod file*.
Any .v file beside or below the folder where the v.mod file is, can use `#flag @VROOT/abc` to refer to this folder. Any .v file beside or below the folder where the v.mod file is,
The @VROOT folder is also *prepended* to the module lookup path, so you can *import* other can use `#flag @VROOT/abc` to refer to this folder.
modules under your @VROOT, by just naming them. The @VROOT folder is also *prepended* to the module lookup path,
so you can *import* other modules under your @VROOT, by just naming them.
The instructions above will make V look for an compiled .o file in your module `folder/c/implementation.o`. The instructions above will make V look for an compiled .o file in
your module `folder/c/implementation.o`.
If V finds it, the .o file will get linked to the main executable, that used the module. If V finds it, the .o file will get linked to the main executable, that used the module.
If it does not find it, V assumes that there is a `@VROOT/c/implementation.c` file, If it does not find it, V assumes that there is a `@VROOT/c/implementation.c` file,
and tries to compile it to a .o file, then will use that. and tries to compile it to a .o file, then will use that.
@ -2416,15 +2451,19 @@ You can see a complete minimal example for using C code in a V wrapper module he
Another example, demonstrating passing structs from C to V and back again: Another example, demonstrating passing structs from C to V and back again:
[interoperate between C to V to C](https://github.com/vlang/v/tree/master/vlib/v/tests/project_with_c_code_2). [interoperate between C to V to C](https://github.com/vlang/v/tree/master/vlib/v/tests/project_with_c_code_2).
You can use `-cflags` to pass custom flags to the backend C compiler. You can also use `-cc` to change the default C backend compiler. You can use `-cflags` to pass custom flags to the backend C compiler.
You can also use `-cc` to change the default C backend compiler.
For example: `-cc gcc-9 -cflags -fsanitize=thread`. For example: `-cc gcc-9 -cflags -fsanitize=thread`.
### C types ### C types
Ordinary zero terminated C strings can be converted to V strings with `string(cstring)` or `string(cstring, len)`. Ordinary zero terminated C strings can be converted to V strings with `string(cstring)`
or `string(cstring, len)`.
NB: Each `string(...)` function does NOT create a copy of the `cstring`, so you should NOT free it after calling `string()`. If you need to make a copy of the C string (some libc APIs like `getenv` pretty much require that, since they NB: Each `string(...)` function does NOT create a copy of the `cstring`,
return pointers to internal libc memory), you can use `cstring_to_vstring(cstring)`. so you should NOT free it after calling `string()`.
If you need to make a copy of the C string (some libc APIs like `getenv` pretty much require that,
since they return pointers to internal libc memory), you can use `cstring_to_vstring(cstring)`.
On Windows, C APIs often return so called `wide` strings (utf16 encoding). On Windows, C APIs often return so called `wide` strings (utf16 encoding).
These can be converted to V strings with `string_from_wide(&u16(cwidestring))` . These can be converted to V strings with `string_from_wide(&u16(cwidestring))` .
@ -2449,13 +2488,19 @@ To debug issues in the generated C code, you can pass these flags:
- `-cg` - produces a less optimized executable with more debug information in it. - `-cg` - produces a less optimized executable with more debug information in it.
- `-showcc` - prints the C command that is used to build the program. - `-showcc` - prints the C command that is used to build the program.
For the best debugging experience, you can pass all of them at the same time: `v -cg -showcc yourprogram.v` , then just run your debugger (gdb/lldb) or IDE on the produced executable `yourprogram`. For the best debugging experience, you can pass all of them at the same time:
`v -cg -showcc yourprogram.v`,
then just run your debugger (gdb/lldb) or IDE on the produced executable `yourprogram`.
If you just want to inspect the generated C code, without further compilation, you can also use the `-o` flag (e.g. `-o file.c`). This will make V produce the `file.c` then stop. If you just want to inspect the generated C code,
without further compilation, you can also use the `-o` flag (e.g. `-o file.c`).
This will make V produce the `file.c` then stop.
If you want to see the generated C source code for *just* a single C function, for example `main`, you can use: `-printfn main -o file.c` . If you want to see the generated C source code for *just* a single C function,
for example `main`, you can use: `-printfn main -o file.c`.
To see a detailed list of all flags that V supports, use `v help`, `v help build`, `v help build-c` . To see a detailed list of all flags that V supports,
use `v help`, `v help build` and `v help build-c`.
## Conditional compilation ## Conditional compilation
@ -2513,7 +2558,8 @@ Full list of builtin options:
## Compile time pseudo variables ## Compile time pseudo variables
V also gives your code access to a set of pseudo string variables, that are substituted at compile time: V also gives your code access to a set of pseudo string variables,
that are substituted at compile time:
- `@FN` => replaced with the name of the current V function - `@FN` => replaced with the name of the current V function
- `@MOD` => replaced with the name of the current V module - `@MOD` => replaced with the name of the current V module
@ -2641,9 +2687,9 @@ fn main() {
} }
``` ```
Operator overloading goes against V's philosophy of simplicity and predictability. But since Operator overloading goes against V's philosophy of simplicity and predictability.
scientific and graphical applications are among V's domains, operator overloading is an important feature to have But since scientific and graphical applications are among V's domains,
in order to improve readability: operator overloading is an important feature to have in order to improve readability:
`a.add(b).add(c.mul(d))` is a lot less readable than `a + b + c * d`. `a.add(b).add(c.mul(d))` is a lot less readable than `a + b + c * d`.
@ -2705,11 +2751,13 @@ An online C/C++ to V translator is coming soon.
When should you translate C code and when should you simply call C code from V? When should you translate C code and when should you simply call C code from V?
If you have well-written, well-tested C code, then of course you can always simply call this C code from V. If you have well-written, well-tested C code,
then of course you can always simply call this C code from V.
Translating it to V gives you several advantages: Translating it to V gives you several advantages:
- If you plan to develop that code base, you now have everything in one language, which is much safer and easier to develop in than C. - If you plan to develop that code base, you now have everything in one language,
which is much safer and easier to develop in than C.
- Cross-compilation becomes a lot easier. You don't have to worry about it at all. - Cross-compilation becomes a lot easier. You don't have to worry about it at all.
- No more build flags and include files either. - No more build flags and include files either.
@ -2812,7 +2860,8 @@ On Unix-like platforms, the file can be run directly after making it executable
V has several attributes that modify the behavior of functions and structs. V has several attributes that modify the behavior of functions and structs.
An attribute is specified inside `[]` right before a function/struct declaration and applies only to the following declaration. An attribute is specified inside `[]` right before a function/struct declaration
and applies only to the following declaration.
```v ```v
// Calling this function will result in a deprecation warning // Calling this function will result in a deprecation warning