Samir Parikh / Blog

Originally published on 05 October 2019

When working through the Project Euler problems, you are often asked to determine whether a given integer is prime, especially early on. Rather than copying and pasting the same function from program to program, I thought I would see if I could "package" up the function in a module which could then be imported into any program that required it. This would make the function more reusable.

To do this, create a subdirectory func within your current working directory (you can name the subdirectory anything you want) and then create the module isprime.d within the func directory. Then save the following as func/isprime.d:

module func.isprime;
bool isPrime(int n) {
    // check to see if n is prime

Now, within your main working directory, you can create the program that needs to call the isPrime function to solve whatever problem you are working on. For example, main.d could be:

import func.isprime;
void main() {

Originally, when I tried to compile main.d, I would get the following error:

$ dmd main.d
main.o: In function `_Dmain':
main.d:(.text._Dmain[_Dmain]+0xa): undefined reference to '_D4func7isprime7isPrimeFiZb'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1

I posted this question on the Learn mailing list and Adam Ruppe thankfully set me straight. The issue really boiled down to how I was compiling the program. You either need to include the module being imported:

$ dmd main.d func/isprime.d

or you need to use the -i flag which tells the compiler to include any imported modules in the compilation:

$ dmd -i main.d

Just a couple of things to note:

  1. By convention, module names (e.g. func.isprime) should be lower case.
  2. The name of the module (e.g. isprime) should not be the same as the function, or member (isPrime).

This topic is covered fairly well in Chapter 2 of Michael Parker's "Learning D" and Ali Çehreli's "Programming in D" book.