Roll is an interactive dice language designed to help play games or to conduct experiments with probability. Roll is implemented as an interactive interpreter. Unlike most similar systems, Roll supports evaluation modes in which distributions can be computed exactly or approximated using random sampling.
The source code is available on Github.
The script roll
runs the interpreter inside rlwrap
to provide
history and line editing. An initial expression or command may optionally be provided
as a commandline argument, e.g.:
roll 3d6
roll load dnd.roll
If the commandline argument is an expression rather than a command, the interpreter merely prints the evalmode result and immediately terminates without offering an interactive prompt.
The dice language is a functional language. Possible expressions exp include the following:
(any positive integer literal)  Examples: 3, 5, 2. 
(a literal bag of values)  Examples: {3,4,2}, {1,2,3,4,5,6}, {}, {4} 
d exp 
d is the most important expression in
Roll. d n means roll an nsided die and return the result. For example,
d6 evaluates to any of the integers 1–6. The
expression after d need not be an integer, but it should
evaluate to an integer; for example, d(d6) is a valid
expression. To compute this expression, the interpreter will roll
a sixsided die to get a value n, then roll an nsided die and return
the result. 
exp # exp 
# is the " repeat n
times" operator. The interpreter evaluates the first
expression to an integer n. Then it
evaluates the second expression n times and unions the results into a
single bag of integers. For example, the expression 3#d6 rolls 3 sixsided dice
and returns a bag containing the results; the expression 3#(2#d6) is equivalent
to 6#d6 . 
exp + exp 
This expression acts differently depending
on the results of the subexpressions. If both of the operands are
integers, it computes the sum of the two integers. If one operand
is an integer and the other is a bag, it adds the integer value to each
element of the bag and returns the result. It is a runtime type
error for both operands to be bags. In addition to + ,
the operators − , * , / , and % (mod)
are supported.

exp ++ exp 
Take the union of two subexpression results. For example,
2#d4++d6 returns the values from rolling 2 foursided dice and one
sixsided die, in no particular order. 
compare exp relop exp 
Perform the specified comparison, returning 1 if true and 0 if false. 
sum exp 
If the subexpression is a bag, the result
is to sum the elements of the bag. If it is an integer, this
expression returns that integer. So, sum(3#d6) would
return the sum of 3 sixsided dice. 
count exp 
Similar to sum, but it returns the number of elements in the subexpression. If the subexpression is an integer, it returns 1. 
min exp in exp 
Given operands n and
b respectively, returns the least
n elements of b. b
must be a bag. An example is min 2 (3#d6) , which rolls
3 sixsided dice and returns the two least values rolled. 
max exp in exp 
Like min , but selects the largest elements.

let id=exp
in exp 
Binds the result of evaluating the first
subexpression to the identifier id and uses the
binding to evaluate the second subexpression. Identifiers start
with a letter and consist of letters, underscores, and primes.
For example, let x = d6 in x+x will roll a sixsided
die and double the result. Notice that the d6 in this expression
is evaluated only once. 
if exp relop exp then exp else exp 
Similar to the ML
if/then/else expression. If the condition is
true, returns the result of evaluating the first expression, otherwise
of the second expression. An example is
if d6 < 4 then d4 else d5 , which rolls a 6sided die; if the
result is less than 4, then it rolls a 4sided dice else rolls a 5sided
die. The list of relational operators is mentioned below. Relational operators relop may be any of < ,
<= , = , != , >= , >
Note: since
each element of the test is parsed separately, it is not possible to
put parentheses around the comparison as in if (exp op exp) then
... . 
filter exp relop
exp 
A filter
e1
op
e2
evaluates e1
and e2
to get results v1
and v2.
Value v1 must be an integer; v2
must be a bag. Then the comparison (v1
op v) for
each element v
in bag v2
and the result is the bag with all elements for which (v1
op
v) holds.
For example, the expression filter 4 < 5#d6
rolls 5 sixsided dice and returns any values greater than
4. If the 5#d6 evaluated to {1,2,4,6,6}, the filter
result would be {6, 6}. 
Example expressions:
d6
: Roll a 6 sided die
2 # d6
: Roll two 6 sided dice
d(d 6)
: Roll a 6 sided die to get 'n', and then role an
'n' sided die
d(sum(2#d6))
: Roll an 'n' sided die where n is the
sum of two sixsided die rolls.
if d6 < 4 then 4 else 2#d4
Roll a d6, and if that
is less than 4 return 4, otherwise return a bag consisting of the results
of rolling 2 d4's.max 2 in (3#d5)
: Return the largest 2 values after
rolling three fivesided dice. min 2 in (3#(if d6 < d6 then 1 else 2))
: Roll
two dice. If the first is smaller, return 1 else 2. Do this three times
and select the lowest two values.
(2#d6) # d6
: First argument to # must be an int.
d(2#d6)
: Argument to d
should be an int.
min 2 in 5
: Second argument to min should be a bag.
min 2 in d5
: Second argument to min should be a bag.
(2#d6) + (2#d6)
: Cannot add two bags.
let x = d6 in x + y
: Unbound identifier y.
A definition can be introduced for later use. Defined names may be multipart identifiers:
new char = 6 # sum max 3 in 4#d6
plus1 = new char + 1
Each time a definition is used, its expression is evaluated anew, unlike
identifiers introduced using let
.
Roll expressions are evaluated in the current mode. There are three different modes,
eval
, dist
, and sample
, each of which can be
entered by using them as commands:
eval
mode  evaluates the expression and returns a
single result. This is the initial mode.
dist
mode  evaluates the expression, but this time
instead of giving out a single result, returns all possible values of
the expression, with their frequency distribution.sample
mode  evaluates the expression multiple times
and returns all of the results. Run with a large enough sample size, the
frequency of certain results should approach those returned in
dist
mode.Additional commands:
mode
: view the current mode
help
: print a help message
prompt.
quit
or q
: quit
load filename
: load definitions from an external file.