пятница, 6 ноября 2009 г.

[comp.prog.flame] Почему мне не нравятся соревнования на длину программы

В комментарии к одной из предыдущих заметок ув.тов.Ctapmex поделился ссылкой на отбор задачи для очередного сравнения Haskell vs C (да и вообще все против всех). Ну не подходит тов._adept_-у The Computer Language Benchmark Game (равно как и WideFinder, и Raytracer), ну что поделать – нужно придумать свой конкурс ;)

Я к такого рода соревнованиям отношусь скептически. Хотя и положительные стороны у них так же есть. Если не брать в расчет замеры скоростей на микробенчмарках (чем и является Benchmark Game), то самое важное достоинство таких соревнований – это демонстрация более-менее обычного кода на конкретном языке программирования. Поскольку примеры типа ping-pong на Erlang и QuickSort на Haskell, равно как и числа Фибоначчи на OCaml уже всех забабахали. А тут можно увидеть “живую” программу на языке, о котором ты раньше только слышал. Ну и впечатлиться. Или в очередной раз сказать: “ну нах”.

На этом достоинства, пожалуй, заканчиваются. А начинаются расхождения с реальной жизнью. Главное из которых – это несоответствие масштабов. Подобные соревнования обречены на микроскопический масштаб: делается все это just for fun, в свободное время, которое мало кто хочет тратить на написание большой и ненужной ему программы. Что плохо, поскольку:

  • программирование ради удовольствия сильно отличается от программирования за едуденьги. Ведь когда все делается с интересом, с удовольствием, с соревновательным азартом, возможности конкретного программиста значительно возрастают. Кроме того, программист может не замечать каких-то отрицательных моментов. Тогда как в обычной жизни очень многим приходится решать задачи, которые бы мы с радостью не решали. В таких условиях какой-то мелкий недостаток языка будет восприниматься как большая проблема и будет регулярно отнимать время и вызывать фразы, вроде “вот бл*, как меня это все заеб*ло!” (в качестве примера – в C/C++ после объявления типа структуры/класса нужно ставить точку с запятой, что я временами забываю делать). Поэтому, на мой взгляд, высоки шансы того, что разработчик с удовольствием решает соревновательные задачки на Ruby, но потом плюется от необходимости сопровождения 30K строк собственного Ruby-кода в mission critical приложении;
  • написание больших и маленьких программ очень сильно отличается по трудозатратам. И некоторые качества языка непосредственно сказываются на возможностях писать программы большого объема. Например, наличие пространств имен или модульности, наличие сборки мусора, наличие/отсутствие статической типизации и т.д. Поэтому, например, на маленьких задачках Ruby и Python по лаконичности будут рвать C++/Java/C# в клочья. Но на объемах свыше 100KLoc ситуация сильно изменится, а на объемах свыше 1MLoc станет совершенно другой;
  • программы редко пишутся в одиночку. Обычно это командный процесс. Но даже если над программой изначально работает один-два человека, то успешная программа, как правило, переживает не одну серьезную переделку разными людьми. Маленькие программки не позволят оценить удобство языка в условиях командной разработки. Так, один-два хороших C++ника способны наваять отличную, быструю и безглючную программу на C++. Но, стоит увеличить команду разработчиков в 10-20 раз, как вероятность успешного создания очень большой программы на C++ окажется сильно ниже, чем аналогичной на Java. Точно так же, пока над Lisp-евским кодом корпит один человек – это одно, но когда этот код будет передан второму разработчику на сопровождение, затем третьему, затем четвертому – насколько удобно каждому следующему программисту будет разбираться с творчеством предыдущих разработчиков?
  • в мелких соревновательных программах внешние библиотеки играют совсем незначительную роль. По определению. Ведь задача изначально ставится так, чтобы показать возможности языка – это предполагает, что все решение придется писать с нуля и полностью, с минимальным использованием внешних библиотек. Тогда как в обыденном, повседневном программировании приходится комбинировать обращения к сторонним компонентам/библиотекам;
  • не учитывается, что принцип “для каждой задачи свой язык” применим далеко не всегда. Например, есть группа C++ программистов, работающих над С++ проектом. Один из них сталкивается со вспомогательной задачкой, которую проще решить на Ruby (Python, OCaml, Haskell), а ее решение на C++ обойдется на 30-50% дороже. Имеет ли смысл брать Ruby? Зачастую нет. Поскольку кто это решение дальше будет сопровождать? Ведь это команда C++ников, отношение которых к Ruby может быть самым разнообразным. И если вы думаете, что выгодно научить кого-то языку Ruby, то задумайтесь, хотите ли вы, чтобы вас учили какому-нибудь Perl или Rebol?

В общем, если резюмировать, то подобные соревнования так же объективны, как соревнования между аккумуляторной дрелью и перфоратором. Дрелью вы сможете сделать маленькие и аккуратненькие отверстия в деревянном ящике, но не сделаете ни одной дырки в бетоне. А с перфоратором наоборот. Поэтому сравнивать языки нужно на больших задачах (например, пусть бы кто-нибудь реализовал gold не на C++, а на своем любимом языке – это было бы более адекватным сравнением).

Реализация простой задачи на разных языках имеет большой смысл в одном случае: когда вы сами хотите получить впечатление от работы на каком-то языке. Ведь почему мы пробуем новые языки? Потому, что нас в них что-то цепляет. Скажем, я когда-то давно перешел на C++ потому, что там можно было создать класс “множество” и этот класс не отличался бы от встроенного в язык типа. Этого мне в C/Pascal очень не хватало.

Вот когда в языке что-то зацепило, что-то в нем понравилось, хочется проверить, как оно – программирование на нем? Тогда можно самому сделать на новом языке что-то, что уже делал раньше. И сравнить собственные впечатления. Тут главное – программировать самому. Конечно, перечисленные выше недостатки на счет несовпадения масштабов и здесь присутствуют. Но задача уже другая – не выяснить, кто круче, а понять для самого себя – лежит ли инструмент в своей руке.

Для себя такую задачу я уже нашел. Но, думаю, у каждого она должна быть своей.

Отправить комментарий