Basic cons cells in C
A few comments:

typedef your structs:

typedef struct Cell
{
    int val;
    struct Cell *next;
} Cell;


typedef means you no longer have to write struct all over the place:

Cell *cons(int val, Cell *rest)
{
    Cell *cell = malloc(sizeof(Cell));
    cell-&gt;val = val;
    cell-&gt;next = rest;
    return cell;
}


That not only saves keystrokes, it also can make the code cleaner since it provides a bit more abstraction.



I would check if the pointer is NULL rather than if it isn't (related question):

int length(struct Cell *list)
{
    if (!list) return NULL; // or something else like -1
    return 1 + length(rest(list));
}




Set the pointer to NULL after freeing it.

void destroy(struct Cell *list)
{
    if (list)
    {
        destroy(rest(list));
        free(list);
        list = NULL;
    }
}


Re-using a freed pointer can be a subtle error. Your code keeps right on working, and then crashes for no clear reason because some seemingly unrelated code wrote in the memory that the re-used pointer happens to be pointing at.  This is to prevent that.