Other V Features

Inline assembly

a := 100 b := 20 mut c := 0 asm amd64 { mov eax, a add eax, b mov c, eax ; =r (c) as c // output ; r (a) as a // input r (b) as b } println('a: ${a}') // 100 println('b: ${b}') // 20 println('c: ${c}') // 120

For more examples, see vlib/v/slow_tests/assembly/asm_test.amd64.v

Hot code reloading

module main import time @[live] fn print_message() { println('Hello! Modify this message while the program is running.') } fn main() { for { print_message() time.sleep(500 * time.millisecond) } }

Build this example with v -live message.v.

You can also run this example with v -live run message.v. Make sure that in command you use a path to a V's file, not a path to a folder (like v -live run .) - in that case you need to modify content of a folder (add new file, for example), because changes in message.v will have no effect.

Functions that you want to be reloaded must have @[live] attribute before their definition.

Right now it's not possible to modify types while the program is running.

More examples, including a graphical application: github.com/vlang/v/tree/master/examples/hot_reload.

About keeping states in hot reloading functions with v -live run

V's hot code reloading relies on marking the functions that you want to reload with @[live], then compiling a shared library of these @[live] functions, and then your v program loads that shared library at runtime.

V (with the -live option) starts a new thread, that monitors the source files for changes, and when it detects modifications, it recompiles the shared library, and reloads it at runtime, so that new calls to those @[live] functions will be made to the newly loaded library.

It keeps all the accumulated state (from locals outside the @[live] functions, from heap variables and from globals), allowing to tweak the code in the merged functions quickly.

When there are more substantial changes (to data structures, or to functions that were not marked), you will have to restart the running app manually.

Cross-platform shell scripts in V

V can be used as an alternative to Bash to write deployment scripts, build scripts, etc.

The advantage of using V for this, is the simplicity and predictability of the language, and cross-platform support. "V scripts" run on Unix-like systems, as well as on Windows.

To use V's script mode, save your source file with the .vsh file extension. It will make all functions in the os module global (so that you can use mkdir() instead of os.mkdir(), for example).

V also knows to compile & run .vsh files immediately, so you do not need a separate step to compile them. V will also recompile an executable, produced by a .vsh file, only when it is older than the .vsh source file, i.e. runs after the first one, will be faster, since there is no need for a re-compilation of a script, that has not been changed.

An example deploy.vsh:

#!/usr/bin/env -S v // Note: The shebang line above, associates the .vsh file to V on Unix-like systems, // so it can be run just by specifying the path to the .vsh file, once it's made // executable, using `chmod +x deploy.vsh`, i.e. after that chmod command, you can // run the .vsh script, by just typing its name/path like this: `./deploy.vsh` // print command then execute it fn sh(cmd string) { println('❯ ${cmd}') print(execute_or_exit(cmd).output) } // Remove if build/ exits, ignore any errors if it doesn't rmdir_all('build') or {} // Create build/, never fails as build/ does not exist mkdir('build')! // Move *.v files to build/ result := execute('mv *.v build/') if result.exit_code != 0 { println(result.output) } sh('ls') // Similar to: // files := ls('.')! // mut count := 0 // if files.len > 0 { // for file in files { // if file.ends_with('.v') { // mv(file, 'build/') or { // println('err: ${err}') // return // } // } // count++ // } // } // if count == 0 { // println('No files') // }

Now you can either compile this like a normal V program and get an executable you can deploy and run anywhere: v -skip-running deploy.vsh && ./deploy

Or run it like a traditional Bash script: v run deploy.vsh (or simply just v deploy.vsh)

On Unix-like platforms, the file can be run directly after making it executable using chmod +x: ./deploy.vsh

Vsh scripts with no extension

Whilst V does normally not allow vsh scripts without the designated file extension, there is a way to circumvent this rule and have a file with a fully custom name and shebang. Whilst this feature exists it is only recommended for specific usecases like scripts that will be put in the path and should not be used for things like build or deploy scripts. To access this feature start the file with #!/usr/bin/env -S v -raw-vsh-tmp-prefix tmp where tmp is the prefix for the built executable. This will run in crun mode so it will only rebuild if changes to the script were made and keep the binary as tmp.<scriptfilename>. Caution: if this filename already exists the file will be overridden. If you want to rebuild each time and not keep this binary instead use #!/usr/bin/env -S v -raw-vsh-tmp-prefix tmp run.

Appendices