Подтвердить что ты не робот

Если функциональные языки действительно кратки, почему бы им не получить лучший ранг в игре по перестрелке?

Я сравнивал языки на языке перестрелки только по размеру их кода. Вот краткое изложение того, что я получил (кратчайший сначала, сгруппированный по аналогичной оценке).

  • 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:

Я нашел проницательный пост на эту тему с графиками. Я также нашел аналогичное сравнение языков для более крупной программы (простой трассировщик лучей). В целом, я бы не сказал, что получил ответ "я", но у меня есть еда для размышлений.

4b9b3361

Ответ 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 более длинным и медленным), поэтому вы можете предположить, что все результаты были субъективно учтены специально для введения предвзятости.

В принципе, с такими данными низкого качества вы не можете надеяться сделать какие-либо проницательные выводы. Вам будет намного лучше искать более важные программы, которые были перенесены между языками, но даже тогда ваши результаты будут специфичными для домена. Я рекомендую забыть о перестрелке полностью...