Verse Cheat Sheet
The code snippet below is Verse code written to form a cheat sheet for various features of the programming language. It goes over variables, types, control flow and other trappings that you might find in a typical programming language cheat sheet. It is not comprehensive nor guaranteed to be accurate as Verse continues to evolve constantly.
cheat_sheet := class():
# Verse Cheat Sheet (version 0.1 - UEFN 5.6/33.30)
## Comments ##
# This is a Comment - the compiler ignores text, for just this line, after the first # symbol
<# This is an Inline Comment, differs from single-line comments, ends with → #>
<#> This is used to make Indented Comments
<# and #> can be used for nested comments and to make Multi-Line comments too.
This line is still part of the indented comment btw.
Un-indenting will end this comment block.
<#
An Expression is the smallest unit of code that evaluates to a result.
Everything in Verse is an expression!!
<#
An expression can succeed or fail.
For example, integer division can fail since you could divide by zero.
Such "failable" expressions can only exist in special contexts where we can
handle what happens on failure.
#>
#>
## Functions ##
<# Functions are a sequence of expressions that do something or
take in an input (parameters) and produce an output (result). #>
GiveMeA5() : int = # ← Defining a function called GiveMeA5 that outputs or returns an integer
# This is a code block (a group of expressions) with its own scope
2 + 3
# The last expression's result is the output but you can use an explicit `return` too
# The code block and its scope has ended here because of un-indenting.
# You can invoke or call the above function with GiveMeA5()
# Some functions can be set to fail, these use [] instead of ()
# Functions can accept inputs by defining parameters. Parameters need a name and type.
Add5To(InputParam : int) : int =
GiveMeA5() + InputParam
# Values are supplied as arguments when the function is invoked.
UseTheAboveFunctions() : void =
Add5To(10) # supplying 10 as the argument
Add5To( GiveMeA5() ) # supplying the result of GiveMeA5() as the input
## Variables & Types ##
MyConstantVariable : int = 42 # This is a constant, cannot be changed at runtime
# Note the 3 elements of variable declaration → name : type = value
var MyMutableName : string = "foo" # the var keyword allows value changing
# set MyMutableName = "bar" # the set keyword is used to change variables
# [Styling] PascalCase variable names
### Basic Types ###
BakersDozen : int = 13 # Integer, no fractional components
EulersNumber : float = 2.71828 # Floating-point values, can also be NaN
UserName : string = "admin" # String, sequence of characters
IsActive : logic = true # Logic represents Boolean values true and false
### Container Types ###
TriNumbers : []int = array{1, 3, 6} # Array, stores values of the same type
PowerLevel : ?int = option{9001} # Option, either a value or empty
# 0..3 # Range, series of integers (restricted use cases)
Info : tuple(string, int) = ("Age", 18) # Tuple, set of values of any type
Pairs : [string]int = map{"Age" => 18} # Map, collection of key-value pairs
### Composite Types ###
target := enum{Hi, Med, Low} # Enumeration, set of named values, declared outside scope
attack := struct: # Structure, group of related variables. No functions (yet)!
Name : string
FirstHit : target = target.Med # using the target enum in the struct
MaxDamage : int = 10
street_fighter := class: # Class, a blueprint for creating objects
Name : string
HealthPoints : int = 100
Special : attack := attack{Name:="Throw"} # using the attack struct in the class
PlayIntro() : void = # defining a function to make a class' method
Print("Hello World!")
pro_wrestler := class(street_fighter): # Subclass, extends another class
HealthPoints<override> : int = 200 # <override> allows superclass value changes
GenerateEnemy<constructor>() := street_fighter: # Constructor, creates a class instance
Name := "Scrub"
# Notice the lack of return type in the constructor
# Unlike some languages, a single class can have many constructors.
achievable := interface(): # Interface, empty methods for classes to implement
Unlock() : void
# Using the above interface
achievement := class(achievable): # Making a new class that implements interface
Unlock<override>() : void = # Methods must be overridden and implemented
Print("Achievement Unlocked!")
<#> [Styling]
lower_snake_case is used for the names of enums, structs, classes and interfaces.
Constructors are special but they are still functions so they should use PascalCase
Interface names should describe the properties of the classes using adjectives.
If adjectives don't exist, suffix _interface.
### Other Types ###
Error<localizes> : message = "Error" # Message, localization friendly piece of text
NIL : void = {} # Void, special type that means "not important"
Add(First:any, Second:any):any = {} # Any, special type that *all* types derive from
IsZero(X:comparable):logic = false # Comparable, allows types to be compared
GiveMePI()<decides> : rational =
MathPI : rational = 22 / 7 # Rational, division of two integers
## Operators ##
<#> Special functions with symbols for names. Their parameters are called operands.
An expression can use multiple operators. There is an evaluation order.
? Query Check if logic value is true
not Not Negates success or failure of expression
+ Positive Unary plus operator, no operation on number
- Negative Unary minus operator, negates a number
* Multiply Multiplies two values
/ Division Divides left value by right value
+ Addition Adds or concatenates two values
- Subtraction Subtracts right value from left value
+= Addition assignment Add and assign at the same time
-= Subtract assignment Subtract and assign at the same time
*= Multiply assignment Multiply and assign at the same time
/= Divide assignment Divide and assign at the same time
= Equal to Succeeds when left value equals right value
<> Not equal to Succeeds when left value equals right value
< Less than Succeeds when left value is less than right value
<= Less than or eq to Succeeds when left value is less than or equal to right value
> Greater than Succeeds when left value is greater than right value
>= Greater than or eq to Succeeds when left value is greater than or equal to right value
and And Succeeds when all operands succeed
or Or Succeeds if at least one operand succeeds
:= Initialization Stores values in a constant or variable. Looks like walrus!
= Assignment Updates values stored in variable
Operator evaluation order can be modified with grouping with round brackets ( )
2 * 1 + 2 results to 4 because multiply 2 and 1 first, then add 2 to it
2 * (1 + 2) results to 6 because we add group 1 and 2 first, then multiply that by 2
## Control Flow ##
# It's the order in which instructions are evaluated.
TestControlFlow() : void =
block: # Block, an explicit code block
Item : string = "Rocks"
block: # nested code block
Name : string = "Jenny"
Print(Name + Item) # variable Item from the parent block is accessible
# The second block has ended here, variable Name is no longer accessible
# Print(Name) throws unknown identifier error
Print(Item) # variable Item still works, we're still in the first block
# The first block has ended here, variable Item is now no longer accessible
if (22 / 7): # If, conditional execution based on success/fail
Print("The expression succeeded!")
else:
Print("The expression failed...")
var SomeInt : int = 5
case (SomeInt): # Case, choose expressions based on value comparisons
0 => Print("Zero")
1 => Print("One")
_ => Print("Not Zero nor One") # a default clause is needed as we can't handle all choices
defer: # Defer, once evaluated, its code block executes
set SomeInt = 0 # when leaving the current code block the it lives in
Print("We've reset SomeInt!")
# Defers cannot be the last code block
loop: # Loop, repeats the block until ended or suspended
set SomeInt += 1
if (SomeInt > 10):
break # here we stop the loop with `break`
# One can use `return` as well
for (Index := 0..99): # For, like a Loop but uses a "generator" to make a sequence
set SomeInt = Index # of values to iterate with
## Attributes & Specifiers ##
<#
Attributes are keywords that describe behaviors external to Verse.
@editable Indicates a value can be set in UEFN
@doc Documentation for classes and functions
Specifiers are keywords that describe behaviors within Verse.
<transacts> Actions can be rolled back
<varies> Same input may not product same output.
<computes> No side effects and may not complete
<converges> No side effects and definitely completes
<decides> Can fail or is a failable expression
<suspends> Is Asynchronous
<public> Universally accessible
<protected> Can only be accessed by self or subtypes
<private> Can only be accessed in current scope
<internal> Can only be accessed in current module
<abstract> Instances cannot be made
<concrete> All fields must be initialized
<unique> Each instance is unique (even if all fields are equal)
<final> Subclasses cannot be made
<native> Definitions are implemented in C++
<native_callable> Native and also callable by other C++ code
<localizes> Defining a new message with a string
#>
## Modules ##
# Modules are redistributable Verse code files that can be imported and used in other Verse files.
# Modules use folders. The folder name is the module name; contained Verse files are part of that module.
# Modules are imported with `using` followed by the path name.
using { /Verse.org/Simulation }
<#> Creating a module can be done like so
my_module := module:
my_class<public> := class{}
## Concurrency ##
<# Verse expressions can be:
* immediate - its evaluation finishes within current update OR
* async - its evaluation may complete in a later update
Async expressions need to run in an async context, specified with <suspends>
#>
Slow()<suspends> : void =
Sleep(10.0) # the Sleep function is from the /Verse.org/Simulation module
Fast()<suspends> : void = {}
TestConcurrency()<suspends> : void =
sync: # Sync, executes all expressions at once
Slow() # waits for all of them to finish before moving on
Fast()
race: # Race, runs all expressions, first expression to finish "wins",
Slow() # the rest are canceled and the code after the block runs
Fast()
rush: # Rush, runs all expressions, proceeds once 1st expression finishes,
Slow() # the rest continue till they finish but can get canceled
Fast() # if the async context completes first
branch: # Branch, executes branch and the code after it.
Slow() # Branch is canceled if code block or context finishes first
Fast()
Print("Let's spawn!")
spawn{Slow()} # Spawn, executes only one async function but it is independent
Print("Spawned a task.") # of the context that spawned it!
# All concurrent expressions return values.
# For example, sync returns a tuple of all results and branch returns void.
# Of note, Spawn returns a Task. Tasks can halt a code block until it finishes
SomeTask := spawn{Slow()}
SomeTask.Await()
Print("This will only run after the spawned Slow() finishes.")