Question

Take the following signature

BigInt* addBigInt(BigInt* arg1, BigInt* arg2);

Traditionally, the safest way to implement this function would be for it not mutate the arguments, and would necessarily need to create a new object to result for the operation. Alternatively, if the aim is to conserve on system memory, arg1 could be the object that the resulting operation would return having mutated that object.

The question is, is there an established naming convention the would delineate the nuance between the two implementation choices? Or is this something that would need to be clearly laid out in the documentation where the developer is establishing the convention?

Let's assume this is in C where function overloading is not possible.

Was it helpful?

Solution

If you create a new object, return it.

public int[] square(int a[], int size)
{
   int b[] = malloc(size * sizeof(int));

   for (int i=0; i<size; i++)
       b[i] = a[i] * 2;

   return b;
}

If you don't create an object, return void.

public void square(int a[], int size)
{
   for (int i=0; i<size; i++)
       a[i] = a[i] * 2;
}

Note that programming languages that support method overloading don't usually distinguish between return types. If you really need both functions, just change the name of one of them; perhaps square and square_copy.

OTHER TIPS

Now I have never thought about trying to find naming convention about that. But If the method is void we can speculate that it may be a Procedure.

If I am to name a procedure I would focus more on describing what it does. In my opinion, it is more common for a Procedure to do more than one thing compared to a function and then a procedure would benefit from a more descriptive name even if it does not start with a verb.

In C, you'd use const to indicate that a pointer argument is not mutable. Using your addBigInt example, if you want to indicate that neither *arg1 nor *arg2 are mutable, you'd write

 BigInt *addBigInt( const BigInt *arg1, const BigInt *arg2 );

Any attempt to write to *arg1 or *arg2 in addBigInt should cause the compiler to issue a diagnostic (even if the actual arguments arg1 and arg2 point to are not const). If you were going to write the function such that the result is stored in *arg1, you could do something like

BigInt *addBigInt( BigInt *arg1, const BigInt *arg2 );

You'd just return arg1 rather than a new object. However, that's not perfectly clear just from the signature - you'd want to add some documentation:

/**
 * Adds two BigInts together, result is stored in the object
 * pointed to by arg1
 *
 * Inputs:
 *    arg1 
 *    arg2 
 *
 * Outputs:
 *    arg1
 *
 * Return value: 
 *    arg1
 */

Note that const doesn't necessarily mean "put this thing in read-only memory" (although that may be the result), it just means "this thing is not meant to be written to, and flag any code that attempts to do so."

Basic rules of const and pointers:

 const T *p;  // p is a non-const pointer to const T; you can write to p, but not *p
 T const *p;  // same as above

 T * const p; // is a const pointer to non-const T; you can write to *p, but not p
 
 const T * const p; // p is a const pointer to const T; you cannot write to either p or *p
 T const * const p; // same as above

If you want to make it super explicit that a function modifies its argument(s), you might name it inplace_something() or something_inplace() so the intention becomes apparent without looking at argument or result types which may not be immediately visible in the context of the call.

Licensed under: CC-BY-SA with attribution
scroll top