Потому что есть разные списки. Есть голые списки как в лиспе, там структура представляет собой цепочку узлов, а есть полноценный список, там в интерфейсе узлов не видно вообще (так в с++).
Разница есть даже семантически. Например, в лиспе, не смотря на высокий уровень языка в общем, невозможно из функции вернуть список без присваивания снаружи функции. То есть если ты передашь список в функцию , и там список модифицируешь, без присваивания снаружи функции после возврата новую версию списка получить можно только ещё одним биндом.
В отличии от голого списка, полноценный список можно передать в функцию по ссылке и модифицировать только в функции.
Я не знаю как это называется в ит-науке, не разу не видел таких исследований, что странно: спискам как структуре очень много лет, а различие очевидно
В общем вот как это получается - есть языки, где список объект первого класса (в том смысле, что в системе типов явно определено понятие списка), LISP (где вообще все, включая программу, - список), Haskell, и где нет (C++), строго говоря они делятся по представлению о списке - это либо контейнер либо монада. Монада разворачивается в цепочку соединений (head . tail) где tail может быть чем угодно, включая еще одно такое соединение. Так вот - монады штуки не изменяемые - все что с ней можно сделать это создать на ее основе новую. C++ оперирует более низкоуровневыми понятиями (как и C) для нее список это цепочка из кусков памяти вида template <typename T> Node { T data; Node *next } для первого случая операции соединения и получения списка определены на уровне языка, для второго все отдано на откуп разработчиков библиотек.