Skip to main content

Frquently Asked Questions


What's wrong with C++?

It inevitably leads to code like this if you want to do certain things at compile time. (Yes, that is my code, and no, I'm not proud of it.) In this case, I was trying create a compile-time plugin infrastructure using the (at the time) new C++11 features such as variadic templates and perfect forwarding (before, it would not have been possible to do this at all).

C++ templates are generally a train wreck. You cannot pass composite objects (like struct or class instances) as template arguments; in fact, you cannot even pass string literals or floating-point values.

Aside from all this, C++ generally suffers from the same problem as C with regards to compile times (because the same headers are read and parsed thousands of times over), except that C++'s templates exacerbate the problem.

Is it V or v?

I use "V" for the name of the language and "v" for the name of the V compiler/interpreter (and its executable).

Why the name "V"?

One-letter names are a staple of programming languages. I just wanted something short (both for the compiler and the file extension) and V (as well as the domain seemed free. It's my language after all :-D

Is there any connection to (by Alex Medvednikov)?

There is no connection whatsoever.

My project started earlier (the first commit is from February 2017 and has been available on GitHub since around the same time; the domain name was registered in March 2017), whereas does not seem to have existed before February 2019.

The namespace of programming languages is a bit of a free-for-all (there have already been a few other projects calling themselves "V" and there's only 26 single-letter names possible after all!) and I don't think it will cause too much confusion.

In any case, we are different projects by different people with completely different goals and philosophies, and there is no ill will between us.


What is the difference between x and @x?

x is evaluated at run-time, whereas @x is evaluated at compile-time.

For example, given a function fib(n) returning the n-th fibonacci number, you can @ in several different places for different behaviours:

  • print fib(10);fib(10) is evaluated and printed at run-time
  • @print fib(10);fib(10) is evaluated and printed at compile-time
  • print @fib(10);fib(10) is evaluated at compile-time but printed at run-time

@ is a prefix operator with low precedence, meaning that e.g. @print fib(10); is semantically the same as @(print fib(10)); and not the same as (@print) fib(10);.

Note that macros are already evaluated at compile-time, which means you don't need to use @ when invoking macros; for example, since ptr is a (built-in) macro, you don't need to write @ptr(int) in order to evaluate the type at compile-time.

What is the juxtaposition operator?

What I call the juxtaposition operator is when you have two expressions next to each other without anything in between, like this: x y. The parse tree for this is (juxtapose (symbol x) (symbol y)). The slightly unusual thing about this operator is that it is the only operator that doesn't actually have a symbol.

The juxtaposition operator is most commonly used for function calls and macro invocations: for example, f(x) parses as (juxtapose (symbol f) (brackets (symbol x))).

Of course, juxtaposition is not always interpreted as a call; it depends on the context. quote x y is parsed as (juxtapose (symbol quote) (juxtapose (symbol x) (symbol y))), and since quote is a macro, (juxtapose (symbol x) (symbol y)) is not evaluated at all. Similarly, the expression if x then y else z is a tree of juxtapositions, but only the outermost one is actually evaluated at compile time (since if is a macro).

What are the language's keywords?

There are no keywords in V per se. What you typically see in other languages as keywords are instead implemented using certain symbols defined as built-in macros. I decided to do things this way for multiple reasons:

  • to keep the parser small and generic,
  • to allow the programmer to refer to and redefine the variables naming the built-in macros, and
  • to allow the programmer to define his/her own "keywords" at will.

In particular, this means that you can reuse the syntax and the parser for generic data that you want to store, i.e. something like this is completely valid code and does not differentiate between "keywords" and other symbols: data := quote [if, while, return];.

Overall, I just found it more elegant to reuse the macro mechanism where other languages have keywords.

That said, we do define a number of symbols such as if, return, etc. at the top-level scope. Please see the handbook for more information.


Is V a compiled or interpreted language?

Either and both.

In theory, you can interpret any "typically compiled" language (like C) simply by first compiling the code and then executing the result. Similarly, you could also compile any "typically interpreted" language (like Python) by combining the interpreter with the to-be-interpreted source code into a binary. Although both of these could be considered cheating a bit.

What you probably wanted to ask was whether the "v" program is a compiler or an interpreter. See the next question :-)

That said, V is statically typed and so naturally lends itself to compilation to fast native/machine code.

Is "v" a compiler or an interpreter?


Because you can evaluate arbitrary code at compile-time, you could view the V compiler as an interpreter.

The top-level program that you pass to "v" is interpreted by compiling it and then immediately executing the result of the compilation.

As opposed to e.g. C where functions are defined declaratively, in V they are the result of actually executing code; when you pass f := function (a: int, b: int) { ... } to the compiler, this is not just a fancy way of declaring a function, it is actually an assignment like any other assignment, and it is compiled like any other assignment; function is a macro that returns a function pointer and f is a local variable.

Any plans to make the compiler self-hosting?

Not at this time.

Having a stable base language is important before writing any substantial amount of code in it, and neither syntax nor libraries are currently anywhere near finished.

C++ is already widespread and also makes it easier to build/install/bootstrap on other systems/architectures.