Search code examples
nim-lang

expression 'a' is of type 'int' and has to be used (or discarded)


I'm trying to rewrite the cryptomath code from here and I'm getting this when I try to compile to JS;

Hint: used config file '/home/*******/.choosenim/toolchains/nim-1.6.8/config/nim.cfg' [Conf]
Hint: used config file '/home/*******/.choosenim/toolchains/nim-1.6.8/config/config.nims' [Conf]
...........................................................
/home/*******/nim/cryptomath.nim(6, 9) Error: expression 'a' is of type 'int' and has to be used (or discarded)

This is my code:

import std/random
import std/math
randomize()
proc gcd*(a: int, b: int): int = 
    while a != 0:
        a, b = floorMod(b,a), a # fails here apparently
    return (b+a)-a

proc find_mod_inverse*(a: int, m: int): int =
    if gcd(a,m) != 1:
        return -1
    var 
        u1 = 1
        u2 = 0
        u3 = a
        v1 = 0
        v2 = 1
        v3 = m
        q = -1

    while v3 != 0:
        q = floorDiv(u3,v3)
        v1 = (u1 - q * v1)
        v2 = (u2 - q * v2)
        v3 = (u3 - q * v3)
        u1 = v1
        u2 = v2
        u3 = v3
    return floorMod(u1,m) 

I tried adding this, but it did nothing

discard a

before the end of the function


Solution

  • Your code has two issues:

    • Function arguments in Nim are immutable by default, so if you want to overwrite them locally, you need to shadow them or use var

    • Nim syntax for multiple variable assignment is different from Python and is done with tuple-like syntax

    Fixed code would look like this:

    import std/random
    import std/math
    randomize()
    proc gcd*(a: int, b: int): int = 
        var (a, b) = (a, b)
        while a != 0:
            (a, b) = (floorMod(b,a), a)
        return (b+a)-a
    
    proc find_mod_inverse*(a: int, m: int): int =
        if gcd(a,m) != 1:
            return -1
        var 
            u1 = 1
            u2 = 0
            u3 = a
            v1 = 0
            v2 = 1
            v3 = m
            q = -1
    
        while v3 != 0:
            q = floorDiv(u3,v3)
            v1 = (u1 - q * v1)
            v2 = (u2 - q * v2)
            v3 = (u3 - q * v3)
            u1 = v1
            u2 = v2
            u3 = v3
        return floorMod(u1,m) 
    

    The compiler error is unclear, I agree.

    Also, just a tip - keep in mind that standard Nim integers are limited by the architecture's native integer size, so if you want to operate on big numbers, you need to use a separate library.