dyslexic
edit
qrcode
+=-

The V Programming Language


I have taught some iteration of COS 350 Computer Graphics for around 10years now. Each year, I reevaluate all aspects of the course, including which language I use. I have already used many different languages for different aspects (ex: Java, JavaScript, WebGL/OpenGL, Python, C++, Dart), and I have considered many others (ex: Go, Rust, Haskell, Zig, C#). While all useful languages are equally capable, I have noticed two issues across all the various languages that I've tried or investigated. These issues are:

Here are a few takeaways from my experiments, thus far:

I have yet to find a programming language that has simple syntax, is hackable yet strongly typed, has a compiler/interpreter that produces helpful error and warning messages, and is fast. However, late in 2022 July, I came across a programming language that seems to tick many of the boxes that make it a potential candidate for COS 350. This language is called, V.

According to the main site, the V programming language is "Simple, fast, safe, compiled". The site goes on to say that V...

Notes:

Quick Notes


The docs, math module, and rand module contain lots of examples that will get you programming in the V language, but below are a few notes:

The gfx Module


The gfx module provides lots of functionality that will be used throughout the COS 350 course. I split up the module across several files to provide some categories for finding needed functionality.

Note: To simplify the code, I have chosen to make nearly all of the struct fields to be immutable. This decision means that many struct objects will be created, but it also means that the code will be much cleaner as you will not need to add mut to function arguments. The exceptions to this are with Image, Image4, Color, and Color4 structs.

Maths


The maths_1d.v, maths_2d.v, and maths_3d.v files contain structs, consts, and fns that deal with mathematics in 1D, 2D, and 3D, respectively.

In general, if a struct ends in i, then the field types are ints. Otherwise, the field types are f64s, double precision floats.

The 1D functions are min3, max3, and int_in_range. min3 and max3 are convenience functions that return the minimim or maximum value (resp) among the three passed numerical arguments (ex: u8, int, f64). int_in_range is a wrapper for rand.int_in_range, returning an int chosen uniformly at random between between the two passed int arguments.

The 2D structs are as follows.

The point2i_rand function acts like a constructor that creates a Point2i with coords chosen uniformly at random between the two given Point2i arguments.

The 3D structs are as follows.

Several "constructor" functions are available for creating structs that have certain properties. For example, all directions and normals should have unit magnitude/length (although, technically they don't have lengths). As another example, the axes of a frame should be orthonormal. The constructors help provide these guarantees.

Vectors have methods for computing different norms or lengths (ex: \(\ell^1\), \(\ell^2\), \(\ell^\infty\) norms, see Vector Norm) Points have methods for computing averages and linear interpolated (LERP) points. There are methods for performing arithmetic operations (add, sub, scale, negate, dot, cross, etc.) on the structs. There are conversion methods for converting from one type to another (ex: convert Direction to Vector, LookAt to Frame) and convenience methods that provide shorthands for common computations (ex: computing the vector from one point to another).

Image and Color


The image.v and color.v files contain lots of functionality for producing, loading, and saving images. There are two main types:

If you make changes to the code relating to Image or Image4, note that the color data of an image are stored in row-major 2D arrays of Color or Color4.

Note: y increases down the image.

Two functions, generate_image0 and generate_image1, will be used in the first project. They demonstrate how to create, modify, and return an image.

The image.v file contains three functions, load_image, load_image4, and save_image, that handle reading/writing an image from/to a file in the NetPBM format. See NetPBM notes for details on the format.

Scene and Intersection (Raytracing only)


The scene.v file contains structs and an enum to represent different aspects of a scene for raytrace rendering.

The structs are as follows.

The single enum gives a name to two different surface shapes: sphere (0 value) and quad (1 value). Note: When representing enum values in JSON, you will need to specify using the corresponding int values.

The scene.v file also contains a few convenience getter functions, and functions/methods for loading scenes from a JSON file.

Note: the camera's frame is oriented so that x increases right, y increases up, and z increases backwards.

The intersection.v file contains a struct for holding details about an intersection. There are several functions and methods to help.

Note: the fields of Intersection could be an optional type (?Surface) to indicate a hit/miss, but making this change causes the readability of the code to drop significantly. Instead, use an infinite distance (distance=math.inf(1)) to indicate a miss, and a finite value (ex: distance=42.0) to indicate a hit.

Pipeline (Pipeline only)


The pipeline.v file contains structs to represent data in different parts of graphics pipeline.

The structs are as follows:

This area is still under construction!

Some Issues with V


While I have enjoyed working in V, I have run into many issues that required weird workarounds for problems or lots of comments on how to use. Below are a few issues I've discovered.

Note: some of these issues have been addressed by the V devs! Sadly, I have not yet updated the list below due to these changes...