Uma declaração de retorno passa um valor de volta para o chamador imediato do quadro de chamadas da função atual. No caso de recursão, esse chamador imediato pode ser outra invocação dessa mesma função.
Na maioria dos idiomas, se você não usar o valor de retorno de uma função chamada (recursivamente ou não), esse valor de retorno será descartado ou será um erro diagnosticável. Em alguns idiomas, o valor de retorno da última chamada de função é reutilizado automaticamente como valor de retorno da chamada de função atual, mas eles não diferenciam entre chamadas de função normais e recursivas.
Supondo que os valores de retorno não utilizados sejam descartados silenciosamente, se você tivesse escrito o código dessa maneira:
list *search_list(list *l, item_type x) {
if (l == NULL) return(NULL);
if (l->item == x)
return(l);
else
search_list(l->next, x); // no return!
}
então search_list
só iria devolver um valor definido para uma lista vazia (NULL) ou se o primeiro item corresponde ao valor que você está procurando. Assim que a função entra na chamada recursiva, você não sabe qual será o resultado, porque o resultado da chamada recursiva é descartado.
Além disso, você promete retornar um valor de sua função, mas possui um caminho (o recursivo) em que não especifica qual valor retornar. Dependendo do idioma que você usa, isso geralmente resulta em um diagnóstico obrigatório ou em um comportamento indefinido (que é uma abreviação de: tudo pode acontecer e pode mudar a qualquer momento sem aviso prévio. Não se responsabilize se alguém estragar tudo sua apresentação mais importante). Há algumas situações em que o valor de retorno ausente pode parecer funcionar, mas isso pode ser alterado na próxima vez em que o programa for executado (com ou sem recompilação).
return
faz.