Язык, Для чего, С чем.
Сперва мини история =)
С недавнего времени занялся изучение программированием, так как это будет в будущем моей профессией. Ну как вы знаете в учебных заведениях нифига не учат и берут только деньги, и студенты ( скажем большая часть ) говорю это, так как я сам на данный момент студент - сидят и играют всякие игры, просто тупое убивание времени. Я этого не понимал, но в скорее я осознал что я "дурак" что тоже сидел, играл игры и т.д. не занимаясь ничём полезным, не думал про будущее.
Скажем так : всё что происходит с человеком - виноват он сам.
Вот я "забыл" на эти игры, начал учится по своей буд. специальности. Сидел на форумах, искал в поисковых системах разную информацию, читал книги.
Я много раз замечал, что на форумах создают темы где спрашивают с чего начать, и почти на всех форумах одинаковые ответы, например ( учи С++ / С# или там Delphi а еще : учи то что тебе нравится ) ну а я подумал, как можно что то изучать, если не знаешь для чего и под что его можно использовать.
Вопрос :
Вот тут я хотел задать вопрос или даже несколько : какой язык и для чего используют, какие направления есть ( там для написание программ, для создание сайта и т.д. ) хотел бы узнать КЛАССИФИКАЦИЮ, НАПРАВЛЕНИЙ чтоб определиться какой язык выбрать ...
Заранее прошу прощение :
- русский у меня хромает - понемногу изучаю.
- если неверно сформулирован вопрос ( от него зависит ответ который я хочу получить, но надеюсь вы поймете что я хочу =) )
- если подобная тема была создана ( типа мне было лень искать, если я даже нашел, ответа того что я хотел - не увидел )
буду очень благодарен, если кто то уделит мне 5-10 мин. своего времени
для написание ответа.
П.С.
- в ходе написания ответа прошу не переходит на личное, типа "купи букварь" и т.д.
- если не знаешь ответ - проходи мимо, глупости не пиши.
Я понимаю, что произвожу впечатления человека, пишущего на лиспе 20 лет, но это не так. Лисп я видел только за стеклом и только в общем и целом знаю что к чему. Поэтому, к сожалению, как-то не приходилось искать исходники на нем, а первые страницы гугла по запросу "исходники lisp" ничего хорошего не дали.
Если тебе интересно проверить себя, то с удовольствием послушаю твои наблюдения. Если есть желание проверить меня, то всегда к вашим услугам;)
Ты наверно не там искал. Рыть исходники нужно на гуглокоде.
Не производишь. Я же дразнюсь просто.
Возьмём какой-нибудь короткий пример:
(let ((var (first var-and-range))
(start (second var-and-range))
(end (third var-and-range)))
`(do ((,var (next-prime ,start) (next-prime (1+ ,var))))
((> ,var ,end))
,@body)))
Вот без объяснения и подготовки мне тут ничего непонятно.
Взято отсюда:
http://lisper.ru/pcl/macros-defining-your-own
Но, в общем, это справедливо не только для Лиспа. Возьмём пример на стандартном C++:
http://forum.codenet.ru/showpost.php?p=342136&postcount=3
Красота? :D
Если он про это говорил:
"""Build a connection string from a dictionary of parameters.
Returns string."""
return ";".join(["%s=%s" % (k, v) for k, v in params.items()])
if __name__ == "__main__":
myParams = {"server":"mpilgrim", \
"database":"master", \
"uid":"sa", \
"pwd":"secret" \
}
print buildConnectionString(myParams)
То тут несоответствие имени функции PEP-8, непонятно, зачем словарь, когда можно было использовать список списков (или кортеж кортежей), да и перенос строк тут не нужен в таком виде.
А что касается примера с матрицей (тот самый на C++), то ниже я привёл аналогичный по смыслу код на Python. При том, он не только во много раз лаконичнее, но и гибче. Но самое главное, это пример того, как знание Python помогает понять некоторые хитроумные выверты в STL.
Вот вам и Паскаль для алгоритмов... И я ещё про значение утиной типизации в ООП не начал рассуждать ;)
Дык и к чему ты это сказал? :)
Я пытался понять, что там "вырвиглазного". Так как там всё сравнительно просто, значит "вирвиглазность" в отклонении от каких-то норм. Вот и предполагал от каких.
Вот без объяснения и подготовки мне тут ничего непонятно.
Кстати, вот вариант do-primes на Nemerle (используется очень примитивный алгоритм):
syntax("for", "primes", "(", varAndRangeDef, ")", body)
{
def makeResult(varName, start, end)
{
<[
def isPrime(x : int) : bool
{
match(x & 1)
{
| 0 => x == 2
| _ =>
def sqrtX = System.Math.Sqrt(x) :> int;
def loop(d)
{
match(x % d)
{
| 0 => false
| _ when d > sqrtX => true
| _ => loop(d + 1)
}
}
loop(3)
}
}
def nextPrime(x : int) : int
{
def loop(_)
{
| x when isPrime(x) => x
| x => loop(x + 1)
}
loop(x)
}
def startValue = $start;
def endValue = $end;
def loop(x) : void
{
when(x <= endValue)
{
def $(varName : name) = nextPrime(x);
{ $body }
loop($(varName : name) + 1);
}
}
loop(startValue);
]>
}
match(varAndRangeDef)
{
| <[ $(varName : name) in [$start, $end] ]> =>
makeResult(varName, start, end)
| x =>
Message.Error(x.Location, "variable and range definition expected");
Parsetree.PExpr.Error(x.Location)
}
}
Использование:
WriteLine(x);
Кода с виду больше из-за того, что я заинлайнил в квазицитату вспомогательные функции isPrime и nextPrime (и написал циклы через рекурсию). По идее следующим шагом должно стать использование нормальных алгоритмов а также предвычисление компилятором простых чисел.
Ну смотри. Во-первых это отдход от темы, что не есть гут. Потому как флуд и оффтоп. Во-вторых, если уж говорить о вырвиглазности приведенного выше кода - ты привык и пишешь на питоне, поэтому ни разу не объективен. Мой взгляд куда объективнее, потому что на питоне я пишу настолько мало, что можно считать, что на питоне я не пишу. А сравнить мне есть с чем. Так что ты давай как-то дискутируй уж посодержательнее, будь добр. :)
Посмотрел на твой пример и понял, что на Лиспе я привёл не всё необходимое. Возможно, если привести остальной код, то он будет ближе по размеру к тому, что на Немерле.
Но это только доказывает, что я в том коде ничего не понял.
George, я не хотел тебя обидеть. Наоборот. Откуда же я знаю, что ты знаешь, а что нет? Вроде бы в разделе по Питону что-то советуешь. А то, что я тебя нечаянно задел, не есть причина говорить "Так что ты давай как-то дискутируй уж посодержательнее, будь добр."
Однако, я понял, что ведение мною этой темы уже многих напрягает, потому завершаю.
На самом деле Лисп лаконичнее из-за использования других макросов и особенностей синтаксиса. :)
Однако, я понял, что ведение мною этой темы уже многих напрягает, потому завершаю.
Ты меня неверно понял. Я на тебя не обижался и не собирался обижаться. Просто ты ушел от темы и я не понял зачем. Речь ведь не шла о вырвиглазности конкретно приведенного примера, речь шла о том, нужно ли начинать с вырвиглазных примеров. Впрочем тут и Санила Сан не совсем прав, ведь Dive Into Python - не для начинающих книга.
Дискутируйте дальше, я че против. Только зачем ж в оффтоп скатываться, это мешает.
Тьфу... Тогда Немерл получается - ацтой. :(
Кстати, не могу рационально объяснить, но написание кода на Лисп и Ским мне доставляет какое-то моральное удовольствие. Куча скобок никак не мешает. Хотя я ничего серьёзного на них не писал, так, баловался в познавательных целях.
А тот же Пайтон щупал - синтаксис с отступами нравится, компактная запись простеньких примеров для начинающих нравится. А как попробовал ООП - отвращение... Опять же, без рационального объяснения.
Раз уж тут разговор идёт на все темы, то спрошу: что лучше - знать один язык на пятёрку или два (несколько) на троечку?
Сам же дам один вариант ответа: думаю, всё зависит от обстоятельств. Если есть шанс получить работу высокооплачиваемого специалиста, то лучше повышать знания и опыт в одном языке. А если карьерного роста не предвидится и т. п., то лучше освоить несколько языков, пусть и посредственно, - тогда проще найти работу хоть на одном из них.
А где в Лиспе (Scheme по-русски - Схема) вывод типов? ;) Или язык с аналогичной мощностью и фичами в .NET-е? И опять же я объяснил почему пример на Nemerle длиннее. В любом случае, действительно качественное решение, расчитывающее на этапе компиляции ("суперкомпиляция") либо берущее откудато еще простые числа будет совершенно иным.
На запрос типа "юнит тесты c#" выдаются ссылки на форумы с минимумом инфы, на запрос типа "юнит тесты python" выдаются ссылки на документацию и т. п. Случайность?
В принципе, оно понятно: то, что в статике отловит компилятор, в динамике придётся ловить тестами.
Я не ради холивара, а для прояснения ситуации.
Естественно (только это культурой язык не поворачивается называть). Попробуй-ка порефактори код в языках, где компилятор тебе не будет говорить что в классе X нету метода A. Вот потому и приходится педалить примитивные тесты :) Напротив, в проектах на статически типизированных языках достаточно крупных функциональных тестов.
Тогда нафига идти в эти конторы работать, если у них HR не способен объявление составить (либо узнать у местного технаря, кто же им всетаки нужен)?
Кстати, вот тут ищут программиста на Brainfuck.
Ок. Продолжим. Трудно сказать был ли оффтоп, ибо я понял так, что книгу критикуют, понимая, что она не для начинающих.
Ты просто не понял преимущества утиной типизации. В компилируемых языках надо выстраивать хитроумные конструкции с абстрактными классами для полиморфизма. Особенно усложняется задача, если уже есть готовый библиотечный класс, который мы планируем заменять на другой в процессе работы.
В Python же объект, упрощенно говоря, сам решает надо ли ему обрабатывать вызов метода или нет, поэтому извращаться с абстрактными классами нет смысла.
Если интересно, можешь ещё тут почитать про подобный принцип:
http://www.smalltalk.ru/articles/smalltalk.html
Тут вот какая штука. Насколько я знаю, юнит-тесты зародились в Smalltalk, затем были переняты в Java, а оттуда перекочевали в Python. Возможно, поэтому они в Python (те, что в стандартной поставке) выглядят немного неестественно.
Не знаю, где больше применяют юнит-тесты, в Java или в Python. Почему-то многие, казалось бы продвинутые питонеры, юнит-тесты не используют, хотя и знают про них.
Юнит-тестами отлавливают смысловые ошибки, типа проверки, что функция sum вычисляет сумму, а не что-то другое. Те ошибки, что выявляются компиляцией, определяются случайно при использовании юнит-тестов.
Кроме того, то что в динамике можно выявить пристальным взглядом на 3 строчки, в статике придётся выискивать в 30 (утрирую немного, но пример с матрицей подтверждает). Это на тему "статика vs динамика".
[QUOTE=hardcase]Попробуй-ка порефактори код в языках, где компилятор тебе не будет говорить что в классе X нету метода A.[/QUOTE]
Рефакторить проще там, где код короче, где классы и функции компактные.
Нельзя отрицать того, что компилятор отлавливает некоторые (в основном, глупые) ошибки. Но приведенный пример неудачен, так как есть инструменты типа:
http://pychecker.sourceforge.net/
которые решают аналогичные задачи.
Честно говоря, сам я использую не этот инструмент, ибо пока устраивает альтернатива, встроенная в UliPad.
И часто ты проверяешь, правильно ли процессор складывает? ;)
Я не спорю, юнит тесты полезны, но в статике их нужно значительно меньше.
В статике придется заюзать такую штуку как "Find Referencies" и - о чудо - IDE покажет в каких местах используется тот или иной класс, метод или переменная.
Рефакторить проще там, где есть тесты. В динамически типизированных языках любого количества тестов всегда будет недостаточно. По построению. В статике же как правило достаточно больших функциональных тестов.
А что делает указанный инструмент? Правильно - занимается статической типизаций динамического кода, при том он никогда не сможет полностью типизировать код, что называется по-построению. А если нет разницы, то зачем закладывать в проект потенциальные проблемы связанные с динамикой?
:D А народу вон - вижуалстудии мало, все решарпер подавай.
Ты просто не понял преимущества утиной типизации. В компилируемых языках надо выстраивать хитроумные конструкции с абстрактными классами для полиморфизма. Особенно усложняется задача, если уже есть готовый библиотечный класс, который мы планируем заменять на другой в процессе работы.
В одних статически типизированных языках (C#, Java, Nemerle) есть такая штука, как интерфейсы. А в других (Scala, Ocaml) поддерживается парадигма структурной типизации (что конечно значительно круче). И вот эта структурная типизация - о чудо - делает то же что и "утиная типизация" в Питоне, только проверка того, подходят ли сигнатуры происходит на этапе компиляции.
Понимаю, юмор. Но не обязательно же складывать 2 числа, можно складывать более сложные структуры.
На счёт значительно - не уверен. Я столько же использую в Python, сколько и в C++. В основном, проверяю, что у меня правильно рассчитываются формулы. Если же использовать TDD, то наверняка в C++ придётся их сделать больше, ибо понадобится больше объектов.
Во первых, тут уже надо использовать мощь IDE.
Во вторых, оно не везде сработает. Там, где будет использованы разные виды полиморфизма, шаблоны и прочие макросы это наверняка не сработает. То есть, когда начнём применять гибкие решения, все инструменты, использующие жесткие конструкции перестанут иметь смысл.
Ну так типизацией занимается инструмент, а не человек. Есть же разница.
Чтобы получить преимущества её и избавиться от проблем статической типизации. Очевидно же.
То есть, когда начнём применять гибкие решения, все инструменты, использующие жесткие конструкции перестанут иметь смысл.
Так ты попробуй что-то отличное от C++ :)
C# хотя бы или Scala. Ясен пень если сравнивать C++ и Python, то на последнем программы значительно быстрее стряпаются - эргономика-с.
Кстати, вопрос про количество строк также решается выбором языка. На том же Boo или Nemerle (в режиме indent) кода будет не больше чем Python-овского на аналогичных задачах, ато и вовсе меньше.
Может и чудо. Я как-то показывал, как на C++ сделать подобное "чудо", используя шаблоны. Но есть тонкости в том, как сами объекты воспринимают сообщения. В динамике они могут, например, сообщение проанализировать как набор строк, а не как вызов определённого метода. Это добавляет гибкости.
Пока нет ничего подходящего для моих задач. Для контроллеров нужен ассемблер, си или C++, а для остального вполне Python-а хватает, учитывая "батарейки" (за которые мне пока не предлагают кабальные условия) и кросплатформенность.
А зачем же этот функционал нужен в каждом классе? Ежели мне потребуется подобного рода тип данных - я его опишу используя тот или иной язык. В одних языках будет короче, в других - длиннее. В статике очень важен вопрос правильного выбора языка. Языки с развитой системой типов и обладающие продвинутым выводом типов способны покрыть все "фичи" динамики - это мой поинт.
Этому треду просто не хватало самоиронии
Возьмём какой-нибудь короткий пример:
(let ((var (first var-and-range))
(start (second var-and-range))
(end (third var-and-range)))
`(do ((,var (next-prime ,start) (next-prime (1+ ,var))))
((> ,var ,end))
,@body)))
Вот без объяснения и подготовки мне тут ничего непонятно.
Взято отсюда:
http://lisper.ru/pcl/macros-defining-your-own
Но, в общем, это справедливо не только для Лиспа. Возьмём пример на стандартном C++:
http://forum.codenet.ru/showpost.php?p=342136&postcount=3
Красота? :D
Каппитан очевидность как бы помог мне быстро расшифровать этот код. Его суть: подается структурированный массив из переменная, начало, конец (начало, конец - range)
Ищутся простые числа (next-prime по всей видимости еще один макрос, который, судя по названию находит простое число) и что-то делается после этого в body.
Знание английского и длань Господня помогли мне понять суть?
З.Ы. Извиняюсь за долгое отсутствие. Пришлось съесть 4 книжки по Лиспу пока не вкурил код:rolleyes:
Сам же дам один вариант ответа: думаю, всё зависит от обстоятельств. Если есть шанс получить работу высокооплачиваемого специалиста, то лучше повышать знания и опыт в одном языке. А если карьерного роста не предвидится и т. п., то лучше освоить несколько языков, пусть и посредственно, - тогда проще найти работу хоть на одном из них.
А ты сам-то как думаешь? ;)
Правильный ответ: и то, и другое. Ещё более правильный ответ: ни то, ни другое. Почему? Опять же, если ты виртуозно программируешь только на Ada, то найти такому знанию коммерческое применение в том же Казахстане будет непросто настолько, насколько непросто тебе дастся убеждение кадровика или ПМ, что ты освоишь работу на C# за неделю.
Вторая причина: если ты виртуозно программируешь на С#, то ты вряд ли скоро попадёшь в команду разработчиков на Django, хотя вряд ли тебя это будет сильно беспокоить: в мире достаточно мест, где нужны хорошие дотнет-разработчики.
Из первых двух причин есть одно дивное следствие: умение виртуозно программировать только на Ada или только на C# никак не сказывается на том, сколько денег ты будешь получать за такое умение. Мастеров сишарпа много, между ними большая конкуренция, и естественно сложившаяся верхняя планка дохода, который такие мастера могут создать и, соответственно, часть которого получить.
Мастеров Ады мало, конкуренции между ними на территории СССР, видимо, нет вовсе, однако там и потребность в них чуть больше нуля. Доход этих мастеров тоже может быть определён как функция от стоимости работы и производительности труда. Более того, доход любого программиста определяется той же функцией.
Отсюда вывод: надо не на языке как таковом заморачиваться, а становиться эффективным программистом. Одним знанием языка тут не отделаешься. Ну а конкретные советы лучше спросите у Green'а, он знает это лучше меня. Меня вообще учили, что если хочешь программировать хорошо, надо учиться по ходу дела и программировать. Много. Тогда что-то получится.
А карьерный рост суть мистификация. Не понимаю, как это может кого-то привлекать.
А карьерный рост суть мистификация. Не понимаю, как это может кого-то привлекать.
Я бы не стал так категорично заявлять. Хорошо, допустим, иметь в 20-30 лет доход в 5 кило баксов, при этом занимаясь кодингом на постоянном месте работы, но когда года бегут неумолимо, и в 40 лет с кодера так и не продвинулся никуда, а над тобой стоят мальчики по 25 лет, и руководят (хорошо или плохо это другой вопрос), то тут начинает точить червячок сомнения, правильно ли ты по жизни идешь. Здесь можно рассмотреть вариант ухода полностью во фриланс, т.е. по сути свой частный бизнес. С другой стороны драть задницу исключительно из карьерного роста это глупо, т.к. сил это отнимает много, а результат не гарантирован.
Оно даётся как бонус за парадигму. И ещё несколько подобных бонусов :)
Я это воспринимаю так: статические языки, обладающие "фичами" динамики, круче тех статических, которые ими не обладают :)
Для меня же не очевидно что круче, программа, рассчитанная на интеллектуальный интерпретатор или программа, рассчитанная на переработку компилятором, создающим код для примитивного интерпретатора. Если уж интерпретатор ни прост, ни сложен, то ещё более неочевидно. Тут интерпретатором зову всё, что исполняет приложение.
...
Знание английского и длань Господня помогли мне понять суть?
З.Ы. Извиняюсь за долгое отсутствие. Пришлось съесть 4 книжки по Лиспу пока не вкурил код:rolleyes:
Самоиронией уже обладаешь. Это я заметил :)
Статически типизированные языки не обладают "фичами" динамических - это очевидно. Они могут (или не могут, в зависимости от языка) предложить типобезопасную альтернативу, хотя динамическая типизация в статически типизированных языках в ограниченной форме присутствует (например приведение типа от общего к частному). Ты понимаешь какие бонусы дает безопасность типов? - это 1) гарантированное отстутствие в программе целых классов логических ошибок, 2) производительность скомпилированного кода.
А кто его знает, что ожидать от языка, который выполняется виртуальной машиной со сборщиком мусора и прочими хитростями? :)
Да и сборщик мусора - это изначально была "фича" динамических языков.
Первое - не очевидно.
Второе, если говорить не о безопасности типов, а о "динамика vs статика" - да. Насколько я знаю, теоретически динамика отстаёт от статики минимум на 40 % (может не точно помню цифру). Если говорить о безопасности типов, то си рвёт по скорости ваши хвалёные "скоростные" языки :)
И не надо говорить, что Java может каждый раз компилироваться в идеальный код, рассчитанный на конкретное железо. То же могут и компиляторы си. Код придётся перекомпилировать вручную, но мы то говорим о скорости :)
Да и сборщик мусора - это изначально была "фича" динамических языков.
Сборщик мусора к способу типизации языка совершненно никакого отношения не имеет, для его работы нужна полная метаинформация о типах в рантайме. Если рантайм языка не предоставляет этой метаинформации, то GC невозможен (например как в C++).
Дык систему типов нужно использовать уметь :) Вот к примеру типичная задача - эскейпинг строковых литералов при выводе в HTML. Что бы ты использовал для этого? Тип string? А я бы сделал тип EscapedString с оператором неявного приведения, который бы осуществлял эскейпинг, все функции вывода в поток принимали бы на вход этот EscapedString. Т.о. можно получить гарантированную защиту от того что я не получу мусора (либо в худем случае скриптовых инъекций) между генерируемыми тегами.
Только в Си нет никакой гарантии типбезопасности.
Я не про то, где невозможен, а про то, откуда пришло. Ибо мне видится, что люди пытаются пилить языки от ассемблера в сторону Лиспа и Смоллталка, и берут оттуда всё, что могут. Вероятно, думают найти особый гибридный путь. Ну, в общем, и находят.
Не совсем удачный пример. В Python тоже можно проверять тип объектов - не проблема. Тип то есть, просто он не задан явно.
И я про это.
А тут и проверять не нужно - компилятор сам проверит и вставит в код нужные преобразования. Автоматически.
Дык это очевидно :) Не знаю какой там был Смоллтолк, но Лисп значительно мощнее чем существующие мейнстримовые языки. Вот мейнстрим потихоньку и впитывает фичи, возможные в нем. Заметь, интерес к функциональному программированию в мейнстриме возник не так давно - год-два назад по сути, и с тех пор он лишь возрастает.
hardcase, скажи, а в Немерле есть что-то уникальное, чего не было в других языках? Или это чистый гибрид?
В Nemerle уникально сочетание фичей: ООП + ФП + развитое МП, все типобезопасно, есть могучий вывод типов. Для особенных извращенцев можно вообще свой фронтэнд городить - т.е. собственные парсеры прицеплять.
Да вроде я понимаю, что такое утиная типизация. Только зачем она?
Вот ты берёшь объект, и начинаешь гадать, чем он является:
так, плавает - возможно, утка (но может быть рыбой);
так, летает - может быть уткой (но может быть летающей рыбой);
так, крякает - сильно возможно, что утка (но есть варианты).
Я беру объект, смотрю на бирку:
Назначение: для ванны
Материал: резина
Фича: с пищалкой
Цена: ***
Made in China
Всё известно сразу! Мне не нужно гадать!
http://www.smalltalk.ru/articles/smalltalk.html
Ссылка интересная, спасибо. После прочтения осознал, что означает посылка сообщения в подобных языках. Раньше приравнивал это к вызову метода.
Да, уникальные языки разрабатывают умные люди, а плохие языки продвигают умные люди...
Сколько читал на rsdn вопросы к немерлистам, чем же хорош Немерл - в ответ лишь расплывчатые фразы с хитрыми-умными словами.
Нужно как-то так: Nemerle позволяет писать компактный код как у динамических языков, но безопасный, как у статических. И поэтому быстро срубать бабло! Кучу бабла! И народ потянется к Немерлу :)
И ещё нужно не употреблять слово макросы: столько времени твердится, что макросы - зло, и народ уже шарахается от них. В данном случае как раз хорошо употреблять взамен умное загадочное слово - метапрограммирование :)
То есть Nemerle, в отличие от Лиспа, например, не представляет научного интереса, а только чисто практический?
Ибо для многих .Net не нужен, а использовать с Nemerle mono уже слишком большой риск - зависимость от двух экзотических разработок, создаваемых энтузиастами. Потому практическая польза для линуксоидов, например, весьма сомнительна. Был бы хотя бы научный - другое дело.
Вот ты берёшь объект, и начинаешь гадать, чем он является:
так, плавает - возможно, утка (но может быть рыбой);
По примеру и ответ. Берём утку, рыбу, катер и говорим им плыть. В динамике они поплывут, в статике они потребуют общего "папу". Можно создать "папу" (этакое чудище), если за классы этих объектов отвечаю я, сложнее, если эти классы делал не я. Придётся хакерствовать. А хакерство при программировании ведёт к ошибкам.
А что ты понимаешь под научным интересом? И каков научный интерес у Лиспа? Диссертации на компиляторе и языке несколько человек защитили, да там и еще можно, если покопать.
Зачем им общий "папа" это же совсем разные по стркутуре и логике сущности.
И мы натыкаемся в этом примере на тот самый "structural typing pitfall" - сигнатуры методов совпадают, но предназначены методы совершенно для различных целей.