Если функциональные языки действительно кратки, почему бы им не получить лучший ранг в игре по перестрелке?
Я сравнивал языки на языке перестрелки только по размеру их кода. Вот краткое изложение того, что я получил (кратчайший сначала, сгруппированный по аналогичной оценке).
- Python, Ruby, JavaScript, Perl, Lua, PHP, Mozart/OZ
- OCaml, Erlang, Racket, Go, Scala, F #, Smalltalk
- Pascal, Clean, Haskell, Common Lisp, С#, Java, C
- С++, Ada, ATS
Интересно, почему. Победители кажутся простыми старыми динамическими языками. Erlang, Racket (nE PLT Scheme) и F # работают нормально. Haskell и Common Lisp не выглядят более краткими, чем заявленная Java-версия.
UPDATE:
Я нашел проницательный пост на эту тему с графиками. Я также нашел аналогичное сравнение языков для более крупной программы (простой трассировщик лучей). В целом, я бы не сказал, что получил ответ "я", но у меня есть еда для размышлений.
Ответы
Ответ 1
- Язык не всегда превосходит другой (ну, есть несколько исключений...;)), так же относится и к группе широко классифицированных языков. Тесты охватывают широкий круг тем, и X может быть менее подходящим для одного, чем Y.
- Исходный код gzipped, мы действительно не знаем, сколько строк какой длины были программы (да, это индикатор)
- Значительное число функциональных языков все еще намного лучше, чем распространенные императивные, статические языки - это не то, что языки функционального программирования не кратки, но динамические языки допускают еще более сжатые программы.
- По крайней мере, в Haskell, большой потенциал для лаконичности исходит из абстракций, которые вы можете создать самостоятельно, но вам нужно их самостоятельно построить и включить в свое решение. Умелый хакер Haskell может реализовать монаду в 20 строках, что позволяет решить небольшую проблему в 20 строках вместо 30 - абстракция не окупается для небольшой программы, но может сэкономить много строк в более крупном (например, 200 строк вместо из 300). Я думаю, что то же самое применимо к Lisps (только макрос вместо монады)
- Не относитесь к поклонникам слишком серьезно. FP является удивительным и заслуживающим внимания, но он не вылечивает рак и не волшебным образом сокращает любой код на 25%.
- Они могут по-прежнему бить динамические языки для некоторых областей: например, древовидные структуры данных и их обработка выражаются чрезвычайно естественно во многих функциональных языках благодаря алгебраическим типам данных и сопоставлению шаблонов.
Ответ 2
Если функциональные языки действительно краткое...
1 - Программирование в целом отличается от программирования в малом.
Ничто в этих крошечных тестах игровых программ не должно восприниматься как пример того, как абстракции и модуляция, предоставляемые каждым языком, будут применяться к программированию в целом.
2 - Большая часть того, что вы видите на тестовых страницах тестов, относится только к самым быстрым программам, предоставляемым для каждой языковой реализации (медленные программы обычно удаляются с веб-сайта через некоторое время - когда и когда более медленные программы удаляются в основном произвольно).
{edit: Adam, так как вы не хотели бы смириться с этим, что итоговые страницы относятся только к самым быстрым программам - смотрите script, который фильтрует строки данных для "Какой язык программирования лучше?" стр. Посмотрите на строку 80 и строку 82 в функции ValidRowsAndMins в lib_scorecard.php - Alioth выдает собственный сертификат безопасности, поэтому ваш браузер будет жаловаться.}
Итак, чтобы взять Haskell в качестве примера, вы смотрите на размер кода самых быстрых программ Haskell, которые были внесены.
3 - Ни одна из программ метеорного конкурса не была удалена, а метеорный конкурс - конкурс без ограничений - самая маленькая программа метеорного конкурса Haskell - самая медленная программа Haskell по метеорному конкурсу.
Ответ 3
Это похоже на возможность выскочить:
Существуют ли статистические исследования, которые показывают, что Python является более продуктивным?
Суть в том, что исходный вопрос пытается использовать некоторые (ничтожные, несоответствующие) данные, чтобы сделать обобщение о сравнении между языками программирования. Но на самом деле почти невозможно использовать какие-либо данные для проведения каких-либо разумных общих количественных сравнений в языках программирования.
Вот немного пищи для размышлений:
- При прочих равных условиях динамически типизированные языки могут быть более краткими, поскольку им не нужно тратить время на описание типов данных.
- При прочих равных условиях между статически типизированными языками типы ввода-вывода могут быть более краткими, поскольку им не нужно декларировать типы по всему месту.
- При прочих равных условиях среди статически типизированных языков те, у которых с generics/templates, скорее всего, будут краткими, поскольку языки без них требуют повторного кода или отбрасываний и косвенности
- При всех равных языках языки с кратким синтаксисом лямбда, скорее всего, будут более краткими, поскольку лямбда, возможно, является самой важной абстракцией в программировании, чтобы избежать повторения и шаблона
Тем не менее, все вещи не равны, а не длинным выстрелом.
Ответ 4
Потому что некоторые алгоритмы более кратки, когда выражаются функционально, а другие алгоритмы более сжатые, когда они выражаются итеративно. Как правило, это зависит от того, насколько вы заинтересованы в отношениях между данными и текущим состоянием данных.
Также имейте в виду, что вы можете выполнять функциональное программирование на языках, таких как python, и программисты будут использовать FP на этих языках для части своей программы, где это будет более кратким или эффективным для этого, часто даже не зная, что они делают FP, В то время как с чистыми функциональными языками у вас нет возможности выполнять итеративное программирование в случаях, когда оно более кратким или эффективным.
Ответ 5
Программы в игре Alioth на самом деле не являются репрезентативными для программ на этих языках в целом. Во-первых, реализации там очень оптимизированы в отношении инфраструктуры Shootout, которая может привести к меньшему количеству идиоматического и более раздутого кода на функциональном языке. Это похоже на то, как некоторые библиотеки Ruby будут писать критически важный для кода код в C, чтобы посмотреть на этот код C и объявить Ruby для раздувания, а низкоуровневый действительно не даст языку справедливого тряска.
С другой стороны, значительная часть того, почему функциональные языки рекламируются как настолько краткие, состоит в том, что они умеют делать абстракции. Это, как правило, помогает в больших программах, чем в однофункциональных чудесах, поэтому языки, специально разработанные для легкой краткости, выигрывают там. Python, Perl и Ruby специально разработаны для коротких коротких программ, тогда как большинство функциональных языков имеют другие цели (хотя это не означает, что они просто игнорируют размер кода).
Ответ 6
Должно быть, что-то связано с обширными библиотеками OOP, доступными для большинства языков вашего уровня 1, и просто старыми хаками, такими как обратные вызовы для вызовов оболочки и синтаксиса relx perl. Отключение python
pw = file("/etc/passwd")
for l in pw:
print l.split(':')[0]
Печать всех имен пользователей в системе потребует гораздо больше кода, если бы не абстракции, которые были засорены языками OO. Я не говорю, что это невозможно сделать в других парадигмах, но тенденция состоит в том, что каждый тип имеет множество функций-членов, которые делают утомительные задачи простыми. Лично я считаю, что чисто функциональные языки полезны только для академических целей (но опять же, что я знаю).
Ответ 7
Вы должны учитывать тот факт, что языки вашей группы 1 (скрипты) в 30-100 раз медленнее, чем C/С++, поскольку функциональные языки одинаковы между 2 и 7 раз. Программы в списке оптимизированы для скорости и измерения чего-либо еще - это второстепенная проблема, которая на самом деле не является хорошим показателем реального состояния языка.
Интереснее посмотреть таблицу где размер и время выполнения каждого из них имеют вес 1. Таким образом вы получите сравнение скорости/коэффициент совместимости, который кажется лучшим показателем, чем просто размер кода.
Ответ 8
Недавно я портировал относительно короткую программу Java в OCaml. Я пробовал в SML и Haskell в прошлом, плюс обширный опыт работы с C.
В этом ответе я рассматриваю сравнение императива с чисто функциональным кодом (т.е. без мутаций). Если вы позволяете императивному коду проникнуть в другие функциональные программы, что вы сравниваете?
По моему опыту, чисто функциональное программирование (PFP) является элегантным, но не более кратким, чем императивным. В ПФП имеется меньше "деклараций", но больше "конверсионных" шаблонов; например, распаковывание из кортежей, хвостовые рекурсивные вспомогательные функции и т.д. Таким образом, ни парадигма не позволяет неограниченному выражению чистого "мяса" программы.
PFP имеет более низкие затраты на то, чтобы что-то запустить, и написав программу, чтобы продемонстрировать, что данный алгоритм работает в принципе хорошо в PFP. Но, увеличивая его, чтобы сделать его "реальным", имея дело с условиями ошибки, и незаконная диагностика ввода и печати добавляет много наворотов, которые легче перешли бы на императивном языке.
Ответ 9
Победители кажутся простыми старыми динамическими языками.
Lisp - очевидный пример встречного примера, являющийся простым старым динамическим языком, который является чрезвычайно многословным. С другой стороны, APL/J/K, вероятно, будет гораздо более кратким, чем любой другой язык, и они динамичны. Также Mathematica...
Haskell и Common Lisp не выглядят более краткими, чем заявленная Java-версия.
Ваши данные относятся к малым программам, которые были оптимизированы для производительности, а размер сжатия после сжатия с использованием алгоритма GZIP для определенного параметра, поэтому вы не можете делать общие выводы только из них. Возможно, более верный вывод заключается в том, что вы наблюдаете раздувание, которое возникает в результате оптимизации производительности, поэтому наиболее сжатые языки из ваших данных - это те, которые невозможно оптимизировать, поскольку они принципиально неэффективны (Python, Ruby, Javascript, Perl, Lua, PHP). И наоборот, Haskell может быть оптимизирован с достаточным усилием для создания быстрых, но подробных программ. Это действительно недостаток Haskell против Python? Еще один справедливый вывод заключается в том, что Python, Ruby, Perl, Lua и PHP лучше сжимаются с использованием алгоритма GZIP для этого параметра. Возможно, если вы повторите эксперимент с использованием кодирования во время выполнения или арифметического кодирования или LZ77/8, возможно, с предварительным условием BWT или другим алгоритмом вы получите совершенно разные результаты?
В коде на этом сайте также имеется огромное количество бесполезных трещин. Посмотрите на этот фрагмент кода OCaml, который необходим только в том случае, если ваша установка OCaml устарела на два поколения:
(* This module is a workaround for a bug in the Str library from the Ocaml
* distribution used in the Computer Language Benchmarks Game. It can be removed
* altogether when using OCaml 3.11 *)
module Str =
struct
include Str
let substitute_first expr repl_fun text =
try
let pos = Str.search_forward expr text 0 in
String.concat "" [Str.string_before text pos;
repl_fun text;
Str.string_after text (Str.match_end())]
with Not_found ->
text
let opt_search_forward re s pos =
try Some(Str.search_forward re s pos) with Not_found -> None
let global_substitute expr repl_fun text =
let rec replace accu start last_was_empty =
let startpos = if last_was_empty then start + 1 else start in
if startpos > String.length text then
Str.string_after text start :: accu
else
match opt_search_forward expr text startpos with
| None ->
Str.string_after text start :: accu
| Some pos ->
let end_pos = Str.match_end() in
let repl_text = repl_fun text in
replace (repl_text :: String.sub text start (pos-start) :: accu)
end_pos (end_pos = pos)
in
String.concat "" (List.rev (replace [] 0 false))
let global_replace expr repl text =
global_substitute expr (Str.replace_matched repl) text
and replace_first expr repl text =
substitute_first expr (Str.replace_matched repl) text
end
Одноядерные версии часто содержат много кода для parallelism, например. regex-dna в OCaml. Посмотрите на чудовище, которое fasta в OCaml: вся программа дублируется дважды, и она включает размер слова! У меня есть старая версия fastam на OCaml, которая меньше, чем пятая по размеру этого...
Наконец, я должен отметить, что я внесла код на этот сайт только для того, чтобы его отклонили, потому что он был слишком хорош. Политика в стороне, бинарные деревья OCaml использовали выражение "де-оптимизировано Исааком Гуи" (хотя комментарий был удален, деоптимизация по-прежнему там делает код OCaml более длинным и медленным), поэтому вы можете предположить, что все результаты были субъективно учтены специально для введения предвзятости.
В принципе, с такими данными низкого качества вы не можете надеяться сделать какие-либо проницательные выводы. Вам будет намного лучше искать более важные программы, которые были перенесены между языками, но даже тогда ваши результаты будут специфичными для домена. Я рекомендую забыть о перестрелке полностью...