# Compile time constants and global variables

I’m trying to convert a Nim program to Rust. I’m able to write and test each proc/functions/routine separately and verify they work (create correct output).

The problem I’m having is creating the whole program where I’m using global variables and am creating at compile time some runtime constants.

Here’s link the whole Nim code:

The particular problem is trying to do the compile time constant compilations, as shown here:

``````proc genPGparameters(prime: int): (int, int, int, seq[int], seq[int], seq[int]) =
## Create constant parameters for given PG at compile time.
echo("generating parameters for P", prime)
let primes = [2, 3, 5, 7, 11, 13, 17, 19, 23]
var modpg = 1
for prm in primes: (modpg *= prm; if prm == prime: break)  # PG's mdoulus

var residues: seq[int] = @[]    # generate PG's residue values here
var (pc, inc) = (5, 2)
while pc < modpg div 2:
pc += inc; inc = inc xor 0b110
let rescnt = residues.len       # PG's residues count

var restwins: seq[int] = @[]    # extract upper twinpair residues here
var j = 0
while j < rescnt - 1:
if residues[j] + 2 == residues[j + 1]: restwins.add(residues[j + 1]); j.inc
j.inc
let twinpairs = restwins.len    # twinpairs count

var inverses: seq[int] = @[]    # create PG's residues inverses here
for res in residues: inverses.add(modinv(res, modpg))

result = (modpg, rescnt, twinpairs, residues, restwins, inverses)

# Generate at compile time the parameters for PGs.
const parametersp5  = genPGparameters(5)
const parametersp7  = genPGparameters(7)
const parametersp11 = genPGparameters(11)
const parametersp13 = genPGparameters(13)
const parametersp17 = genPGparameters(17)

# Global parameters
var
pcnt = 0             # number of primes from r1..sqrt(N)
num = 0'u64          # adjusted (odd) input value
twinscnt = 0'u64     # number of twin primes <= N
primes: seq[int]     # list of primes r1..sqrt(N)
KB = 0               # segment size for each seg restrack
cnts: seq[uint]      # hold twin primes counts for seg bytes
lastwins: seq[uint]  # holds largest twin prime <= num in each thread
pos: seq[int]        # convert residue val to its residues index val
# faster than `residues.index(residue)`
modpg:     int       # PG's modulus value
rescnt:    int       # PG's residues count
pairscnt:  int       # PG's twinpairs count
residues:  seq[int]  # PG's list of residues
restwins:  seq[int]  # PG's list of twinpair residues
resinvrs:  seq[int]  # PG's list of residues inverses
Bn:        int       # segment size factor for PG and input number
``````

I heard Rust doesn’t allow globals, if so what is the equivalent process to achieve what I want?
The ultimate goal is to create the Rust version of this algorithm and benchmark it to the Nim and D versions I have. Someone did an old Rust version of an older (slower) implementation, but now I’m trying to see if I can do a Rust version myself to implement the new version.

I would appreciate any help and suggestions.

Rust does have globals, but it is very hard to use them. I would recommend trying to refactor your code to not use globals.

Here is how you create globals, not that globals are read-only be default, so you will need to use some syncronization like a `Mutex` to write to them.

``````static NAME: Type = Value;
``````
1 Like

The lazy_static crate might also be worth to have a look at. I use it in rs-pbrt

In particular (see RADICAL_INVERSE_PERMUTATIONS, a `Vec<u16>`, which gets initialized by the
compute_radical_inverse_permutations function which gets called only once by `lazy_static!`):

``````lazy_static::lazy_static! {
#[derive(Debug)]
static ref RADICAL_INVERSE_PERMUTATIONS: Vec<u16> = {
let mut rng: Rng = Rng::new();