В чем отличие данной записи с дженериком и без?
Но что нам мешает сделать такую же функцию без дженерика, а с типом Any? Ничего. Так же можно использовать forEach. Я не говорю что дженерики не нужны, только ответил вопрос.
Два типа Anyи AnyObject являются так называемыми Nonspecific types. Неспецифичные типы служат указателем компилятору о возможности хранения любого типа. НО за такую возможность нужно платить и Вы платите: Во-первых отсутствием информации о типе на момент компиляции, вы не можете вызвать, скажем некоторое св-во у String, даже зная, что присвоенная переменная на самом деле является типом String. У вас просто не будет такой информации ровно до тех пор, пока вы не преобразуете этот тип обратно. 
Конечно во время выполнения Swift прекрасно понимает, какой именно тип находится в переменной типа Any, но это только во время выполнения кода, на момент компиляции информация об этом отсутсвует. Во-вторых вы платите скоростью, при работе с такими типами. У компилятора нету информации о типе, а значит он не может произвести необходимые оптимизации. 
Функция print(_:separator:terminator:) получает информацию о том, что вывести в консоль, исходя из того, что все стандартные типы реализуют протоколы CustomStringConvertible, CustomDebugStringConvertible,CustomReflectable в реализации которых содержится информация о типе(текстовая). Если у типа нет реализации этих протоколов, print(_:separator:terminator:) выводит просто название типа. 
Более того, вы всегда можете вывести так называемый дамп у абсолютного любого типа в консоль посредством функции dump(_:name:indent:maxDepth:maxItems:).
За более подробной информации о всех возможностях и разновидностях функций для работы с Debugging and Reflection можно глянуть тут 
------------------------------------------------------------------------------------------------------------------------
Дженерики же - это просто заместители(placeholders) типов. На момент компиляции, компилятор вместе вашего заместителя, скажем T подставит конкретный тип, скажем String. Что в свою очередь приводит к тому, что у дженериков отсутствуют проблемы указанные выше. (Даже моё "во-первых" у дженериков отсутствуют, если вы накладываете на них ограничения. )
------------------------------------------------------------------------------------------------------------------------
P.S. На самом деле Дженерики одна из самых прекрасных и Сильных сторон языка Swift, и моя жалкая попытка вам пояснить - не объясняет должном счётом ничего. Изучайте их.